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