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 } // namespace llvm 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 /// ABIInfo - Target specific hooks for defining how a type should be 43 /// passed or returned from functions. 44 class ABIInfo { 45 protected: 46 CodeGen::CodeGenTypes &CGT; 47 llvm::CallingConv::ID RuntimeCC; 48 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 { return RuntimeCC; } 67 68 virtual void computeInfo(CodeGen::CGFunctionInfo &FI) const = 0; 69 70 /// EmitVAArg - Emit the target dependent code to load a value of 71 /// \arg Ty from the va_list pointed to by \arg VAListAddr. 72 73 // FIXME: This is a gaping layering violation if we wanted to drop 74 // the ABI information any lower than CodeGen. Of course, for 75 // VAArg handling it has to be at this level; there is no way to 76 // abstract this out. 77 virtual CodeGen::Address EmitVAArg(CodeGen::CodeGenFunction &CGF, 78 CodeGen::Address VAListAddr, 79 QualType Ty) const = 0; 80 81 bool isAndroid() const; 82 bool isOHOSFamily() const; 83 84 /// Emit the target dependent code to load a value of 85 /// \arg Ty from the \c __builtin_ms_va_list pointed to by \arg VAListAddr. 86 virtual CodeGen::Address EmitMSVAArg(CodeGen::CodeGenFunction &CGF, 87 CodeGen::Address VAListAddr, 88 QualType Ty) const; 89 90 virtual bool isHomogeneousAggregateBaseType(QualType Ty) const; 91 92 virtual bool isHomogeneousAggregateSmallEnough(const Type *Base, 93 uint64_t Members) const; 94 virtual bool isZeroLengthBitfieldPermittedInHomogeneousAggregate() const; 95 96 /// isHomogeneousAggregate - Return true if a type is an ELFv2 homogeneous 97 /// aggregate. Base is set to the base element type, and Members is set 98 /// to the number of base elements. 99 bool isHomogeneousAggregate(QualType Ty, const Type *&Base, 100 uint64_t &Members) const; 101 102 // Implement the Type::IsPromotableIntegerType for ABI specific needs. The 103 // only difference is that this considers bit-precise integer types as well. 104 bool isPromotableIntegerTypeForABI(QualType Ty) const; 105 106 /// A convenience method to return an indirect ABIArgInfo with an 107 /// expected alignment equal to the ABI alignment of the given type. 108 CodeGen::ABIArgInfo 109 getNaturalAlignIndirect(QualType Ty, bool ByVal = true, bool Realign = false, 110 llvm::Type *Padding = nullptr) const; 111 112 CodeGen::ABIArgInfo getNaturalAlignIndirectInReg(QualType Ty, 113 bool Realign = false) const; 114 }; 115 116 /// Target specific hooks for defining how a type should be passed or returned 117 /// from functions with one of the Swift calling conventions. 118 class SwiftABIInfo { 119 protected: 120 CodeGenTypes &CGT; 121 bool SwiftErrorInRegister; 122 123 bool occupiesMoreThan(ArrayRef<llvm::Type *> scalarTypes, 124 unsigned maxAllRegisters) const; 125 126 public: 127 SwiftABIInfo(CodeGen::CodeGenTypes &CGT, bool SwiftErrorInRegister) 128 : CGT(CGT), SwiftErrorInRegister(SwiftErrorInRegister) {} 129 130 virtual ~SwiftABIInfo(); 131 132 /// Returns true if an aggregate which expands to the given type sequence 133 /// should be passed / returned indirectly. 134 virtual bool shouldPassIndirectly(ArrayRef<llvm::Type *> ComponentTys, 135 bool AsReturnValue) const; 136 137 /// Returns true if the given vector type is legal from Swift's calling 138 /// convention perspective. 139 virtual bool isLegalVectorType(CharUnits VectorSize, llvm::Type *EltTy, 140 unsigned NumElts) const; 141 142 /// Returns true if swifterror is lowered to a register by the target ABI. 143 bool isSwiftErrorInRegister() const { return SwiftErrorInRegister; }; 144 }; 145 } // end namespace CodeGen 146 } // end namespace clang 147 148 #endif 149