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