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