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