//===----- ABIInfo.h - ABI information access & encapsulation ---*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_LIB_CODEGEN_ABIINFO_H #define LLVM_CLANG_LIB_CODEGEN_ABIINFO_H #include "clang/AST/CharUnits.h" #include "clang/AST/Type.h" #include "llvm/IR/CallingConv.h" #include "llvm/IR/Type.h" namespace llvm { class Value; class LLVMContext; class DataLayout; class Type; } namespace clang { class ASTContext; class CodeGenOptions; class TargetInfo; namespace CodeGen { class ABIArgInfo; class Address; class CGCXXABI; class CGFunctionInfo; class CodeGenFunction; class CodeGenTypes; class SwiftABIInfo; namespace swiftcall { class SwiftAggLowering; } // FIXME: All of this stuff should be part of the target interface // somehow. It is currently here because it is not clear how to factor // the targets to support this, since the Targets currently live in a // layer below types n'stuff. /// ABIInfo - Target specific hooks for defining how a type should be /// passed or returned from functions. class ABIInfo { public: CodeGen::CodeGenTypes &CGT; protected: llvm::CallingConv::ID RuntimeCC; public: ABIInfo(CodeGen::CodeGenTypes &cgt) : CGT(cgt), RuntimeCC(llvm::CallingConv::C) {} virtual ~ABIInfo(); virtual bool supportsSwift() const { return false; } virtual bool allowBFloatArgsAndRet() const { return false; } CodeGen::CGCXXABI &getCXXABI() const; ASTContext &getContext() const; llvm::LLVMContext &getVMContext() const; const llvm::DataLayout &getDataLayout() const; const TargetInfo &getTarget() const; const CodeGenOptions &getCodeGenOpts() const; /// Return the calling convention to use for system runtime /// functions. llvm::CallingConv::ID getRuntimeCC() const { return RuntimeCC; } virtual void computeInfo(CodeGen::CGFunctionInfo &FI) const = 0; /// EmitVAArg - Emit the target dependent code to load a value of /// \arg Ty from the va_list pointed to by \arg VAListAddr. // FIXME: This is a gaping layering violation if we wanted to drop // the ABI information any lower than CodeGen. Of course, for // VAArg handling it has to be at this level; there is no way to // abstract this out. virtual CodeGen::Address EmitVAArg(CodeGen::CodeGenFunction &CGF, CodeGen::Address VAListAddr, QualType Ty) const = 0; bool isAndroid() const; /// Emit the target dependent code to load a value of /// \arg Ty from the \c __builtin_ms_va_list pointed to by \arg VAListAddr. virtual CodeGen::Address EmitMSVAArg(CodeGen::CodeGenFunction &CGF, CodeGen::Address VAListAddr, QualType Ty) const; virtual bool isHomogeneousAggregateBaseType(QualType Ty) const; virtual bool isHomogeneousAggregateSmallEnough(const Type *Base, uint64_t Members) const; bool isHomogeneousAggregate(QualType Ty, const Type *&Base, uint64_t &Members) const; // Implement the Type::IsPromotableIntegerType for ABI specific needs. The // only difference is that this considers bit-precise integer types as well. bool isPromotableIntegerTypeForABI(QualType Ty) const; /// A convenience method to return an indirect ABIArgInfo with an /// expected alignment equal to the ABI alignment of the given type. CodeGen::ABIArgInfo getNaturalAlignIndirect(QualType Ty, bool ByVal = true, bool Realign = false, llvm::Type *Padding = nullptr) const; CodeGen::ABIArgInfo getNaturalAlignIndirectInReg(QualType Ty, bool Realign = false) const; }; /// A refining implementation of ABIInfo for targets that support swiftcall. /// /// If we find ourselves wanting multiple such refinements, they'll probably /// be independent refinements, and we should probably find another way /// to do it than simple inheritance. class SwiftABIInfo : public ABIInfo { public: SwiftABIInfo(CodeGen::CodeGenTypes &cgt) : ABIInfo(cgt) {} bool supportsSwift() const final override { return true; } virtual bool shouldPassIndirectlyForSwift(ArrayRef types, bool asReturnValue) const = 0; virtual bool isLegalVectorTypeForSwift(CharUnits totalSize, llvm::Type *eltTy, unsigned elts) const; virtual bool isSwiftErrorInRegister() const = 0; static bool classof(const ABIInfo *info) { return info->supportsSwift(); } }; } // end namespace CodeGen } // end namespace clang #endif