ABIInfo.h revision a3c109bbf6e198f463fbe204da4d25b40dab65c4
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
42                 /// converted LLVM type. Complex and structure types
43                 /// are passed using first class aggregates.
44
45      Extend,    /// Valid only for integer argument types. Same as 'direct'
46                 /// but also emit a zero/sign extension attribute.
47
48      Coerce,    /// Only valid for aggregate return types, the argument
49                 /// should be accessed by coercion to a provided type.
50
51
52      Indirect,  /// Pass the argument indirectly via a hidden pointer
53                 /// with the specified alignment (0 indicates default
54                 /// alignment).
55
56      Ignore,    /// Ignore the argument (treat as void). Useful for
57                 /// void and empty structs.
58
59       Expand,    /// Only valid for aggregate argument types. The
60                 /// structure should be expanded into consecutive
61                 /// arguments for its constituent fields. Currently
62                 /// expand is only allowed on structures whose fields
63                 /// are all scalar types or are themselves expandable
64                 /// types.
65
66      KindFirst=Direct, KindLast=Expand
67    };
68
69  private:
70    Kind TheKind;
71    llvm::PATypeHolder TypeData;
72    unsigned UIntData;
73    bool BoolData;
74
75    ABIArgInfo(Kind K, const llvm::Type *TD=0,
76               unsigned UI=0, bool B = false)
77      : TheKind(K), TypeData(TD), UIntData(UI), BoolData(B) {}
78
79  public:
80    ABIArgInfo() : TheKind(Direct), TypeData(0), UIntData(0) {}
81
82    static ABIArgInfo getDirect() {
83      return ABIArgInfo(Direct);
84    }
85    static ABIArgInfo getExtend() {
86      return ABIArgInfo(Extend);
87    }
88    static ABIArgInfo getIgnore() {
89      return ABIArgInfo(Ignore);
90    }
91    static ABIArgInfo getCoerce(const llvm::Type *T) {
92      return ABIArgInfo(Coerce, T);
93    }
94    static ABIArgInfo getIndirect(unsigned Alignment, bool ByVal = true) {
95      return ABIArgInfo(Indirect, 0, Alignment, ByVal);
96    }
97    static ABIArgInfo getExpand() {
98      return ABIArgInfo(Expand);
99    }
100
101    Kind getKind() const { return TheKind; }
102    bool isDirect() const { return TheKind == Direct; }
103    bool isExtend() const { return TheKind == Extend; }
104    bool isIgnore() const { return TheKind == Ignore; }
105    bool isCoerce() const { return TheKind == Coerce; }
106    bool isIndirect() const { return TheKind == Indirect; }
107    bool isExpand() const { return TheKind == Expand; }
108
109    // Coerce accessors
110    const llvm::Type *getCoerceToType() const {
111      assert(TheKind == Coerce && "Invalid kind!");
112      return TypeData;
113    }
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,
143                             // This is the preferred type for argument lowering
144                             // which can be used to generate better IR.
145                             const llvm::Type *const *PrefTypes = 0,
146                             unsigned NumPrefTypes = 0) const = 0;
147
148    /// EmitVAArg - Emit the target dependent code to load a value of
149    /// \arg Ty from the va_list pointed to by \arg VAListAddr.
150
151    // FIXME: This is a gaping layering violation if we wanted to drop
152    // the ABI information any lower than CodeGen. Of course, for
153    // VAArg handling it has to be at this level; there is no way to
154    // abstract this out.
155    virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
156                                   CodeGen::CodeGenFunction &CGF) const = 0;
157  };
158}  // end namespace clang
159
160#endif
161