clang: include/clang/CodeGen/CGFunctionInfo.h Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15#ifndef LLVM_CLANG_CODEGEN_CGFUNCTIONINFO_H

16#define LLVM_CLANG_CODEGEN_CGFUNCTIONINFO_H

17

22#include "llvm/IR/DerivedTypes.h"

23#include "llvm/ADT/FoldingSet.h"

24#include "llvm/Support/TrailingObjects.h"

25#include

26

28namespace CodeGen {

29

30

31

33public:

35

36

37

38

39

40

42

43

44

46

47

48

50

51

52

53

54

55

56

57

58

59

60

61

63

64

65

67

68

69

70

71

73

74

75

76

77

79

80

81

82

83

84

89

90private:

91 llvm::Type *TypeData;

92 union {

95 };

96 struct DirectAttrInfo {

97 unsigned Offset;

98 unsigned Align;

99 };

100 struct IndirectAttrInfo {

101 unsigned Align;

102 unsigned AddrSpace;

103 };

104 union {

105 DirectAttrInfo DirectAttr;

108 };

109 Kind TheKind;

110 bool PaddingInReg : 1;

111 bool InAllocaSRet : 1;

112 bool InAllocaIndirect : 1;

113 bool IndirectByVal : 1;

114 bool IndirectRealign : 1;

115 bool SRetAfterThis : 1;

116 bool InReg : 1;

117 bool CanBeFlattened: 1;

118 bool SignExt : 1;

119 bool ZeroExt : 1;

120

121 bool canHavePaddingType() const {

124 }

125 void setPaddingType(llvm::Type *T) {

126 assert(canHavePaddingType());

128 }

129

130 void setUnpaddedCoerceToType(llvm::Type *T) {

133 }

134

135public:

138 PaddingInReg(false), InAllocaSRet(false),

139 InAllocaIndirect(false), IndirectByVal(false), IndirectRealign(false),

140 SRetAfterThis(false), InReg(false), CanBeFlattened(false),

142

144 llvm::Type *Padding = nullptr,

145 bool CanBeFlattened = true, unsigned Align = 0) {

147 AI.setCoerceToType(T);

148 AI.setPaddingType(Padding);

149 AI.setDirectOffset(Offset);

150 AI.setDirectAlign(Align);

151 AI.setCanBeFlattened(CanBeFlattened);

152 return AI;

153 }

156 AI.setInReg(true);

157 return AI;

158 }

159

163 AI.setCoerceToType(T);

164 AI.setPaddingType(nullptr);

165 AI.setDirectOffset(0);

166 AI.setDirectAlign(0);

167 AI.setSignExt(true);

168 return AI;

169 }

170

174 AI.setCoerceToType(T);

175 AI.setPaddingType(nullptr);

176 AI.setDirectOffset(0);

177 AI.setDirectAlign(0);

178 AI.setZeroExt(true);

179 return AI;

180 }

181

182

183

189 }

190

191

194 AI.setCoerceToType(T);

195 AI.setPaddingType(nullptr);

196 AI.setDirectOffset(0);

197 AI.setDirectAlign(0);

198 return AI;

199 }

200

203 AI.setInReg(true);

204 return AI;

205 }

208 }

210 bool Realign = false,

211 llvm::Type *Padding = nullptr) {

213 AI.setIndirectAlign(Alignment);

214 AI.setIndirectByVal(ByVal);

215 AI.setIndirectRealign(Realign);

216 AI.setSRetAfterThis(false);

217 AI.setPaddingType(Padding);

218 return AI;

219 }

220

221

223 bool Realign = false,

224 llvm::Type *Padding = nullptr) {

226 AI.setIndirectAlign(Alignment);

227 AI.setIndirectRealign(Realign);

228 AI.setPaddingType(Padding);

229 AI.setIndirectAddrSpace(AddrSpace);

230 return AI;

231 }

232

234 bool Realign = false) {

235 auto AI = getIndirect(Alignment, ByVal, Realign);

236 AI.setInReg(true);

237 return AI;

238 }

241 AI.setInAllocaFieldIndex(FieldIndex);

242 AI.setInAllocaIndirect(Indirect);

243 return AI;

244 }

247 AI.setPaddingType(nullptr);

248 return AI;

249 }

251 llvm::Type *Padding) {

253 AI.setPaddingInReg(PaddingInReg);

254 AI.setPaddingType(Padding);

255 return AI;

256 }

257

258

