17330f729Sjoerg //===----- ABIInfo.h - ABI information access & encapsulation ---*- C++ -*-===// 27330f729Sjoerg // 37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information. 57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 67330f729Sjoerg // 77330f729Sjoerg //===----------------------------------------------------------------------===// 87330f729Sjoerg 97330f729Sjoerg #ifndef LLVM_CLANG_LIB_CODEGEN_ABIINFO_H 107330f729Sjoerg #define LLVM_CLANG_LIB_CODEGEN_ABIINFO_H 117330f729Sjoerg 127330f729Sjoerg #include "clang/AST/CharUnits.h" 137330f729Sjoerg #include "clang/AST/Type.h" 147330f729Sjoerg #include "llvm/IR/CallingConv.h" 157330f729Sjoerg #include "llvm/IR/Type.h" 167330f729Sjoerg 177330f729Sjoerg namespace llvm { 187330f729Sjoerg class Value; 197330f729Sjoerg class LLVMContext; 207330f729Sjoerg class DataLayout; 217330f729Sjoerg class Type; 227330f729Sjoerg } 237330f729Sjoerg 247330f729Sjoerg namespace clang { 257330f729Sjoerg class ASTContext; 267330f729Sjoerg class CodeGenOptions; 277330f729Sjoerg class TargetInfo; 287330f729Sjoerg 297330f729Sjoerg namespace CodeGen { 307330f729Sjoerg class ABIArgInfo; 317330f729Sjoerg class Address; 327330f729Sjoerg class CGCXXABI; 337330f729Sjoerg class CGFunctionInfo; 347330f729Sjoerg class CodeGenFunction; 357330f729Sjoerg class CodeGenTypes; 367330f729Sjoerg class SwiftABIInfo; 377330f729Sjoerg 387330f729Sjoerg namespace swiftcall { 397330f729Sjoerg class SwiftAggLowering; 407330f729Sjoerg } 417330f729Sjoerg 427330f729Sjoerg // FIXME: All of this stuff should be part of the target interface 437330f729Sjoerg // somehow. It is currently here because it is not clear how to factor 447330f729Sjoerg // the targets to support this, since the Targets currently live in a 457330f729Sjoerg // layer below types n'stuff. 467330f729Sjoerg 477330f729Sjoerg 487330f729Sjoerg /// ABIInfo - Target specific hooks for defining how a type should be 497330f729Sjoerg /// passed or returned from functions. 507330f729Sjoerg class ABIInfo { 517330f729Sjoerg public: 527330f729Sjoerg CodeGen::CodeGenTypes &CGT; 537330f729Sjoerg protected: 547330f729Sjoerg llvm::CallingConv::ID RuntimeCC; 557330f729Sjoerg public: ABIInfo(CodeGen::CodeGenTypes & cgt)567330f729Sjoerg ABIInfo(CodeGen::CodeGenTypes &cgt) 577330f729Sjoerg : CGT(cgt), RuntimeCC(llvm::CallingConv::C) {} 587330f729Sjoerg 597330f729Sjoerg virtual ~ABIInfo(); 607330f729Sjoerg supportsSwift()617330f729Sjoerg virtual bool supportsSwift() const { return false; } 627330f729Sjoerg allowBFloatArgsAndRet()63*e038c9c4Sjoerg virtual bool allowBFloatArgsAndRet() const { return false; } 64*e038c9c4Sjoerg 657330f729Sjoerg CodeGen::CGCXXABI &getCXXABI() const; 667330f729Sjoerg ASTContext &getContext() const; 677330f729Sjoerg llvm::LLVMContext &getVMContext() const; 687330f729Sjoerg const llvm::DataLayout &getDataLayout() const; 697330f729Sjoerg const TargetInfo &getTarget() const; 707330f729Sjoerg const CodeGenOptions &getCodeGenOpts() const; 717330f729Sjoerg 727330f729Sjoerg /// Return the calling convention to use for system runtime 737330f729Sjoerg /// functions. getRuntimeCC()747330f729Sjoerg llvm::CallingConv::ID getRuntimeCC() const { 757330f729Sjoerg return RuntimeCC; 767330f729Sjoerg } 777330f729Sjoerg 787330f729Sjoerg virtual void computeInfo(CodeGen::CGFunctionInfo &FI) const = 0; 797330f729Sjoerg 807330f729Sjoerg /// EmitVAArg - Emit the target dependent code to load a value of 817330f729Sjoerg /// \arg Ty from the va_list pointed to by \arg VAListAddr. 827330f729Sjoerg 837330f729Sjoerg // FIXME: This is a gaping layering violation if we wanted to drop 847330f729Sjoerg // the ABI information any lower than CodeGen. Of course, for 857330f729Sjoerg // VAArg handling it has to be at this level; there is no way to 867330f729Sjoerg // abstract this out. 877330f729Sjoerg virtual CodeGen::Address EmitVAArg(CodeGen::CodeGenFunction &CGF, 887330f729Sjoerg CodeGen::Address VAListAddr, 897330f729Sjoerg QualType Ty) const = 0; 907330f729Sjoerg 917330f729Sjoerg bool isAndroid() const; 927330f729Sjoerg 937330f729Sjoerg /// Emit the target dependent code to load a value of 947330f729Sjoerg /// \arg Ty from the \c __builtin_ms_va_list pointed to by \arg VAListAddr. 957330f729Sjoerg virtual CodeGen::Address EmitMSVAArg(CodeGen::CodeGenFunction &CGF, 967330f729Sjoerg CodeGen::Address VAListAddr, 977330f729Sjoerg QualType Ty) const; 987330f729Sjoerg 997330f729Sjoerg virtual bool isHomogeneousAggregateBaseType(QualType Ty) const; 1007330f729Sjoerg 1017330f729Sjoerg virtual bool isHomogeneousAggregateSmallEnough(const Type *Base, 1027330f729Sjoerg uint64_t Members) const; 1037330f729Sjoerg 1047330f729Sjoerg bool isHomogeneousAggregate(QualType Ty, const Type *&Base, 1057330f729Sjoerg uint64_t &Members) const; 1067330f729Sjoerg 107*e038c9c4Sjoerg // Implement the Type::IsPromotableIntegerType for ABI specific needs. The 108*e038c9c4Sjoerg // only difference is that this considers _ExtInt as well. 109*e038c9c4Sjoerg bool isPromotableIntegerTypeForABI(QualType Ty) const; 110*e038c9c4Sjoerg 1117330f729Sjoerg /// A convenience method to return an indirect ABIArgInfo with an 1127330f729Sjoerg /// expected alignment equal to the ABI alignment of the given type. 1137330f729Sjoerg CodeGen::ABIArgInfo 114*e038c9c4Sjoerg getNaturalAlignIndirect(QualType Ty, bool ByVal = true, 1157330f729Sjoerg bool Realign = false, 1167330f729Sjoerg llvm::Type *Padding = nullptr) const; 1177330f729Sjoerg 1187330f729Sjoerg CodeGen::ABIArgInfo 1197330f729Sjoerg getNaturalAlignIndirectInReg(QualType Ty, bool Realign = false) const; 1207330f729Sjoerg 1217330f729Sjoerg 1227330f729Sjoerg }; 1237330f729Sjoerg 1247330f729Sjoerg /// A refining implementation of ABIInfo for targets that support swiftcall. 1257330f729Sjoerg /// 1267330f729Sjoerg /// If we find ourselves wanting multiple such refinements, they'll probably 1277330f729Sjoerg /// be independent refinements, and we should probably find another way 1287330f729Sjoerg /// to do it than simple inheritance. 1297330f729Sjoerg class SwiftABIInfo : public ABIInfo { 1307330f729Sjoerg public: SwiftABIInfo(CodeGen::CodeGenTypes & cgt)1317330f729Sjoerg SwiftABIInfo(CodeGen::CodeGenTypes &cgt) : ABIInfo(cgt) {} 1327330f729Sjoerg supportsSwift()1337330f729Sjoerg bool supportsSwift() const final override { return true; } 1347330f729Sjoerg 1357330f729Sjoerg virtual bool shouldPassIndirectlyForSwift(ArrayRef<llvm::Type*> types, 1367330f729Sjoerg bool asReturnValue) const = 0; 1377330f729Sjoerg 1387330f729Sjoerg virtual bool isLegalVectorTypeForSwift(CharUnits totalSize, 1397330f729Sjoerg llvm::Type *eltTy, 1407330f729Sjoerg unsigned elts) const; 1417330f729Sjoerg 1427330f729Sjoerg virtual bool isSwiftErrorInRegister() const = 0; 1437330f729Sjoerg classof(const ABIInfo * info)1447330f729Sjoerg static bool classof(const ABIInfo *info) { 1457330f729Sjoerg return info->supportsSwift(); 1467330f729Sjoerg } 1477330f729Sjoerg }; 1487330f729Sjoerg } // end namespace CodeGen 1497330f729Sjoerg } // end namespace clang 1507330f729Sjoerg 1517330f729Sjoerg #endif 152