clang: lib/CodeGen/Targets/ARM.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

10#include "TargetInfo.h"

11

12using namespace clang;

14

15

16

17

18

19namespace {

20

21class ARMABIInfo : public ABIInfo {

23 bool IsFloatABISoftFP;

24

25public:

26 ARMABIInfo(CodeGenTypes &CGT, ARMABIKind Kind) : ABIInfo(CGT), Kind(Kind) {

27 setCCs();

30 }

31

32 bool isEABI() const {

33 switch (getTarget().getTriple().getEnvironment()) {

34 case llvm::Triple::Android:

35 case llvm::Triple::EABI:

36 case llvm::Triple::EABIHF:

37 case llvm::Triple::GNUEABI:

38 case llvm::Triple::GNUEABIT64:

39 case llvm::Triple::GNUEABIHF:

40 case llvm::Triple::GNUEABIHFT64:

41 case llvm::Triple::MuslEABI:

42 case llvm::Triple::MuslEABIHF:

43 return true;

44 default:

45 return getTarget().getTriple().isOHOSFamily();

46 }

47 }

48

49 bool isEABIHF() const {

50 switch (getTarget().getTriple().getEnvironment()) {

51 case llvm::Triple::EABIHF:

52 case llvm::Triple::GNUEABIHF:

53 case llvm::Triple::GNUEABIHFT64:

54 case llvm::Triple::MuslEABIHF:

55 return true;

56 default:

57 return false;

58 }

59 }

60

61 ARMABIKind getABIKind() const { return Kind; }

62

63 bool allowBFloatArgsAndRet() const override {

64 return !IsFloatABISoftFP && getTarget().hasBFloat16Type();

65 }

66

67private:

69 unsigned functionCallConv) const;

71 unsigned functionCallConv) const;

72 ABIArgInfo classifyHomogeneousAggregate(QualType Ty, const Type *Base,

73 uint64_t Members) const;

74 bool shouldIgnoreEmptyArg(QualType Ty) const;

75 ABIArgInfo coerceIllegalVector(QualType Ty) const;

76 bool isIllegalVectorType(QualType Ty) const;

77 bool containsAnyFP16Vectors(QualType Ty) const;

78

79 bool isHomogeneousAggregateBaseType(QualType Ty) const override;

80 bool isHomogeneousAggregateSmallEnough(const Type *Ty,

81 uint64_t Members) const override;

82 bool isZeroLengthBitfieldPermittedInHomogeneousAggregate() const override;

83

84 bool isEffectivelyAAPCS_VFP(unsigned callConvention, bool acceptHalf) const;

85

86 void computeInfo(CGFunctionInfo &FI) const override;

87

88 RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,

89 AggValueSlot Slot) const override;

90

91 llvm::CallingConv::ID getLLVMDefaultCC() const;

92 llvm::CallingConv::ID getABIDefaultCC() const;

93 void setCCs();

94};

95

97public:

98 explicit ARMSwiftABIInfo(CodeGenTypes &CGT)

99 : SwiftABIInfo(CGT, true) {}

100

102 unsigned NumElts) const override;

103};

104

106public:

107 ARMTargetCodeGenInfo(CodeGenTypes &CGT, ARMABIKind K)

108 : TargetCodeGenInfo(std::make_unique(CGT, K)) {

109 SwiftInfo = std::make_unique(CGT);

110 }

111

112 int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override {

113 return 13;

114 }

115

116 StringRef getARCRetainAutoreleasedReturnValueMarker() const override {

117 return "mov\tr7, r7\t\t// marker for objc_retainAutoreleaseReturnValue";

118 }

119

120 bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,

121 llvm::Value *Address) const override {

122 llvm::Value *Four8 = llvm::ConstantInt::get(CGF.Int8Ty, 4);

123

124

126 return false;

127 }

128

129 unsigned getSizeOfUnwindException() const override {

130 if (getABIInfo().isEABI())

131 return 88;

133 }

134

135 void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,