259

260

262 llvm::Type *unpaddedCoerceToType) {

263#ifndef NDEBUG

264

265

266

267 auto unpaddedStruct = dyn_castllvm::StructType(unpaddedCoerceToType);

268 assert(!unpaddedStruct || unpaddedStruct->getNumElements() != 1);

269

270

271

272 unsigned unpaddedIndex = 0;

273 for (auto eltType : coerceToType->elements()) {

275 continue;

276 unpaddedIndex++;

277 }

278

279

280 if (unpaddedStruct) {

281 assert(unpaddedStruct->getNumElements() == unpaddedIndex);

282 } else {

283 assert(unpaddedIndex == 1);

284 }

285#endif

286

288 AI.setCoerceToType(coerceToType);

289 AI.setUnpaddedCoerceToType(unpaddedCoerceToType);

290 return AI;

291 }

292

294 return eltType->isArrayTy() &&

295 eltType->getArrayElementType()->isIntegerTy(8);

296 }

297

307

310 }

311

312

314 assert((isDirect() || isExtend()) && "Not a direct or extend kind");

316 }

318 assert((isDirect() || isExtend()) && "Not a direct or extend kind");

320 }

321

323 assert((isDirect() || isExtend()) && "Not a direct or extend kind");

325 }

327 assert((isDirect() || isExtend()) && "Not a direct or extend kind");

329 }

330

332 assert(isExtend() && (SignExt + ZeroExt <= 1) && "Invalid kind / flags!");

333 return SignExt;

334 }

336 assert(isExtend() && "Invalid kind!");

337 SignExt = SExt;

338 }

339

341 assert(isExtend() && (SignExt + ZeroExt <= 1) && "Invalid kind / flags!");

342 return ZeroExt;

343 }

345 assert(isExtend() && "Invalid kind!");

346 ZeroExt = ZExt;

347 }

348

350 assert(isExtend() && (SignExt + ZeroExt <= 1) && "Invalid kind / flags!");

351 return !SignExt && !ZeroExt;

352 }

353

355 return (canHavePaddingType() ? PaddingType : nullptr);

356 }

357

359 return PaddingInReg;

360 }

362 PaddingInReg = PIR;

363 }

364

367 return TypeData;

368 }

369

372 TypeData = T;

373 }

374

377 return castllvm::StructType(TypeData);

378 }

379

383 }

384

387 if (auto structTy =

389 return structTy->elements();

390 } else {

392 }

393 }

394

397 return InReg;

398 }

399

402 InReg = IR;

403 }

404

405

409 }

413 }

414

416 assert(isIndirect() && "Invalid kind!");

417 return IndirectByVal;

418 }

420 assert(isIndirect() && "Invalid kind!");

421 IndirectByVal = IBV;

422 }

423

427 }

428

432 }

433

436 return IndirectRealign;

437 }

440 IndirectRealign = IR;

441 }

442

444 assert(isIndirect() && "Invalid kind!");

445 return SRetAfterThis;

446 }

448 assert(isIndirect() && "Invalid kind!");

449 SRetAfterThis = AfterThis;

450 }

451

453 assert(isInAlloca() && "Invalid kind!");

455 }

457 assert(isInAlloca() && "Invalid kind!");

459 }

460

462 assert(isInAlloca() && "Invalid kind!");

463 return InAllocaIndirect;

464 }

466 assert(isInAlloca() && "Invalid kind!");

468 }

469

470

471

473 assert(isInAlloca() && "Invalid kind!");

474 return InAllocaSRet;

475 }

476

478 assert(isInAlloca() && "Invalid kind!");

479 InAllocaSRet = SRet;

480 }

481

483 assert(isDirect() && "Invalid kind!");

484 return CanBeFlattened;

485 }

486

488 assert(isDirect() && "Invalid kind!");

489 CanBeFlattened = Flatten;

490 }

491

492 void dump() const;

493};

494

495

496

498

499

500 unsigned NumRequired;

501public:

503

506 assert(n != ~0U);

507 }

508

509

510

511

512

513

515 unsigned additional) {

517

519 additional += llvm::count_if(

522 return ExtInfo.hasPassObjectSize();

523 });

524

526 }

527

529 unsigned additional) {

531 }

532

535 }

536

539 }

540

544 return NumRequired;

545 }

546

547

549 return argIdx == ~0U || argIdx < NumRequired;

550 }

551

554 if (value == ~0U) return All;

