clang 18.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
27namespace clang {
28namespace 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.
33public:
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 with the
48 /// specified alignment (0 indicates default alignment) and address space.
50
51 /// IndirectAliased - Similar to Indirect, but the pointer may be to an
52 /// object that is otherwise referenced. The object is known to not be
53 /// modified through any other references for the duration of the call, and
54 /// the callee must not itself modify the object. Because C allows
55 /// parameter variables to be modified and guarantees that they have unique
56 /// addresses, the callee must defensively copy the object into a local
57 /// variable if it might be modified or its address might be compared.
58 /// Since those are uncommon, in principle this convention allows programs
59 /// to avoid copies in more situations. However, it may introduce *extra*
60 /// copies if the callee fails to prove that a copy is unnecessary and the
61 /// caller naturally produces an unaliased object for the argument.
63
64 /// Ignore - Ignore the argument (treat as void). Useful for void and
65 /// empty structs.
67
68 /// Expand - Only valid for aggregate argument types. The structure should
69 /// be expanded into consecutive arguments for its constituent fields.
70 /// Currently expand is only allowed on structures whose fields
71 /// are all scalar types or are themselves expandable types.
73
74 /// CoerceAndExpand - Only valid for aggregate argument types. The
75 /// structure should be expanded into consecutive arguments corresponding
76 /// to the non-array elements of the type stored in CoerceToType.
77 /// Array elements in the type are assumed to be padding and skipped.
79
80 /// InAlloca - Pass the argument directly using the LLVM inalloca attribute.
81 /// This is similar to indirect with byval, except it only applies to
82 /// arguments stored in memory and forbids any implicit copies. When
83 /// applied to a return type, it means the value is returned indirectly via
84 /// an implicit sret parameter stored in the argument struct.
88 };
89
90private:
91 llvm::Type *TypeData; // canHaveCoerceToType()
92 union {
93 llvm::Type *PaddingType; // canHavePaddingType()
94 llvm::Type *UnpaddedCoerceAndExpandType; // isCoerceAndExpand()
95 };
96 struct DirectAttrInfo {
97 unsigned Offset;
98 unsigned Align;
99 };
100 struct IndirectAttrInfo {
101 unsigned Align;
102 unsigned AddrSpace;
103 };
104 union {
105 DirectAttrInfo DirectAttr; // isDirect() || isExtend()
106 IndirectAttrInfo IndirectAttr; // isIndirect()
107 unsigned AllocaFieldIndex; // isInAlloca()
108 };
109 Kind TheKind;
110 bool PaddingInReg : 1;
111 bool InAllocaSRet : 1; // isInAlloca()
112 bool InAllocaIndirect : 1;// isInAlloca()
113 bool IndirectByVal : 1; // isIndirect()
114 bool IndirectRealign : 1; // isIndirect()
115 bool SRetAfterThis : 1; // isIndirect()
116 bool InReg : 1; // isDirect() || isExtend() || isIndirect()
117 bool CanBeFlattened: 1; // isDirect()
118 bool SignExt : 1; // isExtend()
119
120 bool canHavePaddingType() const {
121 return isDirect() || isExtend() || isIndirect() || isIndirectAliased() ||
122 isExpand();
123 }
124 void setPaddingType(llvm::Type *T) {
125 assert(canHavePaddingType());
126 PaddingType = T;
127 }
128
129 void setUnpaddedCoerceToType(llvm::Type *T) {
130 assert(isCoerceAndExpand());
132 }
133
134public:
136 : TypeData(nullptr), PaddingType(nullptr), DirectAttr{0, 0}, TheKind(K),
137 PaddingInReg(false), InAllocaSRet(false),
138 InAllocaIndirect(false), IndirectByVal(false), IndirectRealign(false),
139 SRetAfterThis(false), InReg(false), CanBeFlattened(false),
140 SignExt(false) {}
141
142 static ABIArgInfo getDirect(llvm::Type *T = nullptr, unsigned Offset = 0,
143 llvm::Type *Padding = nullptr,
144 bool CanBeFlattened = true, unsigned Align = 0) {
145 auto AI = ABIArgInfo(Direct);
146 AI.setCoerceToType(T);
147 AI.setPaddingType(Padding);
148 AI.setDirectOffset(Offset);
149 AI.setDirectAlign(Align);
150 AI.setCanBeFlattened(CanBeFlattened);
151 return AI;
152 }
153 static ABIArgInfo getDirectInReg(llvm::Type *T = nullptr) {
154 auto AI = getDirect(T);
155 AI.setInReg(true);
156 return AI;
157 }
158
159 static ABIArgInfo getSignExtend(QualType Ty, llvm::Type *T = nullptr) {
160 assert(Ty->isIntegralOrEnumerationType() && "Unexpected QualType");
161 auto AI = ABIArgInfo(Extend);
162 AI.setCoerceToType(T);
163 AI.setPaddingType(nullptr);
164 AI.setDirectOffset(0);
165 AI.setDirectAlign(0);
166 AI.setSignExt(true);
167 return AI;
168 }
169
170 static ABIArgInfo getZeroExtend(QualType Ty, llvm::Type *T = nullptr) {
171 assert(Ty->isIntegralOrEnumerationType() && "Unexpected QualType");
172 auto AI = ABIArgInfo(Extend);
173 AI.setCoerceToType(T);
174 AI.setPaddingType(nullptr);
175 AI.setDirectOffset(0);
176 AI.setDirectAlign(0);
177 AI.setSignExt(false);
178 return AI;
179 }
180
181 // ABIArgInfo will record the argument as being extended based on the sign
182 // of its type.
183 static ABIArgInfo getExtend(QualType Ty, llvm::Type *T = nullptr) {
184 assert(Ty->isIntegralOrEnumerationType() && "Unexpected QualType");
186 return getSignExtend(Ty, T);
187 return getZeroExtend(Ty, T);
188 }
189
190 static ABIArgInfo getExtendInReg(QualType Ty, llvm::Type *T = nullptr) {
191 auto AI = getExtend(Ty, T);
192 AI.setInReg(true);
193 return AI;
194 }
196 return ABIArgInfo(Ignore);
197 }
198 static ABIArgInfo getIndirect(CharUnits Alignment, bool ByVal = true,
199 bool Realign = false,
200 llvm::Type *Padding = nullptr) {
201 auto AI = ABIArgInfo(Indirect);
202 AI.setIndirectAlign(Alignment);
203 AI.setIndirectByVal(ByVal);
204 AI.setIndirectRealign(Realign);
205 AI.setSRetAfterThis(false);
206 AI.setPaddingType(Padding);
207 return AI;
208 }
209
210 /// Pass this in memory using the IR byref attribute.
211 static ABIArgInfo getIndirectAliased(CharUnits Alignment, unsigned AddrSpace,
212 bool Realign = false,
213 llvm::Type *Padding = nullptr) {
214 auto AI = ABIArgInfo(IndirectAliased);
215 AI.setIndirectAlign(Alignment);
216 AI.setIndirectRealign(Realign);
217 AI.setPaddingType(Padding);
218 AI.setIndirectAddrSpace(AddrSpace);
219 return AI;
220 }
221
222 static ABIArgInfo getIndirectInReg(CharUnits Alignment, bool ByVal = true,
223 bool Realign = false) {
224 auto AI = getIndirect(Alignment, ByVal, Realign);
225 AI.setInReg(true);
226 return AI;
227 }
228 static ABIArgInfo getInAlloca(unsigned FieldIndex, bool Indirect = false) {
229 auto AI = ABIArgInfo(InAlloca);
230 AI.setInAllocaFieldIndex(FieldIndex);
231 AI.setInAllocaIndirect(Indirect);
232 return AI;
233 }
235 auto AI = ABIArgInfo(Expand);
236 AI.setPaddingType(nullptr);
237 return AI;
238 }
239 static ABIArgInfo getExpandWithPadding(bool PaddingInReg,
240 llvm::Type *Padding) {
241 auto AI = getExpand();
242 AI.setPaddingInReg(PaddingInReg);
243 AI.setPaddingType(Padding);
244 return AI;
245 }
246
247 /// \param unpaddedCoerceToType The coerce-to type with padding elements
248 /// removed, canonicalized to a single element if it would otherwise
249 /// have exactly one element.
250 static ABIArgInfo getCoerceAndExpand(llvm::StructType *coerceToType,
251 llvm::Type *unpaddedCoerceToType) {
252#ifndef NDEBUG
253 // Check that unpaddedCoerceToType has roughly the right shape.
254
255 // Assert that we only have a struct type if there are multiple elements.
256 auto unpaddedStruct = dyn_cast<llvm::StructType>(unpaddedCoerceToType);
257 assert(!unpaddedStruct || unpaddedStruct->getNumElements() != 1);
258
259 // Assert that all the non-padding elements have a corresponding element
260 // in the unpadded type.
261 unsigned unpaddedIndex = 0;
262 for (auto eltType : coerceToType->elements()) {
263 if (isPaddingForCoerceAndExpand(eltType)) continue;
264 if (unpaddedStruct) {
265 assert(unpaddedStruct->getElementType(unpaddedIndex) == eltType);
266 } else {
267 assert(unpaddedIndex == 0 && unpaddedCoerceToType == eltType);
268 }
269 unpaddedIndex++;
270 }
271
272 // Assert that there aren't extra elements in the unpadded type.
273 if (unpaddedStruct) {
274 assert(unpaddedStruct->getNumElements() == unpaddedIndex);
275 } else {
276 assert(unpaddedIndex == 1);
277 }
278#endif
279
280 auto AI = ABIArgInfo(CoerceAndExpand);
281 AI.setCoerceToType(coerceToType);
282 AI.setUnpaddedCoerceToType(unpaddedCoerceToType);
283 return AI;
284 }
285
286 static bool isPaddingForCoerceAndExpand(llvm::Type *eltType) {
287 if (eltType->isArrayTy()) {
288 assert(eltType->getArrayElementType()->isIntegerTy(8));
289 return true;
290 } else {
291 return false;
292 }
293 }
294
295 Kind getKind() const { return TheKind; }
296 bool isDirect() const { return TheKind == Direct; }
297 bool isInAlloca() const { return TheKind == InAlloca; }
298 bool isExtend() const { return TheKind == Extend; }
299 bool isIgnore() const { return TheKind == Ignore; }
300 bool isIndirect() const { return TheKind == Indirect; }
301 bool isIndirectAliased() const { return TheKind == IndirectAliased; }
302 bool isExpand() const { return TheKind == Expand; }
303 bool isCoerceAndExpand() const { return TheKind == CoerceAndExpand; }
304
305 bool canHaveCoerceToType() const {
306 return isDirect() || isExtend() || isCoerceAndExpand();
307 }
308
309 // Direct/Extend accessors
310 unsigned getDirectOffset() const {
311 assert((isDirect() || isExtend()) && "Not a direct or extend kind");
312 return DirectAttr.Offset;
313 }
314 void setDirectOffset(unsigned Offset) {
315 assert((isDirect() || isExtend()) && "Not a direct or extend kind");
316 DirectAttr.Offset = Offset;
317 }
318
319 unsigned getDirectAlign() const {
320 assert((isDirect() || isExtend()) && "Not a direct or extend kind");
321 return DirectAttr.Align;
322 }
323 void setDirectAlign(unsigned Align) {
324 assert((isDirect() || isExtend()) && "Not a direct or extend kind");
325 DirectAttr.Align = Align;
326 }
327
328 bool isSignExt() const {
329 assert(isExtend() && "Invalid kind!");
330 return SignExt;
331 }
332 void setSignExt(bool SExt) {
333 assert(isExtend() && "Invalid kind!");
334 SignExt = SExt;
335 }
336
337 llvm::Type *getPaddingType() const {
338 return (canHavePaddingType() ? PaddingType : nullptr);
339 }
340
341 bool getPaddingInReg() const {
342 return PaddingInReg;
343 }
344 void setPaddingInReg(bool PIR) {
345 PaddingInReg = PIR;
346 }
347
348 llvm::Type *getCoerceToType() const {
349 assert(canHaveCoerceToType() && "Invalid kind!");
350 return TypeData;
351 }
352
353 void setCoerceToType(llvm::Type *T) {
354 assert(canHaveCoerceToType() && "Invalid kind!");
355 TypeData = T;
356 }
357
358 llvm::StructType *getCoerceAndExpandType() const {
359 assert(isCoerceAndExpand());
360 return cast<llvm::StructType>(TypeData);
361 }
362
363 llvm::Type *getUnpaddedCoerceAndExpandType() const {
364 assert(isCoerceAndExpand());
366 }
367
369 assert(isCoerceAndExpand());
370 if (auto structTy =
371 dyn_cast<llvm::StructType>(UnpaddedCoerceAndExpandType)) {
372 return structTy->elements();
373 } else {
375 }
376 }
377
378 bool getInReg() const {
379 assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!");
380 return InReg;
381 }
382
383 void setInReg(bool IR) {
384 assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!");
385 InReg = IR;
386 }
387
388 // Indirect accessors
390 assert((isIndirect() || isIndirectAliased()) && "Invalid kind!");
392 }
394 assert((isIndirect() || isIndirectAliased()) && "Invalid kind!");
395 IndirectAttr.Align = IA.getQuantity();
396 }
397
398 bool getIndirectByVal() const {
399 assert(isIndirect() && "Invalid kind!");
400 return IndirectByVal;
401 }
402 void setIndirectByVal(bool IBV) {
403 assert(isIndirect() && "Invalid kind!");
404 IndirectByVal = IBV;
405 }
406
407 unsigned getIndirectAddrSpace() const {
408 assert(isIndirectAliased() && "Invalid kind!");
409 return IndirectAttr.AddrSpace;
410 }
411
412 void setIndirectAddrSpace(unsigned AddrSpace) {
413 assert(isIndirectAliased() && "Invalid kind!");
414 IndirectAttr.AddrSpace = AddrSpace;
415 }
416
417 bool getIndirectRealign() const {
418 assert((isIndirect() || isIndirectAliased()) && "Invalid kind!");
419 return IndirectRealign;
420 }
421 void setIndirectRealign(bool IR) {
422 assert((isIndirect() || isIndirectAliased()) && "Invalid kind!");
423 IndirectRealign = IR;
424 }
425
426 bool isSRetAfterThis() const {
427 assert(isIndirect() && "Invalid kind!");
428 return SRetAfterThis;
429 }
430 void setSRetAfterThis(bool AfterThis) {
431 assert(isIndirect() && "Invalid kind!");
432 SRetAfterThis = AfterThis;
433 }
434
435 unsigned getInAllocaFieldIndex() const {
436 assert(isInAlloca() && "Invalid kind!");
437 return AllocaFieldIndex;
438 }
439 void setInAllocaFieldIndex(unsigned FieldIndex) {
440 assert(isInAlloca() && "Invalid kind!");
441 AllocaFieldIndex = FieldIndex;
442 }
443
444 unsigned getInAllocaIndirect() const {
445 assert(isInAlloca() && "Invalid kind!");
446 return InAllocaIndirect;
447 }
449 assert(isInAlloca() && "Invalid kind!");
450 InAllocaIndirect = Indirect;
451 }
452
453 /// Return true if this field of an inalloca struct should be returned
454 /// to implement a struct return calling convention.
455 bool getInAllocaSRet() const {
456 assert(isInAlloca() && "Invalid kind!");
457 return InAllocaSRet;
458 }
459
460 void setInAllocaSRet(bool SRet) {
461 assert(isInAlloca() && "Invalid kind!");
462 InAllocaSRet = SRet;
463 }
464
465 bool getCanBeFlattened() const {
466 assert(isDirect() && "Invalid kind!");
467 return CanBeFlattened;
468 }
469
470 void setCanBeFlattened(bool Flatten) {
471 assert(isDirect() && "Invalid kind!");
472 CanBeFlattened = Flatten;
473 }
474
475 void dump() const;
476};
477
478/// A class for recording the number of arguments that a function
479/// signature requires.
481 /// The number of required arguments, or ~0 if the signature does
482 /// not permit optional arguments.
483 unsigned NumRequired;
484public:
485 enum All_t { All };
486
487 RequiredArgs(All_t _) : NumRequired(~0U) {}
488 explicit RequiredArgs(unsigned n) : NumRequired(n) {
489 assert(n != ~0U);
490 }
491
492 /// Compute the arguments required by the given formal prototype,
493 /// given that there may be some additional, non-formal arguments
494 /// in play.
495 ///
496 /// If FD is not null, this will consider pass_object_size params in FD.
498 unsigned additional) {
499 if (!prototype->isVariadic()) return All;
500
501 if (prototype->hasExtParameterInfos())
502 additional += llvm::count_if(
503 prototype->getExtParameterInfos(),
504 [](const FunctionProtoType::ExtParameterInfo &ExtInfo) {
505 return ExtInfo.hasPassObjectSize();
506 });
507
508 return RequiredArgs(prototype->getNumParams() + additional);
509 }
510
512 unsigned additional) {
513 return forPrototypePlus(prototype.getTypePtr(), additional);
514 }
515
516 static RequiredArgs forPrototype(const FunctionProtoType *prototype) {
517 return forPrototypePlus(prototype, 0);
518 }
519
521 return forPrototypePlus(prototype.getTypePtr(), 0);
522 }
523
524 bool allowsOptionalArgs() const { return NumRequired != ~0U; }
525 unsigned getNumRequiredArgs() const {
526 assert(allowsOptionalArgs());
527 return NumRequired;
528 }
529
530 /// Return true if the argument at a given index is required.
531 bool isRequiredArg(unsigned argIdx) const {
532 return argIdx == ~0U || argIdx < NumRequired;
533 }
534
535 unsigned getOpaqueData() const { return NumRequired; }
536 static RequiredArgs getFromOpaqueData(unsigned value) {
537 if (value == ~0U) return All;
538 return RequiredArgs(value);
539 }
540};
541
542// Implementation detail of CGFunctionInfo, factored out so it can be named
543// in the TrailingObjects base class of CGFunctionInfo.
547};
548
549/// CGFunctionInfo - Class to encapsulate the information about a
550/// function definition.
551class CGFunctionInfo final
552 : public llvm::FoldingSetNode,
553 private llvm::TrailingObjects<CGFunctionInfo, CGFunctionInfoArgInfo,
554 FunctionProtoType::ExtParameterInfo> {
557
558 /// The LLVM::CallingConv to use for this function (as specified by the
559 /// user).
560 unsigned CallingConvention : 8;
561
562 /// The LLVM::CallingConv to actually use for this function, which may
563 /// depend on the ABI.
564 unsigned EffectiveCallingConvention : 8;
565
566 /// The clang::CallingConv that this was originally created with.
567 unsigned ASTCallingConvention : 6;
568
569 /// Whether this is an instance method.
570 unsigned InstanceMethod : 1;
571
572 /// Whether this is a chain call.
573 unsigned ChainCall : 1;
574
575 /// Whether this function is called by forwarding arguments.
576 /// This doesn't support inalloca or varargs.
577 unsigned DelegateCall : 1;
578
579 /// Whether this function is a CMSE nonsecure call
580 unsigned CmseNSCall : 1;
581
582 /// Whether this function is noreturn.
583 unsigned NoReturn : 1;
584
585 /// Whether this function is returns-retained.
586 unsigned ReturnsRetained : 1;
587
588 /// Whether this function saved caller registers.
589 unsigned NoCallerSavedRegs : 1;
590
591 /// How many arguments to pass inreg.
592 unsigned HasRegParm : 1;
593 unsigned RegParm : 3;
594
595 /// Whether this function has nocf_check attribute.
596 unsigned NoCfCheck : 1;
597
598 /// Log 2 of the maximum vector width.
599 unsigned MaxVectorWidth : 4;
600
601 RequiredArgs Required;
602
603 /// The struct representing all arguments passed in memory. Only used when
604 /// passing non-trivial types with inalloca. Not part of the profile.
605 llvm::StructType *ArgStruct;
606 unsigned ArgStructAlign : 31;
607 unsigned HasExtParameterInfos : 1;
608
609 unsigned NumArgs;
610
611 ArgInfo *getArgsBuffer() {
612 return getTrailingObjects<ArgInfo>();
613 }
614 const ArgInfo *getArgsBuffer() const {
615 return getTrailingObjects<ArgInfo>();
616 }
617
618 ExtParameterInfo *getExtParameterInfosBuffer() {
619 return getTrailingObjects<ExtParameterInfo>();
620 }
621 const ExtParameterInfo *getExtParameterInfosBuffer() const{
622 return getTrailingObjects<ExtParameterInfo>();
623 }
624
626
627public:
628 static CGFunctionInfo *
629 create(unsigned llvmCC, bool instanceMethod, bool chainCall,
630 bool delegateCall, const FunctionType::ExtInfo &extInfo,
631 ArrayRef<ExtParameterInfo> paramInfos, CanQualType resultType,
632 ArrayRef<CanQualType> argTypes, RequiredArgs required);
633 void operator delete(void *p) { ::operator delete(p); }
634
635 // Friending class TrailingObjects is apparently not good enough for MSVC,
636 // so these have to be public.
637 friend class TrailingObjects;
638 size_t numTrailingObjects(OverloadToken<ArgInfo>) const {
639 return NumArgs + 1;
640 }
641 size_t numTrailingObjects(OverloadToken<ExtParameterInfo>) const {
642 return (HasExtParameterInfos ? NumArgs : 0);
643 }
644
647
649 return MutableArrayRef<ArgInfo>(arg_begin(), NumArgs);
650 }
652 return ArrayRef<ArgInfo>(arg_begin(), NumArgs);
653 }
654
655 const_arg_iterator arg_begin() const { return getArgsBuffer() + 1; }
656 const_arg_iterator arg_end() const { return getArgsBuffer() + 1 + NumArgs; }
657 arg_iterator arg_begin() { return getArgsBuffer() + 1; }
658 arg_iterator arg_end() { return getArgsBuffer() + 1 + NumArgs; }
659
660 unsigned arg_size() const { return NumArgs; }
661
662 bool isVariadic() const { return Required.allowsOptionalArgs(); }
664 unsigned getNumRequiredArgs() const {
666 }
667
668 bool isInstanceMethod() const { return InstanceMethod; }
669
670 bool isChainCall() const { return ChainCall; }
671
672 bool isDelegateCall() const { return DelegateCall; }
673
674 bool isCmseNSCall() const { return CmseNSCall; }
675
676 bool isNoReturn() const { return NoReturn; }
677
678 /// In ARC, whether this function retains its return value. This
679 /// is not always reliable for call sites.
680 bool isReturnsRetained() const { return ReturnsRetained; }
681
682 /// Whether this function no longer saves caller registers.
683 bool isNoCallerSavedRegs() const { return NoCallerSavedRegs; }
684
685 /// Whether this function has nocf_check attribute.
686 bool isNoCfCheck() const { return NoCfCheck; }
687
688 /// getASTCallingConvention() - Return the AST-specified calling
689 /// convention.
691 return CallingConv(ASTCallingConvention);
692 }
693
694 /// getCallingConvention - Return the user specified calling
695 /// convention, which has been translated into an LLVM CC.
696 unsigned getCallingConvention() const { return CallingConvention; }
697
698 /// getEffectiveCallingConvention - Return the actual calling convention to
699 /// use, which may depend on the ABI.
701 return EffectiveCallingConvention;
702 }
704 EffectiveCallingConvention = Value;
705 }
706
707 bool getHasRegParm() const { return HasRegParm; }
708 unsigned getRegParm() const { return RegParm; }
709
714 isCmseNSCall());
715 }
716
717 CanQualType getReturnType() const { return getArgsBuffer()[0].type; }
718
719 ABIArgInfo &getReturnInfo() { return getArgsBuffer()[0].info; }
720 const ABIArgInfo &getReturnInfo() const { return getArgsBuffer()[0].info; }
721
723 if (!HasExtParameterInfos) return {};
724 return llvm::ArrayRef(getExtParameterInfosBuffer(), NumArgs);
725 }
726 ExtParameterInfo getExtParameterInfo(unsigned argIndex) const {
727 assert(argIndex <= NumArgs);
728 if (!HasExtParameterInfos) return ExtParameterInfo();
729 return getExtParameterInfos()[argIndex];
730 }
731
732 /// Return true if this function uses inalloca arguments.
733 bool usesInAlloca() const { return ArgStruct; }
734
735 /// Get the struct type used to represent all the arguments in memory.
736 llvm::StructType *getArgStruct() const { return ArgStruct; }
738 return CharUnits::fromQuantity(ArgStructAlign);
739 }
740 void setArgStruct(llvm::StructType *Ty, CharUnits Align) {
741 ArgStruct = Ty;
742 ArgStructAlign = Align.getQuantity();
743 }
744
745 /// Return the maximum vector width in the arguments.
746 unsigned getMaxVectorWidth() const {
747 return MaxVectorWidth ? 1U << (MaxVectorWidth - 1) : 0;
748 }
749
750 /// Set the maximum vector width in the arguments.
751 void setMaxVectorWidth(unsigned Width) {
752 assert(llvm::isPowerOf2_32(Width) && "Expected power of 2 vector");
753 MaxVectorWidth = llvm::countr_zero(Width) + 1;
754 }
755
756 void Profile(llvm::FoldingSetNodeID &ID) {
757 ID.AddInteger(getASTCallingConvention());
758 ID.AddBoolean(InstanceMethod);
759 ID.AddBoolean(ChainCall);
760 ID.AddBoolean(DelegateCall);
761 ID.AddBoolean(NoReturn);
762 ID.AddBoolean(ReturnsRetained);
763 ID.AddBoolean(NoCallerSavedRegs);
764 ID.AddBoolean(HasRegParm);
765 ID.AddInteger(RegParm);
766 ID.AddBoolean(NoCfCheck);
767 ID.AddBoolean(CmseNSCall);
768 ID.AddInteger(Required.getOpaqueData());
769 ID.AddBoolean(HasExtParameterInfos);
770 if (HasExtParameterInfos) {
771 for (auto paramInfo : getExtParameterInfos())
772 ID.AddInteger(paramInfo.getOpaqueValue());
773 }
775 for (const auto &I : arguments())
776 I.type.Profile(ID);
777 }
778 static void Profile(llvm::FoldingSetNodeID &ID, bool InstanceMethod,
779 bool ChainCall, bool IsDelegateCall,
780 const FunctionType::ExtInfo &info,
782 RequiredArgs required, CanQualType resultType,
783 ArrayRef<CanQualType> argTypes) {
784 ID.AddInteger(info.getCC());
785 ID.AddBoolean(InstanceMethod);
786 ID.AddBoolean(ChainCall);
787 ID.AddBoolean(IsDelegateCall);
788 ID.AddBoolean(info.getNoReturn());
789 ID.AddBoolean(info.getProducesResult());
790 ID.AddBoolean(info.getNoCallerSavedRegs());
791 ID.AddBoolean(info.getHasRegParm());
792 ID.AddInteger(info.getRegParm());
793 ID.AddBoolean(info.getNoCfCheck());
794 ID.AddBoolean(info.getCmseNSCall());
795 ID.AddInteger(required.getOpaqueData());
796 ID.AddBoolean(!paramInfos.empty());
797 if (!paramInfos.empty()) {
798 for (auto paramInfo : paramInfos)
799 ID.AddInteger(paramInfo.getOpaqueValue());
800 }
801 resultType.Profile(ID);
803 i = argTypes.begin(), e = argTypes.end(); i != e; ++i) {
804 i->Profile(ID);
805 }
806 }
807};
808
809} // end namespace CodeGen
810} // end namespace clang
811
812#endif
static char ID
Definition: Arena.cpp:183
C Language Family Type Representation.
Represents a canonical, potentially-qualified type.
Definition: CanonicalType.h:65
void Profile(llvm::FoldingSetNodeID &ID) const
const T * getTypePtr() const
Retrieve the underlying type pointer, which refers to a canonical type.
Definition: CanonicalType.h:83
CharUnits - This is an opaque type for sizes expressed in character units.
Definition: CharUnits.h:38
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Definition: CharUnits.h:185
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
Definition: CharUnits.h:63
ABIArgInfo - Helper class to encapsulate information about how a specific C type should be passed to ...
unsigned getInAllocaFieldIndex() const
void setIndirectAddrSpace(unsigned AddrSpace)
llvm::StructType * getCoerceAndExpandType() const
static ABIArgInfo getInAlloca(unsigned FieldIndex, bool Indirect=false)
static ABIArgInfo getIgnore()
static ABIArgInfo getExpand()
void setCoerceToType(llvm::Type *T)
llvm::Type * getUnpaddedCoerceAndExpandType() const
unsigned getDirectOffset() const
static bool isPaddingForCoerceAndExpand(llvm::Type *eltType)
void setDirectOffset(unsigned Offset)
void setPaddingInReg(bool PIR)
bool getInAllocaSRet() const
Return true if this field of an inalloca struct should be returned to implement a struct return calli...
void setIndirectAlign(CharUnits IA)
llvm::Type * getPaddingType() const
void setIndirectByVal(bool IBV)
static ABIArgInfo getExtendInReg(QualType Ty, llvm::Type *T=nullptr)
static ABIArgInfo getExpandWithPadding(bool PaddingInReg, llvm::Type *Padding)
unsigned getDirectAlign() const
unsigned getIndirectAddrSpace() const
static ABIArgInfo getIndirectInReg(CharUnits Alignment, bool ByVal=true, bool Realign=false)
static ABIArgInfo getIndirect(CharUnits Alignment, bool ByVal=true, bool Realign=false, llvm::Type *Padding=nullptr)
void setIndirectRealign(bool IR)
static ABIArgInfo getDirect(llvm::Type *T=nullptr, unsigned Offset=0, llvm::Type *Padding=nullptr, bool CanBeFlattened=true, unsigned Align=0)
@ Extend
Extend - Valid only for integer argument types.
@ Ignore
Ignore - Ignore the argument (treat as void).
@ IndirectAliased
IndirectAliased - Similar to Indirect, but the pointer may be to an object that is otherwise referenc...
@ Expand
Expand - Only valid for aggregate argument types.
@ InAlloca
InAlloca - Pass the argument directly using the LLVM inalloca attribute.
@ Indirect
Indirect - Pass the argument indirectly via a hidden pointer with the specified alignment (0 indicate...
@ CoerceAndExpand
CoerceAndExpand - Only valid for aggregate argument types.
@ Direct
Direct - Pass the argument directly using the normal converted LLVM type, or by coercing to another s...
ArrayRef< llvm::Type * > getCoerceAndExpandTypeSequence() const
static ABIArgInfo getIndirectAliased(CharUnits Alignment, unsigned AddrSpace, bool Realign=false, llvm::Type *Padding=nullptr)
Pass this in memory using the IR byref attribute.
void setSRetAfterThis(bool AfterThis)
void setInAllocaIndirect(bool Indirect)
void setInAllocaSRet(bool SRet)
static ABIArgInfo getZeroExtend(QualType Ty, llvm::Type *T=nullptr)
static ABIArgInfo getExtend(QualType Ty, llvm::Type *T=nullptr)
static ABIArgInfo getCoerceAndExpand(llvm::StructType *coerceToType, llvm::Type *unpaddedCoerceToType)
unsigned getInAllocaIndirect() const
llvm::Type * getCoerceToType() const
void setInAllocaFieldIndex(unsigned FieldIndex)
IndirectAttrInfo IndirectAttr
llvm::Type * UnpaddedCoerceAndExpandType
void setCanBeFlattened(bool Flatten)
void setDirectAlign(unsigned Align)
static ABIArgInfo getSignExtend(QualType Ty, llvm::Type *T=nullptr)
CharUnits getIndirectAlign() const
static ABIArgInfo getDirectInReg(llvm::Type *T=nullptr)
CGFunctionInfo - Class to encapsulate the information about a function definition.
bool usesInAlloca() const
Return true if this function uses inalloca arguments.
FunctionType::ExtInfo getExtInfo() const
bool isReturnsRetained() const
In ARC, whether this function retains its return value.
unsigned getCallingConvention() const
getCallingConvention - Return the user specified calling convention, which has been translated into a...
void Profile(llvm::FoldingSetNodeID &ID)
const_arg_iterator arg_begin() const
bool isNoCallerSavedRegs() const
Whether this function no longer saves caller registers.
ArrayRef< ExtParameterInfo > getExtParameterInfos() const
CanQualType getReturnType() const
bool isNoCfCheck() const
Whether this function has nocf_check attribute.
CallingConv getASTCallingConvention() const
getASTCallingConvention() - Return the AST-specified calling convention.
const ABIArgInfo & getReturnInfo() const
ArrayRef< ArgInfo > arguments() const
static CGFunctionInfo * create(unsigned llvmCC, bool instanceMethod, bool chainCall, bool delegateCall, const FunctionType::ExtInfo &extInfo, ArrayRef< ExtParameterInfo > paramInfos, CanQualType resultType, ArrayRef< CanQualType > argTypes, RequiredArgs required)
Definition: CGCall.cpp:819
static void Profile(llvm::FoldingSetNodeID &ID, bool InstanceMethod, bool ChainCall, bool IsDelegateCall, const FunctionType::ExtInfo &info, ArrayRef< ExtParameterInfo > paramInfos, RequiredArgs required, CanQualType resultType, ArrayRef< CanQualType > argTypes)
MutableArrayRef< ArgInfo > arguments()
const_arg_iterator arg_end() const
unsigned getEffectiveCallingConvention() const
getEffectiveCallingConvention - Return the actual calling convention to use, which may depend on the ...
void setArgStruct(llvm::StructType *Ty, CharUnits Align)
size_t numTrailingObjects(OverloadToken< ArgInfo >) const
ExtParameterInfo getExtParameterInfo(unsigned argIndex) const
unsigned getMaxVectorWidth() const
Return the maximum vector width in the arguments.
CharUnits getArgStructAlignment() const
size_t numTrailingObjects(OverloadToken< ExtParameterInfo >) const
RequiredArgs getRequiredArgs() const
void setEffectiveCallingConvention(unsigned Value)
unsigned getNumRequiredArgs() const
llvm::StructType * getArgStruct() const
Get the struct type used to represent all the arguments in memory.
void setMaxVectorWidth(unsigned Width)
Set the maximum vector width in the arguments.
A class for recording the number of arguments that a function signature requires.
static RequiredArgs forPrototypePlus(CanQual< FunctionProtoType > prototype, unsigned additional)
unsigned getNumRequiredArgs() const
static RequiredArgs forPrototype(CanQual< FunctionProtoType > prototype)
static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype, unsigned additional)
Compute the arguments required by the given formal prototype, given that there may be some additional...
static RequiredArgs getFromOpaqueData(unsigned value)
bool isRequiredArg(unsigned argIdx) const
Return true if the argument at a given index is required.
static RequiredArgs forPrototype(const FunctionProtoType *prototype)
unsigned getOpaqueData() const
Represents a prototype with parameter type info, e.g.
Definition: Type.h:4159
unsigned getNumParams() const
Definition: Type.h:4376
bool isVariadic() const
Whether this function prototype is variadic.
Definition: Type.h:4499
ArrayRef< ExtParameterInfo > getExtParameterInfos() const
Definition: Type.h:4564
bool hasExtParameterInfos() const
Is there any interesting extra information for any of the parameters of this function type?
Definition: Type.h:4560
A class which abstracts out some details necessary for making a call.
Definition: Type.h:3904
CallingConv getCC() const
Definition: Type.h:3966
bool getCmseNSCall() const
Definition: Type.h:3954
bool getNoCfCheck() const
Definition: Type.h:3956
unsigned getRegParm() const
Definition: Type.h:3959
bool getNoCallerSavedRegs() const
Definition: Type.h:3955
bool getHasRegParm() const
Definition: Type.h:3957
bool getNoReturn() const
Definition: Type.h:3952
bool getProducesResult() const
Definition: Type.h:3953
Interesting information about a specific parameter that can't simply be reflected in parameter's type...
Definition: Type.h:3819
A (possibly-)qualified type.
Definition: Type.h:737
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
Definition: Type.h:7446
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g....
Definition: Type.cpp:2123
CallingConv
CallingConv - Specifies the calling convention that a function uses.
Definition: Specifiers.h:273
#define false
Definition: stdbool.h:22