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