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