clang  8.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  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());
112  }
113 
114  ABIArgInfo(Kind K)
115  : TheKind(K), PaddingInReg(false), InReg(false), SuppressSRet(false) {
116  }
117 
118 public:
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");
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  }
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  }
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");
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 
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 
304  assert(canHaveCoerceToType() && "Invalid kind!");
305  return TypeData;
306  }
307 
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 
319  assert(isCoerceAndExpand());
321  }
322 
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
345  assert(isIndirect() && "Invalid kind!");
347  }
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.
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.
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 
461  const FunctionDecl *FD) {
462  return forPrototype(prototype.getTypePtr(), FD);
463  }
464 
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.
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> {
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> const_arg_range;
585 
586  arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
587  const_arg_range arguments() const {
588  return const_arg_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.
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  }
636  EffectiveCallingConvention = Value;
637  }
638 
639  bool getHasRegParm() const { return HasRegParm; }
640  unsigned getRegParm() const { return RegParm; }
641 
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 
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; }
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);
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
Ignore - Ignore the argument (treat as void).
Represents a function declaration or definition.
Definition: Decl.h:1722
void setEffectiveCallingConvention(unsigned Value)
void setSRetAfterThis(bool AfterThis)
A (possibly-)qualified type.
Definition: Type.h:641
llvm::Type * UnpaddedCoerceAndExpandType
bool getNoCfCheck() const
Definition: Type.h:3389
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.
const_arg_range arguments() const
bool isVariadic() const
Definition: Type.h:3878
llvm::iterator_range< const_arg_iterator > const_arg_range
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:3772
void setCoerceToType(llvm::Type *T)
static ABIArgInfo getIgnore()
Represents a parameter to a function.
Definition: Decl.h:1541
void setDirectOffset(unsigned Offset)
bool usesInAlloca() const
Return true if this function uses inalloca arguments.
unsigned getRegParm() const
Definition: Type.h:3392
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:3557
void setPaddingInReg(bool PIR)
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
Definition: Type.h:6539
static ABIArgInfo getIndirectInReg(CharUnits Alignment, bool ByVal=true, bool Realign=false)
ArrayRef< ParmVarDecl * > parameters() const
Definition: Decl.h:2236
bool getProducesResult() const
Definition: Type.h:3387
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 ...
static ABIArgInfo getExpand()
FunctionType::ExtInfo getExtInfo() const
bool getNoReturn() const
Definition: Type.h:3386
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:3388
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:3536
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
bool getHasRegParm() const
Definition: Type.h:3390
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
void setSuppressSRet(bool Suppress)
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:3399
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:93
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:1878
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
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:3340