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