136 CodeGen::CodeGenModule &CGM) const override {

137 auto *Fn = dyn_castllvm::Function(GV);

138 if (!Fn)

139 return;

140 const auto *FD = dyn_cast_or_null(D);

141

142 if (FD && FD->hasAttr()) {

143 const auto *TA = FD->getAttr();

144 ParsedTargetAttr Attr =

146 if (!Attr.BranchProtection.empty()) {

147 TargetInfo::BranchProtectionInfo BPI{};

148 StringRef DiagMsg;

149 StringRef Arch =

152 Attr.BranchProtection, Arch, BPI, CGM.getLangOpts(), DiagMsg)) {

155 diag::warn_target_unsupported_branch_protection_attribute)

157 } else

158 setBranchProtectionFnAttributes(BPI, (*Fn));

159 } else if (CGM.getLangOpts().BranchTargetEnforcement ||

161

162

163

167 diag::warn_target_unsupported_branch_protection_attribute)

168 << Attr.CPU;

169 }

172 TargetInfo::BranchProtectionInfo BPI(CGM.getLangOpts());

173 setBranchProtectionFnAttributes(BPI, (*Fn));

174 }

175

176 if (!FD || !FD->hasAttr())

177 return;

178

179 const ARMInterruptAttr *Attr = FD->getAttr();

180 const char *Kind;

181 switch (Attr->getInterrupt()) {

182 case ARMInterruptAttr::Generic: Kind = ""; break;

183 case ARMInterruptAttr::IRQ: Kind = "IRQ"; break;

184 case ARMInterruptAttr::FIQ: Kind = "FIQ"; break;

185 case ARMInterruptAttr::SWI: Kind = "SWI"; break;

186 case ARMInterruptAttr::ABORT: Kind = "ABORT"; break;

187 case ARMInterruptAttr::UNDEF: Kind = "UNDEF"; break;

188 }

189

190 Fn->addFnAttr("interrupt", Kind);

191

192

193

194 const ARMSaveFPAttr *SaveFPAttr = FD->getAttr();

195 if (SaveFPAttr)

196 Fn->addFnAttr("save-fp");

197

198 ARMABIKind ABI = getABIInfo().getABIKind();

199 if (ABI == ARMABIKind::APCS)

200 return;

201

202

203

204

205 llvm::AttrBuilder B(Fn->getContext());

206 B.addStackAlignmentAttr(8);

207 Fn->addFnAttrs(B);

208 }

209};

210

211class WindowsARMTargetCodeGenInfo : public ARMTargetCodeGenInfo {

212public:

213 WindowsARMTargetCodeGenInfo(CodeGenTypes &CGT, ARMABIKind K)

214 : ARMTargetCodeGenInfo(CGT, K) {}

215

216 void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,

217 CodeGen::CodeGenModule &CGM) const override;

218

219 void getDependentLibraryOption(llvm::StringRef Lib,

220 llvm::SmallString<24> &Opt) const override {

221 Opt = "/DEFAULTLIB:" + qualifyWindowsLibrary(Lib);

222 }

223

224 void getDetectMismatchOption(llvm::StringRef Name, llvm::StringRef Value,

225 llvm::SmallString<32> &Opt) const override {

226 Opt = "/FAILIFMISMATCH:\"" + Name.str() + "=" + Value.str() + "\"";

227 }

228};

229

230void WindowsARMTargetCodeGenInfo::setTargetAttributes(

232 ARMTargetCodeGenInfo::setTargetAttributes(D, GV, CGM);

233 if (GV->isDeclaration())

234 return;

235 addStackProbeTargetAttributes(D, GV, CGM);

236}

237}

238

239void ARMABIInfo::computeInfo(CGFunctionInfo &FI) const {

243

247

248

249

251 return;

252

253 llvm::CallingConv::ID cc = getRuntimeCC();

254 if (cc != llvm::CallingConv::C)

256}

257

258

259llvm::CallingConv::ID ARMABIInfo::getLLVMDefaultCC() const {

260

261 if (isEABIHF() || getTarget().getTriple().isWatchABI())

262 return llvm::CallingConv::ARM_AAPCS_VFP;

263 else if (isEABI())

264 return llvm::CallingConv::ARM_AAPCS;

265 else

266 return llvm::CallingConv::ARM_APCS;

267}

268

269

270

