ABIInfo.h revision 8640cd6bf077e007fdb9bc8c9c5e319f7d70da96
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 15#include <cassert> 16 17namespace llvm { 18 class Type; 19 class Value; 20 class LLVMContext; 21} 22 23namespace clang { 24 class ASTContext; 25 26 // FIXME: This is a layering issue if we want to move ABIInfo 27 // down. Fortunately CGFunctionInfo has no real tie to CodeGen. 28 namespace CodeGen { 29 class CGFunctionInfo; 30 class CodeGenFunction; 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 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 45 /// converted LLVM type. Complex and structure types 46 /// are passed using first class aggregates. 47 48 Extend, /// Valid only for integer argument types. Same as 'direct' 49 /// but also emit a zero/sign extension attribute. 50 51 Indirect, /// Pass the argument indirectly via a hidden pointer 52 /// with the specified alignment (0 indicates default 53 /// alignment). 54 55 Ignore, /// Ignore the argument (treat as void). Useful for 56 /// void and empty structs. 57 58 Coerce, /// Only valid for aggregate return types, the argument 59 /// should be accessed by coercion to a provided type. 60 61 Expand, /// Only valid for aggregate argument types. The 62 /// structure should be expanded into consecutive 63 /// arguments for its constituent fields. Currently 64 /// expand is only allowed on structures whose fields 65 /// are all scalar types or are themselves expandable 66 /// types. 67 68 KindFirst=Direct, KindLast=Expand 69 }; 70 71 private: 72 Kind TheKind; 73 const llvm::Type *TypeData; 74 unsigned UIntData; 75 bool BoolData; 76 77 ABIArgInfo(Kind K, const llvm::Type *TD=0, 78 unsigned UI=0, bool B = false) 79 : TheKind(K), TypeData(TD), UIntData(UI), BoolData(B) {} 80 81 public: 82 ABIArgInfo() : TheKind(Direct), TypeData(0), UIntData(0) {} 83 84 static ABIArgInfo getDirect() { 85 return ABIArgInfo(Direct); 86 } 87 static ABIArgInfo getExtend() { 88 return ABIArgInfo(Extend); 89 } 90 static ABIArgInfo getIgnore() { 91 return ABIArgInfo(Ignore); 92 } 93 static ABIArgInfo getCoerce(const llvm::Type *T) { 94 return ABIArgInfo(Coerce, T); 95 } 96 static ABIArgInfo getIndirect(unsigned Alignment, bool ByVal = true) { 97 return ABIArgInfo(Indirect, 0, Alignment, ByVal); 98 } 99 static ABIArgInfo getExpand() { 100 return ABIArgInfo(Expand); 101 } 102 103 Kind getKind() const { return TheKind; } 104 bool isDirect() const { return TheKind == Direct; } 105 bool isExtend() const { return TheKind == Extend; } 106 bool isIgnore() const { return TheKind == Ignore; } 107 bool isCoerce() const { return TheKind == Coerce; } 108 bool isIndirect() const { return TheKind == Indirect; } 109 bool isExpand() const { return TheKind == Expand; } 110 111 // Coerce accessors 112 const llvm::Type *getCoerceToType() const { 113 assert(TheKind == Coerce && "Invalid kind!"); 114 return TypeData; 115 } 116 117 // Indirect accessors 118 unsigned getIndirectAlign() const { 119 assert(TheKind == Indirect && "Invalid kind!"); 120 return UIntData; 121 } 122 123 bool getIndirectByVal() const { 124 assert(TheKind == Indirect && "Invalid kind!"); 125 return BoolData; 126 } 127 128 void dump() const; 129 }; 130 131 /// ABIInfo - Target specific hooks for defining how a type should be 132 /// passed or returned from functions. 133 class ABIInfo { 134 public: 135 virtual ~ABIInfo(); 136 137 virtual void computeInfo(CodeGen::CGFunctionInfo &FI, 138 ASTContext &Ctx, 139 llvm::LLVMContext &VMContext, 140 // This is the preferred type for argument lowering 141 // which can be used to generate better IR. 142 const llvm::Type *const *PrefTypes = 0, 143 unsigned NumPrefTypes = 0) const = 0; 144 145 /// EmitVAArg - Emit the target dependent code to load a value of 146 /// \arg Ty from the va_list pointed to by \arg VAListAddr. 147 148 // FIXME: This is a gaping layering violation if we wanted to drop 149 // the ABI information any lower than CodeGen. Of course, for 150 // VAArg handling it has to be at this level; there is no way to 151 // abstract this out. 152 virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, 153 CodeGen::CodeGenFunction &CGF) const = 0; 154 }; 155} // end namespace clang 156 157#endif 158