556 }

557};

558

559

560

564};

565

566

567

569 : public llvm::FoldingSetNode,

570 private llvm::TrailingObjects<CGFunctionInfo, CGFunctionInfoArgInfo,

571 FunctionProtoType::ExtParameterInfo> {

574

575

576

577 unsigned CallingConvention : 8;

578

579

580

581 unsigned EffectiveCallingConvention : 8;

582

583

585 unsigned ASTCallingConvention : 6;

586

587

588 LLVM_PREFERRED_TYPE(bool)

589 unsigned InstanceMethod : 1;

590

591

592 LLVM_PREFERRED_TYPE(bool)

593 unsigned ChainCall : 1;

594

595

596

597 LLVM_PREFERRED_TYPE(bool)

598 unsigned DelegateCall : 1;

599

600

601 LLVM_PREFERRED_TYPE(bool)

602 unsigned CmseNSCall : 1;

603

604

605 LLVM_PREFERRED_TYPE(bool)

606 unsigned NoReturn : 1;

607

608

609 LLVM_PREFERRED_TYPE(bool)

610 unsigned ReturnsRetained : 1;

611

612

613 LLVM_PREFERRED_TYPE(bool)

614 unsigned NoCallerSavedRegs : 1;

615

616

617 LLVM_PREFERRED_TYPE(bool)

618 unsigned HasRegParm : 1;

619 unsigned RegParm : 3;

620

621

622 LLVM_PREFERRED_TYPE(bool)

623 unsigned NoCfCheck : 1;

624

625

626 unsigned MaxVectorWidth : 4;

627

629

630

631

632 llvm::StructType *ArgStruct;

633 unsigned ArgStructAlign : 31;

634 LLVM_PREFERRED_TYPE(bool)

635 unsigned HasExtParameterInfos : 1;

636

637 unsigned NumArgs;

638

639 ArgInfo *getArgsBuffer() {

640 return getTrailingObjects();

641 }

642 const ArgInfo *getArgsBuffer() const {

643 return getTrailingObjects();

644 }

645

647 return getTrailingObjects();

648 }

650 return getTrailingObjects();

651 }

652

654

655public:

657 create(unsigned llvmCC, bool instanceMethod, bool chainCall,

661 void operator delete(void *p) { ::operator delete(p); }

662

663

664

667 return NumArgs + 1;

668 }

670 return (HasExtParameterInfos ? NumArgs : 0);

671 }

672

675

678 }

681 }

682

687

688 unsigned arg_size() const { return NumArgs; }

689

694 }

695

697

699

701

703

705

706

707

709

710

712

713

715

716

717

719 return CallingConv(ASTCallingConvention);

720 }

721

722

723

725

726

727

729 return EffectiveCallingConvention;

730 }

732 EffectiveCallingConvention = Value;

733 }

734

737

743 }

744

746

749

751 if (!HasExtParameterInfos) return {};

752 return llvm::ArrayRef(getExtParameterInfosBuffer(), NumArgs);

753 }

755 assert(argIndex <= NumArgs);

758 }

759

760

762

763

764 llvm::StructType *getArgStruct() const { return ArgStruct; }

767 }

769 ArgStruct = Ty;

771 }

772

773

775 return MaxVectorWidth ? 1U << (MaxVectorWidth - 1) : 0;

776 }

777

778

780 assert(llvm::isPowerOf2_32(Width) && "Expected power of 2 vector");

781 MaxVectorWidth = llvm::countr_zero(Width) + 1;

782 }

783

786 ID.AddBoolean(InstanceMethod);

787 ID.AddBoolean(ChainCall);

788 ID.AddBoolean(DelegateCall);

789 ID.AddBoolean(NoReturn);

790 ID.AddBoolean(ReturnsRetained);

791 ID.AddBoolean(NoCallerSavedRegs);

792 ID.AddBoolean(HasRegParm);

793 ID.AddInteger(RegParm);

794 ID.AddBoolean(NoCfCheck);

795 ID.AddBoolean(CmseNSCall);

796 ID.AddInteger(Required.getOpaqueData());

797 ID.AddBoolean(HasExtParameterInfos);

798 if (HasExtParameterInfos) {

800 ID.AddInteger(paramInfo.getOpaqueValue());

801 }

803 for (const auto &I : arguments())

804 I.type.Profile(ID);

805 }

