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