271llvm::CallingConv::ID ARMABIInfo::getABIDefaultCC() const {

272 switch (getABIKind()) {

273 case ARMABIKind::APCS:

274 return llvm::CallingConv::ARM_APCS;

275 case ARMABIKind::AAPCS:

276 return llvm::CallingConv::ARM_AAPCS;

277 case ARMABIKind::AAPCS_VFP:

278 return llvm::CallingConv::ARM_AAPCS_VFP;

279 case ARMABIKind::AAPCS16_VFP:

280 return llvm::CallingConv::ARM_AAPCS_VFP;

281 }

282 llvm_unreachable("bad ABI kind");

283}

284

285void ARMABIInfo::setCCs() {

286 assert(getRuntimeCC() == llvm::CallingConv::C);

287

288

289

290 llvm::CallingConv::ID abiCC = getABIDefaultCC();

291 if (abiCC != getLLVMDefaultCC())

292 RuntimeCC = abiCC;

293}

294

295ABIArgInfo ARMABIInfo::coerceIllegalVector(QualType Ty) const {

296 uint64_t Size = getContext().getTypeSize(Ty);

297 if (Size <= 32) {

298 llvm::Type *ResType =

299 llvm::Type::getInt32Ty(getVMContext());

301 }

302 if (Size == 64 || Size == 128) {

303 auto *ResType = llvm::FixedVectorType::get(

304 llvm::Type::getInt32Ty(getVMContext()), Size / 32);

306 }

307 return getNaturalAlignIndirect(

308 Ty, getDataLayout().getAllocaAddrSpace(),

309 false);

310}

311

312ABIArgInfo ARMABIInfo::classifyHomogeneousAggregate(QualType Ty,

313 const Type *Base,

314 uint64_t Members) const {

315 assert(Base && "Base class should be set for homogeneous aggregate");

316

317 if (const VectorType *VT = Base->getAs()) {

318

319 if (!getTarget().hasFastHalfType() && containsAnyFP16Vectors(Ty)) {

320 uint64_t Size = getContext().getTypeSize(VT);

321 auto *NewVecTy = llvm::FixedVectorType::get(

322 llvm::Type::getInt32Ty(getVMContext()), Size / 32);

323 llvm::Type *Ty = llvm::ArrayType::get(NewVecTy, Members);

325 }

326 }

327 unsigned Align = 0;

328 if (getABIKind() == ARMABIKind::AAPCS ||

329 getABIKind() == ARMABIKind::AAPCS_VFP) {

330

331

332 Align = getContext().getTypeUnadjustedAlignInChars(Ty).getQuantity();

333 unsigned BaseAlign = getContext().getTypeAlignInChars(Base).getQuantity();

334 Align = (Align > BaseAlign && Align >= 8) ? 8 : 0;

335 }

337}

338

339bool ARMABIInfo::shouldIgnoreEmptyArg(QualType Ty) const {

340 uint64_t Size = getContext().getTypeSize(Ty);

341 assert((isEmptyRecord(getContext(), Ty, true) || Size == 0) &&

342 "Arg is not empty");

343

344

345 if (!getContext().getLangOpts().CPlusPlus ||

346 getABIKind() == ARMABIKind::AAPCS16_VFP)

347 return true;

348

349

350

351

352 if (Size == 0)

353 return true;

354

355

356 if (getContext().getLangOpts().getClangABICompat() <=

357 LangOptions::ClangABI::Ver19)

358 return true;

359

360

361 return false;

362}

363

364ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty, bool isVariadic,

365 unsigned functionCallConv) const {

366

367

368

369

370

371

372

373

374 bool IsAAPCS_VFP =

375 !isVariadic && isEffectivelyAAPCS_VFP(functionCallConv, false);

376

378

379

380 if (isIllegalVectorType(Ty))

381 return coerceIllegalVector(Ty);

382

384

386 Ty = ED->getIntegerType();

387 }

388

389 if (const auto *EIT = Ty->getAs())

390 if (EIT->getNumBits() > 64)

391 return getNaturalAlignIndirect(

392 Ty, getDataLayout().getAllocaAddrSpace(),

393 true);

394

395 return (isPromotableIntegerTypeForABI(Ty)

398 }

399

401 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),

403 }

404

405

406