806 static void Profile(llvm::FoldingSetNodeID &ID, bool InstanceMethod,

812 ID.AddInteger(info.getCC());

813 ID.AddBoolean(InstanceMethod);

814 ID.AddBoolean(ChainCall);

824 ID.AddBoolean(!paramInfos.empty());

825 if (!paramInfos.empty()) {

826 for (auto paramInfo : paramInfos)

827 ID.AddInteger(paramInfo.getOpaqueValue());

828 }

831 i = argTypes.begin(), e = argTypes.end(); i != e; ++i) {

832 i->Profile(ID);

833 }

834 }

835};

836

837}

838}

839

840#endif

C Language Family Type Representation.

Represents a canonical, potentially-qualified type.

void Profile(llvm::FoldingSetNodeID &ID) const

const T * getTypePtr() const

Retrieve the underlying type pointer, which refers to a canonical type.

CharUnits - This is an opaque type for sizes expressed in character units.

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.

ABIArgInfo - Helper class to encapsulate information about how a specific C type should be passed to ...

void setZeroExt(bool ZExt)

unsigned getInAllocaFieldIndex() const

void setIndirectAddrSpace(unsigned AddrSpace)

static ABIArgInfo getNoExtend(llvm::IntegerType *T)

bool getIndirectByVal() const

llvm::StructType * getCoerceAndExpandType() const

bool getIndirectRealign() const

static ABIArgInfo getInAlloca(unsigned FieldIndex, bool Indirect=false)

static ABIArgInfo getIgnore()

static ABIArgInfo getExpand()

void setCoerceToType(llvm::Type *T)

llvm::Type * getUnpaddedCoerceAndExpandType() const

bool getCanBeFlattened() const

unsigned getDirectOffset() const

static bool isPaddingForCoerceAndExpand(llvm::Type *eltType)

void setDirectOffset(unsigned Offset)

void setPaddingInReg(bool PIR)

bool getInAllocaSRet() const

Return true if this field of an inalloca struct should be returned to implement a struct return calli...

void setIndirectAlign(CharUnits IA)

llvm::Type * getPaddingType() const

void setIndirectByVal(bool IBV)

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

bool getPaddingInReg() const

static ABIArgInfo getExpandWithPadding(bool PaddingInReg, llvm::Type *Padding)

unsigned getDirectAlign() const

unsigned getIndirectAddrSpace() const

ABIArgInfo(Kind K=Direct)

static ABIArgInfo getIndirectInReg(CharUnits Alignment, bool ByVal=true, bool Realign=false)

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

void setIndirectRealign(bool IR)

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

@ Extend

Extend - Valid only for integer argument types.

@ Ignore

Ignore - Ignore the argument (treat as void).

@ IndirectAliased

IndirectAliased - Similar to Indirect, but the pointer may be to an object that is otherwise referenc...

@ Expand

Expand - Only valid for aggregate argument types.

@ InAlloca

InAlloca - Pass the argument directly using the LLVM inalloca attribute.

@ Indirect

