1 //===----- ABIInfo.h - ABI information access & encapsulation ---*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef LLVM_CLANG_LIB_CODEGEN_ABIINFO_H 11 #define LLVM_CLANG_LIB_CODEGEN_ABIINFO_H 12 13 #include "clang/AST/CharUnits.h" 14 #include "clang/AST/Type.h" 15 #include "llvm/IR/CallingConv.h" 16 #include "llvm/IR/Type.h" 17 18 namespace llvm { 19 class Value; 20 class LLVMContext; 21 class DataLayout; 22 class Type; 23 } 24 25 namespace clang { 26 class ASTContext; 27 class CodeGenOptions; 28 class TargetInfo; 29 30 namespace CodeGen { 31 class ABIArgInfo; 32 class Address; 33 class CGCXXABI; 34 class CGFunctionInfo; 35 class CodeGenFunction; 36 class CodeGenTypes; 37 class SwiftABIInfo; 38 39 namespace swiftcall { 40 class SwiftAggLowering; 41 } 42 43 // FIXME: All of this stuff should be part of the target interface 44 // somehow. It is currently here because it is not clear how to factor 45 // the targets to support this, since the Targets currently live in a 46 // layer below types n'stuff. 47 48 49 /// ABIInfo - Target specific hooks for defining how a type should be 50 /// passed or returned from functions. 51 class ABIInfo { 52 public: 53 CodeGen::CodeGenTypes &CGT; 54 protected: 55 llvm::CallingConv::ID RuntimeCC; 56 llvm::CallingConv::ID BuiltinCC; 57 public: 58 ABIInfo(CodeGen::CodeGenTypes &cgt) 59 : CGT(cgt), 60 RuntimeCC(llvm::CallingConv::C), 61 BuiltinCC(llvm::CallingConv::C) {} 62 63 virtual ~ABIInfo(); 64 65 virtual bool supportsSwift() const { return false; } 66 67 CodeGen::CGCXXABI &getCXXABI() const; 68 ASTContext &getContext() const; 69 llvm::LLVMContext &getVMContext() const; 70 const llvm::DataLayout &getDataLayout() const; 71 const TargetInfo &getTarget() const; 72 const CodeGenOptions &getCodeGenOpts() const; 73 74 /// Return the calling convention to use for system runtime 75 /// functions. 76 llvm::CallingConv::ID getRuntimeCC() const { 77 return RuntimeCC; 78 } 79 80 /// Return the calling convention to use for compiler builtins 81 llvm::CallingConv::ID getBuiltinCC() const { 82 return BuiltinCC; 83 } 84 85 virtual void computeInfo(CodeGen::CGFunctionInfo &FI) const = 0; 86 87 /// EmitVAArg - Emit the target dependent code to load a value of 88 /// \arg Ty from the va_list pointed to by \arg VAListAddr. 89 90 // FIXME: This is a gaping layering violation if we wanted to drop 91 // the ABI information any lower than CodeGen. Of course, for 92 // VAArg handling it has to be at this level; there is no way to 93 // abstract this out. 94 virtual CodeGen::Address EmitVAArg(CodeGen::CodeGenFunction &CGF, 95 CodeGen::Address VAListAddr, 96 QualType Ty) const = 0; 97 98 bool isAndroid() const; 99 100 /// Emit the target dependent code to load a value of 101 /// \arg Ty from the \c __builtin_ms_va_list pointed to by \arg VAListAddr. 102 virtual CodeGen::Address EmitMSVAArg(CodeGen::CodeGenFunction &CGF, 103 CodeGen::Address VAListAddr, 104 QualType Ty) const; 105 106 virtual bool isHomogeneousAggregateBaseType(QualType Ty) const; 107 108 virtual bool isHomogeneousAggregateSmallEnough(const Type *Base, 109 uint64_t Members) const; 110 111 bool isHomogeneousAggregate(QualType Ty, const Type *&Base, 112 uint64_t &Members) const; 113 114 /// A convenience method to return an indirect ABIArgInfo with an 115 /// expected alignment equal to the ABI alignment of the given type. 116 CodeGen::ABIArgInfo 117 getNaturalAlignIndirect(QualType Ty, bool ByRef = true, 118 bool Realign = false, 119 llvm::Type *Padding = nullptr) const; 120 121 CodeGen::ABIArgInfo 122 getNaturalAlignIndirectInReg(QualType Ty, bool Realign = false) const; 123 124 125 }; 126 127 /// A refining implementation of ABIInfo for targets that support swiftcall. 128 /// 129 /// If we find ourselves wanting multiple such refinements, they'll probably 130 /// be independent refinements, and we should probably find another way 131 /// to do it than simple inheritance. 132 class SwiftABIInfo : public ABIInfo { 133 public: 134 SwiftABIInfo(CodeGen::CodeGenTypes &cgt) : ABIInfo(cgt) {} 135 136 bool supportsSwift() const final override { return true; } 137 138 virtual bool shouldPassIndirectlyForSwift(ArrayRef<llvm::Type*> types, 139 bool asReturnValue) const = 0; 140 141 virtual bool isLegalVectorTypeForSwift(CharUnits totalSize, 142 llvm::Type *eltTy, 143 unsigned elts) const; 144 145 virtual bool isSwiftErrorInRegister() const = 0; 146 147 static bool classof(const ABIInfo *info) { 148 return info->supportsSwift(); 149 } 150 }; 151 } // end namespace CodeGen 152 } // end namespace clang 153 154 #endif 155