xref: /freebsd-src/contrib/llvm-project/clang/lib/CodeGen/ABIInfoImpl.h (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
1*06c3fb27SDimitry Andric //===- ABIInfoImpl.h --------------------------------------------*- C++ -*-===//
2*06c3fb27SDimitry Andric //
3*06c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*06c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*06c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*06c3fb27SDimitry Andric //
7*06c3fb27SDimitry Andric //===----------------------------------------------------------------------===//
8*06c3fb27SDimitry Andric 
9*06c3fb27SDimitry Andric #ifndef LLVM_CLANG_LIB_CODEGEN_ABIINFOIMPL_H
10*06c3fb27SDimitry Andric #define LLVM_CLANG_LIB_CODEGEN_ABIINFOIMPL_H
11*06c3fb27SDimitry Andric 
12*06c3fb27SDimitry Andric #include "ABIInfo.h"
13*06c3fb27SDimitry Andric #include "CGCXXABI.h"
14*06c3fb27SDimitry Andric 
15*06c3fb27SDimitry Andric namespace clang::CodeGen {
16*06c3fb27SDimitry Andric 
17*06c3fb27SDimitry Andric /// DefaultABIInfo - The default implementation for ABI specific
18*06c3fb27SDimitry Andric /// details. This implementation provides information which results in
19*06c3fb27SDimitry Andric /// self-consistent and sensible LLVM IR generation, but does not
20*06c3fb27SDimitry Andric /// conform to any particular ABI.
21*06c3fb27SDimitry Andric class DefaultABIInfo : public ABIInfo {
22*06c3fb27SDimitry Andric public:
23*06c3fb27SDimitry Andric   DefaultABIInfo(CodeGen::CodeGenTypes &CGT) : ABIInfo(CGT) {}
24*06c3fb27SDimitry Andric 
25*06c3fb27SDimitry Andric   virtual ~DefaultABIInfo();
26*06c3fb27SDimitry Andric 
27*06c3fb27SDimitry Andric   ABIArgInfo classifyReturnType(QualType RetTy) const;
28*06c3fb27SDimitry Andric   ABIArgInfo classifyArgumentType(QualType RetTy) const;
29*06c3fb27SDimitry Andric 
30*06c3fb27SDimitry Andric   void computeInfo(CGFunctionInfo &FI) const override;
31*06c3fb27SDimitry Andric 
32*06c3fb27SDimitry Andric   Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
33*06c3fb27SDimitry Andric                     QualType Ty) const override;
34*06c3fb27SDimitry Andric };
35*06c3fb27SDimitry Andric 
36*06c3fb27SDimitry Andric // Helper for coercing an aggregate argument or return value into an integer
37*06c3fb27SDimitry Andric // array of the same size (including padding) and alignment.  This alternate
38*06c3fb27SDimitry Andric // coercion happens only for the RenderScript ABI and can be removed after
39*06c3fb27SDimitry Andric // runtimes that rely on it are no longer supported.
40*06c3fb27SDimitry Andric //
41*06c3fb27SDimitry Andric // RenderScript assumes that the size of the argument / return value in the IR
42*06c3fb27SDimitry Andric // is the same as the size of the corresponding qualified type. This helper
43*06c3fb27SDimitry Andric // coerces the aggregate type into an array of the same size (including
44*06c3fb27SDimitry Andric // padding).  This coercion is used in lieu of expansion of struct members or
45*06c3fb27SDimitry Andric // other canonical coercions that return a coerced-type of larger size.
46*06c3fb27SDimitry Andric //
47*06c3fb27SDimitry Andric // Ty          - The argument / return value type
48*06c3fb27SDimitry Andric // Context     - The associated ASTContext
49*06c3fb27SDimitry Andric // LLVMContext - The associated LLVMContext
50*06c3fb27SDimitry Andric ABIArgInfo coerceToIntArray(QualType Ty, ASTContext &Context,
51*06c3fb27SDimitry Andric                             llvm::LLVMContext &LLVMContext);
52*06c3fb27SDimitry Andric 
53*06c3fb27SDimitry Andric void AssignToArrayRange(CodeGen::CGBuilderTy &Builder, llvm::Value *Array,
54*06c3fb27SDimitry Andric                         llvm::Value *Value, unsigned FirstIndex,
55*06c3fb27SDimitry Andric                         unsigned LastIndex);
56*06c3fb27SDimitry Andric 
57*06c3fb27SDimitry Andric bool isAggregateTypeForABI(QualType T);
58*06c3fb27SDimitry Andric 
59*06c3fb27SDimitry Andric llvm::Type *getVAListElementType(CodeGenFunction &CGF);
60*06c3fb27SDimitry Andric 
61*06c3fb27SDimitry Andric CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI);
62*06c3fb27SDimitry Andric 
63*06c3fb27SDimitry Andric CGCXXABI::RecordArgABI getRecordArgABI(QualType T, CGCXXABI &CXXABI);
64*06c3fb27SDimitry Andric 
65*06c3fb27SDimitry Andric bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI,
66*06c3fb27SDimitry Andric                         const ABIInfo &Info);
67*06c3fb27SDimitry Andric 
68*06c3fb27SDimitry Andric /// Pass transparent unions as if they were the type of the first element. Sema
69*06c3fb27SDimitry Andric /// should ensure that all elements of the union have the same "machine type".
70*06c3fb27SDimitry Andric QualType useFirstFieldIfTransparentUnion(QualType Ty);
71*06c3fb27SDimitry Andric 
72*06c3fb27SDimitry Andric // Dynamically round a pointer up to a multiple of the given alignment.
73*06c3fb27SDimitry Andric llvm::Value *emitRoundPointerUpToAlignment(CodeGenFunction &CGF,
74*06c3fb27SDimitry Andric                                            llvm::Value *Ptr, CharUnits Align);
75*06c3fb27SDimitry Andric 
76*06c3fb27SDimitry Andric /// Emit va_arg for a platform using the common void* representation,
77*06c3fb27SDimitry Andric /// where arguments are simply emitted in an array of slots on the stack.
78*06c3fb27SDimitry Andric ///
79*06c3fb27SDimitry Andric /// This version implements the core direct-value passing rules.
80*06c3fb27SDimitry Andric ///
81*06c3fb27SDimitry Andric /// \param SlotSize - The size and alignment of a stack slot.
82*06c3fb27SDimitry Andric ///   Each argument will be allocated to a multiple of this number of
83*06c3fb27SDimitry Andric ///   slots, and all the slots will be aligned to this value.
84*06c3fb27SDimitry Andric /// \param AllowHigherAlign - The slot alignment is not a cap;
85*06c3fb27SDimitry Andric ///   an argument type with an alignment greater than the slot size
86*06c3fb27SDimitry Andric ///   will be emitted on a higher-alignment address, potentially
87*06c3fb27SDimitry Andric ///   leaving one or more empty slots behind as padding.  If this
88*06c3fb27SDimitry Andric ///   is false, the returned address might be less-aligned than
89*06c3fb27SDimitry Andric ///   DirectAlign.
90*06c3fb27SDimitry Andric /// \param ForceRightAdjust - Default is false. On big-endian platform and
91*06c3fb27SDimitry Andric ///   if the argument is smaller than a slot, set this flag will force
92*06c3fb27SDimitry Andric ///   right-adjust the argument in its slot irrespective of the type.
93*06c3fb27SDimitry Andric Address emitVoidPtrDirectVAArg(CodeGenFunction &CGF, Address VAListAddr,
94*06c3fb27SDimitry Andric                                llvm::Type *DirectTy, CharUnits DirectSize,
95*06c3fb27SDimitry Andric                                CharUnits DirectAlign, CharUnits SlotSize,
96*06c3fb27SDimitry Andric                                bool AllowHigherAlign,
97*06c3fb27SDimitry Andric                                bool ForceRightAdjust = false);
98*06c3fb27SDimitry Andric 
99*06c3fb27SDimitry Andric /// Emit va_arg for a platform using the common void* representation,
100*06c3fb27SDimitry Andric /// where arguments are simply emitted in an array of slots on the stack.
101*06c3fb27SDimitry Andric ///
102*06c3fb27SDimitry Andric /// \param IsIndirect - Values of this type are passed indirectly.
103*06c3fb27SDimitry Andric /// \param ValueInfo - The size and alignment of this type, generally
104*06c3fb27SDimitry Andric ///   computed with getContext().getTypeInfoInChars(ValueTy).
105*06c3fb27SDimitry Andric /// \param SlotSizeAndAlign - The size and alignment of a stack slot.
106*06c3fb27SDimitry Andric ///   Each argument will be allocated to a multiple of this number of
107*06c3fb27SDimitry Andric ///   slots, and all the slots will be aligned to this value.
108*06c3fb27SDimitry Andric /// \param AllowHigherAlign - The slot alignment is not a cap;
109*06c3fb27SDimitry Andric ///   an argument type with an alignment greater than the slot size
110*06c3fb27SDimitry Andric ///   will be emitted on a higher-alignment address, potentially
111*06c3fb27SDimitry Andric ///   leaving one or more empty slots behind as padding.
112*06c3fb27SDimitry Andric /// \param ForceRightAdjust - Default is false. On big-endian platform and
113*06c3fb27SDimitry Andric ///   if the argument is smaller than a slot, set this flag will force
114*06c3fb27SDimitry Andric ///   right-adjust the argument in its slot irrespective of the type.
115*06c3fb27SDimitry Andric Address emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr,
116*06c3fb27SDimitry Andric                          QualType ValueTy, bool IsIndirect,
117*06c3fb27SDimitry Andric                          TypeInfoChars ValueInfo, CharUnits SlotSizeAndAlign,
118*06c3fb27SDimitry Andric                          bool AllowHigherAlign, bool ForceRightAdjust = false);
119*06c3fb27SDimitry Andric 
120*06c3fb27SDimitry Andric Address emitMergePHI(CodeGenFunction &CGF, Address Addr1,
121*06c3fb27SDimitry Andric                      llvm::BasicBlock *Block1, Address Addr2,
122*06c3fb27SDimitry Andric                      llvm::BasicBlock *Block2, const llvm::Twine &Name = "");
123*06c3fb27SDimitry Andric 
124*06c3fb27SDimitry Andric /// isEmptyField - Return true iff a the field is "empty", that is it
125*06c3fb27SDimitry Andric /// is an unnamed bit-field or an (array of) empty record(s).
126*06c3fb27SDimitry Andric bool isEmptyField(ASTContext &Context, const FieldDecl *FD, bool AllowArrays);
127*06c3fb27SDimitry Andric 
128*06c3fb27SDimitry Andric /// isEmptyRecord - Return true iff a structure contains only empty
129*06c3fb27SDimitry Andric /// fields. Note that a structure with a flexible array member is not
130*06c3fb27SDimitry Andric /// considered empty.
131*06c3fb27SDimitry Andric bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays);
132*06c3fb27SDimitry Andric 
133*06c3fb27SDimitry Andric /// isSingleElementStruct - Determine if a structure is a "single
134*06c3fb27SDimitry Andric /// element struct", i.e. it has exactly one non-empty field or
135*06c3fb27SDimitry Andric /// exactly one field which is itself a single element
136*06c3fb27SDimitry Andric /// struct. Structures with flexible array members are never
137*06c3fb27SDimitry Andric /// considered single element structs.
138*06c3fb27SDimitry Andric ///
139*06c3fb27SDimitry Andric /// \return The field declaration for the single non-empty field, if
140*06c3fb27SDimitry Andric /// it exists.
141*06c3fb27SDimitry Andric const Type *isSingleElementStruct(QualType T, ASTContext &Context);
142*06c3fb27SDimitry Andric 
143*06c3fb27SDimitry Andric Address EmitVAArgInstr(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
144*06c3fb27SDimitry Andric                        const ABIArgInfo &AI);
145*06c3fb27SDimitry Andric 
146*06c3fb27SDimitry Andric bool isSIMDVectorType(ASTContext &Context, QualType Ty);
147*06c3fb27SDimitry Andric 
148*06c3fb27SDimitry Andric bool isRecordWithSIMDVectorType(ASTContext &Context, QualType Ty);
149*06c3fb27SDimitry Andric 
150*06c3fb27SDimitry Andric } // namespace clang::CodeGen
151*06c3fb27SDimitry Andric 
152*06c3fb27SDimitry Andric #endif // LLVM_CLANG_LIB_CODEGEN_ABIINFOIMPL_H
153