1 //===----- ABIInfo.h - ABI information access & encapsulation ---*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_CLANG_LIB_CODEGEN_ABIINFO_H 10 #define LLVM_CLANG_LIB_CODEGEN_ABIINFO_H 11 12 #include "clang/AST/CharUnits.h" 13 #include "clang/AST/Type.h" 14 #include "llvm/IR/CallingConv.h" 15 #include "llvm/IR/Type.h" 16 17 namespace llvm { 18 class Value; 19 class LLVMContext; 20 class DataLayout; 21 class Type; 22 } 23 24 namespace clang { 25 class ASTContext; 26 class CodeGenOptions; 27 class TargetInfo; 28 29 namespace CodeGen { 30 class ABIArgInfo; 31 class Address; 32 class CGCXXABI; 33 class CGFunctionInfo; 34 class CodeGenFunction; 35 class CodeGenTypes; 36 37 // FIXME: All of this stuff should be part of the target interface 38 // somehow. It is currently here because it is not clear how to factor 39 // the targets to support this, since the Targets currently live in a 40 // layer below types n'stuff. 41 42 43 /// ABIInfo - Target specific hooks for defining how a type should be 44 /// passed or returned from functions. 45 class ABIInfo { 46 protected: 47 CodeGen::CodeGenTypes &CGT; 48 llvm::CallingConv::ID RuntimeCC; 49 public: 50 ABIInfo(CodeGen::CodeGenTypes &cgt) 51 : CGT(cgt), RuntimeCC(llvm::CallingConv::C) {} 52 53 virtual ~ABIInfo(); 54 55 virtual bool allowBFloatArgsAndRet() const { return false; } 56 57 CodeGen::CGCXXABI &getCXXABI() const; 58 ASTContext &getContext() const; 59 llvm::LLVMContext &getVMContext() const; 60 const llvm::DataLayout &getDataLayout() const; 61 const TargetInfo &getTarget() const; 62 const CodeGenOptions &getCodeGenOpts() const; 63 64 /// Return the calling convention to use for system runtime 65 /// functions. 66 llvm::CallingConv::ID getRuntimeCC() const { 67 return RuntimeCC; 68 } 69 70 virtual void computeInfo(CodeGen::CGFunctionInfo &FI) const = 0; 71 72 /// EmitVAArg - Emit the target dependent code to load a value of 73 /// \arg Ty from the va_list pointed to by \arg VAListAddr. 74 75 // FIXME: This is a gaping layering violation if we wanted to drop 76 // the ABI information any lower than CodeGen. Of course, for 77 // VAArg handling it has to be at this level; there is no way to 78 // abstract this out. 79 virtual CodeGen::Address EmitVAArg(CodeGen::CodeGenFunction &CGF, 80 CodeGen::Address VAListAddr, 81 QualType Ty) const = 0; 82 83 bool isAndroid() const; 84 85 /// Emit the target dependent code to load a value of 86 /// \arg Ty from the \c __builtin_ms_va_list pointed to by \arg VAListAddr. 87 virtual CodeGen::Address EmitMSVAArg(CodeGen::CodeGenFunction &CGF, 88 CodeGen::Address VAListAddr, 89 QualType Ty) const; 90 91 virtual bool isHomogeneousAggregateBaseType(QualType Ty) const; 92 93 virtual bool isHomogeneousAggregateSmallEnough(const Type *Base, 94 uint64_t Members) const; 95 virtual bool isZeroLengthBitfieldPermittedInHomogeneousAggregate() const; 96 97 bool isHomogeneousAggregate(QualType Ty, const Type *&Base, 98 uint64_t &Members) const; 99 100 // Implement the Type::IsPromotableIntegerType for ABI specific needs. The 101 // only difference is that this considers bit-precise integer types as well. 102 bool isPromotableIntegerTypeForABI(QualType Ty) const; 103 104 /// A convenience method to return an indirect ABIArgInfo with an 105 /// expected alignment equal to the ABI alignment of the given type. 106 CodeGen::ABIArgInfo 107 getNaturalAlignIndirect(QualType Ty, bool ByVal = true, 108 bool Realign = false, 109 llvm::Type *Padding = nullptr) const; 110 111 CodeGen::ABIArgInfo 112 getNaturalAlignIndirectInReg(QualType Ty, bool Realign = false) const; 113 }; 114 115 /// Target specific hooks for defining how a type should be passed or returned 116 /// from functions with one of the Swift calling conventions. 117 class SwiftABIInfo { 118 protected: 119 CodeGenTypes &CGT; 120 bool SwiftErrorInRegister; 121 122 public: 123 SwiftABIInfo(CodeGen::CodeGenTypes &CGT, bool SwiftErrorInRegister) 124 : CGT(CGT), SwiftErrorInRegister(SwiftErrorInRegister) {} 125 126 virtual ~SwiftABIInfo(); 127 128 /// Returns true if an aggregate which expands to the given type sequence 129 /// should be passed / returned indirectly. 130 virtual bool shouldPassIndirectly(ArrayRef<llvm::Type *> ComponentTys, 131 bool AsReturnValue) const; 132 133 /// Returns true if the given vector type is legal from Swift's calling 134 /// convention perspective. 135 virtual bool isLegalVectorType(CharUnits VectorSize, llvm::Type *EltTy, 136 unsigned NumElts) const; 137 138 /// Returns true if swifterror is lowered to a register by the target ABI. 139 bool isSwiftErrorInRegister() const { return SwiftErrorInRegister; }; 140 }; 141 } // end namespace CodeGen 142 } // end namespace clang 143 144 #endif 145