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