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 CLANG_CODEGEN_ABIINFO_H 11 #define CLANG_CODEGEN_ABIINFO_H 12 13 #include "clang/AST/Type.h" 14 #include "llvm/IR/Type.h" 15 #include "llvm/IR/CallingConv.h" 16 17 namespace llvm { 18 class Value; 19 class LLVMContext; 20 class DataLayout; 21 } 22 23 namespace clang { 24 class ASTContext; 25 26 namespace CodeGen { 27 class CGFunctionInfo; 28 class CodeGenFunction; 29 class CodeGenTypes; 30 } 31 32 // FIXME: All of this stuff should be part of the target interface 33 // somehow. It is currently here because it is not clear how to factor 34 // the targets to support this, since the Targets currently live in a 35 // layer below types n'stuff. 36 37 /// ABIArgInfo - Helper class to encapsulate information about how a 38 /// specific C type should be passed to or returned from a function. 39 class ABIArgInfo { 40 public: 41 enum Kind { 42 /// Direct - Pass the argument directly using the normal converted LLVM 43 /// type, or by coercing to another specified type stored in 44 /// 'CoerceToType'). If an offset is specified (in UIntData), then the 45 /// argument passed is offset by some number of bytes in the memory 46 /// representation. A dummy argument is emitted before the real argument 47 /// if the specified type stored in "PaddingType" is not zero. 48 Direct, 49 50 /// Extend - Valid only for integer argument types. Same as 'direct' 51 /// but also emit a zero/sign extension attribute. 52 Extend, 53 54 /// Indirect - Pass the argument indirectly via a hidden pointer 55 /// with the specified alignment (0 indicates default alignment). 56 Indirect, 57 58 /// Ignore - Ignore the argument (treat as void). Useful for void and 59 /// empty structs. 60 Ignore, 61 62 /// Expand - Only valid for aggregate argument types. The structure should 63 /// be expanded into consecutive arguments for its constituent fields. 64 /// Currently expand is only allowed on structures whose fields 65 /// are all scalar types or are themselves expandable types. 66 Expand, 67 68 KindFirst=Direct, KindLast=Expand 69 }; 70 71 private: 72 Kind TheKind; 73 llvm::Type *TypeData; 74 llvm::Type *PaddingType; 75 unsigned UIntData; 76 bool BoolData0; 77 bool BoolData1; 78 bool InReg; 79 bool PaddingInReg; 80 81 ABIArgInfo(Kind K, llvm::Type *TD, unsigned UI, bool B0, bool B1, bool IR, 82 bool PIR, llvm::Type* P) 83 : TheKind(K), TypeData(TD), PaddingType(P), UIntData(UI), BoolData0(B0), 84 BoolData1(B1), InReg(IR), PaddingInReg(PIR) {} 85 86 public: 87 ABIArgInfo() : TheKind(Direct), TypeData(0), UIntData(0) {} 88 89 static ABIArgInfo getDirect(llvm::Type *T = 0, unsigned Offset = 0, 90 llvm::Type *Padding = 0) { 91 return ABIArgInfo(Direct, T, Offset, false, false, false, false, Padding); 92 } 93 static ABIArgInfo getDirectInReg(llvm::Type *T = 0) { 94 return ABIArgInfo(Direct, T, 0, false, false, true, false, 0); 95 } 96 static ABIArgInfo getExtend(llvm::Type *T = 0) { 97 return ABIArgInfo(Extend, T, 0, false, false, false, false, 0); 98 } 99 static ABIArgInfo getExtendInReg(llvm::Type *T = 0) { 100 return ABIArgInfo(Extend, T, 0, false, false, true, false, 0); 101 } 102 static ABIArgInfo getIgnore() { 103 return ABIArgInfo(Ignore, 0, 0, false, false, false, false, 0); 104 } 105 static ABIArgInfo getIndirect(unsigned Alignment, bool ByVal = true 106 , bool Realign = false 107 , llvm::Type *Padding = 0) { 108 return ABIArgInfo(Indirect, 0, Alignment, ByVal, Realign, false, false, 109 Padding); 110 } 111 static ABIArgInfo getIndirectInReg(unsigned Alignment, bool ByVal = true 112 , bool Realign = false) { 113 return ABIArgInfo(Indirect, 0, Alignment, ByVal, Realign, true, false, 0); 114 } 115 static ABIArgInfo getExpand() { 116 return ABIArgInfo(Expand, 0, 0, false, false, false, false, 0); 117 } 118 static ABIArgInfo getExpandWithPadding(bool PaddingInReg, 119 llvm::Type *Padding) { 120 return ABIArgInfo(Expand, 0, 0, false, false, false, PaddingInReg, 121 Padding); 122 } 123 124 Kind getKind() const { return TheKind; } 125 bool isDirect() const { return TheKind == Direct; } 126 bool isExtend() const { return TheKind == Extend; } 127 bool isIgnore() const { return TheKind == Ignore; } 128 bool isIndirect() const { return TheKind == Indirect; } 129 bool isExpand() const { return TheKind == Expand; } 130 131 bool canHaveCoerceToType() const { 132 return TheKind == Direct || TheKind == Extend; 133 } 134 135 // Direct/Extend accessors 136 unsigned getDirectOffset() const { 137 assert((isDirect() || isExtend()) && "Not a direct or extend kind"); 138 return UIntData; 139 } 140 141 llvm::Type *getPaddingType() const { 142 return PaddingType; 143 } 144 145 bool getPaddingInReg() const { 146 return PaddingInReg; 147 } 148 149 llvm::Type *getCoerceToType() const { 150 assert(canHaveCoerceToType() && "Invalid kind!"); 151 return TypeData; 152 } 153 154 void setCoerceToType(llvm::Type *T) { 155 assert(canHaveCoerceToType() && "Invalid kind!"); 156 TypeData = T; 157 } 158 159 bool getInReg() const { 160 assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!"); 161 return InReg; 162 } 163 164 // Indirect accessors 165 unsigned getIndirectAlign() const { 166 assert(TheKind == Indirect && "Invalid kind!"); 167 return UIntData; 168 } 169 170 bool getIndirectByVal() const { 171 assert(TheKind == Indirect && "Invalid kind!"); 172 return BoolData0; 173 } 174 175 bool getIndirectRealign() const { 176 assert(TheKind == Indirect && "Invalid kind!"); 177 return BoolData1; 178 } 179 180 void dump() const; 181 }; 182 183 /// ABIInfo - Target specific hooks for defining how a type should be 184 /// passed or returned from functions. 185 class ABIInfo { 186 public: 187 CodeGen::CodeGenTypes &CGT; 188 protected: 189 llvm::CallingConv::ID RuntimeCC; 190 public: 191 ABIInfo(CodeGen::CodeGenTypes &cgt) 192 : CGT(cgt), RuntimeCC(llvm::CallingConv::C) {} 193 194 virtual ~ABIInfo(); 195 196 ASTContext &getContext() const; 197 llvm::LLVMContext &getVMContext() const; 198 const llvm::DataLayout &getDataLayout() const; 199 200 /// Return the calling convention to use for system runtime 201 /// functions. 202 llvm::CallingConv::ID getRuntimeCC() const { 203 return RuntimeCC; 204 } 205 206 virtual void computeInfo(CodeGen::CGFunctionInfo &FI) const = 0; 207 208 /// EmitVAArg - Emit the target dependent code to load a value of 209 /// \arg Ty from the va_list pointed to by \arg VAListAddr. 210 211 // FIXME: This is a gaping layering violation if we wanted to drop 212 // the ABI information any lower than CodeGen. Of course, for 213 // VAArg handling it has to be at this level; there is no way to 214 // abstract this out. 215 virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, 216 CodeGen::CodeGenFunction &CGF) const = 0; 217 }; 218 } // end namespace clang 219 220 #endif 221