clang 19.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 LLVM_PREFERRED_TYPE(CallingConv)
568 unsigned ASTCallingConvention : 6;
569
570 /// Whether this is an instance method.
571 LLVM_PREFERRED_TYPE(bool)
572 unsigned InstanceMethod : 1;
573
574 /// Whether this is a chain call.
575 LLVM_PREFERRED_TYPE(bool)
576 unsigned ChainCall : 1;
577
578 /// Whether this function is called by forwarding arguments.
579 /// This doesn't support inalloca or varargs.
580 LLVM_PREFERRED_TYPE(bool)
581 unsigned DelegateCall : 1;
582
583 /// Whether this function is a CMSE nonsecure call
584 LLVM_PREFERRED_TYPE(bool)
585 unsigned CmseNSCall : 1;
586
587 /// Whether this function is noreturn.
588 LLVM_PREFERRED_TYPE(bool)
589 unsigned NoReturn : 1;
590
591 /// Whether this function is returns-retained.
592 LLVM_PREFERRED_TYPE(bool)
593 unsigned ReturnsRetained : 1;
594
595 /// Whether this function saved caller registers.
596 LLVM_PREFERRED_TYPE(bool)
597 unsigned NoCallerSavedRegs : 1;
598
599 /// How many arguments to pass inreg.
600 LLVM_PREFERRED_TYPE(bool)
601 unsigned HasRegParm : 1;
602 unsigned RegParm : 3;
603
604 /// Whether this function has nocf_check attribute.
605 LLVM_PREFERRED_TYPE(bool)
606 unsigned NoCfCheck : 1;
607
608 /// Log 2 of the maximum vector width.
609 unsigned MaxVectorWidth : 4;
610
611 RequiredArgs Required;
612
613 /// The struct representing all arguments passed in memory. Only used when
614 /// passing non-trivial types with inalloca. Not part of the profile.
615 llvm::StructType *ArgStruct;
616 unsigned ArgStructAlign : 31;
617 LLVM_PREFERRED_TYPE(bool)
618 unsigned HasExtParameterInfos : 1;
619
620 unsigned NumArgs;
621
622 ArgInfo *getArgsBuffer() {
623 return getTrailingObjects<ArgInfo>();
624 }
625 const ArgInfo *getArgsBuffer() const {
626 return getTrailingObjects<ArgInfo>();
627 }
628
629 ExtParameterInfo *getExtParameterInfosBuffer() {
630 return getTrailingObjects<ExtParameterInfo>();
631 }
632 const ExtParameterInfo *getExtParameterInfosBuffer() const{
633 return getTrailingObjects<ExtParameterInfo>();
634 }
635
637
638public:
639 static CGFunctionInfo *
640 create(unsigned llvmCC, bool instanceMethod, bool chainCall,
641 bool delegateCall, const FunctionType::ExtInfo &extInfo,
642 ArrayRef<ExtParameterInfo> paramInfos, CanQualType resultType,
643 ArrayRef<CanQualType> argTypes, RequiredArgs required);
644 void operator delete(void *p) { ::operator delete(p); }
645
646 // Friending class TrailingObjects is apparently not good enough for MSVC,
647 // so these have to be public.
648 friend class TrailingObjects;
649 size_t numTrailingObjects(OverloadToken<ArgInfo>) const {
650 return NumArgs + 1;
651 }
652 size_t numTrailingObjects(OverloadToken<ExtParameterInfo>) const {
653 return (HasExtParameterInfos ? NumArgs : 0);
654 }
655
658
660 return MutableArrayRef<ArgInfo>(arg_begin(), NumArgs);
661 }
663 return ArrayRef<ArgInfo>(arg_begin(), NumArgs);
664 }
665
666 const_arg_iterator arg_begin() const { return getArgsBuffer() + 1; }
667 const_arg_iterator arg_end() const { return getArgsBuffer() + 1 + NumArgs; }
668 arg_iterator arg_begin() { return getArgsBuffer() + 1; }
669 arg_iterator arg_end() { return getArgsBuffer() + 1 + NumArgs; }
670
671 unsigned arg_size() const { return NumArgs; }
672
673 bool isVariadic() const { return Required.allowsOptionalArgs(); }
675 unsigned getNumRequiredArgs() const {
677 }
678
679 bool isInstanceMethod() const { return InstanceMethod; }
680
681 bool isChainCall() const { return ChainCall; }
682
683 bool isDelegateCall() const { return DelegateCall; }
684
685 bool isCmseNSCall() const { return CmseNSCall; }
686
687 bool isNoReturn() const { return NoReturn; }
688
689 /// In ARC, whether this function retains its return value. This
690 /// is not always reliable for call sites.
691 bool isReturnsRetained() const { return ReturnsRetained; }
692
693 /// Whether this function no longer saves caller registers.
694 bool isNoCallerSavedRegs() const { return NoCallerSavedRegs; }
695
696 /// Whether this function has nocf_check attribute.
697 bool isNoCfCheck() const { return NoCfCheck; }
698
699 /// getASTCallingConvention() - Return the AST-specified calling
700 /// convention.
702 return CallingConv(ASTCallingConvention);
703 }
704
705 /// getCallingConvention - Return the user specified calling
706 /// convention, which has been translated into an LLVM CC.
707 unsigned getCallingConvention() const { return CallingConvention; }
708
709 /// getEffectiveCallingConvention - Return the actual calling convention to
710 /// use, which may depend on the ABI.
712 return EffectiveCallingConvention;
713 }
715 EffectiveCallingConvention = Value;
716 }
717
718 bool getHasRegParm() const { return HasRegParm; }
719 unsigned getRegParm() const { return RegParm; }
720
725 isCmseNSCall());
726 }
727
728 CanQualType getReturnType() const { return getArgsBuffer()[0].type; }
729
730 ABIArgInfo &getReturnInfo() { return getArgsBuffer()[0].info; }
731 const ABIArgInfo &getReturnInfo() const { return getArgsBuffer()[0].info; }
732
734 if (!HasExtParameterInfos) return {};
735 return llvm::ArrayRef(getExtParameterInfosBuffer(), NumArgs);
736 }
737 ExtParameterInfo getExtParameterInfo(unsigned argIndex) const {
738 assert(argIndex <= NumArgs);
739 if (!HasExtParameterInfos) return ExtParameterInfo();
740 return getExtParameterInfos()[argIndex];
741 }
742
743 /// Return true if this function uses inalloca arguments.
744 bool usesInAlloca() const { return ArgStruct; }
745
746 /// Get the struct type used to represent all the arguments in memory.
747 llvm::StructType *getArgStruct() const { return ArgStruct; }
749 return CharUnits::fromQuantity(ArgStructAlign);
750 }
751 void setArgStruct(llvm::StructType *Ty, CharUnits Align) {
752 ArgStruct = Ty;
753 ArgStructAlign = Align.getQuantity();
754 }
755
756 /// Return the maximum vector width in the arguments.
757 unsigned getMaxVectorWidth() const {
758 return MaxVectorWidth ? 1U << (MaxVectorWidth - 1) : 0;
759 }
760
761 /// Set the maximum vector width in the arguments.
762 void setMaxVectorWidth(unsigned Width) {
763 assert(llvm::isPowerOf2_32(Width) && "Expected power of 2 vector");
764 MaxVectorWidth = llvm::countr_zero(Width) + 1;
765 }
766
767 void Profile(llvm::FoldingSetNodeID &ID) {
768 ID.AddInteger(getASTCallingConvention());
769 ID.AddBoolean(InstanceMethod);
770 ID.AddBoolean(ChainCall);
771 ID.AddBoolean(DelegateCall);
772 ID.AddBoolean(NoReturn);
773 ID.AddBoolean(ReturnsRetained);
774 ID.AddBoolean(NoCallerSavedRegs);
775 ID.AddBoolean(HasRegParm);
776 ID.AddInteger(RegParm);
777 ID.AddBoolean(NoCfCheck);
778 ID.AddBoolean(CmseNSCall);
779 ID.AddInteger(Required.getOpaqueData());
780 ID.AddBoolean(HasExtParameterInfos);
781 if (HasExtParameterInfos) {
782 for (auto paramInfo : getExtParameterInfos())
783 ID.AddInteger(paramInfo.getOpaqueValue());
784 }
786 for (const auto &I : arguments())
787 I.type.Profile(ID);
788 }
789 static void Profile(llvm::FoldingSetNodeID &ID, bool InstanceMethod,
790 bool ChainCall, bool IsDelegateCall,
791 const FunctionType::ExtInfo &info,
793 RequiredArgs required, CanQualType resultType,
794 ArrayRef<CanQualType> argTypes) {
795 ID.AddInteger(info.getCC());
796 ID.AddBoolean(InstanceMethod);
797 ID.AddBoolean(ChainCall);
798 ID.AddBoolean(IsDelegateCall);
799 ID.AddBoolean(info.getNoReturn());
800 ID.AddBoolean(info.getProducesResult());
801 ID.AddBoolean(info.getNoCallerSavedRegs());
802 ID.AddBoolean(info.getHasRegParm());
803 ID.AddInteger(info.getRegParm());
804 ID.AddBoolean(info.getNoCfCheck());
805 ID.AddBoolean(info.getCmseNSCall());
806 ID.AddInteger(required.getOpaqueData());
807 ID.AddBoolean(!paramInfos.empty());
808 if (!paramInfos.empty()) {
809 for (auto paramInfo : paramInfos)
810 ID.AddInteger(paramInfo.getOpaqueValue());
811 }
812 resultType.Profile(ID);
814 i = argTypes.begin(), e = argTypes.end(); i != e; ++i) {
815 i->Profile(ID);
816 }
817 }
818};
819
820} // end namespace CodeGen
821} // end namespace clang
822
823#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:823
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:4199
unsigned getNumParams() const
Definition: Type.h:4432
bool isVariadic() const
Whether this function prototype is variadic.
Definition: Type.h:4555
ArrayRef< ExtParameterInfo > getExtParameterInfos() const
Definition: Type.h:4620
bool hasExtParameterInfos() const
Is there any interesting extra information for any of the parameters of this function type?
Definition: Type.h:4616
A class which abstracts out some details necessary for making a call.
Definition: Type.h:3910
CallingConv getCC() const
Definition: Type.h:3972
bool getCmseNSCall() const
Definition: Type.h:3960
bool getNoCfCheck() const
Definition: Type.h:3962
unsigned getRegParm() const
Definition: Type.h:3965
bool getNoCallerSavedRegs() const
Definition: Type.h:3961
bool getHasRegParm() const
Definition: Type.h:3963
bool getNoReturn() const
Definition: Type.h:3958
bool getProducesResult() const
Definition: Type.h:3959
Interesting information about a specific parameter that can't simply be reflected in parameter's type...
Definition: Type.h:3825
A (possibly-)qualified type.
Definition: Type.h:737
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
Definition: Type.h:7554
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g....
Definition: Type.cpp:2123
The JSON file list parser is used to communicate input to InstallAPI.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
Definition: Specifiers.h:275
#define false
Definition: stdbool.h:22