File indexing completed on 2026-05-10 08:36:52
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef LLVM_CLANG_CODEGEN_CGFUNCTIONINFO_H
0016 #define LLVM_CLANG_CODEGEN_CGFUNCTIONINFO_H
0017
0018 #include "clang/AST/CanonicalType.h"
0019 #include "clang/AST/CharUnits.h"
0020 #include "clang/AST/Decl.h"
0021 #include "clang/AST/Type.h"
0022 #include "llvm/IR/DerivedTypes.h"
0023 #include "llvm/ADT/FoldingSet.h"
0024 #include "llvm/Support/TrailingObjects.h"
0025 #include <cassert>
0026
0027 namespace clang {
0028 namespace CodeGen {
0029
0030
0031
0032 class ABIArgInfo {
0033 public:
0034 enum Kind : uint8_t {
0035
0036
0037
0038
0039
0040
0041 Direct,
0042
0043
0044
0045 Extend,
0046
0047
0048
0049 Indirect,
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062 IndirectAliased,
0063
0064
0065
0066 Ignore,
0067
0068
0069
0070
0071
0072 Expand,
0073
0074
0075
0076
0077
0078 CoerceAndExpand,
0079
0080
0081
0082
0083
0084
0085 InAlloca,
0086 KindFirst = Direct,
0087 KindLast = InAlloca
0088 };
0089
0090 private:
0091 llvm::Type *TypeData;
0092 union {
0093 llvm::Type *PaddingType;
0094 llvm::Type *UnpaddedCoerceAndExpandType;
0095 };
0096 struct DirectAttrInfo {
0097 unsigned Offset;
0098 unsigned Align;
0099 };
0100 struct IndirectAttrInfo {
0101 unsigned Align;
0102 unsigned AddrSpace;
0103 };
0104 union {
0105 DirectAttrInfo DirectAttr;
0106 IndirectAttrInfo IndirectAttr;
0107 unsigned AllocaFieldIndex;
0108 };
0109 Kind TheKind;
0110 bool PaddingInReg : 1;
0111 bool InAllocaSRet : 1;
0112 bool InAllocaIndirect : 1;
0113 bool IndirectByVal : 1;
0114 bool IndirectRealign : 1;
0115 bool SRetAfterThis : 1;
0116 bool InReg : 1;
0117 bool CanBeFlattened: 1;
0118 bool SignExt : 1;
0119 bool ZeroExt : 1;
0120
0121 bool canHavePaddingType() const {
0122 return isDirect() || isExtend() || isIndirect() || isIndirectAliased() ||
0123 isExpand();
0124 }
0125 void setPaddingType(llvm::Type *T) {
0126 assert(canHavePaddingType());
0127 PaddingType = T;
0128 }
0129
0130 void setUnpaddedCoerceToType(llvm::Type *T) {
0131 assert(isCoerceAndExpand());
0132 UnpaddedCoerceAndExpandType = T;
0133 }
0134
0135 public:
0136 ABIArgInfo(Kind K = Direct)
0137 : TypeData(nullptr), PaddingType(nullptr), DirectAttr{0, 0}, TheKind(K),
0138 PaddingInReg(false), InAllocaSRet(false),
0139 InAllocaIndirect(false), IndirectByVal(false), IndirectRealign(false),
0140 SRetAfterThis(false), InReg(false), CanBeFlattened(false),
0141 SignExt(false), ZeroExt(false) {}
0142
0143 static ABIArgInfo getDirect(llvm::Type *T = nullptr, unsigned Offset = 0,
0144 llvm::Type *Padding = nullptr,
0145 bool CanBeFlattened = true, unsigned Align = 0) {
0146 auto AI = ABIArgInfo(Direct);
0147 AI.setCoerceToType(T);
0148 AI.setPaddingType(Padding);
0149 AI.setDirectOffset(Offset);
0150 AI.setDirectAlign(Align);
0151 AI.setCanBeFlattened(CanBeFlattened);
0152 return AI;
0153 }
0154 static ABIArgInfo getDirectInReg(llvm::Type *T = nullptr) {
0155 auto AI = getDirect(T);
0156 AI.setInReg(true);
0157 return AI;
0158 }
0159
0160 static ABIArgInfo getSignExtend(QualType Ty, llvm::Type *T = nullptr) {
0161 assert(Ty->isIntegralOrEnumerationType() && "Unexpected QualType");
0162 auto AI = ABIArgInfo(Extend);
0163 AI.setCoerceToType(T);
0164 AI.setPaddingType(nullptr);
0165 AI.setDirectOffset(0);
0166 AI.setDirectAlign(0);
0167 AI.setSignExt(true);
0168 return AI;
0169 }
0170
0171 static ABIArgInfo getZeroExtend(QualType Ty, llvm::Type *T = nullptr) {
0172 assert(Ty->isIntegralOrEnumerationType() && "Unexpected QualType");
0173 auto AI = ABIArgInfo(Extend);
0174 AI.setCoerceToType(T);
0175 AI.setPaddingType(nullptr);
0176 AI.setDirectOffset(0);
0177 AI.setDirectAlign(0);
0178 AI.setZeroExt(true);
0179 return AI;
0180 }
0181
0182
0183
0184 static ABIArgInfo getExtend(QualType Ty, llvm::Type *T = nullptr) {
0185 assert(Ty->isIntegralOrEnumerationType() && "Unexpected QualType");
0186 if (Ty->hasSignedIntegerRepresentation())
0187 return getSignExtend(Ty, T);
0188 return getZeroExtend(Ty, T);
0189 }
0190
0191
0192 static ABIArgInfo getNoExtend(llvm::IntegerType *T) {
0193 auto AI = ABIArgInfo(Extend);
0194 AI.setCoerceToType(T);
0195 AI.setPaddingType(nullptr);
0196 AI.setDirectOffset(0);
0197 AI.setDirectAlign(0);
0198 return AI;
0199 }
0200
0201 static ABIArgInfo getExtendInReg(QualType Ty, llvm::Type *T = nullptr) {
0202 auto AI = getExtend(Ty, T);
0203 AI.setInReg(true);
0204 return AI;
0205 }
0206 static ABIArgInfo getIgnore() {
0207 return ABIArgInfo(Ignore);
0208 }
0209 static ABIArgInfo getIndirect(CharUnits Alignment, bool ByVal = true,
0210 bool Realign = false,
0211 llvm::Type *Padding = nullptr) {
0212 auto AI = ABIArgInfo(Indirect);
0213 AI.setIndirectAlign(Alignment);
0214 AI.setIndirectByVal(ByVal);
0215 AI.setIndirectRealign(Realign);
0216 AI.setSRetAfterThis(false);
0217 AI.setPaddingType(Padding);
0218 return AI;
0219 }
0220
0221
0222 static ABIArgInfo getIndirectAliased(CharUnits Alignment, unsigned AddrSpace,
0223 bool Realign = false,
0224 llvm::Type *Padding = nullptr) {
0225 auto AI = ABIArgInfo(IndirectAliased);
0226 AI.setIndirectAlign(Alignment);
0227 AI.setIndirectRealign(Realign);
0228 AI.setPaddingType(Padding);
0229 AI.setIndirectAddrSpace(AddrSpace);
0230 return AI;
0231 }
0232
0233 static ABIArgInfo getIndirectInReg(CharUnits Alignment, bool ByVal = true,
0234 bool Realign = false) {
0235 auto AI = getIndirect(Alignment, ByVal, Realign);
0236 AI.setInReg(true);
0237 return AI;
0238 }
0239 static ABIArgInfo getInAlloca(unsigned FieldIndex, bool Indirect = false) {
0240 auto AI = ABIArgInfo(InAlloca);
0241 AI.setInAllocaFieldIndex(FieldIndex);
0242 AI.setInAllocaIndirect(Indirect);
0243 return AI;
0244 }
0245 static ABIArgInfo getExpand() {
0246 auto AI = ABIArgInfo(Expand);
0247 AI.setPaddingType(nullptr);
0248 return AI;
0249 }
0250 static ABIArgInfo getExpandWithPadding(bool PaddingInReg,
0251 llvm::Type *Padding) {
0252 auto AI = getExpand();
0253 AI.setPaddingInReg(PaddingInReg);
0254 AI.setPaddingType(Padding);
0255 return AI;
0256 }
0257
0258
0259
0260
0261 static ABIArgInfo getCoerceAndExpand(llvm::StructType *coerceToType,
0262 llvm::Type *unpaddedCoerceToType) {
0263 #ifndef NDEBUG
0264
0265
0266
0267 auto unpaddedStruct = dyn_cast<llvm::StructType>(unpaddedCoerceToType);
0268 assert(!unpaddedStruct || unpaddedStruct->getNumElements() != 1);
0269
0270
0271
0272 unsigned unpaddedIndex = 0;
0273 for (auto eltType : coerceToType->elements()) {
0274 if (isPaddingForCoerceAndExpand(eltType))
0275 continue;
0276 unpaddedIndex++;
0277 }
0278
0279
0280 if (unpaddedStruct) {
0281 assert(unpaddedStruct->getNumElements() == unpaddedIndex);
0282 } else {
0283 assert(unpaddedIndex == 1);
0284 }
0285 #endif
0286
0287 auto AI = ABIArgInfo(CoerceAndExpand);
0288 AI.setCoerceToType(coerceToType);
0289 AI.setUnpaddedCoerceToType(unpaddedCoerceToType);
0290 return AI;
0291 }
0292
0293 static bool isPaddingForCoerceAndExpand(llvm::Type *eltType) {
0294 return eltType->isArrayTy() &&
0295 eltType->getArrayElementType()->isIntegerTy(8);
0296 }
0297
0298 Kind getKind() const { return TheKind; }
0299 bool isDirect() const { return TheKind == Direct; }
0300 bool isInAlloca() const { return TheKind == InAlloca; }
0301 bool isExtend() const { return TheKind == Extend; }
0302 bool isIgnore() const { return TheKind == Ignore; }
0303 bool isIndirect() const { return TheKind == Indirect; }
0304 bool isIndirectAliased() const { return TheKind == IndirectAliased; }
0305 bool isExpand() const { return TheKind == Expand; }
0306 bool isCoerceAndExpand() const { return TheKind == CoerceAndExpand; }
0307
0308 bool canHaveCoerceToType() const {
0309 return isDirect() || isExtend() || isCoerceAndExpand();
0310 }
0311
0312
0313 unsigned getDirectOffset() const {
0314 assert((isDirect() || isExtend()) && "Not a direct or extend kind");
0315 return DirectAttr.Offset;
0316 }
0317 void setDirectOffset(unsigned Offset) {
0318 assert((isDirect() || isExtend()) && "Not a direct or extend kind");
0319 DirectAttr.Offset = Offset;
0320 }
0321
0322 unsigned getDirectAlign() const {
0323 assert((isDirect() || isExtend()) && "Not a direct or extend kind");
0324 return DirectAttr.Align;
0325 }
0326 void setDirectAlign(unsigned Align) {
0327 assert((isDirect() || isExtend()) && "Not a direct or extend kind");
0328 DirectAttr.Align = Align;
0329 }
0330
0331 bool isSignExt() const {
0332 assert(isExtend() && (SignExt + ZeroExt <= 1) && "Invalid kind / flags!");
0333 return SignExt;
0334 }
0335 void setSignExt(bool SExt) {
0336 assert(isExtend() && "Invalid kind!");
0337 SignExt = SExt;
0338 }
0339
0340 bool isZeroExt() const {
0341 assert(isExtend() && (SignExt + ZeroExt <= 1) && "Invalid kind / flags!");
0342 return ZeroExt;
0343 }
0344 void setZeroExt(bool ZExt) {
0345 assert(isExtend() && "Invalid kind!");
0346 ZeroExt = ZExt;
0347 }
0348
0349 bool isNoExt() const {
0350 assert(isExtend() && (SignExt + ZeroExt <= 1) && "Invalid kind / flags!");
0351 return !SignExt && !ZeroExt;
0352 }
0353
0354 llvm::Type *getPaddingType() const {
0355 return (canHavePaddingType() ? PaddingType : nullptr);
0356 }
0357
0358 bool getPaddingInReg() const {
0359 return PaddingInReg;
0360 }
0361 void setPaddingInReg(bool PIR) {
0362 PaddingInReg = PIR;
0363 }
0364
0365 llvm::Type *getCoerceToType() const {
0366 assert(canHaveCoerceToType() && "Invalid kind!");
0367 return TypeData;
0368 }
0369
0370 void setCoerceToType(llvm::Type *T) {
0371 assert(canHaveCoerceToType() && "Invalid kind!");
0372 TypeData = T;
0373 }
0374
0375 llvm::StructType *getCoerceAndExpandType() const {
0376 assert(isCoerceAndExpand());
0377 return cast<llvm::StructType>(TypeData);
0378 }
0379
0380 llvm::Type *getUnpaddedCoerceAndExpandType() const {
0381 assert(isCoerceAndExpand());
0382 return UnpaddedCoerceAndExpandType;
0383 }
0384
0385 ArrayRef<llvm::Type *>getCoerceAndExpandTypeSequence() const {
0386 assert(isCoerceAndExpand());
0387 if (auto structTy =
0388 dyn_cast<llvm::StructType>(UnpaddedCoerceAndExpandType)) {
0389 return structTy->elements();
0390 } else {
0391 return llvm::ArrayRef(&UnpaddedCoerceAndExpandType, 1);
0392 }
0393 }
0394
0395 bool getInReg() const {
0396 assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!");
0397 return InReg;
0398 }
0399
0400 void setInReg(bool IR) {
0401 assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!");
0402 InReg = IR;
0403 }
0404
0405
0406 CharUnits getIndirectAlign() const {
0407 assert((isIndirect() || isIndirectAliased()) && "Invalid kind!");
0408 return CharUnits::fromQuantity(IndirectAttr.Align);
0409 }
0410 void setIndirectAlign(CharUnits IA) {
0411 assert((isIndirect() || isIndirectAliased()) && "Invalid kind!");
0412 IndirectAttr.Align = IA.getQuantity();
0413 }
0414
0415 bool getIndirectByVal() const {
0416 assert(isIndirect() && "Invalid kind!");
0417 return IndirectByVal;
0418 }
0419 void setIndirectByVal(bool IBV) {
0420 assert(isIndirect() && "Invalid kind!");
0421 IndirectByVal = IBV;
0422 }
0423
0424 unsigned getIndirectAddrSpace() const {
0425 assert(isIndirectAliased() && "Invalid kind!");
0426 return IndirectAttr.AddrSpace;
0427 }
0428
0429 void setIndirectAddrSpace(unsigned AddrSpace) {
0430 assert(isIndirectAliased() && "Invalid kind!");
0431 IndirectAttr.AddrSpace = AddrSpace;
0432 }
0433
0434 bool getIndirectRealign() const {
0435 assert((isIndirect() || isIndirectAliased()) && "Invalid kind!");
0436 return IndirectRealign;
0437 }
0438 void setIndirectRealign(bool IR) {
0439 assert((isIndirect() || isIndirectAliased()) && "Invalid kind!");
0440 IndirectRealign = IR;
0441 }
0442
0443 bool isSRetAfterThis() const {
0444 assert(isIndirect() && "Invalid kind!");
0445 return SRetAfterThis;
0446 }
0447 void setSRetAfterThis(bool AfterThis) {
0448 assert(isIndirect() && "Invalid kind!");
0449 SRetAfterThis = AfterThis;
0450 }
0451
0452 unsigned getInAllocaFieldIndex() const {
0453 assert(isInAlloca() && "Invalid kind!");
0454 return AllocaFieldIndex;
0455 }
0456 void setInAllocaFieldIndex(unsigned FieldIndex) {
0457 assert(isInAlloca() && "Invalid kind!");
0458 AllocaFieldIndex = FieldIndex;
0459 }
0460
0461 unsigned getInAllocaIndirect() const {
0462 assert(isInAlloca() && "Invalid kind!");
0463 return InAllocaIndirect;
0464 }
0465 void setInAllocaIndirect(bool Indirect) {
0466 assert(isInAlloca() && "Invalid kind!");
0467 InAllocaIndirect = Indirect;
0468 }
0469
0470
0471
0472 bool getInAllocaSRet() const {
0473 assert(isInAlloca() && "Invalid kind!");
0474 return InAllocaSRet;
0475 }
0476
0477 void setInAllocaSRet(bool SRet) {
0478 assert(isInAlloca() && "Invalid kind!");
0479 InAllocaSRet = SRet;
0480 }
0481
0482 bool getCanBeFlattened() const {
0483 assert(isDirect() && "Invalid kind!");
0484 return CanBeFlattened;
0485 }
0486
0487 void setCanBeFlattened(bool Flatten) {
0488 assert(isDirect() && "Invalid kind!");
0489 CanBeFlattened = Flatten;
0490 }
0491
0492 void dump() const;
0493 };
0494
0495
0496
0497 class RequiredArgs {
0498
0499
0500 unsigned NumRequired;
0501 public:
0502 enum All_t { All };
0503
0504 RequiredArgs(All_t _) : NumRequired(~0U) {}
0505 explicit RequiredArgs(unsigned n) : NumRequired(n) {
0506 assert(n != ~0U);
0507 }
0508
0509
0510
0511
0512
0513
0514 static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype,
0515 unsigned additional) {
0516 if (!prototype->isVariadic()) return All;
0517
0518 if (prototype->hasExtParameterInfos())
0519 additional += llvm::count_if(
0520 prototype->getExtParameterInfos(),
0521 [](const FunctionProtoType::ExtParameterInfo &ExtInfo) {
0522 return ExtInfo.hasPassObjectSize();
0523 });
0524
0525 return RequiredArgs(prototype->getNumParams() + additional);
0526 }
0527
0528 static RequiredArgs forPrototypePlus(CanQual<FunctionProtoType> prototype,
0529 unsigned additional) {
0530 return forPrototypePlus(prototype.getTypePtr(), additional);
0531 }
0532
0533 static RequiredArgs forPrototype(const FunctionProtoType *prototype) {
0534 return forPrototypePlus(prototype, 0);
0535 }
0536
0537 static RequiredArgs forPrototype(CanQual<FunctionProtoType> prototype) {
0538 return forPrototypePlus(prototype.getTypePtr(), 0);
0539 }
0540
0541 bool allowsOptionalArgs() const { return NumRequired != ~0U; }
0542 unsigned getNumRequiredArgs() const {
0543 assert(allowsOptionalArgs());
0544 return NumRequired;
0545 }
0546
0547
0548 bool isRequiredArg(unsigned argIdx) const {
0549 return argIdx == ~0U || argIdx < NumRequired;
0550 }
0551
0552 unsigned getOpaqueData() const { return NumRequired; }
0553 static RequiredArgs getFromOpaqueData(unsigned value) {
0554 if (value == ~0U) return All;
0555 return RequiredArgs(value);
0556 }
0557 };
0558
0559
0560
0561 struct CGFunctionInfoArgInfo {
0562 CanQualType type;
0563 ABIArgInfo info;
0564 };
0565
0566
0567
0568 class CGFunctionInfo final
0569 : public llvm::FoldingSetNode,
0570 private llvm::TrailingObjects<CGFunctionInfo, CGFunctionInfoArgInfo,
0571 FunctionProtoType::ExtParameterInfo> {
0572 typedef CGFunctionInfoArgInfo ArgInfo;
0573 typedef FunctionProtoType::ExtParameterInfo ExtParameterInfo;
0574
0575
0576
0577 unsigned CallingConvention : 8;
0578
0579
0580
0581 unsigned EffectiveCallingConvention : 8;
0582
0583
0584 LLVM_PREFERRED_TYPE(CallingConv)
0585 unsigned ASTCallingConvention : 6;
0586
0587
0588 LLVM_PREFERRED_TYPE(bool)
0589 unsigned InstanceMethod : 1;
0590
0591
0592 LLVM_PREFERRED_TYPE(bool)
0593 unsigned ChainCall : 1;
0594
0595
0596
0597 LLVM_PREFERRED_TYPE(bool)
0598 unsigned DelegateCall : 1;
0599
0600
0601 LLVM_PREFERRED_TYPE(bool)
0602 unsigned CmseNSCall : 1;
0603
0604
0605 LLVM_PREFERRED_TYPE(bool)
0606 unsigned NoReturn : 1;
0607
0608
0609 LLVM_PREFERRED_TYPE(bool)
0610 unsigned ReturnsRetained : 1;
0611
0612
0613 LLVM_PREFERRED_TYPE(bool)
0614 unsigned NoCallerSavedRegs : 1;
0615
0616
0617 LLVM_PREFERRED_TYPE(bool)
0618 unsigned HasRegParm : 1;
0619 unsigned RegParm : 3;
0620
0621
0622 LLVM_PREFERRED_TYPE(bool)
0623 unsigned NoCfCheck : 1;
0624
0625
0626 unsigned MaxVectorWidth : 4;
0627
0628 RequiredArgs Required;
0629
0630
0631
0632 llvm::StructType *ArgStruct;
0633 unsigned ArgStructAlign : 31;
0634 LLVM_PREFERRED_TYPE(bool)
0635 unsigned HasExtParameterInfos : 1;
0636
0637 unsigned NumArgs;
0638
0639 ArgInfo *getArgsBuffer() {
0640 return getTrailingObjects<ArgInfo>();
0641 }
0642 const ArgInfo *getArgsBuffer() const {
0643 return getTrailingObjects<ArgInfo>();
0644 }
0645
0646 ExtParameterInfo *getExtParameterInfosBuffer() {
0647 return getTrailingObjects<ExtParameterInfo>();
0648 }
0649 const ExtParameterInfo *getExtParameterInfosBuffer() const{
0650 return getTrailingObjects<ExtParameterInfo>();
0651 }
0652
0653 CGFunctionInfo() : Required(RequiredArgs::All) {}
0654
0655 public:
0656 static CGFunctionInfo *
0657 create(unsigned llvmCC, bool instanceMethod, bool chainCall,
0658 bool delegateCall, const FunctionType::ExtInfo &extInfo,
0659 ArrayRef<ExtParameterInfo> paramInfos, CanQualType resultType,
0660 ArrayRef<CanQualType> argTypes, RequiredArgs required);
0661 void operator delete(void *p) { ::operator delete(p); }
0662
0663
0664
0665 friend class TrailingObjects;
0666 size_t numTrailingObjects(OverloadToken<ArgInfo>) const {
0667 return NumArgs + 1;
0668 }
0669 size_t numTrailingObjects(OverloadToken<ExtParameterInfo>) const {
0670 return (HasExtParameterInfos ? NumArgs : 0);
0671 }
0672
0673 typedef const ArgInfo *const_arg_iterator;
0674 typedef ArgInfo *arg_iterator;
0675
0676 MutableArrayRef<ArgInfo> arguments() {
0677 return MutableArrayRef<ArgInfo>(arg_begin(), NumArgs);
0678 }
0679 ArrayRef<ArgInfo> arguments() const {
0680 return ArrayRef<ArgInfo>(arg_begin(), NumArgs);
0681 }
0682
0683 const_arg_iterator arg_begin() const { return getArgsBuffer() + 1; }
0684 const_arg_iterator arg_end() const { return getArgsBuffer() + 1 + NumArgs; }
0685 arg_iterator arg_begin() { return getArgsBuffer() + 1; }
0686 arg_iterator arg_end() { return getArgsBuffer() + 1 + NumArgs; }
0687
0688 unsigned arg_size() const { return NumArgs; }
0689
0690 bool isVariadic() const { return Required.allowsOptionalArgs(); }
0691 RequiredArgs getRequiredArgs() const { return Required; }
0692 unsigned getNumRequiredArgs() const {
0693 return isVariadic() ? getRequiredArgs().getNumRequiredArgs() : arg_size();
0694 }
0695
0696 bool isInstanceMethod() const { return InstanceMethod; }
0697
0698 bool isChainCall() const { return ChainCall; }
0699
0700 bool isDelegateCall() const { return DelegateCall; }
0701
0702 bool isCmseNSCall() const { return CmseNSCall; }
0703
0704 bool isNoReturn() const { return NoReturn; }
0705
0706
0707
0708 bool isReturnsRetained() const { return ReturnsRetained; }
0709
0710
0711 bool isNoCallerSavedRegs() const { return NoCallerSavedRegs; }
0712
0713
0714 bool isNoCfCheck() const { return NoCfCheck; }
0715
0716
0717
0718 CallingConv getASTCallingConvention() const {
0719 return CallingConv(ASTCallingConvention);
0720 }
0721
0722
0723
0724 unsigned getCallingConvention() const { return CallingConvention; }
0725
0726
0727
0728 unsigned getEffectiveCallingConvention() const {
0729 return EffectiveCallingConvention;
0730 }
0731 void setEffectiveCallingConvention(unsigned Value) {
0732 EffectiveCallingConvention = Value;
0733 }
0734
0735 bool getHasRegParm() const { return HasRegParm; }
0736 unsigned getRegParm() const { return RegParm; }
0737
0738 FunctionType::ExtInfo getExtInfo() const {
0739 return FunctionType::ExtInfo(isNoReturn(), getHasRegParm(), getRegParm(),
0740 getASTCallingConvention(), isReturnsRetained(),
0741 isNoCallerSavedRegs(), isNoCfCheck(),
0742 isCmseNSCall());
0743 }
0744
0745 CanQualType getReturnType() const { return getArgsBuffer()[0].type; }
0746
0747 ABIArgInfo &getReturnInfo() { return getArgsBuffer()[0].info; }
0748 const ABIArgInfo &getReturnInfo() const { return getArgsBuffer()[0].info; }
0749
0750 ArrayRef<ExtParameterInfo> getExtParameterInfos() const {
0751 if (!HasExtParameterInfos) return {};
0752 return llvm::ArrayRef(getExtParameterInfosBuffer(), NumArgs);
0753 }
0754 ExtParameterInfo getExtParameterInfo(unsigned argIndex) const {
0755 assert(argIndex <= NumArgs);
0756 if (!HasExtParameterInfos) return ExtParameterInfo();
0757 return getExtParameterInfos()[argIndex];
0758 }
0759
0760
0761 bool usesInAlloca() const { return ArgStruct; }
0762
0763
0764 llvm::StructType *getArgStruct() const { return ArgStruct; }
0765 CharUnits getArgStructAlignment() const {
0766 return CharUnits::fromQuantity(ArgStructAlign);
0767 }
0768 void setArgStruct(llvm::StructType *Ty, CharUnits Align) {
0769 ArgStruct = Ty;
0770 ArgStructAlign = Align.getQuantity();
0771 }
0772
0773
0774 unsigned getMaxVectorWidth() const {
0775 return MaxVectorWidth ? 1U << (MaxVectorWidth - 1) : 0;
0776 }
0777
0778
0779 void setMaxVectorWidth(unsigned Width) {
0780 assert(llvm::isPowerOf2_32(Width) && "Expected power of 2 vector");
0781 MaxVectorWidth = llvm::countr_zero(Width) + 1;
0782 }
0783
0784 void Profile(llvm::FoldingSetNodeID &ID) {
0785 ID.AddInteger(getASTCallingConvention());
0786 ID.AddBoolean(InstanceMethod);
0787 ID.AddBoolean(ChainCall);
0788 ID.AddBoolean(DelegateCall);
0789 ID.AddBoolean(NoReturn);
0790 ID.AddBoolean(ReturnsRetained);
0791 ID.AddBoolean(NoCallerSavedRegs);
0792 ID.AddBoolean(HasRegParm);
0793 ID.AddInteger(RegParm);
0794 ID.AddBoolean(NoCfCheck);
0795 ID.AddBoolean(CmseNSCall);
0796 ID.AddInteger(Required.getOpaqueData());
0797 ID.AddBoolean(HasExtParameterInfos);
0798 if (HasExtParameterInfos) {
0799 for (auto paramInfo : getExtParameterInfos())
0800 ID.AddInteger(paramInfo.getOpaqueValue());
0801 }
0802 getReturnType().Profile(ID);
0803 for (const auto &I : arguments())
0804 I.type.Profile(ID);
0805 }
0806 static void Profile(llvm::FoldingSetNodeID &ID, bool InstanceMethod,
0807 bool ChainCall, bool IsDelegateCall,
0808 const FunctionType::ExtInfo &info,
0809 ArrayRef<ExtParameterInfo> paramInfos,
0810 RequiredArgs required, CanQualType resultType,
0811 ArrayRef<CanQualType> argTypes) {
0812 ID.AddInteger(info.getCC());
0813 ID.AddBoolean(InstanceMethod);
0814 ID.AddBoolean(ChainCall);
0815 ID.AddBoolean(IsDelegateCall);
0816 ID.AddBoolean(info.getNoReturn());
0817 ID.AddBoolean(info.getProducesResult());
0818 ID.AddBoolean(info.getNoCallerSavedRegs());
0819 ID.AddBoolean(info.getHasRegParm());
0820 ID.AddInteger(info.getRegParm());
0821 ID.AddBoolean(info.getNoCfCheck());
0822 ID.AddBoolean(info.getCmseNSCall());
0823 ID.AddInteger(required.getOpaqueData());
0824 ID.AddBoolean(!paramInfos.empty());
0825 if (!paramInfos.empty()) {
0826 for (auto paramInfo : paramInfos)
0827 ID.AddInteger(paramInfo.getOpaqueValue());
0828 }
0829 resultType.Profile(ID);
0830 for (ArrayRef<CanQualType>::iterator
0831 i = argTypes.begin(), e = argTypes.end(); i != e; ++i) {
0832 i->Profile(ID);
0833 }
0834 }
0835 };
0836
0837 }
0838 }
0839
0840 #endif