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