blob: 3de461242ab00bda053562d209ef6e58b4ec3c5c [file] [log] [blame]
Daniel Dunbar9eb5c6d2009-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 Dunbar88c2fa92009-02-03 05:31:23 +000013namespace llvm {
14 class Type;
15}
16
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +000017namespace clang {
Daniel Dunbar6bad2652009-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;
Daniel Dunbarb53e3e72009-02-10 21:44:36 +000024 class CodeGenFunction;
Daniel Dunbar6bad2652009-02-03 06:51:18 +000025 }
26
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +000027 /* FIXME: All of this stuff should be part of the target interface
28 somehow. It is currently here because it is not clear how to factor
29 the targets to support this, since the Targets currently live in a
30 layer below types n'stuff.
31 */
32
33 /// ABIArgInfo - Helper class to encapsulate information about how a
34 /// specific C type should be passed to or returned from a function.
35 class ABIArgInfo {
36 public:
37 enum Kind {
Daniel Dunbar46327aa2009-02-03 06:17:37 +000038 Direct, /// Pass the argument directly using the normal
Daniel Dunbar11e383a2009-02-05 08:00:50 +000039 /// converted LLVM type. Complex and structure types
40 /// are passed using first class aggregates.
41
42 Indirect, /// Pass the argument indirectly via a hidden pointer
43 /// with the specified alignment (0 indicates default
44 /// alignment).
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +000045
46 Ignore, /// Ignore the argument (treat as void). Useful for
47 /// void and empty structs.
48
49 Coerce, /// Only valid for aggregate return types, the argument
50 /// should be accessed by coercion to a provided type.
51
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +000052 Expand, /// Only valid for aggregate argument types. The
53 /// structure should be expanded into consecutive
54 /// arguments for its constituent fields. Currently
55 /// expand is only allowed on structures whose fields
56 /// are all scalar types or are themselves expandable
57 /// types.
58
Daniel Dunbar0bcc5212009-02-03 06:30:17 +000059 KindFirst=Direct, KindLast=Expand
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +000060 };
61
62 private:
63 Kind TheKind;
64 const llvm::Type *TypeData;
65 unsigned UIntData;
66
67 ABIArgInfo(Kind K, const llvm::Type *TD=0,
68 unsigned UI=0) : TheKind(K),
69 TypeData(TD),
Daniel Dunbar497a8562009-02-05 01:01:30 +000070 UIntData(UI) {}
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +000071 public:
Daniel Dunbar0bcc5212009-02-03 06:30:17 +000072 ABIArgInfo() : TheKind(Direct), TypeData(0), UIntData(0) {}
Daniel Dunbar88c2fa92009-02-03 05:31:23 +000073
Daniel Dunbar46327aa2009-02-03 06:17:37 +000074 static ABIArgInfo getDirect() {
75 return ABIArgInfo(Direct);
76 }
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +000077 static ABIArgInfo getIgnore() {
78 return ABIArgInfo(Ignore);
79 }
80 static ABIArgInfo getCoerce(const llvm::Type *T) {
81 return ABIArgInfo(Coerce, T);
82 }
Daniel Dunbar11e383a2009-02-05 08:00:50 +000083 static ABIArgInfo getIndirect(unsigned Alignment) {
84 return ABIArgInfo(Indirect, 0, Alignment);
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +000085 }
86 static ABIArgInfo getExpand() {
87 return ABIArgInfo(Expand);
88 }
89
90 Kind getKind() const { return TheKind; }
Daniel Dunbar46327aa2009-02-03 06:17:37 +000091 bool isDirect() const { return TheKind == Direct; }
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +000092 bool isIgnore() const { return TheKind == Ignore; }
93 bool isCoerce() const { return TheKind == Coerce; }
Daniel Dunbar11e383a2009-02-05 08:00:50 +000094 bool isIndirect() const { return TheKind == Indirect; }
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +000095 bool isExpand() const { return TheKind == Expand; }
96
97 // Coerce accessors
98 const llvm::Type *getCoerceToType() const {
99 assert(TheKind == Coerce && "Invalid kind!");
100 return TypeData;
101 }
102
103 // ByVal accessors
Daniel Dunbar11e383a2009-02-05 08:00:50 +0000104 unsigned getIndirectAlign() const {
105 assert(TheKind == Indirect && "Invalid kind!");
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +0000106 return UIntData;
107 }
Daniel Dunbar6f7279b2009-02-04 23:24:38 +0000108
109 void dump() const;
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +0000110 };
111
112 /// ABIInfo - Target specific hooks for defining how a type should be
113 /// passed or returned from functions.
114 class ABIInfo {
115 public:
116 virtual ~ABIInfo();
Daniel Dunbar6bad2652009-02-03 06:51:18 +0000117
118 virtual void computeInfo(CodeGen::CGFunctionInfo &FI,
119 ASTContext &Ctx) const = 0;
Daniel Dunbarb53e3e72009-02-10 21:44:36 +0000120
121 /// EmitVAArg - Emit the target dependent code to load a value of
122 /// \arg Ty from the va_list pointed to by \arg VAListAddr.
123
124 // FIXME: This is a gaping layering violation if we wanted to drop
125 // the ABI information any lower than CodeGen. Of course, for
126 // VAArg handling it has to be at this level; there is no way to
127 // abstract this out.
128 virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
129 CodeGen::CodeGenFunction &CGF) const = 0;
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +0000130 };
131} // end namespace clang
132
133#endif