408 getContext().getTypeSize(Ty) == 0) {

409 if (shouldIgnoreEmptyArg(Ty))

411 else

413 }

414

415 if (IsAAPCS_VFP) {

416

417

420 if (isHomogeneousAggregate(Ty, Base, Members))

421 return classifyHomogeneousAggregate(Ty, Base, Members);

422 } else if (getABIKind() == ARMABIKind::AAPCS16_VFP) {

423

424

425

428 if (isHomogeneousAggregate(Ty, Base, Members)) {

429 assert(Base && Members <= 4 && "unexpected homogeneous aggregate");

430 llvm::Type *Ty =

431 llvm::ArrayType::get(CGT.ConvertType(QualType(Base, 0)), Members);

433 }

434 }

435

436 if (getABIKind() == ARMABIKind::AAPCS16_VFP &&

438

439

440

443 getDataLayout().getAllocaAddrSpace(), false);

444 }

445

446

447

448

449

452 if (getABIKind() == ARMABIKind::AAPCS_VFP ||

453 getABIKind() == ARMABIKind::AAPCS) {

454 TyAlign = getContext().getTypeUnadjustedAlignInChars(Ty).getQuantity();

455 ABIAlign = std::clamp(TyAlign, (uint64_t)4, (uint64_t)8);

456 } else {

457 TyAlign = getContext().getTypeAlignInChars(Ty).getQuantity();

458 }

460 assert(getABIKind() != ARMABIKind::AAPCS16_VFP && "unexpected byval");

463 getDataLayout().getAllocaAddrSpace(),

464 true, TyAlign > ABIAlign);

465 }

466

467

468 llvm::Type* ElemTy;

469 unsigned SizeRegs;

470

471

472 if (TyAlign <= 4) {

473 ElemTy = llvm::Type::getInt32Ty(getVMContext());

474 SizeRegs = (getContext().getTypeSize(Ty) + 31) / 32;

475 } else {

476 ElemTy = llvm::Type::getInt64Ty(getVMContext());

477 SizeRegs = (getContext().getTypeSize(Ty) + 63) / 64;

478 }

479

481}

482

484 llvm::LLVMContext &VMContext) {

485

486

487

488

489 uint64_t Size = Context.getTypeSize(Ty);

490

491

492 if (Size > 32)

493 return false;

494

495

497 return false;

498

499

501 return false;

502

503

505 return true;

506

507

509 return isIntegerLikeType(CT->getElementType(), Context, VMContext);

510

511

512

513

514

515 const RecordType *RT = Ty->getAsCanonical();

516 if (!RT) return false;

517

518

519 const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf();

521 return false;

522

523

524

525 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);

526

527 bool HadField = false;

528 unsigned idx = 0;

530 i != e; ++i, ++idx) {

532

533

534

535

536

539 HadField = true;

540

542 return false;

543

544 continue;

545 }

546

547

549 return false;

550

552 return false;

553

554

555

556

558 if (HadField)

559 return false;

560

561 HadField = true;

562 }

563 }

564

565 return true;

566}

567

568ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy, bool isVariadic,

569 unsigned functionCallConv) const {

570

571

572 bool IsAAPCS_VFP =

573 !isVariadic && isEffectivelyAAPCS_VFP(functionCallConv, true);

574

577

578 if (const VectorType *VT = RetTy->getAs()) {

579

580 if (getContext().getTypeSize(RetTy) > 128)

581 return getNaturalAlignIndirect(RetTy,

582 getDataLayout().getAllocaAddrSpace());

583

584

585 if ((!getTarget().hasFastHalfType() &&

586 (VT->getElementType()->isFloat16Type() ||

587 VT->getElementType()->isHalfType())) ||

588 (IsFloatABISoftFP &&

589 VT->getElementType()->isBFloat16Type()))

590 return coerceIllegalVector(RetTy);

591 }

592

594

596 RetTy = ED->getIntegerType();

597

598 if (const auto *EIT = RetTy->getAs())

599 if (EIT->getNumBits() > 64)

600 return getNaturalAlignIndirect(

601 RetTy, getDataLayout().getAllocaAddrSpace(),

602 false);

603

605 : ABIArgInfo::getDirect();

606 }

607

608

