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