Indirect - Pass the argument indirectly via a hidden pointer with the specified alignment (0 indicate...

@ CoerceAndExpand

CoerceAndExpand - Only valid for aggregate argument types.

@ Direct

Direct - Pass the argument directly using the normal converted LLVM type, or by coercing to another s...

ArrayRef< llvm::Type * > getCoerceAndExpandTypeSequence() const

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

Pass this in memory using the IR byref attribute.

void setSRetAfterThis(bool AfterThis)

void setInAllocaIndirect(bool Indirect)

void setInAllocaSRet(bool SRet)

bool isCoerceAndExpand() const

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

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

DirectAttrInfo DirectAttr

static ABIArgInfo getCoerceAndExpand(llvm::StructType *coerceToType, llvm::Type *unpaddedCoerceToType)

unsigned AllocaFieldIndex

unsigned getInAllocaIndirect() const

llvm::Type * getCoerceToType() const

bool isIndirectAliased() const

void setInAllocaFieldIndex(unsigned FieldIndex)

bool isSRetAfterThis() const

IndirectAttrInfo IndirectAttr

bool canHaveCoerceToType() const

llvm::Type * UnpaddedCoerceAndExpandType

void setSignExt(bool SExt)

void setCanBeFlattened(bool Flatten)

void setDirectAlign(unsigned Align)

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

CharUnits getIndirectAlign() const

static ABIArgInfo getDirectInReg(llvm::Type *T=nullptr)

CGFunctionInfo - Class to encapsulate the information about a function definition.

bool usesInAlloca() const

Return true if this function uses inalloca arguments.

FunctionType::ExtInfo getExtInfo() const

bool isInstanceMethod() const

ABIArgInfo & getReturnInfo()

bool isReturnsRetained() const

In ARC, whether this function retains its return value.

unsigned getCallingConvention() const

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

void Profile(llvm::FoldingSetNodeID &ID)

const_arg_iterator arg_begin() const

bool isNoCallerSavedRegs() const

Whether this function no longer saves caller registers.

unsigned getRegParm() const

ArrayRef< ExtParameterInfo > getExtParameterInfos() const

CanQualType getReturnType() const

bool isNoCfCheck() const

Whether this function has nocf_check attribute.

CallingConv getASTCallingConvention() const

getASTCallingConvention() - Return the AST-specified calling convention.

const ABIArgInfo & getReturnInfo() const

bool getHasRegParm() const

ArrayRef< ArgInfo > arguments() const

const ArgInfo * const_arg_iterator

static CGFunctionInfo * create(unsigned llvmCC, bool instanceMethod, bool chainCall, bool delegateCall, const FunctionType::ExtInfo &extInfo, ArrayRef< ExtParameterInfo > paramInfos, CanQualType resultType, ArrayRef< CanQualType > argTypes, RequiredArgs required)

static void Profile(llvm::FoldingSetNodeID &ID, bool InstanceMethod, bool ChainCall, bool IsDelegateCall, const FunctionType::ExtInfo &info, ArrayRef< ExtParameterInfo > paramInfos, RequiredArgs required, CanQualType resultType, ArrayRef< CanQualType > argTypes)

friend class TrailingObjects

bool isCmseNSCall() const

bool isDelegateCall() const

MutableArrayRef< ArgInfo > arguments()

const_arg_iterator arg_end() const

unsigned getEffectiveCallingConvention() const

getEffectiveCallingConvention - Return the actual calling convention to use, which may depend on the ...

void setArgStruct(llvm::StructType *Ty, CharUnits Align)

size_t numTrailingObjects(OverloadToken< ArgInfo >) const

ExtParameterInfo getExtParameterInfo(unsigned argIndex) const

unsigned getMaxVectorWidth() const

Return the maximum vector width in the arguments.

CharUnits getArgStructAlignment() const

size_t numTrailingObjects(OverloadToken< ExtParameterInfo >) const

unsigned arg_size() const

RequiredArgs getRequiredArgs() const

void setEffectiveCallingConvention(unsigned Value)

unsigned getNumRequiredArgs() const

llvm::StructType * getArgStruct() const

Get the struct type used to represent all the arguments in memory.

void setMaxVectorWidth(unsigned Width)

Set the maximum vector width in the arguments.

A class for recording the number of arguments that a function signature requires.

static RequiredArgs forPrototypePlus(CanQual< FunctionProtoType > prototype, unsigned additional)

bool allowsOptionalArgs() const

unsigned getNumRequiredArgs() const

static RequiredArgs forPrototype(CanQual< FunctionProtoType > prototype)

static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype, unsigned additional)

Compute the arguments required by the given formal prototype, given that there may be some additional...

static RequiredArgs getFromOpaqueData(unsigned value)

bool isRequiredArg(unsigned argIdx) const

Return true if the argument at a given index is required.

static RequiredArgs forPrototype(const FunctionProtoType *prototype)

unsigned getOpaqueData() const

Represents a prototype with parameter type info, e.g.

unsigned getNumParams() const

bool isVariadic() const

Whether this function prototype is variadic.

ArrayRef< ExtParameterInfo > getExtParameterInfos() const

bool hasExtParameterInfos() const

Is there any interesting extra information for any of the parameters of this function type?

A class which abstracts out some details necessary for making a call.

CallingConv getCC() const

bool getCmseNSCall() const

bool getNoCfCheck() const

unsigned getRegParm() const

bool getNoCallerSavedRegs() const

bool getHasRegParm() const

bool getProducesResult() const

Interesting information about a specific parameter that can't simply be reflected in parameter's type...

A (possibly-)qualified type.

bool isIntegralOrEnumerationType() const

Determine whether this type is an integral or enumeration type.

bool hasSignedIntegerRepresentation() const

Determine whether this type has an signed integer representation of some sort, e.g....

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

const FunctionProtoType * T

CallingConv

CallingConv - Specifies the calling convention that a function uses.