609 if (getABIKind() == ARMABIKind::APCS) {

612

613

614

615

616

619 getVMContext(), getContext().getTypeSize(RetTy)));

620

621

623

624 uint64_t Size = getContext().getTypeSize(RetTy);

625 if (Size <= 8)

627 if (Size <= 16)

630 }

631

632

633 return getNaturalAlignIndirect(RetTy, getDataLayout().getAllocaAddrSpace());

634 }

635

636

637

639 getContext().getTypeSize(RetTy) == 0)

641

642

643 if (IsAAPCS_VFP) {

646 if (isHomogeneousAggregate(RetTy, Base, Members))

647 return classifyHomogeneousAggregate(RetTy, Base, Members);

648 }

649

650

651

652 uint64_t Size = getContext().getTypeSize(RetTy);

653 if (Size <= 32) {

654 if (getDataLayout().isBigEndian())

655

657

658

659 if (Size <= 8)

661 if (Size <= 16)

664 } else if (Size <= 128 && getABIKind() == ARMABIKind::AAPCS16_VFP) {

665 llvm::Type *Int32Ty = llvm::Type::getInt32Ty(getVMContext());

666 llvm::Type *CoerceTy =

667 llvm::ArrayType::get(Int32Ty, llvm::alignTo(Size, 32) / 32);

669 }

670

671 return getNaturalAlignIndirect(RetTy, getDataLayout().getAllocaAddrSpace());

672}

673

674

675bool ARMABIInfo::isIllegalVectorType(QualType Ty) const {

676 if (const VectorType *VT = Ty->getAs ()) {

677

678

679

680

681

682

683 if ((!getTarget().hasFastHalfType() &&

684 (VT->getElementType()->isFloat16Type() ||

685 VT->getElementType()->isHalfType())) ||

686 (IsFloatABISoftFP &&

687 VT->getElementType()->isBFloat16Type()))

688 return true;

689 if (isAndroid()) {

690

691

692

693

694

695 unsigned NumElements = VT->getNumElements();

696

697 if (!llvm::isPowerOf2_32(NumElements) && NumElements != 3)

698 return true;

699 } else {

700

701 unsigned NumElements = VT->getNumElements();

702 uint64_t Size = getContext().getTypeSize(VT);

703

704 if (!llvm::isPowerOf2_32(NumElements))

705 return true;

706

707 return Size <= 32;

708 }

709 }

710 return false;

711}

712

713

714bool ARMABIInfo::containsAnyFP16Vectors(QualType Ty) const {

715 if (const ConstantArrayType *AT = getContext().getAsConstantArrayType(Ty)) {

716 uint64_t NElements = AT->getZExtSize();

717 if (NElements == 0)

718 return false;

719 return containsAnyFP16Vectors(AT->getElementType());

720 }

722

723 if (const CXXRecordDecl *CXXRD = dyn_cast(RD))

724 if (llvm::any_of(CXXRD->bases(), [this](const CXXBaseSpecifier &B) {

725 return containsAnyFP16Vectors(B.getType());

726 }))

727 return true;

728

729 if (llvm::any_of(RD->fields(), [this](FieldDecl *FD) {

730 return FD && containsAnyFP16Vectors(FD->getType());

731 }))

732 return true;

733

734 return false;

735 } else {

736 if (const VectorType *VT = Ty->getAs())

737 return (VT->getElementType()->isFloat16Type() ||

738 VT->getElementType()->isBFloat16Type() ||

739 VT->getElementType()->isHalfType());

740 return false;

741 }

742}

743

744bool ARMSwiftABIInfo::isLegalVectorType(CharUnits VectorSize, llvm::Type *EltTy,

745 unsigned NumElts) const {

746 if (!llvm::isPowerOf2_32(NumElts))

747 return false;

748 unsigned size = CGT.getDataLayout().getTypeStoreSizeInBits(EltTy);

749 if (size > 64)

750 return false;

752 (VectorSize.getQuantity() != 16 || NumElts == 1))

753 return false;

754 return true;

755}

756

