ABIInfo.h revision 47a434ff3d49e7906eda88e8e8242e4297725b32
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  struct 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
76    ABIArgInfo(Kind K, const llvm::Type *TD=0,
77               unsigned UI=0) : TheKind(K),
78                                TypeData(TD),
79                                UIntData(UI) {}
80  public:
81    ABIArgInfo() : TheKind(Direct), TypeData(0), UIntData(0) {}
82
83    static ABIArgInfo getDirect() {
84      return ABIArgInfo(Direct);
85    }
86    static ABIArgInfo getExtend() {
87      return ABIArgInfo(Extend);
88    }
89    static ABIArgInfo getIgnore() {
90      return ABIArgInfo(Ignore);
91    }
92    static ABIArgInfo getCoerce(const llvm::Type *T) {
93      return ABIArgInfo(Coerce, T);
94    }
95    static ABIArgInfo getIndirect(unsigned Alignment) {
96      return ABIArgInfo(Indirect, 0, Alignment);
97    }
98    static ABIArgInfo getExpand() {
99      return ABIArgInfo(Expand);
100    }
101
102    Kind getKind() const { return TheKind; }
103    bool isDirect() const { return TheKind == Direct; }
104    bool isExtend() const { return TheKind == Extend; }
105    bool isIgnore() const { return TheKind == Ignore; }
106    bool isCoerce() const { return TheKind == Coerce; }
107    bool isIndirect() const { return TheKind == Indirect; }
108    bool isExpand() const { return TheKind == Expand; }
109
110    // Coerce accessors
111    const llvm::Type *getCoerceToType() const {
112      assert(TheKind == Coerce && "Invalid kind!");
113      return TypeData;
114    }
115
116    // ByVal accessors
117    unsigned getIndirectAlign() const {
118      assert(TheKind == Indirect && "Invalid kind!");
119      return UIntData;
120    }
121
122    void dump() const;
123  };
124
125  /// ABIInfo - Target specific hooks for defining how a type should be
126  /// passed or returned from functions.
127  class ABIInfo {
128  public:
129    virtual ~ABIInfo();
130
131    virtual void computeInfo(CodeGen::CGFunctionInfo &FI,
132                             ASTContext &Ctx,
133                             llvm::LLVMContext &VMContext) const = 0;
134
135    /// EmitVAArg - Emit the target dependent code to load a value of
136    /// \arg Ty from the va_list pointed to by \arg VAListAddr.
137
138    // FIXME: This is a gaping layering violation if we wanted to drop
139    // the ABI information any lower than CodeGen. Of course, for
140    // VAArg handling it has to be at this level; there is no way to
141    // abstract this out.
142    virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
143                                   CodeGen::CodeGenFunction &CGF) const = 0;
144  };
145}  // end namespace clang
146
147#endif
148