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