757bool ARMABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const {

758

759

760 if (const BuiltinType *BT = Ty->getAs()) {

761 if (BT->getKind() == BuiltinType::Float ||

762 BT->getKind() == BuiltinType::Double ||

763 BT->getKind() == BuiltinType::LongDouble)

764 return true;

765 } else if (const VectorType *VT = Ty->getAs()) {

766 unsigned VecSize = getContext().getTypeSize(VT);

767 if (VecSize == 64 || VecSize == 128)

768 return true;

769 }

770 return false;

771}

772

773bool ARMABIInfo::isHomogeneousAggregateSmallEnough(const Type *Base,

774 uint64_t Members) const {

775 return Members <= 4;

776}

777

778bool ARMABIInfo::isZeroLengthBitfieldPermittedInHomogeneousAggregate() const {

779

780

781

782

783

784 return true;

785}

786

787bool ARMABIInfo::isEffectivelyAAPCS_VFP(unsigned callConvention,

788 bool acceptHalf) const {

789

790 if (callConvention != llvm::CallingConv::C)

791 return (callConvention == llvm::CallingConv::ARM_AAPCS_VFP);

792 else

793 return (getABIKind() == ARMABIKind::AAPCS_VFP) ||

794 (acceptHalf && (getABIKind() == ARMABIKind::AAPCS16_VFP));

795}

796

797RValue ARMABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,

798 QualType Ty, AggValueSlot Slot) const {

800

801

802 uint64_t Size = getContext().getTypeSize(Ty);

803 bool IsEmpty = isEmptyRecord(getContext(), Ty, true);

804 if ((IsEmpty || Size == 0) && shouldIgnoreEmptyArg(Ty))

806

807 CharUnits TySize = getContext().getTypeSizeInChars(Ty);

808 CharUnits TyAlignForABI = getContext().getTypeUnadjustedAlignInChars(Ty);

809

810

811 bool IsIndirect = false;

815 IsIndirect = true;

816

817

818

820 getABIKind() == ARMABIKind::AAPCS16_VFP &&

821 !isHomogeneousAggregate(Ty, Base, Members)) {

822 IsIndirect = true;

823

824

825

826

827

828 } else if (getABIKind() == ARMABIKind::AAPCS_VFP ||

829 getABIKind() == ARMABIKind::AAPCS) {

832 } else if (getABIKind() == ARMABIKind::AAPCS16_VFP) {

833

836 } else {

838 }

839

840 TypeInfoChars TyInfo(TySize, TyAlignForABI, AlignRequirementKind::None);

841 return emitVoidPtrVAArg(CGF, VAListAddr, Ty, IsIndirect, TyInfo, SlotSize,

842 true, Slot);

843}

844

845std::unique_ptr

847 return std::make_unique(CGM.getTypes(), Kind);

848}

849

850std::unique_ptr

852 return std::make_unique(CGM.getTypes(), K);

853}

static bool isIntegerLikeType(QualType Ty, ASTContext &Context, llvm::LLVMContext &VMContext)

Definition ARM.cpp:483

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...

uint64_t getFieldOffset(unsigned FieldNo) const

getFieldOffset - Get the offset of the given field index, in bits.

This class is used for builtin types like 'int'.

QuantityType getQuantity() const

getQuantity - Get the raw integer representation of this quantity.

static CharUnits fromQuantity(QuantityType Quantity)

fromQuantity - Construct a CharUnits quantity from a raw integer type.

std::string FloatABI

The ABI to use for passing floating point arguments.

static ABIArgInfo getIgnore()

static ABIArgInfo getDirect(llvm::Type *T=nullptr, unsigned Offset=0, llvm::Type *Padding=nullptr, bool CanBeFlattened=true, unsigned Align=0)

static ABIArgInfo getIndirect(CharUnits Alignment, unsigned AddrSpace, bool ByVal=true, bool Realign=false, llvm::Type *Padding=nullptr)

static ABIArgInfo getExtend(QualType Ty, llvm::Type *T=nullptr)

ABIInfo - Target specific hooks for defining how a type should be passed or returned from functions.

RecordArgABI

Specify how one should pass an argument of a record type.

@ RAA_DirectInMemory

Pass it on the stack using its defined layout.

ABIArgInfo & getReturnInfo()

unsigned getCallingConvention() const

getCallingConvention - Return the user specified calling convention, which has been translated into a...

