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