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