CanQualType getReturnType() const

MutableArrayRef< ArgInfo > arguments()

void setEffectiveCallingConvention(unsigned Value)

This class organizes the cross-function state that is used while generating LLVM code.

DiagnosticsEngine & getDiags() const

const LangOptions & getLangOpts() const

CodeGenTypes & getTypes()

const TargetInfo & getTarget() const

llvm::Type * ConvertType(QualType T)

ConvertType - Convert type T into a llvm::Type.

const CodeGenOptions & getCodeGenOpts() const

const llvm::DataLayout & getDataLayout() const

Target specific hooks for defining how a type should be passed or returned from functions with one of...

TargetCodeGenInfo - This class organizes various target-specific codegeneration issues,...

virtual unsigned getSizeOfUnwindException() const

Determines the size of struct _Unwind_Exception on this platform, in 8-bit units.

Complex values, per C99 6.2.5p11.

Decl - This represents one declaration (or definition), e.g.

SourceLocation getLocation() const

DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)

Issue the message to the client.

Represents a member of a struct/union/class.

bool isBitField() const

Determines whether this field is a bitfield.

bool hasSignReturnAddress() const

Check if return address signing is enabled.

A (possibly-)qualified type.

Represents a struct/union/class.

bool hasFlexibleArrayMember() const

field_iterator field_end() const

specific_decl_iterator< FieldDecl > field_iterator

field_iterator field_begin() const

TargetOptions & getTargetOpts() const

Retrieve the target options.

virtual bool isBranchProtectionSupportedArch(StringRef Arch) const

Determine if the Architecture in this TargetInfo supports branch protection.

virtual bool validateBranchProtection(StringRef Spec, StringRef Arch, BranchProtectionInfo &BPI, const LangOptions &LO, StringRef &Err) const

Determine if this TargetInfo supports the given branch protection specification.

virtual ParsedTargetAttr parseTargetAttr(StringRef Str) const

std::string CPU

If given, the name of the target CPU to generate code for.

RecordDecl * getAsRecordDecl() const

Retrieves the RecordDecl this type refers to.

bool isPointerType() const

bool isAnyComplexType() const

EnumDecl * getAsEnumDecl() const

Retrieves the EnumDecl this type refers to.

bool isVectorType() const

bool isRealFloatingType() const

Floating point categories.

const T * getAsCanonical() const

If this type is canonically the specified type, return its canonical type cast to that specified type...

const T * getAs() const

Member-template getAs'.

ABIArgInfo classifyArgumentType(CodeGenModule &CGM, CanQualType type)

Classify the rules for how to pass a particular type.

bool isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize, llvm::VectorType *vectorTy)

Is the given vector type "legal" for Swift's perspective on the current platform?

std::unique_ptr< TargetCodeGenInfo > createARMTargetCodeGenInfo(CodeGenModule &CGM, ARMABIKind Kind)

Definition ARM.cpp:846

@ Decl

The l-value was an access to a declared entity or something equivalently strong, like the address of ...

CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI)

bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, const ABIInfo &Info)

RValue emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType ValueTy, bool IsIndirect, TypeInfoChars ValueInfo, CharUnits SlotSizeAndAlign, bool AllowHigherAlign, AggValueSlot Slot, bool ForceRightAdjust=false)

Emit va_arg for a platform using the common void* representation, where arguments are simply emitted ...

bool isAggregateTypeForABI(QualType T)

std::unique_ptr< TargetCodeGenInfo > createWindowsARMTargetCodeGenInfo(CodeGenModule &CGM, ARMABIKind K)

Definition ARM.cpp:851

void AssignToArrayRange(CodeGen::CGBuilderTy &Builder, llvm::Value *Array, llvm::Value *Value, unsigned FirstIndex, unsigned LastIndex)

QualType useFirstFieldIfTransparentUnion(QualType Ty)

Pass transparent unions as if they were the type of the first element.

bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays, bool AsIfNoUniqueAddr=false)

isEmptyRecord - Return true iff a structure contains only empty fields.

The JSON file list parser is used to communicate input to InstallAPI.

@ Type

The name was classified as a type.

llvm::IntegerType * Int8Ty

i8, i16, i32, and i64