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