Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

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