blob: a52ed8450fe6d83fdacd188498bbf4eea7cc7aab [file] [log] [blame]
Daniel Dunbard283e632009-02-03 01:05:53 +00001//===----- 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
Daniel Dunbare92e0ab2009-02-03 05:31:23 +000013namespace llvm {
14 class Type;
15}
16
Daniel Dunbard283e632009-02-03 01:05:53 +000017namespace clang {
Daniel Dunbar749e36b2009-02-03 06:51:18 +000018 class ASTContext;
19
20 // FIXME: This is a layering issue if we want to move ABIInfo
21 // down. Fortunately CGFunctionInfo has no real tie to CodeGen.
22 namespace CodeGen {
23 class CGFunctionInfo;
24 }
25
Daniel Dunbard283e632009-02-03 01:05:53 +000026 /* FIXME: All of this stuff should be part of the target interface
27 somehow. It is currently here because it is not clear how to factor
28 the targets to support this, since the Targets currently live in a
29 layer below types n'stuff.
30 */
31
32 /// ABIArgInfo - Helper class to encapsulate information about how a
33 /// specific C type should be passed to or returned from a function.
34 class ABIArgInfo {
35 public:
36 enum Kind {
Daniel Dunbarb1a60c02009-02-03 06:17:37 +000037 Direct, /// Pass the argument directly using the normal
Daniel Dunbar88dde9b2009-02-05 08:00:50 +000038 /// converted LLVM type. Complex and structure types
39 /// are passed using first class aggregates.
40
41 Indirect, /// Pass the argument indirectly via a hidden pointer
42 /// with the specified alignment (0 indicates default
43 /// alignment).
Daniel Dunbard283e632009-02-03 01:05:53 +000044
45 Ignore, /// Ignore the argument (treat as void). Useful for
46 /// void and empty structs.
47
48 Coerce, /// Only valid for aggregate return types, the argument
49 /// should be accessed by coercion to a provided type.
50
Daniel Dunbard283e632009-02-03 01:05:53 +000051 Expand, /// Only valid for aggregate argument types. The
52 /// structure should be expanded into consecutive
53 /// arguments for its constituent fields. Currently
54 /// expand is only allowed on structures whose fields
55 /// are all scalar types or are themselves expandable
56 /// types.
57
Daniel Dunbareec02622009-02-03 06:30:17 +000058 KindFirst=Direct, KindLast=Expand
Daniel Dunbard283e632009-02-03 01:05:53 +000059 };
60
61 private:
62 Kind TheKind;
63 const llvm::Type *TypeData;
64 unsigned UIntData;
65
66 ABIArgInfo(Kind K, const llvm::Type *TD=0,
67 unsigned UI=0) : TheKind(K),
68 TypeData(TD),
Daniel Dunbare6d233a2009-02-05 01:01:30 +000069 UIntData(UI) {}
Daniel Dunbard283e632009-02-03 01:05:53 +000070 public:
Daniel Dunbareec02622009-02-03 06:30:17 +000071 ABIArgInfo() : TheKind(Direct), TypeData(0), UIntData(0) {}
Daniel Dunbare92e0ab2009-02-03 05:31:23 +000072
Daniel Dunbarb1a60c02009-02-03 06:17:37 +000073 static ABIArgInfo getDirect() {
74 return ABIArgInfo(Direct);
75 }
Daniel Dunbard283e632009-02-03 01:05:53 +000076 static ABIArgInfo getIgnore() {
77 return ABIArgInfo(Ignore);
78 }
79 static ABIArgInfo getCoerce(const llvm::Type *T) {
80 return ABIArgInfo(Coerce, T);
81 }
Daniel Dunbar88dde9b2009-02-05 08:00:50 +000082 static ABIArgInfo getIndirect(unsigned Alignment) {
83 return ABIArgInfo(Indirect, 0, Alignment);
Daniel Dunbard283e632009-02-03 01:05:53 +000084 }
85 static ABIArgInfo getExpand() {
86 return ABIArgInfo(Expand);
87 }
88
89 Kind getKind() const { return TheKind; }
Daniel Dunbarb1a60c02009-02-03 06:17:37 +000090 bool isDirect() const { return TheKind == Direct; }
Daniel Dunbard283e632009-02-03 01:05:53 +000091 bool isIgnore() const { return TheKind == Ignore; }
92 bool isCoerce() const { return TheKind == Coerce; }
Daniel Dunbar88dde9b2009-02-05 08:00:50 +000093 bool isIndirect() const { return TheKind == Indirect; }
Daniel Dunbard283e632009-02-03 01:05:53 +000094 bool isExpand() const { return TheKind == Expand; }
95
96 // Coerce accessors
97 const llvm::Type *getCoerceToType() const {
98 assert(TheKind == Coerce && "Invalid kind!");
99 return TypeData;
100 }
101
102 // ByVal accessors
Daniel Dunbar88dde9b2009-02-05 08:00:50 +0000103 unsigned getIndirectAlign() const {
104 assert(TheKind == Indirect && "Invalid kind!");
Daniel Dunbard283e632009-02-03 01:05:53 +0000105 return UIntData;
106 }
Daniel Dunbar9f4874e2009-02-04 23:24:38 +0000107
108 void dump() const;
Daniel Dunbard283e632009-02-03 01:05:53 +0000109 };
110
111 /// ABIInfo - Target specific hooks for defining how a type should be
112 /// passed or returned from functions.
113 class ABIInfo {
114 public:
115 virtual ~ABIInfo();
Daniel Dunbar749e36b2009-02-03 06:51:18 +0000116
117 virtual void computeInfo(CodeGen::CGFunctionInfo &FI,
118 ASTContext &Ctx) const = 0;
Daniel Dunbard283e632009-02-03 01:05:53 +0000119 };
120} // end namespace clang
121
122#endif