ABIInfo.h revision cf3b6f2504596812db1fcef0df8ce5b3449c4aac
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
16namespace llvm {
17  class Value;
18  class LLVMContext;
19  class TargetData;
20}
21
22namespace 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::PATypeHolder TypeData;
72    unsigned UIntData;
73    bool BoolData0;
74    bool BoolData1;
75
76    ABIArgInfo(Kind K, const 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(const llvm::Type *T = 0, unsigned Offset = 0) {
84      return ABIArgInfo(Direct, T, Offset);
85    }
86    static ABIArgInfo getExtend(const 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    const llvm::Type *getCoerceToType() const {
117      assert(canHaveCoerceToType() && "Invalid kind!");
118      return TypeData;
119    }
120
121    void setCoerceToType(const 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