//===----- ABIInfo.h - ABI information access & encapsulation ---*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_LIB_CODEGEN_ABIINFO_H #define LLVM_CLANG_LIB_CODEGEN_ABIINFO_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 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; llvm::CallingConv::ID BuiltinCC; public: ABIInfo(CodeGen::CodeGenTypes &cgt) : CGT(cgt), RuntimeCC(llvm::CallingConv::C), BuiltinCC(llvm::CallingConv::C) {} virtual ~ABIInfo(); virtual bool supportsSwift() const { return false; } CodeGen::CGCXXABI &getCXXABI() const; ASTContext &getContext() const; llvm::LLVMContext &getVMContext() const; const llvm::DataLayout &getDataLayout() const; const TargetInfo &getTarget() const; /// Return the calling convention to use for system runtime /// functions. llvm::CallingConv::ID getRuntimeCC() const { return RuntimeCC; } /// Return the calling convention to use for compiler builtins llvm::CallingConv::ID getBuiltinCC() const { return BuiltinCC; } 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; virtual bool shouldSignExtUnsignedType(QualType Ty) const; bool isHomogeneousAggregate(QualType Ty, const Type *&Base, uint64_t &Members) 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 ByRef = 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(CharUnits totalSize, ArrayRef<llvm::Type*> types, bool asReturnValue) const = 0; virtual bool isLegalVectorTypeForSwift(CharUnits totalSize, llvm::Type *eltTy, unsigned elts) const; static bool classof(const ABIInfo *info) { return info->supportsSwift(); } }; } // end namespace CodeGen } // end namespace clang #endif