xref: /freebsd-src/contrib/llvm-project/clang/lib/CodeGen/ABIInfoImpl.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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