Home | History | Annotate | Download | only in CodeGen
      1 //==-- CGFunctionInfo.h - Representation of function argument/return types -==//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // Defines CGFunctionInfo and associated types used in representing the
     11 // LLVM source types and ABI-coerced types for function arguments and
     12 // return values.
     13 //
     14 //===----------------------------------------------------------------------===//
     15 
     16 #ifndef LLVM_CLANG_CODEGEN_CGFUNCTIONINFO_H
     17 #define LLVM_CLANG_CODEGEN_CGFUNCTIONINFO_H
     18 
     19 #include "clang/AST/Attr.h"
     20 #include "clang/AST/CanonicalType.h"
     21 #include "clang/AST/CharUnits.h"
     22 #include "clang/AST/Decl.h"
     23 #include "clang/AST/Type.h"
     24 #include "llvm/IR/DerivedTypes.h"
     25 #include "llvm/ADT/FoldingSet.h"
     26 #include "llvm/Support/TrailingObjects.h"
     27 #include <cassert>
     28 
     29 namespace clang {
     30 namespace CodeGen {
     31 
     32 /// ABIArgInfo - Helper class to encapsulate information about how a
     33 /// specific C type should be passed to or returned from a function.
     34 class ABIArgInfo {
     35 public:
     36   enum Kind : uint8_t {
     37     /// Direct - Pass the argument directly using the normal converted LLVM
     38     /// type, or by coercing to another specified type stored in
     39     /// 'CoerceToType').  If an offset is specified (in UIntData), then the
     40     /// argument passed is offset by some number of bytes in the memory
     41     /// representation. A dummy argument is emitted before the real argument
     42     /// if the specified type stored in "PaddingType" is not zero.
     43     Direct,
     44 
     45     /// Extend - Valid only for integer argument types. Same as 'direct'
     46     /// but also emit a zero/sign extension attribute.
     47     Extend,
     48 
     49     /// Indirect - Pass the argument indirectly via a hidden pointer
     50     /// with the specified alignment (0 indicates default alignment).
     51     Indirect,
     52 
     53     /// Ignore - Ignore the argument (treat as void). Useful for void and
     54     /// empty structs.
     55     Ignore,
     56 
     57     /// Expand - Only valid for aggregate argument types. The structure should
     58     /// be expanded into consecutive arguments for its constituent fields.
     59     /// Currently expand is only allowed on structures whose fields
     60     /// are all scalar types or are themselves expandable types.
     61     Expand,
     62 
     63     /// CoerceAndExpand - Only valid for aggregate argument types. The
     64     /// structure should be expanded into consecutive arguments corresponding
     65     /// to the non-array elements of the type stored in CoerceToType.
     66     /// Array elements in the type are assumed to be padding and skipped.
     67     CoerceAndExpand,
     68 
     69     /// InAlloca - Pass the argument directly using the LLVM inalloca attribute.
     70     /// This is similar to indirect with byval, except it only applies to
     71     /// arguments stored in memory and forbids any implicit copies.  When
     72     /// applied to a return type, it means the value is returned indirectly via
     73     /// an implicit sret parameter stored in the argument struct.
     74     InAlloca,
     75     KindFirst = Direct,
     76     KindLast = InAlloca
     77   };
     78 
     79 private:
     80   llvm::Type *TypeData; // canHaveCoerceToType()
     81   union {
     82     llvm::Type *PaddingType; // canHavePaddingType()
     83     llvm::Type *UnpaddedCoerceAndExpandType; // isCoerceAndExpand()
     84   };
     85   union {
     86     unsigned DirectOffset;     // isDirect() || isExtend()
     87     unsigned IndirectAlign;    // isIndirect()
     88     unsigned AllocaFieldIndex; // isInAlloca()
     89   };
     90   Kind TheKind;
     91   bool PaddingInReg : 1;
     92   bool InAllocaSRet : 1;    // isInAlloca()
     93   bool IndirectByVal : 1;   // isIndirect()
     94   bool IndirectRealign : 1; // isIndirect()
     95   bool SRetAfterThis : 1;   // isIndirect()
     96   bool InReg : 1;           // isDirect() || isExtend() || isIndirect()
     97   bool CanBeFlattened: 1;   // isDirect()
     98 
     99   bool canHavePaddingType() const {
    100     return isDirect() || isExtend() || isIndirect() || isExpand();
    101   }
    102   void setPaddingType(llvm::Type *T) {
    103     assert(canHavePaddingType());
    104     PaddingType = T;
    105   }
    106 
    107   void setUnpaddedCoerceToType(llvm::Type *T) {
    108     assert(isCoerceAndExpand());
    109     UnpaddedCoerceAndExpandType = T;
    110   }
    111 
    112   ABIArgInfo(Kind K)
    113       : TheKind(K), PaddingInReg(false), InReg(false) {
    114   }
    115 
    116 public:
    117   ABIArgInfo()
    118       : TypeData(nullptr), PaddingType(nullptr), DirectOffset(0),
    119         TheKind(Direct), PaddingInReg(false), InReg(false) {}
    120 
    121   static ABIArgInfo getDirect(llvm::Type *T = nullptr, unsigned Offset = 0,
    122                               llvm::Type *Padding = nullptr,
    123                               bool CanBeFlattened = true) {
    124     auto AI = ABIArgInfo(Direct);
    125     AI.setCoerceToType(T);
    126     AI.setPaddingType(Padding);
    127     AI.setDirectOffset(Offset);
    128     AI.setCanBeFlattened(CanBeFlattened);
    129     return AI;
    130   }
    131   static ABIArgInfo getDirectInReg(llvm::Type *T = nullptr) {
    132     auto AI = getDirect(T);
    133     AI.setInReg(true);
    134     return AI;
    135   }
    136   static ABIArgInfo getExtend(llvm::Type *T = nullptr) {
    137     auto AI = ABIArgInfo(Extend);
    138     AI.setCoerceToType(T);
    139     AI.setPaddingType(nullptr);
    140     AI.setDirectOffset(0);
    141     return AI;
    142   }
    143   static ABIArgInfo getExtendInReg(llvm::Type *T = nullptr) {
    144     auto AI = getExtend(T);
    145     AI.setInReg(true);
    146     return AI;
    147   }
    148   static ABIArgInfo getIgnore() {
    149     return ABIArgInfo(Ignore);
    150   }
    151   static ABIArgInfo getIndirect(CharUnits Alignment, bool ByVal = true,
    152                                 bool Realign = false,
    153                                 llvm::Type *Padding = nullptr) {
    154     auto AI = ABIArgInfo(Indirect);
    155     AI.setIndirectAlign(Alignment);
    156     AI.setIndirectByVal(ByVal);
    157     AI.setIndirectRealign(Realign);
    158     AI.setSRetAfterThis(false);
    159     AI.setPaddingType(Padding);
    160     return AI;
    161   }
    162   static ABIArgInfo getIndirectInReg(CharUnits Alignment, bool ByVal = true,
    163                                      bool Realign = false) {
    164     auto AI = getIndirect(Alignment, ByVal, Realign);
    165     AI.setInReg(true);
    166     return AI;
    167   }
    168   static ABIArgInfo getInAlloca(unsigned FieldIndex) {
    169     auto AI = ABIArgInfo(InAlloca);
    170     AI.setInAllocaFieldIndex(FieldIndex);
    171     return AI;
    172   }
    173   static ABIArgInfo getExpand() {
    174     auto AI = ABIArgInfo(Expand);
    175     AI.setPaddingType(nullptr);
    176     return AI;
    177   }
    178   static ABIArgInfo getExpandWithPadding(bool PaddingInReg,
    179                                          llvm::Type *Padding) {
    180     auto AI = getExpand();
    181     AI.setPaddingInReg(PaddingInReg);
    182     AI.setPaddingType(Padding);
    183     return AI;
    184   }
    185 
    186   /// \param unpaddedCoerceToType The coerce-to type with padding elements
    187   ///   removed, canonicalized to a single element if it would otherwise
    188   ///   have exactly one element.
    189   static ABIArgInfo getCoerceAndExpand(llvm::StructType *coerceToType,
    190                                        llvm::Type *unpaddedCoerceToType) {
    191 #ifndef NDEBUG
    192     // Sanity checks on unpaddedCoerceToType.
    193 
    194     // Assert that we only have a struct type if there are multiple elements.
    195     auto unpaddedStruct = dyn_cast<llvm::StructType>(unpaddedCoerceToType);
    196     assert(!unpaddedStruct || unpaddedStruct->getNumElements() != 1);
    197 
    198     // Assert that all the non-padding elements have a corresponding element
    199     // in the unpadded type.
    200     unsigned unpaddedIndex = 0;
    201     for (auto eltType : coerceToType->elements()) {
    202       if (isPaddingForCoerceAndExpand(eltType)) continue;
    203       if (unpaddedStruct) {
    204         assert(unpaddedStruct->getElementType(unpaddedIndex) == eltType);
    205       } else {
    206         assert(unpaddedIndex == 0 && unpaddedCoerceToType == eltType);
    207       }
    208       unpaddedIndex++;
    209     }
    210 
    211     // Assert that there aren't extra elements in the unpadded type.
    212     if (unpaddedStruct) {
    213       assert(unpaddedStruct->getNumElements() == unpaddedIndex);
    214     } else {
    215       assert(unpaddedIndex == 1);
    216     }
    217 #endif
    218 
    219     auto AI = ABIArgInfo(CoerceAndExpand);
    220     AI.setCoerceToType(coerceToType);
    221     AI.setUnpaddedCoerceToType(unpaddedCoerceToType);
    222     return AI;
    223   }
    224 
    225   static bool isPaddingForCoerceAndExpand(llvm::Type *eltType) {
    226     if (eltType->isArrayTy()) {
    227       assert(eltType->getArrayElementType()->isIntegerTy(8));
    228       return true;
    229     } else {
    230       return false;
    231     }
    232   }
    233 
    234   Kind getKind() const { return TheKind; }
    235   bool isDirect() const { return TheKind == Direct; }
    236   bool isInAlloca() const { return TheKind == InAlloca; }
    237   bool isExtend() const { return TheKind == Extend; }
    238   bool isIgnore() const { return TheKind == Ignore; }
    239   bool isIndirect() const { return TheKind == Indirect; }
    240   bool isExpand() const { return TheKind == Expand; }
    241   bool isCoerceAndExpand() const { return TheKind == CoerceAndExpand; }
    242 
    243   bool canHaveCoerceToType() const {
    244     return isDirect() || isExtend() || isCoerceAndExpand();
    245   }
    246 
    247   // Direct/Extend accessors
    248   unsigned getDirectOffset() const {
    249     assert((isDirect() || isExtend()) && "Not a direct or extend kind");
    250     return DirectOffset;
    251   }
    252   void setDirectOffset(unsigned Offset) {
    253     assert((isDirect() || isExtend()) && "Not a direct or extend kind");
    254     DirectOffset = Offset;
    255   }
    256 
    257   llvm::Type *getPaddingType() const {
    258     return (canHavePaddingType() ? PaddingType : nullptr);
    259   }
    260 
    261   bool getPaddingInReg() const {
    262     return PaddingInReg;
    263   }
    264   void setPaddingInReg(bool PIR) {
    265     PaddingInReg = PIR;
    266   }
    267 
    268   llvm::Type *getCoerceToType() const {
    269     assert(canHaveCoerceToType() && "Invalid kind!");
    270     return TypeData;
    271   }
    272 
    273   void setCoerceToType(llvm::Type *T) {
    274     assert(canHaveCoerceToType() && "Invalid kind!");
    275     TypeData = T;
    276   }
    277 
    278   llvm::StructType *getCoerceAndExpandType() const {
    279     assert(isCoerceAndExpand());
    280     return cast<llvm::StructType>(TypeData);
    281   }
    282 
    283   llvm::Type *getUnpaddedCoerceAndExpandType() const {
    284     assert(isCoerceAndExpand());
    285     return UnpaddedCoerceAndExpandType;
    286   }
    287 
    288   ArrayRef<llvm::Type *>getCoerceAndExpandTypeSequence() const {
    289     assert(isCoerceAndExpand());
    290     if (auto structTy =
    291           dyn_cast<llvm::StructType>(UnpaddedCoerceAndExpandType)) {
    292       return structTy->elements();
    293     } else {
    294       return llvm::makeArrayRef(&UnpaddedCoerceAndExpandType, 1);
    295     }
    296   }
    297 
    298   bool getInReg() const {
    299     assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!");
    300     return InReg;
    301   }
    302 
    303   void setInReg(bool IR) {
    304     assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!");
    305     InReg = IR;
    306   }
    307 
    308   // Indirect accessors
    309   CharUnits getIndirectAlign() const {
    310     assert(isIndirect() && "Invalid kind!");
    311     return CharUnits::fromQuantity(IndirectAlign);
    312   }
    313   void setIndirectAlign(CharUnits IA) {
    314     assert(isIndirect() && "Invalid kind!");
    315     IndirectAlign = IA.getQuantity();
    316   }
    317 
    318   bool getIndirectByVal() const {
    319     assert(isIndirect() && "Invalid kind!");
    320     return IndirectByVal;
    321   }
    322   void setIndirectByVal(bool IBV) {
    323     assert(isIndirect() && "Invalid kind!");
    324     IndirectByVal = IBV;
    325   }
    326 
    327   bool getIndirectRealign() const {
    328     assert(isIndirect() && "Invalid kind!");
    329     return IndirectRealign;
    330   }
    331   void setIndirectRealign(bool IR) {
    332     assert(isIndirect() && "Invalid kind!");
    333     IndirectRealign = IR;
    334   }
    335 
    336   bool isSRetAfterThis() const {
    337     assert(isIndirect() && "Invalid kind!");
    338     return SRetAfterThis;
    339   }
    340   void setSRetAfterThis(bool AfterThis) {
    341     assert(isIndirect() && "Invalid kind!");
    342     SRetAfterThis = AfterThis;
    343   }
    344 
    345   unsigned getInAllocaFieldIndex() const {
    346     assert(isInAlloca() && "Invalid kind!");
    347     return AllocaFieldIndex;
    348   }
    349   void setInAllocaFieldIndex(unsigned FieldIndex) {
    350     assert(isInAlloca() && "Invalid kind!");
    351     AllocaFieldIndex = FieldIndex;
    352   }
    353 
    354   /// \brief Return true if this field of an inalloca struct should be returned
    355   /// to implement a struct return calling convention.
    356   bool getInAllocaSRet() const {
    357     assert(isInAlloca() && "Invalid kind!");
    358     return InAllocaSRet;
    359   }
    360 
    361   void setInAllocaSRet(bool SRet) {
    362     assert(isInAlloca() && "Invalid kind!");
    363     InAllocaSRet = SRet;
    364   }
    365 
    366   bool getCanBeFlattened() const {
    367     assert(isDirect() && "Invalid kind!");
    368     return CanBeFlattened;
    369   }
    370 
    371   void setCanBeFlattened(bool Flatten) {
    372     assert(isDirect() && "Invalid kind!");
    373     CanBeFlattened = Flatten;
    374   }
    375 
    376   void dump() const;
    377 };
    378 
    379 /// A class for recording the number of arguments that a function
    380 /// signature requires.
    381 class RequiredArgs {
    382   /// The number of required arguments, or ~0 if the signature does
    383   /// not permit optional arguments.
    384   unsigned NumRequired;
    385 public:
    386   enum All_t { All };
    387 
    388   RequiredArgs(All_t _) : NumRequired(~0U) {}
    389   explicit RequiredArgs(unsigned n) : NumRequired(n) {
    390     assert(n != ~0U);
    391   }
    392 
    393   /// Compute the arguments required by the given formal prototype,
    394   /// given that there may be some additional, non-formal arguments
    395   /// in play.
    396   ///
    397   /// If FD is not null, this will consider pass_object_size params in FD.
    398   static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype,
    399                                        unsigned additional,
    400                                        const FunctionDecl *FD) {
    401     if (!prototype->isVariadic()) return All;
    402     if (FD)
    403       additional +=
    404           llvm::count_if(FD->parameters(), [](const ParmVarDecl *PVD) {
    405             return PVD->hasAttr<PassObjectSizeAttr>();
    406           });
    407     return RequiredArgs(prototype->getNumParams() + additional);
    408   }
    409 
    410   static RequiredArgs forPrototype(const FunctionProtoType *prototype,
    411                                    const FunctionDecl *FD) {
    412     return forPrototypePlus(prototype, 0, FD);
    413   }
    414 
    415   static RequiredArgs forPrototype(CanQual<FunctionProtoType> prototype,
    416                                    const FunctionDecl *FD) {
    417     return forPrototype(prototype.getTypePtr(), FD);
    418   }
    419 
    420   static RequiredArgs forPrototypePlus(CanQual<FunctionProtoType> prototype,
    421                                        unsigned additional,
    422                                        const FunctionDecl *FD) {
    423     return forPrototypePlus(prototype.getTypePtr(), additional, FD);
    424   }
    425 
    426   bool allowsOptionalArgs() const { return NumRequired != ~0U; }
    427   unsigned getNumRequiredArgs() const {
    428     assert(allowsOptionalArgs());
    429     return NumRequired;
    430   }
    431 
    432   unsigned getOpaqueData() const { return NumRequired; }
    433   static RequiredArgs getFromOpaqueData(unsigned value) {
    434     if (value == ~0U) return All;
    435     return RequiredArgs(value);
    436   }
    437 };
    438 
    439 // Implementation detail of CGFunctionInfo, factored out so it can be named
    440 // in the TrailingObjects base class of CGFunctionInfo.
    441 struct CGFunctionInfoArgInfo {
    442   CanQualType type;
    443   ABIArgInfo info;
    444 };
    445 
    446 /// CGFunctionInfo - Class to encapsulate the information about a
    447 /// function definition.
    448 class CGFunctionInfo final
    449     : public llvm::FoldingSetNode,
    450       private llvm::TrailingObjects<CGFunctionInfo, CGFunctionInfoArgInfo,
    451                                     FunctionProtoType::ExtParameterInfo> {
    452   typedef CGFunctionInfoArgInfo ArgInfo;
    453   typedef FunctionProtoType::ExtParameterInfo ExtParameterInfo;
    454 
    455   /// The LLVM::CallingConv to use for this function (as specified by the
    456   /// user).
    457   unsigned CallingConvention : 8;
    458 
    459   /// The LLVM::CallingConv to actually use for this function, which may
    460   /// depend on the ABI.
    461   unsigned EffectiveCallingConvention : 8;
    462 
    463   /// The clang::CallingConv that this was originally created with.
    464   unsigned ASTCallingConvention : 7;
    465 
    466   /// Whether this is an instance method.
    467   unsigned InstanceMethod : 1;
    468 
    469   /// Whether this is a chain call.
    470   unsigned ChainCall : 1;
    471 
    472   /// Whether this function is noreturn.
    473   unsigned NoReturn : 1;
    474 
    475   /// Whether this function is returns-retained.
    476   unsigned ReturnsRetained : 1;
    477 
    478   /// Whether this function saved caller registers.
    479   unsigned NoCallerSavedRegs : 1;
    480 
    481   /// How many arguments to pass inreg.
    482   unsigned HasRegParm : 1;
    483   unsigned RegParm : 3;
    484 
    485   RequiredArgs Required;
    486 
    487   /// The struct representing all arguments passed in memory.  Only used when
    488   /// passing non-trivial types with inalloca.  Not part of the profile.
    489   llvm::StructType *ArgStruct;
    490   unsigned ArgStructAlign : 31;
    491   unsigned HasExtParameterInfos : 1;
    492 
    493   unsigned NumArgs;
    494 
    495   ArgInfo *getArgsBuffer() {
    496     return getTrailingObjects<ArgInfo>();
    497   }
    498   const ArgInfo *getArgsBuffer() const {
    499     return getTrailingObjects<ArgInfo>();
    500   }
    501 
    502   ExtParameterInfo *getExtParameterInfosBuffer() {
    503     return getTrailingObjects<ExtParameterInfo>();
    504   }
    505   const ExtParameterInfo *getExtParameterInfosBuffer() const{
    506     return getTrailingObjects<ExtParameterInfo>();
    507   }
    508 
    509   CGFunctionInfo() : Required(RequiredArgs::All) {}
    510 
    511 public:
    512   static CGFunctionInfo *create(unsigned llvmCC,
    513                                 bool instanceMethod,
    514                                 bool chainCall,
    515                                 const FunctionType::ExtInfo &extInfo,
    516                                 ArrayRef<ExtParameterInfo> paramInfos,
    517                                 CanQualType resultType,
    518                                 ArrayRef<CanQualType> argTypes,
    519                                 RequiredArgs required);
    520   void operator delete(void *p) { ::operator delete(p); }
    521 
    522   // Friending class TrailingObjects is apparently not good enough for MSVC,
    523   // so these have to be public.
    524   friend class TrailingObjects;
    525   size_t numTrailingObjects(OverloadToken<ArgInfo>) const {
    526     return NumArgs + 1;
    527   }
    528   size_t numTrailingObjects(OverloadToken<ExtParameterInfo>) const {
    529     return (HasExtParameterInfos ? NumArgs : 0);
    530   }
    531 
    532   typedef const ArgInfo *const_arg_iterator;
    533   typedef ArgInfo *arg_iterator;
    534 
    535   typedef llvm::iterator_range<arg_iterator> arg_range;
    536   typedef llvm::iterator_range<const_arg_iterator> arg_const_range;
    537 
    538   arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
    539   arg_const_range arguments() const {
    540     return arg_const_range(arg_begin(), arg_end());
    541   }
    542 
    543   const_arg_iterator arg_begin() const { return getArgsBuffer() + 1; }
    544   const_arg_iterator arg_end() const { return getArgsBuffer() + 1 + NumArgs; }
    545   arg_iterator arg_begin() { return getArgsBuffer() + 1; }
    546   arg_iterator arg_end() { return getArgsBuffer() + 1 + NumArgs; }
    547 
    548   unsigned  arg_size() const { return NumArgs; }
    549 
    550   bool isVariadic() const { return Required.allowsOptionalArgs(); }
    551   RequiredArgs getRequiredArgs() const { return Required; }
    552   unsigned getNumRequiredArgs() const {
    553     return isVariadic() ? getRequiredArgs().getNumRequiredArgs() : arg_size();
    554   }
    555 
    556   bool isInstanceMethod() const { return InstanceMethod; }
    557 
    558   bool isChainCall() const { return ChainCall; }
    559 
    560   bool isNoReturn() const { return NoReturn; }
    561 
    562   /// In ARC, whether this function retains its return value.  This
    563   /// is not always reliable for call sites.
    564   bool isReturnsRetained() const { return ReturnsRetained; }
    565 
    566   /// Whether this function no longer saves caller registers.
    567   bool isNoCallerSavedRegs() const { return NoCallerSavedRegs; }
    568 
    569   /// getASTCallingConvention() - Return the AST-specified calling
    570   /// convention.
    571   CallingConv getASTCallingConvention() const {
    572     return CallingConv(ASTCallingConvention);
    573   }
    574 
    575   /// getCallingConvention - Return the user specified calling
    576   /// convention, which has been translated into an LLVM CC.
    577   unsigned getCallingConvention() const { return CallingConvention; }
    578 
    579   /// getEffectiveCallingConvention - Return the actual calling convention to
    580   /// use, which may depend on the ABI.
    581   unsigned getEffectiveCallingConvention() const {
    582     return EffectiveCallingConvention;
    583   }
    584   void setEffectiveCallingConvention(unsigned Value) {
    585     EffectiveCallingConvention = Value;
    586   }
    587 
    588   bool getHasRegParm() const { return HasRegParm; }
    589   unsigned getRegParm() const { return RegParm; }
    590 
    591   FunctionType::ExtInfo getExtInfo() const {
    592     return FunctionType::ExtInfo(isNoReturn(), getHasRegParm(), getRegParm(),
    593                                  getASTCallingConvention(), isReturnsRetained(),
    594                                  isNoCallerSavedRegs());
    595   }
    596 
    597   CanQualType getReturnType() const { return getArgsBuffer()[0].type; }
    598 
    599   ABIArgInfo &getReturnInfo() { return getArgsBuffer()[0].info; }
    600   const ABIArgInfo &getReturnInfo() const { return getArgsBuffer()[0].info; }
    601 
    602   ArrayRef<ExtParameterInfo> getExtParameterInfos() const {
    603     if (!HasExtParameterInfos) return {};
    604     return llvm::makeArrayRef(getExtParameterInfosBuffer(), NumArgs);
    605   }
    606   ExtParameterInfo getExtParameterInfo(unsigned argIndex) const {
    607     assert(argIndex <= NumArgs);
    608     if (!HasExtParameterInfos) return ExtParameterInfo();
    609     return getExtParameterInfos()[argIndex];
    610   }
    611 
    612   /// \brief Return true if this function uses inalloca arguments.
    613   bool usesInAlloca() const { return ArgStruct; }
    614 
    615   /// \brief Get the struct type used to represent all the arguments in memory.
    616   llvm::StructType *getArgStruct() const { return ArgStruct; }
    617   CharUnits getArgStructAlignment() const {
    618     return CharUnits::fromQuantity(ArgStructAlign);
    619   }
    620   void setArgStruct(llvm::StructType *Ty, CharUnits Align) {
    621     ArgStruct = Ty;
    622     ArgStructAlign = Align.getQuantity();
    623   }
    624 
    625   void Profile(llvm::FoldingSetNodeID &ID) {
    626     ID.AddInteger(getASTCallingConvention());
    627     ID.AddBoolean(InstanceMethod);
    628     ID.AddBoolean(ChainCall);
    629     ID.AddBoolean(NoReturn);
    630     ID.AddBoolean(ReturnsRetained);
    631     ID.AddBoolean(NoCallerSavedRegs);
    632     ID.AddBoolean(HasRegParm);
    633     ID.AddInteger(RegParm);
    634     ID.AddInteger(Required.getOpaqueData());
    635     ID.AddBoolean(HasExtParameterInfos);
    636     if (HasExtParameterInfos) {
    637       for (auto paramInfo : getExtParameterInfos())
    638         ID.AddInteger(paramInfo.getOpaqueValue());
    639     }
    640     getReturnType().Profile(ID);
    641     for (const auto &I : arguments())
    642       I.type.Profile(ID);
    643   }
    644   static void Profile(llvm::FoldingSetNodeID &ID,
    645                       bool InstanceMethod,
    646                       bool ChainCall,
    647                       const FunctionType::ExtInfo &info,
    648                       ArrayRef<ExtParameterInfo> paramInfos,
    649                       RequiredArgs required,
    650                       CanQualType resultType,
    651                       ArrayRef<CanQualType> argTypes) {
    652     ID.AddInteger(info.getCC());
    653     ID.AddBoolean(InstanceMethod);
    654     ID.AddBoolean(ChainCall);
    655     ID.AddBoolean(info.getNoReturn());
    656     ID.AddBoolean(info.getProducesResult());
    657     ID.AddBoolean(info.getNoCallerSavedRegs());
    658     ID.AddBoolean(info.getHasRegParm());
    659     ID.AddInteger(info.getRegParm());
    660     ID.AddInteger(required.getOpaqueData());
    661     ID.AddBoolean(!paramInfos.empty());
    662     if (!paramInfos.empty()) {
    663       for (auto paramInfo : paramInfos)
    664         ID.AddInteger(paramInfo.getOpaqueValue());
    665     }
    666     resultType.Profile(ID);
    667     for (ArrayRef<CanQualType>::iterator
    668            i = argTypes.begin(), e = argTypes.end(); i != e; ++i) {
    669       i->Profile(ID);
    670     }
    671   }
    672 };
    673 
    674 }  // end namespace CodeGen
    675 }  // end namespace clang
    676 
    677 #endif
    678