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. 46 Direct, 47 48 /// Extend - Valid only for integer argument types. Same as 'direct' 49 /// but also emit a zero/sign extension attribute. 50 Extend, 51 52 /// Indirect - Pass the argument indirectly via a hidden pointer 53 /// with the specified alignment (0 indicates default alignment). 54 Indirect, 55 56 /// Ignore - Ignore the argument (treat as void). Useful for void and 57 /// empty structs. 58 Ignore, 59 60 /// Expand - Only valid for aggregate argument types. The structure should 61 /// be expanded into consecutive arguments for its constituent fields. 62 /// Currently expand is only allowed on structures whose fields 63 /// are all scalar types or are themselves expandable types. 64 Expand, 65 66 KindFirst=Direct, KindLast=Expand 67 }; 68 69 private: 70 Kind TheKind; 71 llvm::Type *TypeData; 72 unsigned UIntData; 73 bool BoolData0; 74 bool BoolData1; 75 76 ABIArgInfo(Kind K, llvm::Type *TD=0, 77 unsigned UI=0, bool B0 = false, bool B1 = false) 78 : TheKind(K), TypeData(TD), UIntData(UI), BoolData0(B0), BoolData1(B1) {} 79 80 public: 81 ABIArgInfo() : TheKind(Direct), TypeData(0), UIntData(0) {} 82 83 static ABIArgInfo getDirect(llvm::Type *T = 0, unsigned Offset = 0) { 84 return ABIArgInfo(Direct, T, Offset); 85 } 86 static ABIArgInfo getExtend(llvm::Type *T = 0) { 87 return ABIArgInfo(Extend, T, 0); 88 } 89 static ABIArgInfo getIgnore() { 90 return ABIArgInfo(Ignore); 91 } 92 static ABIArgInfo getIndirect(unsigned Alignment, bool ByVal = true 93 , bool Realign = false) { 94 return ABIArgInfo(Indirect, 0, Alignment, ByVal, Realign); 95 } 96 static ABIArgInfo getExpand() { 97 return ABIArgInfo(Expand); 98 } 99 100 Kind getKind() const { return TheKind; } 101 bool isDirect() const { return TheKind == Direct; } 102 bool isExtend() const { return TheKind == Extend; } 103 bool isIgnore() const { return TheKind == Ignore; } 104 bool isIndirect() const { return TheKind == Indirect; } 105 bool isExpand() const { return TheKind == Expand; } 106 107 bool canHaveCoerceToType() const { 108 return TheKind == Direct || TheKind == Extend; 109 } 110 111 // Direct/Extend accessors 112 unsigned getDirectOffset() const { 113 assert((isDirect() || isExtend()) && "Not a direct or extend kind"); 114 return UIntData; 115 } 116 llvm::Type *getCoerceToType() const { 117 assert(canHaveCoerceToType() && "Invalid kind!"); 118 return TypeData; 119 } 120 121 void setCoerceToType(llvm::Type *T) { 122 assert(canHaveCoerceToType() && "Invalid kind!"); 123 TypeData = T; 124 } 125 126 // Indirect accessors 127 unsigned getIndirectAlign() const { 128 assert(TheKind == Indirect && "Invalid kind!"); 129 return UIntData; 130 } 131 132 bool getIndirectByVal() const { 133 assert(TheKind == Indirect && "Invalid kind!"); 134 return BoolData0; 135 } 136 137 bool getIndirectRealign() const { 138 assert(TheKind == Indirect && "Invalid kind!"); 139 return BoolData1; 140 } 141 142 void dump() const; 143 }; 144 145 /// ABIInfo - Target specific hooks for defining how a type should be 146 /// passed or returned from functions. 147 class ABIInfo { 148 public: 149 CodeGen::CodeGenTypes &CGT; 150 151 ABIInfo(CodeGen::CodeGenTypes &cgt) : CGT(cgt) {} 152 virtual ~ABIInfo(); 153 154 ASTContext &getContext() const; 155 llvm::LLVMContext &getVMContext() const; 156 const llvm::TargetData &getTargetData() const; 157 158 virtual void computeInfo(CodeGen::CGFunctionInfo &FI) const = 0; 159 160 /// EmitVAArg - Emit the target dependent code to load a value of 161 /// \arg Ty from the va_list pointed to by \arg VAListAddr. 162 163 // FIXME: This is a gaping layering violation if we wanted to drop 164 // the ABI information any lower than CodeGen. Of course, for 165 // VAArg handling it has to be at this level; there is no way to 166 // abstract this out. 167 virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, 168 CodeGen::CodeGenFunction &CGF) const = 0; 169 }; 170 } // end namespace clang 171 172 #endif 173