clang 20.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 bool ZeroExt : 1; // isExtend()
120
121 bool canHavePaddingType() const {
122 return isDirect() || isExtend() || isIndirect() || isIndirectAliased() ||
123 isExpand();
124 }
125 void setPaddingType(llvm::Type *T) {
126 assert(canHavePaddingType());
127 PaddingType = T;
128 }
129
130 void setUnpaddedCoerceToType(llvm::Type *T) {
131 assert(isCoerceAndExpand());
133 }
134
135public:
137 : TypeData(nullptr), PaddingType(nullptr), DirectAttr{0, 0}, TheKind(K),
138 PaddingInReg(false), InAllocaSRet(false),
139 InAllocaIndirect(false), IndirectByVal(false), IndirectRealign(false),
140 SRetAfterThis(false), InReg(false), CanBeFlattened(false),
141 SignExt(false), ZeroExt(false) {}
142
143 static ABIArgInfo getDirect(llvm::Type *T = nullptr, unsigned Offset = 0,
144 llvm::Type *Padding = nullptr,
145 bool CanBeFlattened = true, unsigned Align = 0) {
146 auto AI = ABIArgInfo(Direct);
147 AI.setCoerceToType(T);
148 AI.setPaddingType(Padding);
149 AI.setDirectOffset(Offset);
150 AI.setDirectAlign(Align);
151 AI.setCanBeFlattened(CanBeFlattened);
152 return AI;
153 }
154 static ABIArgInfo getDirectInReg(llvm::Type *T = nullptr) {
155 auto AI = getDirect(T);
156 AI.setInReg(true);
157 return AI;
158 }
159
160 static ABIArgInfo getSignExtend(QualType Ty, llvm::Type *T = nullptr) {
161 assert(Ty->isIntegralOrEnumerationType() && "Unexpected QualType");
162 auto AI = ABIArgInfo(Extend);
163 AI.setCoerceToType(T);
164 AI.setPaddingType(nullptr);
165 AI.setDirectOffset(0);
166 AI.setDirectAlign(0);
167 AI.setSignExt(true);
168 return AI;
169 }
170
171 static ABIArgInfo getZeroExtend(QualType Ty, llvm::Type *T = nullptr) {
172 assert(Ty->isIntegralOrEnumerationType() && "Unexpected QualType");
173 auto AI = ABIArgInfo(Extend);
174 AI.setCoerceToType(T);
175 AI.setPaddingType(nullptr);
176 AI.setDirectOffset(0);
177 AI.setDirectAlign(0);
178 AI.setZeroExt(true);
179 return AI;
180 }
181
182 // ABIArgInfo will record the argument as being extended based on the sign
183 // of its type. Produces a sign or zero extension.
184 static ABIArgInfo getExtend(QualType Ty, llvm::Type *T = nullptr) {
185 assert(Ty->isIntegralOrEnumerationType() && "Unexpected QualType");
187 return getSignExtend(Ty, T);
188 return getZeroExtend(Ty, T);
189 }
190
191 // Struct in register marked explicitly as not needing extension.
192 static ABIArgInfo getNoExtend(llvm::IntegerType *T) {
193 auto AI = ABIArgInfo(Extend);
194 AI.setCoerceToType(T);
195 AI.setPaddingType(nullptr);
196 AI.setDirectOffset(0);
197 AI.setDirectAlign(0);
198 return AI;
199 }
200
201 static ABIArgInfo getExtendInReg(QualType Ty, llvm::Type *T = nullptr) {
202 auto AI = getExtend(Ty, T);
203 AI.setInReg(true);
204 return AI;
205 }
207 return ABIArgInfo(Ignore);
208 }
209 static ABIArgInfo getIndirect(CharUnits Alignment, bool ByVal = true,
210 bool Realign = false,
211 llvm::Type *Padding = nullptr) {
212 auto AI = ABIArgInfo(Indirect);
213 AI.setIndirectAlign(Alignment);
214 AI.setIndirectByVal(ByVal);
215 AI.setIndirectRealign(Realign);
216 AI.setSRetAfterThis(false);
217 AI.setPaddingType(Padding);
218 return AI;
219 }
220
221 /// Pass this in memory using the IR byref attribute.
222 static ABIArgInfo getIndirectAliased(CharUnits Alignment, unsigned AddrSpace,
223 bool Realign = false,
224 llvm::Type *Padding = nullptr) {
225 auto AI = ABIArgInfo(IndirectAliased);
226 AI.setIndirectAlign(Alignment);
227 AI.setIndirectRealign(Realign);
228 AI.setPaddingType(Padding);
229 AI.setIndirectAddrSpace(AddrSpace);
230 return AI;
231 }
232
233 static ABIArgInfo getIndirectInReg(CharUnits Alignment, bool ByVal = true,
234 bool Realign = false) {
235 auto AI = getIndirect(Alignment, ByVal, Realign);
236 AI.setInReg(true);
237 return AI;
238 }
239 static ABIArgInfo getInAlloca(unsigned FieldIndex, bool Indirect = false) {
240 auto AI = ABIArgInfo(InAlloca);
241 AI.setInAllocaFieldIndex(FieldIndex);
242 AI.setInAllocaIndirect(Indirect);
243 return AI;
244 }
246 auto AI = ABIArgInfo(Expand);
247 AI.setPaddingType(nullptr);
248 return AI;
249 }
250 static ABIArgInfo getExpandWithPadding(bool PaddingInReg,
251 llvm::Type *Padding) {
252 auto AI = getExpand();
253 AI.setPaddingInReg(PaddingInReg);
254 AI.setPaddingType(Padding);
255 return AI;
256 }
257
258 /// \param unpaddedCoerceToType The coerce-to type with padding elements
259 /// removed, canonicalized to a single element if it would otherwise
260 /// have exactly one element.
261 static ABIArgInfo getCoerceAndExpand(llvm::StructType *coerceToType,
262 llvm::Type *unpaddedCoerceToType) {
263#ifndef NDEBUG
264 // Check that unpaddedCoerceToType has roughly the right shape.
265
266 // Assert that we only have a struct type if there are multiple elements.
267 auto unpaddedStruct = dyn_cast<llvm::StructType>(unpaddedCoerceToType);
268 assert(!unpaddedStruct || unpaddedStruct->getNumElements() != 1);
269
270 // Assert that all the non-padding elements have a corresponding element
271 // in the unpadded type.
272 unsigned unpaddedIndex = 0;
273 for (auto eltType : coerceToType->elements()) {
274 if (isPaddingForCoerceAndExpand(eltType))
275 continue;
276 unpaddedIndex++;
277 }
278
279 // Assert that there aren't extra elements in the unpadded type.
280 if (unpaddedStruct) {
281 assert(unpaddedStruct->getNumElements() == unpaddedIndex);
282 } else {
283 assert(unpaddedIndex == 1);
284 }
285#endif
286
287 auto AI = ABIArgInfo(CoerceAndExpand);
288 AI.setCoerceToType(coerceToType);
289 AI.setUnpaddedCoerceToType(unpaddedCoerceToType);
290 return AI;
291 }
292
293 static bool isPaddingForCoerceAndExpand(llvm::Type *eltType) {
294 return eltType->isArrayTy() &&
295 eltType->getArrayElementType()->isIntegerTy(8);
296 }
297
298 Kind getKind() const { return TheKind; }
299 bool isDirect() const { return TheKind == Direct; }
300 bool isInAlloca() const { return TheKind == InAlloca; }
301 bool isExtend() const { return TheKind == Extend; }
302 bool isIgnore() const { return TheKind == Ignore; }
303 bool isIndirect() const { return TheKind == Indirect; }
304 bool isIndirectAliased() const { return TheKind == IndirectAliased; }
305 bool isExpand() const { return TheKind == Expand; }
306 bool isCoerceAndExpand() const { return TheKind == CoerceAndExpand; }
307
308 bool canHaveCoerceToType() const {
309 return isDirect() || isExtend() || isCoerceAndExpand();
310 }
311
312 // Direct/Extend accessors
313 unsigned getDirectOffset() const {
314 assert((isDirect() || isExtend()) && "Not a direct or extend kind");
315 return DirectAttr.Offset;
316 }
317 void setDirectOffset(unsigned Offset) {
318 assert((isDirect() || isExtend()) && "Not a direct or extend kind");
319 DirectAttr.Offset = Offset;
320 }
321
322 unsigned getDirectAlign() const {
323 assert((isDirect() || isExtend()) && "Not a direct or extend kind");
324 return DirectAttr.Align;
325 }
326 void setDirectAlign(unsigned Align) {
327 assert((isDirect() || isExtend()) && "Not a direct or extend kind");
328 DirectAttr.Align = Align;
329 }
330
331 bool isSignExt() const {
332 assert(isExtend() && (SignExt + ZeroExt <= 1) && "Invalid kind / flags!");
333 return SignExt;
334 }
335 void setSignExt(bool SExt) {
336 assert(isExtend() && "Invalid kind!");
337 SignExt = SExt;
338 }
339
340 bool isZeroExt() const {
341 assert(isExtend() && (SignExt + ZeroExt <= 1) && "Invalid kind / flags!");
342 return ZeroExt;
343 }
344 void setZeroExt(bool ZExt) {
345 assert(isExtend() && "Invalid kind!");
346 ZeroExt = ZExt;
347 }
348
349 bool isNoExt() const {
350 assert(isExtend() && (SignExt + ZeroExt <= 1) && "Invalid kind / flags!");
351 return !SignExt && !ZeroExt;
352 }
353
354 llvm::Type *getPaddingType() const {
355 return (canHavePaddingType() ? PaddingType : nullptr);
356 }
357
358 bool getPaddingInReg() const {
359 return PaddingInReg;
360 }
361 void setPaddingInReg(bool PIR) {
362 PaddingInReg = PIR;
363 }
364
365 llvm::Type *getCoerceToType() const {
366 assert(canHaveCoerceToType() && "Invalid kind!");
367 return TypeData;
368 }
369
370 void setCoerceToType(llvm::Type *T) {
371 assert(canHaveCoerceToType() && "Invalid kind!");
372 TypeData = T;
373 }
374
375 llvm::StructType *getCoerceAndExpandType() const {
376 assert(isCoerceAndExpand());
377 return cast<llvm::StructType>(TypeData);
378 }
379
380 llvm::Type *getUnpaddedCoerceAndExpandType() const {
381 assert(isCoerceAndExpand());
383 }
384
386 assert(isCoerceAndExpand());
387 if (auto structTy =
388 dyn_cast<llvm::StructType>(UnpaddedCoerceAndExpandType)) {
389 return structTy->elements();
390 } else {
392 }
393 }
394
395 bool getInReg() const {
396 assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!");
397 return InReg;
398 }
399
400 void setInReg(bool IR) {
401 assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!");
402 InReg = IR;
403 }
404
405 // Indirect accessors
407 assert((isIndirect() || isIndirectAliased()) && "Invalid kind!");
409 }
411 assert((isIndirect() || isIndirectAliased()) && "Invalid kind!");
412 IndirectAttr.Align = IA.getQuantity();
413 }
414
415 bool getIndirectByVal() const {
416 assert(isIndirect() && "Invalid kind!");
417 return IndirectByVal;
418 }
419 void setIndirectByVal(bool IBV) {
420 assert(isIndirect() && "Invalid kind!");
421 IndirectByVal = IBV;
422 }
423
424 unsigned getIndirectAddrSpace() const {
425 assert(isIndirectAliased() && "Invalid kind!");
426 return IndirectAttr.AddrSpace;
427 }
428
429 void setIndirectAddrSpace(unsigned AddrSpace) {
430 assert(isIndirectAliased() && "Invalid kind!");
431 IndirectAttr.AddrSpace = AddrSpace;
432 }
433
434 bool getIndirectRealign() const {
435 assert((isIndirect() || isIndirectAliased()) && "Invalid kind!");
436 return IndirectRealign;
437 }
438 void setIndirectRealign(bool IR) {
439 assert((isIndirect() || isIndirectAliased()) && "Invalid kind!");
440 IndirectRealign = IR;
441 }
442
443 bool isSRetAfterThis() const {
444 assert(isIndirect() && "Invalid kind!");
445 return SRetAfterThis;
446 }
447 void setSRetAfterThis(bool AfterThis) {
448 assert(isIndirect() && "Invalid kind!");
449 SRetAfterThis = AfterThis;
450 }
451
452 unsigned getInAllocaFieldIndex() const {
453 assert(isInAlloca() && "Invalid kind!");
454 return AllocaFieldIndex;
455 }
456 void setInAllocaFieldIndex(unsigned FieldIndex) {
457 assert(isInAlloca() && "Invalid kind!");
458 AllocaFieldIndex = FieldIndex;
459 }
460
461 unsigned getInAllocaIndirect() const {
462 assert(isInAlloca() && "Invalid kind!");
463 return InAllocaIndirect;
464 }
466 assert(isInAlloca() && "Invalid kind!");
467 InAllocaIndirect = Indirect;
468 }
469
470 /// Return true if this field of an inalloca struct should be returned
471 /// to implement a struct return calling convention.
472 bool getInAllocaSRet() const {
473 assert(isInAlloca() && "Invalid kind!");
474 return InAllocaSRet;
475 }
476
477 void setInAllocaSRet(bool SRet) {
478 assert(isInAlloca() && "Invalid kind!");
479 InAllocaSRet = SRet;
480 }
481
482 bool getCanBeFlattened() const {
483 assert(isDirect() && "Invalid kind!");
484 return CanBeFlattened;
485 }
486
487 void setCanBeFlattened(bool Flatten) {
488 assert(isDirect() && "Invalid kind!");
489 CanBeFlattened = Flatten;
490 }
491
492 void dump() const;
493};
494
495/// A class for recording the number of arguments that a function
496/// signature requires.
498 /// The number of required arguments, or ~0 if the signature does
499 /// not permit optional arguments.
500 unsigned NumRequired;
501public:
502 enum All_t { All };
503
504 RequiredArgs(All_t _) : NumRequired(~0U) {}
505 explicit RequiredArgs(unsigned n) : NumRequired(n) {
506 assert(n != ~0U);
507 }
508
509 /// Compute the arguments required by the given formal prototype,
510 /// given that there may be some additional, non-formal arguments
511 /// in play.
512 ///
513 /// If FD is not null, this will consider pass_object_size params in FD.
515 unsigned additional) {
516 if (!prototype->isVariadic()) return All;
517
518 if (prototype->hasExtParameterInfos())
519 additional += llvm::count_if(
520 prototype->getExtParameterInfos(),
521 [](const FunctionProtoType::ExtParameterInfo &ExtInfo) {
522 return ExtInfo.hasPassObjectSize();
523 });
524
525 return RequiredArgs(prototype->getNumParams() + additional);
526 }
527
529 unsigned additional) {
530 return forPrototypePlus(prototype.getTypePtr(), additional);
531 }
532
533 static RequiredArgs forPrototype(const FunctionProtoType *prototype) {
534 return forPrototypePlus(prototype, 0);
535 }
536
538 return forPrototypePlus(prototype.getTypePtr(), 0);
539 }
540
541 bool allowsOptionalArgs() const { return NumRequired != ~0U; }
542 unsigned getNumRequiredArgs() const {
543 assert(allowsOptionalArgs());
544 return NumRequired;
545 }
546
547 /// Return true if the argument at a given index is required.
548 bool isRequiredArg(unsigned argIdx) const {
549 return argIdx == ~0U || argIdx < NumRequired;
550 }
551
552 unsigned getOpaqueData() const { return NumRequired; }
553 static RequiredArgs getFromOpaqueData(unsigned value) {
554 if (value == ~0U) return All;
555 return RequiredArgs(value);
556 }
557};
558
559// Implementation detail of CGFunctionInfo, factored out so it can be named
560// in the TrailingObjects base class of CGFunctionInfo.
564};
565
566/// CGFunctionInfo - Class to encapsulate the information about a
567/// function definition.
568class CGFunctionInfo final
569 : public llvm::FoldingSetNode,
570 private llvm::TrailingObjects<CGFunctionInfo, CGFunctionInfoArgInfo,
571 FunctionProtoType::ExtParameterInfo> {
574
575 /// The LLVM::CallingConv to use for this function (as specified by the
576 /// user).
577 unsigned CallingConvention : 8;
578
579 /// The LLVM::CallingConv to actually use for this function, which may
580 /// depend on the ABI.
581 unsigned EffectiveCallingConvention : 8;
582
583 /// The clang::CallingConv that this was originally created with.
584 LLVM_PREFERRED_TYPE(CallingConv)
585 unsigned ASTCallingConvention : 6;
586
587 /// Whether this is an instance method.
588 LLVM_PREFERRED_TYPE(bool)
589 unsigned InstanceMethod : 1;
590
591 /// Whether this is a chain call.
592 LLVM_PREFERRED_TYPE(bool)
593 unsigned ChainCall : 1;
594
595 /// Whether this function is called by forwarding arguments.
596 /// This doesn't support inalloca or varargs.
597 LLVM_PREFERRED_TYPE(bool)
598 unsigned DelegateCall : 1;
599
600 /// Whether this function is a CMSE nonsecure call
601 LLVM_PREFERRED_TYPE(bool)
602 unsigned CmseNSCall : 1;
603
604 /// Whether this function is noreturn.
605 LLVM_PREFERRED_TYPE(bool)
606 unsigned NoReturn : 1;
607
608 /// Whether this function is returns-retained.
609 LLVM_PREFERRED_TYPE(bool)
610 unsigned ReturnsRetained : 1;
611
612 /// Whether this function saved caller registers.
613 LLVM_PREFERRED_TYPE(bool)
614 unsigned NoCallerSavedRegs : 1;
615
616 /// How many arguments to pass inreg.
617 LLVM_PREFERRED_TYPE(bool)
618 unsigned HasRegParm : 1;
619 unsigned RegParm : 3;
620
621 /// Whether this function has nocf_check attribute.
622 LLVM_PREFERRED_TYPE(bool)
623 unsigned NoCfCheck : 1;
624
625 /// Log 2 of the maximum vector width.
626 unsigned MaxVectorWidth : 4;
627
628 RequiredArgs Required;
629
630 /// The struct representing all arguments passed in memory. Only used when
631 /// passing non-trivial types with inalloca. Not part of the profile.
632 llvm::StructType *ArgStruct;
633 unsigned ArgStructAlign : 31;
634 LLVM_PREFERRED_TYPE(bool)
635 unsigned HasExtParameterInfos : 1;
636
637 unsigned NumArgs;
638
639 ArgInfo *getArgsBuffer() {
640 return getTrailingObjects<ArgInfo>();
641 }
642 const ArgInfo *getArgsBuffer() const {
643 return getTrailingObjects<ArgInfo>();
644 }
645
646 ExtParameterInfo *getExtParameterInfosBuffer() {
647 return getTrailingObjects<ExtParameterInfo>();
648 }
649 const ExtParameterInfo *getExtParameterInfosBuffer() const{
650 return getTrailingObjects<ExtParameterInfo>();
651 }
652
654
655public:
656 static CGFunctionInfo *
657 create(unsigned llvmCC, bool instanceMethod, bool chainCall,
658 bool delegateCall, const FunctionType::ExtInfo &extInfo,
659 ArrayRef<ExtParameterInfo> paramInfos, CanQualType resultType,
660 ArrayRef<CanQualType> argTypes, RequiredArgs required);
661 void operator delete(void *p) { ::operator delete(p); }
662
663 // Friending class TrailingObjects is apparently not good enough for MSVC,
664 // so these have to be public.
665 friend class TrailingObjects;
666 size_t numTrailingObjects(OverloadToken<ArgInfo>) const {
667 return NumArgs + 1;
668 }
669 size_t numTrailingObjects(OverloadToken<ExtParameterInfo>) const {
670 return (HasExtParameterInfos ? NumArgs : 0);
671 }
672
675
677 return MutableArrayRef<ArgInfo>(arg_begin(), NumArgs);
678 }
680 return ArrayRef<ArgInfo>(arg_begin(), NumArgs);
681 }
682
683 const_arg_iterator arg_begin() const { return getArgsBuffer() + 1; }
684 const_arg_iterator arg_end() const { return getArgsBuffer() + 1 + NumArgs; }
685 arg_iterator arg_begin() { return getArgsBuffer() + 1; }
686 arg_iterator arg_end() { return getArgsBuffer() + 1 + NumArgs; }
687
688 unsigned arg_size() const { return NumArgs; }
689
690 bool isVariadic() const { return Required.allowsOptionalArgs(); }
692 unsigned getNumRequiredArgs() const {
694 }
695
696 bool isInstanceMethod() const { return InstanceMethod; }
697
698 bool isChainCall() const { return ChainCall; }
699
700 bool isDelegateCall() const { return DelegateCall; }
701
702 bool isCmseNSCall() const { return CmseNSCall; }
703
704 bool isNoReturn() const { return NoReturn; }
705
706 /// In ARC, whether this function retains its return value. This
707 /// is not always reliable for call sites.
708 bool isReturnsRetained() const { return ReturnsRetained; }
709
710 /// Whether this function no longer saves caller registers.
711 bool isNoCallerSavedRegs() const { return NoCallerSavedRegs; }
712
713 /// Whether this function has nocf_check attribute.
714 bool isNoCfCheck() const { return NoCfCheck; }
715
716 /// getASTCallingConvention() - Return the AST-specified calling
717 /// convention.
719 return CallingConv(ASTCallingConvention);
720 }
721
722 /// getCallingConvention - Return the user specified calling
723 /// convention, which has been translated into an LLVM CC.
724 unsigned getCallingConvention() const { return CallingConvention; }
725
726 /// getEffectiveCallingConvention - Return the actual calling convention to
727 /// use, which may depend on the ABI.
729 return EffectiveCallingConvention;
730 }
732 EffectiveCallingConvention = Value;
733 }
734
735 bool getHasRegParm() const { return HasRegParm; }
736 unsigned getRegParm() const { return RegParm; }
737
742 isCmseNSCall());
743 }
744
745 CanQualType getReturnType() const { return getArgsBuffer()[0].type; }
746
747 ABIArgInfo &getReturnInfo() { return getArgsBuffer()[0].info; }
748 const ABIArgInfo &getReturnInfo() const { return getArgsBuffer()[0].info; }
749
751 if (!HasExtParameterInfos) return {};
752 return llvm::ArrayRef(getExtParameterInfosBuffer(), NumArgs);
753 }
754 ExtParameterInfo getExtParameterInfo(unsigned argIndex) const {
755 assert(argIndex <= NumArgs);
756 if (!HasExtParameterInfos) return ExtParameterInfo();
757 return getExtParameterInfos()[argIndex];
758 }
759
760 /// Return true if this function uses inalloca arguments.
761 bool usesInAlloca() const { return ArgStruct; }
762
763 /// Get the struct type used to represent all the arguments in memory.
764 llvm::StructType *getArgStruct() const { return ArgStruct; }
766 return CharUnits::fromQuantity(ArgStructAlign);
767 }
768 void setArgStruct(llvm::StructType *Ty, CharUnits Align) {
769 ArgStruct = Ty;
770 ArgStructAlign = Align.getQuantity();
771 }
772
773 /// Return the maximum vector width in the arguments.
774 unsigned getMaxVectorWidth() const {
775 return MaxVectorWidth ? 1U << (MaxVectorWidth - 1) : 0;
776 }
777
778 /// Set the maximum vector width in the arguments.
779 void setMaxVectorWidth(unsigned Width) {
780 assert(llvm::isPowerOf2_32(Width) && "Expected power of 2 vector");
781 MaxVectorWidth = llvm::countr_zero(Width) + 1;
782 }
783
784 void Profile(llvm::FoldingSetNodeID &ID) {
785 ID.AddInteger(getASTCallingConvention());
786 ID.AddBoolean(InstanceMethod);
787 ID.AddBoolean(ChainCall);
788 ID.AddBoolean(DelegateCall);
789 ID.AddBoolean(NoReturn);
790 ID.AddBoolean(ReturnsRetained);
791 ID.AddBoolean(NoCallerSavedRegs);
792 ID.AddBoolean(HasRegParm);
793 ID.AddInteger(RegParm);
794 ID.AddBoolean(NoCfCheck);
795 ID.AddBoolean(CmseNSCall);
796 ID.AddInteger(Required.getOpaqueData());
797 ID.AddBoolean(HasExtParameterInfos);
798 if (HasExtParameterInfos) {
799 for (auto paramInfo : getExtParameterInfos())
800 ID.AddInteger(paramInfo.getOpaqueValue());
801 }
803 for (const auto &I : arguments())
804 I.type.Profile(ID);
805 }
806 static void Profile(llvm::FoldingSetNodeID &ID, bool InstanceMethod,
807 bool ChainCall, bool IsDelegateCall,
808 const FunctionType::ExtInfo &info,
810 RequiredArgs required, CanQualType resultType,
811 ArrayRef<CanQualType> argTypes) {
812 ID.AddInteger(info.getCC());
813 ID.AddBoolean(InstanceMethod);
814 ID.AddBoolean(ChainCall);
815 ID.AddBoolean(IsDelegateCall);
816 ID.AddBoolean(info.getNoReturn());
817 ID.AddBoolean(info.getProducesResult());
818 ID.AddBoolean(info.getNoCallerSavedRegs());
819 ID.AddBoolean(info.getHasRegParm());
820 ID.AddInteger(info.getRegParm());
821 ID.AddBoolean(info.getNoCfCheck());
822 ID.AddBoolean(info.getCmseNSCall());
823 ID.AddInteger(required.getOpaqueData());
824 ID.AddBoolean(!paramInfos.empty());
825 if (!paramInfos.empty()) {
826 for (auto paramInfo : paramInfos)
827 ID.AddInteger(paramInfo.getOpaqueValue());
828 }
829 resultType.Profile(ID);
831 i = argTypes.begin(), e = argTypes.end(); i != e; ++i) {
832 i->Profile(ID);
833 }
834 }
835};
836
837} // end namespace CodeGen
838} // end namespace clang
839
840#endif
static char ID
Definition: Arena.cpp:183
C Language Family Type Representation.
Represents a canonical, potentially-qualified type.
Definition: CanonicalType.h:66
void Profile(llvm::FoldingSetNodeID &ID) const
const T * getTypePtr() const
Retrieve the underlying type pointer, which refers to a canonical type.
Definition: CanonicalType.h:84
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)
static ABIArgInfo getNoExtend(llvm::IntegerType *T)
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:828
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:5102
unsigned getNumParams() const
Definition: Type.h:5355
bool isVariadic() const
Whether this function prototype is variadic.
Definition: Type.h:5479
ArrayRef< ExtParameterInfo > getExtParameterInfos() const
Definition: Type.h:5544
bool hasExtParameterInfos() const
Is there any interesting extra information for any of the parameters of this function type?
Definition: Type.h:5540
A class which abstracts out some details necessary for making a call.
Definition: Type.h:4432
CallingConv getCC() const
Definition: Type.h:4494
bool getCmseNSCall() const
Definition: Type.h:4482
bool getNoCfCheck() const
Definition: Type.h:4484
unsigned getRegParm() const
Definition: Type.h:4487
bool getNoCallerSavedRegs() const
Definition: Type.h:4483
bool getHasRegParm() const
Definition: Type.h:4485
bool getNoReturn() const
Definition: Type.h:4480
bool getProducesResult() const
Definition: Type.h:4481
Interesting information about a specific parameter that can't simply be reflected in parameter's type...
Definition: Type.h:4347
A (possibly-)qualified type.
Definition: Type.h:929
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
Definition: Type.h:8625
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g....
Definition: Type.cpp:2220
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
CallingConv
CallingConv - Specifies the calling convention that a function uses.
Definition: Specifiers.h:278
#define false
Definition: stdbool.h:26