106c3fb27SDimitry Andric //===- ABIInfoImpl.h --------------------------------------------*- C++ -*-===// 206c3fb27SDimitry Andric // 306c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 406c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 506c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 606c3fb27SDimitry Andric // 706c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 806c3fb27SDimitry Andric 906c3fb27SDimitry Andric #ifndef LLVM_CLANG_LIB_CODEGEN_ABIINFOIMPL_H 1006c3fb27SDimitry Andric #define LLVM_CLANG_LIB_CODEGEN_ABIINFOIMPL_H 1106c3fb27SDimitry Andric 1206c3fb27SDimitry Andric #include "ABIInfo.h" 1306c3fb27SDimitry Andric #include "CGCXXABI.h" 1406c3fb27SDimitry Andric 1506c3fb27SDimitry Andric namespace clang::CodeGen { 1606c3fb27SDimitry Andric 1706c3fb27SDimitry Andric /// DefaultABIInfo - The default implementation for ABI specific 1806c3fb27SDimitry Andric /// details. This implementation provides information which results in 1906c3fb27SDimitry Andric /// self-consistent and sensible LLVM IR generation, but does not 2006c3fb27SDimitry Andric /// conform to any particular ABI. 2106c3fb27SDimitry Andric class DefaultABIInfo : public ABIInfo { 2206c3fb27SDimitry Andric public: 2306c3fb27SDimitry Andric DefaultABIInfo(CodeGen::CodeGenTypes &CGT) : ABIInfo(CGT) {} 2406c3fb27SDimitry Andric 2506c3fb27SDimitry Andric virtual ~DefaultABIInfo(); 2606c3fb27SDimitry Andric 2706c3fb27SDimitry Andric ABIArgInfo classifyReturnType(QualType RetTy) const; 2806c3fb27SDimitry Andric ABIArgInfo classifyArgumentType(QualType RetTy) const; 2906c3fb27SDimitry Andric 3006c3fb27SDimitry Andric void computeInfo(CGFunctionInfo &FI) const override; 3106c3fb27SDimitry Andric 32*0fca6ea1SDimitry Andric RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty, 33*0fca6ea1SDimitry Andric AggValueSlot Slot) const override; 3406c3fb27SDimitry Andric }; 3506c3fb27SDimitry Andric 3606c3fb27SDimitry Andric // Helper for coercing an aggregate argument or return value into an integer 3706c3fb27SDimitry Andric // array of the same size (including padding) and alignment. This alternate 3806c3fb27SDimitry Andric // coercion happens only for the RenderScript ABI and can be removed after 3906c3fb27SDimitry Andric // runtimes that rely on it are no longer supported. 4006c3fb27SDimitry Andric // 4106c3fb27SDimitry Andric // RenderScript assumes that the size of the argument / return value in the IR 4206c3fb27SDimitry Andric // is the same as the size of the corresponding qualified type. This helper 4306c3fb27SDimitry Andric // coerces the aggregate type into an array of the same size (including 4406c3fb27SDimitry Andric // padding). This coercion is used in lieu of expansion of struct members or 4506c3fb27SDimitry Andric // other canonical coercions that return a coerced-type of larger size. 4606c3fb27SDimitry Andric // 4706c3fb27SDimitry Andric // Ty - The argument / return value type 4806c3fb27SDimitry Andric // Context - The associated ASTContext 4906c3fb27SDimitry Andric // LLVMContext - The associated LLVMContext 5006c3fb27SDimitry Andric ABIArgInfo coerceToIntArray(QualType Ty, ASTContext &Context, 5106c3fb27SDimitry Andric llvm::LLVMContext &LLVMContext); 5206c3fb27SDimitry Andric 5306c3fb27SDimitry Andric void AssignToArrayRange(CodeGen::CGBuilderTy &Builder, llvm::Value *Array, 5406c3fb27SDimitry Andric llvm::Value *Value, unsigned FirstIndex, 5506c3fb27SDimitry Andric unsigned LastIndex); 5606c3fb27SDimitry Andric 5706c3fb27SDimitry Andric bool isAggregateTypeForABI(QualType T); 5806c3fb27SDimitry Andric 5906c3fb27SDimitry Andric llvm::Type *getVAListElementType(CodeGenFunction &CGF); 6006c3fb27SDimitry Andric 6106c3fb27SDimitry Andric CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI); 6206c3fb27SDimitry Andric 6306c3fb27SDimitry Andric CGCXXABI::RecordArgABI getRecordArgABI(QualType T, CGCXXABI &CXXABI); 6406c3fb27SDimitry Andric 6506c3fb27SDimitry Andric bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, 6606c3fb27SDimitry Andric const ABIInfo &Info); 6706c3fb27SDimitry Andric 6806c3fb27SDimitry Andric /// Pass transparent unions as if they were the type of the first element. Sema 6906c3fb27SDimitry Andric /// should ensure that all elements of the union have the same "machine type". 7006c3fb27SDimitry Andric QualType useFirstFieldIfTransparentUnion(QualType Ty); 7106c3fb27SDimitry Andric 7206c3fb27SDimitry Andric // Dynamically round a pointer up to a multiple of the given alignment. 7306c3fb27SDimitry Andric llvm::Value *emitRoundPointerUpToAlignment(CodeGenFunction &CGF, 7406c3fb27SDimitry Andric llvm::Value *Ptr, CharUnits Align); 7506c3fb27SDimitry Andric 7606c3fb27SDimitry Andric /// Emit va_arg for a platform using the common void* representation, 7706c3fb27SDimitry Andric /// where arguments are simply emitted in an array of slots on the stack. 7806c3fb27SDimitry Andric /// 7906c3fb27SDimitry Andric /// This version implements the core direct-value passing rules. 8006c3fb27SDimitry Andric /// 8106c3fb27SDimitry Andric /// \param SlotSize - The size and alignment of a stack slot. 8206c3fb27SDimitry Andric /// Each argument will be allocated to a multiple of this number of 8306c3fb27SDimitry Andric /// slots, and all the slots will be aligned to this value. 8406c3fb27SDimitry Andric /// \param AllowHigherAlign - The slot alignment is not a cap; 8506c3fb27SDimitry Andric /// an argument type with an alignment greater than the slot size 8606c3fb27SDimitry Andric /// will be emitted on a higher-alignment address, potentially 8706c3fb27SDimitry Andric /// leaving one or more empty slots behind as padding. If this 8806c3fb27SDimitry Andric /// is false, the returned address might be less-aligned than 8906c3fb27SDimitry Andric /// DirectAlign. 9006c3fb27SDimitry Andric /// \param ForceRightAdjust - Default is false. On big-endian platform and 9106c3fb27SDimitry Andric /// if the argument is smaller than a slot, set this flag will force 9206c3fb27SDimitry Andric /// right-adjust the argument in its slot irrespective of the type. 9306c3fb27SDimitry Andric Address emitVoidPtrDirectVAArg(CodeGenFunction &CGF, Address VAListAddr, 9406c3fb27SDimitry Andric llvm::Type *DirectTy, CharUnits DirectSize, 9506c3fb27SDimitry Andric CharUnits DirectAlign, CharUnits SlotSize, 9606c3fb27SDimitry Andric bool AllowHigherAlign, 9706c3fb27SDimitry Andric bool ForceRightAdjust = false); 9806c3fb27SDimitry Andric 9906c3fb27SDimitry Andric /// Emit va_arg for a platform using the common void* representation, 10006c3fb27SDimitry Andric /// where arguments are simply emitted in an array of slots on the stack. 10106c3fb27SDimitry Andric /// 10206c3fb27SDimitry Andric /// \param IsIndirect - Values of this type are passed indirectly. 10306c3fb27SDimitry Andric /// \param ValueInfo - The size and alignment of this type, generally 10406c3fb27SDimitry Andric /// computed with getContext().getTypeInfoInChars(ValueTy). 10506c3fb27SDimitry Andric /// \param SlotSizeAndAlign - The size and alignment of a stack slot. 10606c3fb27SDimitry Andric /// Each argument will be allocated to a multiple of this number of 10706c3fb27SDimitry Andric /// slots, and all the slots will be aligned to this value. 10806c3fb27SDimitry Andric /// \param AllowHigherAlign - The slot alignment is not a cap; 10906c3fb27SDimitry Andric /// an argument type with an alignment greater than the slot size 11006c3fb27SDimitry Andric /// will be emitted on a higher-alignment address, potentially 11106c3fb27SDimitry Andric /// leaving one or more empty slots behind as padding. 11206c3fb27SDimitry Andric /// \param ForceRightAdjust - Default is false. On big-endian platform and 11306c3fb27SDimitry Andric /// if the argument is smaller than a slot, set this flag will force 11406c3fb27SDimitry Andric /// right-adjust the argument in its slot irrespective of the type. 115*0fca6ea1SDimitry Andric RValue emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr, 11606c3fb27SDimitry Andric QualType ValueTy, bool IsIndirect, 11706c3fb27SDimitry Andric TypeInfoChars ValueInfo, CharUnits SlotSizeAndAlign, 118*0fca6ea1SDimitry Andric bool AllowHigherAlign, AggValueSlot Slot, 119*0fca6ea1SDimitry Andric bool ForceRightAdjust = false); 12006c3fb27SDimitry Andric 12106c3fb27SDimitry Andric Address emitMergePHI(CodeGenFunction &CGF, Address Addr1, 12206c3fb27SDimitry Andric llvm::BasicBlock *Block1, Address Addr2, 12306c3fb27SDimitry Andric llvm::BasicBlock *Block2, const llvm::Twine &Name = ""); 12406c3fb27SDimitry Andric 12506c3fb27SDimitry Andric /// isEmptyField - Return true iff a the field is "empty", that is it 1268a4dda33SDimitry Andric /// is an unnamed bit-field or an (array of) empty record(s). If 1278a4dda33SDimitry Andric /// AsIfNoUniqueAddr is true, then C++ record fields are considered empty if 1288a4dda33SDimitry Andric /// the [[no_unique_address]] attribute would have made them empty. 1298a4dda33SDimitry Andric bool isEmptyField(ASTContext &Context, const FieldDecl *FD, bool AllowArrays, 1308a4dda33SDimitry Andric bool AsIfNoUniqueAddr = false); 13106c3fb27SDimitry Andric 13206c3fb27SDimitry Andric /// isEmptyRecord - Return true iff a structure contains only empty 13306c3fb27SDimitry Andric /// fields. Note that a structure with a flexible array member is not 1348a4dda33SDimitry Andric /// considered empty. If AsIfNoUniqueAddr is true, then C++ record fields are 1358a4dda33SDimitry Andric /// considered empty if the [[no_unique_address]] attribute would have made 1368a4dda33SDimitry Andric /// them empty. 1378a4dda33SDimitry Andric bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays, 1388a4dda33SDimitry Andric bool AsIfNoUniqueAddr = false); 13906c3fb27SDimitry Andric 140*0fca6ea1SDimitry Andric /// isEmptyFieldForLayout - Return true iff the field is "empty", that is, 141*0fca6ea1SDimitry Andric /// either a zero-width bit-field or an \ref isEmptyRecordForLayout. 142*0fca6ea1SDimitry Andric bool isEmptyFieldForLayout(const ASTContext &Context, const FieldDecl *FD); 143*0fca6ea1SDimitry Andric 144*0fca6ea1SDimitry Andric /// isEmptyRecordForLayout - Return true iff a structure contains only empty 145*0fca6ea1SDimitry Andric /// base classes (per \ref isEmptyRecordForLayout) and fields (per 146*0fca6ea1SDimitry Andric /// \ref isEmptyFieldForLayout). Note, C++ record fields are considered empty 147*0fca6ea1SDimitry Andric /// if the [[no_unique_address]] attribute would have made them empty. 148*0fca6ea1SDimitry Andric bool isEmptyRecordForLayout(const ASTContext &Context, QualType T); 149*0fca6ea1SDimitry Andric 15006c3fb27SDimitry Andric /// isSingleElementStruct - Determine if a structure is a "single 15106c3fb27SDimitry Andric /// element struct", i.e. it has exactly one non-empty field or 15206c3fb27SDimitry Andric /// exactly one field which is itself a single element 15306c3fb27SDimitry Andric /// struct. Structures with flexible array members are never 15406c3fb27SDimitry Andric /// considered single element structs. 15506c3fb27SDimitry Andric /// 15606c3fb27SDimitry Andric /// \return The field declaration for the single non-empty field, if 15706c3fb27SDimitry Andric /// it exists. 15806c3fb27SDimitry Andric const Type *isSingleElementStruct(QualType T, ASTContext &Context); 15906c3fb27SDimitry Andric 16006c3fb27SDimitry Andric Address EmitVAArgInstr(CodeGenFunction &CGF, Address VAListAddr, QualType Ty, 16106c3fb27SDimitry Andric const ABIArgInfo &AI); 16206c3fb27SDimitry Andric 16306c3fb27SDimitry Andric bool isSIMDVectorType(ASTContext &Context, QualType Ty); 16406c3fb27SDimitry Andric 16506c3fb27SDimitry Andric bool isRecordWithSIMDVectorType(ASTContext &Context, QualType Ty); 16606c3fb27SDimitry Andric 16706c3fb27SDimitry Andric } // namespace clang::CodeGen 16806c3fb27SDimitry Andric 16906c3fb27SDimitry Andric #endif // LLVM_CLANG_LIB_CODEGEN_ABIINFOIMPL_H 170