clang  10.0.0git
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 
19 #include "clang/AST/CharUnits.h"
20 #include "clang/AST/Decl.h"
21 #include "clang/AST/Type.h"
22 #include "llvm/IR/DerivedTypes.h"
23 #include "llvm/ADT/FoldingSet.h"
24 #include "llvm/Support/TrailingObjects.h"
25 #include <cassert>
26 
27 namespace clang {
28 namespace CodeGen {
29 
30 /// ABIArgInfo - Helper class to encapsulate information about how a
31 /// specific C type should be passed to or returned from a function.
32 class ABIArgInfo {
33 public:
34  enum Kind : uint8_t {
35  /// Direct - Pass the argument directly using the normal converted LLVM
36  /// type, or by coercing to another specified type stored in
37  /// 'CoerceToType'). If an offset is specified (in UIntData), then the
38  /// argument passed is offset by some number of bytes in the memory
39  /// representation. A dummy argument is emitted before the real argument
40  /// if the specified type stored in "PaddingType" is not zero.
42 
43  /// Extend - Valid only for integer argument types. Same as 'direct'
44  /// but also emit a zero/sign extension attribute.
46 
47  /// Indirect - Pass the argument indirectly via a hidden pointer
48  /// with the specified alignment (0 indicates default alignment).
50 
51  /// Ignore - Ignore the argument (treat as void). Useful for void and
52  /// empty structs.
54 
55  /// Expand - Only valid for aggregate argument types. The structure should
56  /// be expanded into consecutive arguments for its constituent fields.
57  /// Currently expand is only allowed on structures whose fields
58  /// are all scalar types or are themselves expandable types.
60 
61  /// CoerceAndExpand - Only valid for aggregate argument types. The
62  /// structure should be expanded into consecutive arguments corresponding
63  /// to the non-array elements of the type stored in CoerceToType.
64  /// Array elements in the type are assumed to be padding and skipped.
66 
67  /// InAlloca - Pass the argument directly using the LLVM inalloca attribute.
68  /// This is similar to indirect with byval, except it only applies to
69  /// arguments stored in memory and forbids any implicit copies. When
70  /// applied to a return type, it means the value is returned indirectly via
71  /// an implicit sret parameter stored in the argument struct.
75  };
76 
77 private:
78  llvm::Type *TypeData; // canHaveCoerceToType()
79  union {
80  llvm::Type *PaddingType; // canHavePaddingType()
81  llvm::Type *UnpaddedCoerceAndExpandType; // isCoerceAndExpand()
82  };
83  union {
84  unsigned DirectOffset; // isDirect() || isExtend()
85  unsigned IndirectAlign; // isIndirect()
86  unsigned AllocaFieldIndex; // isInAlloca()
87  };
88  Kind TheKind;
89  bool PaddingInReg : 1;
90  bool InAllocaSRet : 1; // isInAlloca()
91  bool IndirectByVal : 1; // isIndirect()
92  bool IndirectRealign : 1; // isIndirect()
93  bool SRetAfterThis : 1; // isIndirect()
94  bool InReg : 1; // isDirect() || isExtend() || isIndirect()
95  bool CanBeFlattened: 1; // isDirect()
96  bool SignExt : 1; // isExtend()
97 
98  bool canHavePaddingType() const {
99  return isDirect() || isExtend() || isIndirect() || isExpand();
100  }
101  void setPaddingType(llvm::Type *T) {
102  assert(canHavePaddingType());
103  PaddingType = T;
104  }
105 
106  void setUnpaddedCoerceToType(llvm::Type *T) {
107  assert(isCoerceAndExpand());
109  }
110 
111 public:
113  : TypeData(nullptr), PaddingType(nullptr), DirectOffset(0),
114  TheKind(K), PaddingInReg(false), InAllocaSRet(false),
115  IndirectByVal(false), IndirectRealign(false), SRetAfterThis(false),
116  InReg(false), CanBeFlattened(false), SignExt(false) {}
117 
118  static ABIArgInfo getDirect(llvm::Type *T = nullptr, unsigned Offset = 0,
119  llvm::Type *Padding = nullptr,
120  bool CanBeFlattened = true) {
121  auto AI = ABIArgInfo(Direct);
122  AI.setCoerceToType(T);
123  AI.setPaddingType(Padding);
124  AI.setDirectOffset(Offset);
125  AI.setCanBeFlattened(CanBeFlattened);
126  return AI;
127  }
128  static ABIArgInfo getDirectInReg(llvm::Type *T = nullptr) {
129  auto AI = getDirect(T);
130  AI.setInReg(true);
131  return AI;
132  }
133 
134  static ABIArgInfo getSignExtend(QualType Ty, llvm::Type *T = nullptr) {
135  assert(Ty->isIntegralOrEnumerationType() && "Unexpected QualType");
136  auto AI = ABIArgInfo(Extend);
137  AI.setCoerceToType(T);
138  AI.setPaddingType(nullptr);
139  AI.setDirectOffset(0);
140  AI.setSignExt(true);
141  return AI;
142  }
143 
144  static ABIArgInfo getZeroExtend(QualType Ty, llvm::Type *T = nullptr) {
145  assert(Ty->isIntegralOrEnumerationType() && "Unexpected QualType");
146  auto AI = ABIArgInfo(Extend);
147  AI.setCoerceToType(T);
148  AI.setPaddingType(nullptr);
149  AI.setDirectOffset(0);
150  AI.setSignExt(false);
151  return AI;
152  }
153 
154  // ABIArgInfo will record the argument as being extended based on the sign
155  // of its type.
156  static ABIArgInfo getExtend(QualType Ty, llvm::Type *T = nullptr) {
157  assert(Ty->isIntegralOrEnumerationType() && "Unexpected QualType");
159  return getSignExtend(Ty, T);
160  return getZeroExtend(Ty, T);
161  }
162 
163  static ABIArgInfo getExtendInReg(QualType Ty, llvm::Type *T = nullptr) {
164  auto AI = getExtend(Ty, T);
165  AI.setInReg(true);
166  return AI;
167  }
169  return ABIArgInfo(Ignore);
170  }
171  static ABIArgInfo getIndirect(CharUnits Alignment, bool ByVal = true,
172  bool Realign = false,
173  llvm::Type *Padding = nullptr) {
174  auto AI = ABIArgInfo(Indirect);
175  AI.setIndirectAlign(Alignment);
176  AI.setIndirectByVal(ByVal);
177  AI.setIndirectRealign(Realign);
178  AI.setSRetAfterThis(false);
179  AI.setPaddingType(Padding);
180  return AI;
181  }
182  static ABIArgInfo getIndirectInReg(CharUnits Alignment, bool ByVal = true,
183  bool Realign = false) {
184  auto AI = getIndirect(Alignment, ByVal, Realign);
185  AI.setInReg(true);
186  return AI;
187  }
188  static ABIArgInfo getInAlloca(unsigned FieldIndex) {
189  auto AI = ABIArgInfo(InAlloca);
190  AI.setInAllocaFieldIndex(FieldIndex);
191  return AI;
192  }
194  auto AI = ABIArgInfo(Expand);
195  AI.setPaddingType(nullptr);
196  return AI;
197  }
198  static ABIArgInfo getExpandWithPadding(bool PaddingInReg,
199  llvm::Type *Padding) {
200  auto AI = getExpand();
201  AI.setPaddingInReg(PaddingInReg);
202  AI.setPaddingType(Padding);
203  return AI;
204  }
205 
206  /// \param unpaddedCoerceToType The coerce-to type with padding elements
207  /// removed, canonicalized to a single element if it would otherwise
208  /// have exactly one element.
209  static ABIArgInfo getCoerceAndExpand(llvm::StructType *coerceToType,
210  llvm::Type *unpaddedCoerceToType) {
211 #ifndef NDEBUG
212  // Sanity checks on unpaddedCoerceToType.
213 
214  // Assert that we only have a struct type if there are multiple elements.
215  auto unpaddedStruct = dyn_cast<llvm::StructType>(unpaddedCoerceToType);
216  assert(!unpaddedStruct || unpaddedStruct->getNumElements() != 1);
217 
218  // Assert that all the non-padding elements have a corresponding element
219  // in the unpadded type.
220  unsigned unpaddedIndex = 0;
221  for (auto eltType : coerceToType->elements()) {
222  if (isPaddingForCoerceAndExpand(eltType)) continue;
223  if (unpaddedStruct) {
224  assert(unpaddedStruct->getElementType(unpaddedIndex) == eltType);
225  } else {
226  assert(unpaddedIndex == 0 && unpaddedCoerceToType == eltType);
227  }
228  unpaddedIndex++;
229  }
230 
231  // Assert that there aren't extra elements in the unpadded type.
232  if (unpaddedStruct) {
233  assert(unpaddedStruct->getNumElements() == unpaddedIndex);
234  } else {
235  assert(unpaddedIndex == 1);
236  }
237 #endif
238 
239  auto AI = ABIArgInfo(CoerceAndExpand);
240  AI.setCoerceToType(coerceToType);
241  AI.setUnpaddedCoerceToType(unpaddedCoerceToType);
242  return AI;
243  }
244 
245  static bool isPaddingForCoerceAndExpand(llvm::Type *eltType) {
246  if (eltType->isArrayTy()) {
247  assert(eltType->getArrayElementType()->isIntegerTy(8));
248  return true;
249  } else {
250  return false;
251  }
252  }
253 
254  Kind getKind() const { return TheKind; }
255  bool isDirect() const { return TheKind == Direct; }
256  bool isInAlloca() const { return TheKind == InAlloca; }
257  bool isExtend() const { return TheKind == Extend; }
258  bool isIgnore() const { return TheKind == Ignore; }
259  bool isIndirect() const { return TheKind == Indirect; }
260  bool isExpand() const { return TheKind == Expand; }
261  bool isCoerceAndExpand() const { return TheKind == CoerceAndExpand; }
262 
263  bool canHaveCoerceToType() const {
264  return isDirect() || isExtend() || isCoerceAndExpand();
265  }
266 
267  // Direct/Extend accessors
268  unsigned getDirectOffset() const {
269  assert((isDirect() || isExtend()) && "Not a direct or extend kind");
270  return DirectOffset;
271  }
272  void setDirectOffset(unsigned Offset) {
273  assert((isDirect() || isExtend()) && "Not a direct or extend kind");
275  }
276 
277  bool isSignExt() const {
278  assert(isExtend() && "Invalid kind!");
279  return SignExt;
280  }
281  void setSignExt(bool SExt) {
282  assert(isExtend() && "Invalid kind!");
283  SignExt = SExt;
284  }
285 
287  return (canHavePaddingType() ? PaddingType : nullptr);
288  }
289 
290  bool getPaddingInReg() const {
291  return PaddingInReg;
292  }
293  void setPaddingInReg(bool PIR) {
294  PaddingInReg = PIR;
295  }
296 
298  assert(canHaveCoerceToType() && "Invalid kind!");
299  return TypeData;
300  }
301 
303  assert(canHaveCoerceToType() && "Invalid kind!");
304  TypeData = T;
305  }
306 
307  llvm::StructType *getCoerceAndExpandType() const {
308  assert(isCoerceAndExpand());
309  return cast<llvm::StructType>(TypeData);
310  }
311 
313  assert(isCoerceAndExpand());
315  }
316 
318  assert(isCoerceAndExpand());
319  if (auto structTy =
320  dyn_cast<llvm::StructType>(UnpaddedCoerceAndExpandType)) {
321  return structTy->elements();
322  } else {
323  return llvm::makeArrayRef(&UnpaddedCoerceAndExpandType, 1);
324  }
325  }
326 
327  bool getInReg() const {
328  assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!");
329  return InReg;
330  }
331 
332  void setInReg(bool IR) {
333  assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!");
334  InReg = IR;
335  }
336 
337  // Indirect accessors
339  assert(isIndirect() && "Invalid kind!");
341  }
343  assert(isIndirect() && "Invalid kind!");
344  IndirectAlign = IA.getQuantity();
345  }
346 
347  bool getIndirectByVal() const {
348  assert(isIndirect() && "Invalid kind!");
349  return IndirectByVal;
350  }
351  void setIndirectByVal(bool IBV) {
352  assert(isIndirect() && "Invalid kind!");
353  IndirectByVal = IBV;
354  }
355 
356  bool getIndirectRealign() const {
357  assert(isIndirect() && "Invalid kind!");
358  return IndirectRealign;
359  }
360  void setIndirectRealign(bool IR) {
361  assert(isIndirect() && "Invalid kind!");
362  IndirectRealign = IR;
363  }
364 
365  bool isSRetAfterThis() const {
366  assert(isIndirect() && "Invalid kind!");
367  return SRetAfterThis;
368  }
369  void setSRetAfterThis(bool AfterThis) {
370  assert(isIndirect() && "Invalid kind!");
371  SRetAfterThis = AfterThis;
372  }
373 
374  unsigned getInAllocaFieldIndex() const {
375  assert(isInAlloca() && "Invalid kind!");
376  return AllocaFieldIndex;
377  }
378  void setInAllocaFieldIndex(unsigned FieldIndex) {
379  assert(isInAlloca() && "Invalid kind!");
380  AllocaFieldIndex = FieldIndex;
381  }
382 
383  /// Return true if this field of an inalloca struct should be returned
384  /// to implement a struct return calling convention.
385  bool getInAllocaSRet() const {
386  assert(isInAlloca() && "Invalid kind!");
387  return InAllocaSRet;
388  }
389 
390  void setInAllocaSRet(bool SRet) {
391  assert(isInAlloca() && "Invalid kind!");
392  InAllocaSRet = SRet;
393  }
394 
395  bool getCanBeFlattened() const {
396  assert(isDirect() && "Invalid kind!");
397  return CanBeFlattened;
398  }
399 
400  void setCanBeFlattened(bool Flatten) {
401  assert(isDirect() && "Invalid kind!");
402  CanBeFlattened = Flatten;
403  }
404 
405  void dump() const;
406 };
407 
408 /// A class for recording the number of arguments that a function
409 /// signature requires.
411  /// The number of required arguments, or ~0 if the signature does
412  /// not permit optional arguments.
413  unsigned NumRequired;
414 public:
415  enum All_t { All };
416 
417  RequiredArgs(All_t _) : NumRequired(~0U) {}
418  explicit RequiredArgs(unsigned n) : NumRequired(n) {
419  assert(n != ~0U);
420  }
421 
422  /// Compute the arguments required by the given formal prototype,
423  /// given that there may be some additional, non-formal arguments
424  /// in play.
425  ///
426  /// If FD is not null, this will consider pass_object_size params in FD.
428  unsigned additional) {
429  if (!prototype->isVariadic()) return All;
430 
431  if (prototype->hasExtParameterInfos())
432  additional += llvm::count_if(
433  prototype->getExtParameterInfos(),
434  [](const FunctionProtoType::ExtParameterInfo &ExtInfo) {
435  return ExtInfo.hasPassObjectSize();
436  });
437 
438  return RequiredArgs(prototype->getNumParams() + additional);
439  }
440 
442  unsigned additional) {
443  return forPrototypePlus(prototype.getTypePtr(), additional);
444  }
445 
446  static RequiredArgs forPrototype(const FunctionProtoType *prototype) {
447  return forPrototypePlus(prototype, 0);
448  }
449 
451  return forPrototypePlus(prototype.getTypePtr(), 0);
452  }
453 
454  bool allowsOptionalArgs() const { return NumRequired != ~0U; }
455  unsigned getNumRequiredArgs() const {
456  assert(allowsOptionalArgs());
457  return NumRequired;
458  }
459 
460  unsigned getOpaqueData() const { return NumRequired; }
461  static RequiredArgs getFromOpaqueData(unsigned value) {
462  if (value == ~0U) return All;
463  return RequiredArgs(value);
464  }
465 };
466 
467 // Implementation detail of CGFunctionInfo, factored out so it can be named
468 // in the TrailingObjects base class of CGFunctionInfo.
472 };
473 
474 /// CGFunctionInfo - Class to encapsulate the information about a
475 /// function definition.
476 class CGFunctionInfo final
477  : public llvm::FoldingSetNode,
478  private llvm::TrailingObjects<CGFunctionInfo, CGFunctionInfoArgInfo,
479  FunctionProtoType::ExtParameterInfo> {
482 
483  /// The LLVM::CallingConv to use for this function (as specified by the
484  /// user).
485  unsigned CallingConvention : 8;
486 
487  /// The LLVM::CallingConv to actually use for this function, which may
488  /// depend on the ABI.
489  unsigned EffectiveCallingConvention : 8;
490 
491  /// The clang::CallingConv that this was originally created with.
492  unsigned ASTCallingConvention : 6;
493 
494  /// Whether this is an instance method.
495  unsigned InstanceMethod : 1;
496 
497  /// Whether this is a chain call.
498  unsigned ChainCall : 1;
499 
500  /// Whether this function is noreturn.
501  unsigned NoReturn : 1;
502 
503  /// Whether this function is returns-retained.
504  unsigned ReturnsRetained : 1;
505 
506  /// Whether this function saved caller registers.
507  unsigned NoCallerSavedRegs : 1;
508 
509  /// How many arguments to pass inreg.
510  unsigned HasRegParm : 1;
511  unsigned RegParm : 3;
512 
513  /// Whether this function has nocf_check attribute.
514  unsigned NoCfCheck : 1;
515 
516  RequiredArgs Required;
517 
518  /// The struct representing all arguments passed in memory. Only used when
519  /// passing non-trivial types with inalloca. Not part of the profile.
520  llvm::StructType *ArgStruct;
521  unsigned ArgStructAlign : 31;
522  unsigned HasExtParameterInfos : 1;
523 
524  unsigned NumArgs;
525 
526  ArgInfo *getArgsBuffer() {
527  return getTrailingObjects<ArgInfo>();
528  }
529  const ArgInfo *getArgsBuffer() const {
530  return getTrailingObjects<ArgInfo>();
531  }
532 
533  ExtParameterInfo *getExtParameterInfosBuffer() {
534  return getTrailingObjects<ExtParameterInfo>();
535  }
536  const ExtParameterInfo *getExtParameterInfosBuffer() const{
537  return getTrailingObjects<ExtParameterInfo>();
538  }
539 
540  CGFunctionInfo() : Required(RequiredArgs::All) {}
541 
542 public:
543  static CGFunctionInfo *create(unsigned llvmCC,
544  bool instanceMethod,
545  bool chainCall,
546  const FunctionType::ExtInfo &extInfo,
547  ArrayRef<ExtParameterInfo> paramInfos,
548  CanQualType resultType,
549  ArrayRef<CanQualType> argTypes,
550  RequiredArgs required);
551  void operator delete(void *p) { ::operator delete(p); }
552 
553  // Friending class TrailingObjects is apparently not good enough for MSVC,
554  // so these have to be public.
555  friend class TrailingObjects;
556  size_t numTrailingObjects(OverloadToken<ArgInfo>) const {
557  return NumArgs + 1;
558  }
559  size_t numTrailingObjects(OverloadToken<ExtParameterInfo>) const {
560  return (HasExtParameterInfos ? NumArgs : 0);
561  }
562 
563  typedef const ArgInfo *const_arg_iterator;
564  typedef ArgInfo *arg_iterator;
565 
567  return MutableArrayRef<ArgInfo>(arg_begin(), NumArgs);
568  }
570  return ArrayRef<ArgInfo>(arg_begin(), NumArgs);
571  }
572 
573  const_arg_iterator arg_begin() const { return getArgsBuffer() + 1; }
574  const_arg_iterator arg_end() const { return getArgsBuffer() + 1 + NumArgs; }
575  arg_iterator arg_begin() { return getArgsBuffer() + 1; }
576  arg_iterator arg_end() { return getArgsBuffer() + 1 + NumArgs; }
577 
578  unsigned arg_size() const { return NumArgs; }
579 
580  bool isVariadic() const { return Required.allowsOptionalArgs(); }
581  RequiredArgs getRequiredArgs() const { return Required; }
582  unsigned getNumRequiredArgs() const {
583  return isVariadic() ? getRequiredArgs().getNumRequiredArgs() : arg_size();
584  }
585 
586  bool isInstanceMethod() const { return InstanceMethod; }
587 
588  bool isChainCall() const { return ChainCall; }
589 
590  bool isNoReturn() const { return NoReturn; }
591 
592  /// In ARC, whether this function retains its return value. This
593  /// is not always reliable for call sites.
594  bool isReturnsRetained() const { return ReturnsRetained; }
595 
596  /// Whether this function no longer saves caller registers.
597  bool isNoCallerSavedRegs() const { return NoCallerSavedRegs; }
598 
599  /// Whether this function has nocf_check attribute.
600  bool isNoCfCheck() const { return NoCfCheck; }
601 
602  /// getASTCallingConvention() - Return the AST-specified calling
603  /// convention.
605  return CallingConv(ASTCallingConvention);
606  }
607 
608  /// getCallingConvention - Return the user specified calling
609  /// convention, which has been translated into an LLVM CC.
610  unsigned getCallingConvention() const { return CallingConvention; }
611 
612  /// getEffectiveCallingConvention - Return the actual calling convention to
613  /// use, which may depend on the ABI.
614  unsigned getEffectiveCallingConvention() const {
615  return EffectiveCallingConvention;
616  }
618  EffectiveCallingConvention = Value;
619  }
620 
621  bool getHasRegParm() const { return HasRegParm; }
622  unsigned getRegParm() const { return RegParm; }
623 
625  return FunctionType::ExtInfo(isNoReturn(), getHasRegParm(), getRegParm(),
626  getASTCallingConvention(), isReturnsRetained(),
627  isNoCallerSavedRegs(), isNoCfCheck());
628  }
629 
630  CanQualType getReturnType() const { return getArgsBuffer()[0].type; }
631 
632  ABIArgInfo &getReturnInfo() { return getArgsBuffer()[0].info; }
633  const ABIArgInfo &getReturnInfo() const { return getArgsBuffer()[0].info; }
634 
636  if (!HasExtParameterInfos) return {};
637  return llvm::makeArrayRef(getExtParameterInfosBuffer(), NumArgs);
638  }
639  ExtParameterInfo getExtParameterInfo(unsigned argIndex) const {
640  assert(argIndex <= NumArgs);
641  if (!HasExtParameterInfos) return ExtParameterInfo();
642  return getExtParameterInfos()[argIndex];
643  }
644 
645  /// Return true if this function uses inalloca arguments.
646  bool usesInAlloca() const { return ArgStruct; }
647 
648  /// Get the struct type used to represent all the arguments in memory.
649  llvm::StructType *getArgStruct() const { return ArgStruct; }
651  return CharUnits::fromQuantity(ArgStructAlign);
652  }
653  void setArgStruct(llvm::StructType *Ty, CharUnits Align) {
654  ArgStruct = Ty;
655  ArgStructAlign = Align.getQuantity();
656  }
657 
658  void Profile(llvm::FoldingSetNodeID &ID) {
659  ID.AddInteger(getASTCallingConvention());
660  ID.AddBoolean(InstanceMethod);
661  ID.AddBoolean(ChainCall);
662  ID.AddBoolean(NoReturn);
663  ID.AddBoolean(ReturnsRetained);
664  ID.AddBoolean(NoCallerSavedRegs);
665  ID.AddBoolean(HasRegParm);
666  ID.AddInteger(RegParm);
667  ID.AddBoolean(NoCfCheck);
668  ID.AddInteger(Required.getOpaqueData());
669  ID.AddBoolean(HasExtParameterInfos);
670  if (HasExtParameterInfos) {
671  for (auto paramInfo : getExtParameterInfos())
672  ID.AddInteger(paramInfo.getOpaqueValue());
673  }
674  getReturnType().Profile(ID);
675  for (const auto &I : arguments())
676  I.type.Profile(ID);
677  }
678  static void Profile(llvm::FoldingSetNodeID &ID,
679  bool InstanceMethod,
680  bool ChainCall,
681  const FunctionType::ExtInfo &info,
682  ArrayRef<ExtParameterInfo> paramInfos,
683  RequiredArgs required,
684  CanQualType resultType,
685  ArrayRef<CanQualType> argTypes) {
686  ID.AddInteger(info.getCC());
687  ID.AddBoolean(InstanceMethod);
688  ID.AddBoolean(ChainCall);
689  ID.AddBoolean(info.getNoReturn());
690  ID.AddBoolean(info.getProducesResult());
691  ID.AddBoolean(info.getNoCallerSavedRegs());
692  ID.AddBoolean(info.getHasRegParm());
693  ID.AddInteger(info.getRegParm());
694  ID.AddBoolean(info.getNoCfCheck());
695  ID.AddInteger(required.getOpaqueData());
696  ID.AddBoolean(!paramInfos.empty());
697  if (!paramInfos.empty()) {
698  for (auto paramInfo : paramInfos)
699  ID.AddInteger(paramInfo.getOpaqueValue());
700  }
701  resultType.Profile(ID);
703  i = argTypes.begin(), e = argTypes.end(); i != e; ++i) {
704  i->Profile(ID);
705  }
706  }
707 };
708 
709 } // end namespace CodeGen
710 } // end namespace clang
711 
712 #endif
Ignore - Ignore the argument (treat as void).
void setEffectiveCallingConvention(unsigned Value)
void setSRetAfterThis(bool AfterThis)
A (possibly-)qualified type.
Definition: Type.h:654
llvm::Type * UnpaddedCoerceAndExpandType
bool getNoCfCheck() const
Definition: Type.h:3582
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:4148
C Language Family Type Representation.
Extend - Valid only for integer argument types.
bool isNoCfCheck() const
Whether this function has nocf_check attribute.
bool isVariadic() const
Whether this function prototype is variadic.
Definition: Type.h:4086
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
MutableArrayRef< ArgInfo > arguments()
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:3964
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:3585
Indirect - Pass the argument indirectly via a hidden pointer with the specified alignment (0 indicate...
ArrayRef< ExtParameterInfo > getExtParameterInfos() const
Definition: Type.h:4152
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:6881
static ABIArgInfo getIndirectInReg(CharUnits Alignment, bool ByVal=true, bool Realign=false)
bool getProducesResult() const
Definition: Type.h:3580
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:3579
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:3581
static ABIArgInfo getZeroExtend(QualType Ty, llvm::Type *T=nullptr)
ArrayRef< ArgInfo > arguments() const
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:3754
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:1827
static ABIArgInfo getExtend(QualType Ty, llvm::Type *T=nullptr)
llvm::Type * getUnpaddedCoerceAndExpandType() const
bool getHasRegParm() const
Definition: Type.h:3583
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:3592
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.
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:3448
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:1958
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:3533