blob: 1ab2f55295fa005a6ca9de7eb544708b902a8cc5 [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
Anton Korobeynikovc4a59eb2009-06-05 22:08:42 +000013#include "clang/AST/Type.h"
14
15#include <cassert>
16
Daniel Dunbar88c2fa92009-02-03 05:31:23 +000017namespace llvm {
18 class Type;
Anton Korobeynikovc4a59eb2009-06-05 22:08:42 +000019 class Value;
Benjamin Kramerf21efe92009-08-11 17:46:57 +000020 class LLVMContext;
Daniel Dunbar88c2fa92009-02-03 05:31:23 +000021}
22
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +000023namespace clang {
Daniel Dunbar6bad2652009-02-03 06:51:18 +000024 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;
Daniel Dunbarb53e3e72009-02-10 21:44:36 +000030 class CodeGenFunction;
Daniel Dunbar6bad2652009-02-03 06:51:18 +000031 }
32
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +000033 /* 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 {
Daniel Dunbar46327aa2009-02-03 06:17:37 +000044 Direct, /// Pass the argument directly using the normal
Daniel Dunbar11e383a2009-02-05 08:00:50 +000045 /// converted LLVM type. Complex and structure types
46 /// are passed using first class aggregates.
Anton Korobeynikovc4a59eb2009-06-05 22:08:42 +000047
Anton Korobeynikovcc6fa882009-06-06 09:36:29 +000048 Extend, /// Valid only for integer argument types. Same as 'direct'
49 /// but also emit a zero/sign extension attribute.
50
Daniel Dunbar11e383a2009-02-05 08:00:50 +000051 Indirect, /// Pass the argument indirectly via a hidden pointer
52 /// with the specified alignment (0 indicates default
53 /// alignment).
Anton Korobeynikovc4a59eb2009-06-05 22:08:42 +000054
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +000055 Ignore, /// Ignore the argument (treat as void). Useful for
56 /// void and empty structs.
Anton Korobeynikovc4a59eb2009-06-05 22:08:42 +000057
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +000058 Coerce, /// Only valid for aggregate return types, the argument
59 /// should be accessed by coercion to a provided type.
Anton Korobeynikovc4a59eb2009-06-05 22:08:42 +000060
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +000061 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.
Anton Korobeynikovc4a59eb2009-06-05 22:08:42 +000067
Daniel Dunbar0bcc5212009-02-03 06:30:17 +000068 KindFirst=Direct, KindLast=Expand
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +000069 };
Anton Korobeynikovc4a59eb2009-06-05 22:08:42 +000070
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +000071 private:
72 Kind TheKind;
73 const llvm::Type *TypeData;
74 unsigned UIntData;
Anders Carlsson0a8f8472009-09-16 15:53:40 +000075 bool BoolData;
Anton Korobeynikovc4a59eb2009-06-05 22:08:42 +000076
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +000077 ABIArgInfo(Kind K, const llvm::Type *TD=0,
Anders Carlsson0a8f8472009-09-16 15:53:40 +000078 unsigned UI=0, bool B = false)
79 : TheKind(K), TypeData(TD), UIntData(UI), BoolData(B) {}
80
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +000081 public:
Daniel Dunbar0bcc5212009-02-03 06:30:17 +000082 ABIArgInfo() : TheKind(Direct), TypeData(0), UIntData(0) {}
Daniel Dunbar88c2fa92009-02-03 05:31:23 +000083
Anton Korobeynikovc4a59eb2009-06-05 22:08:42 +000084 static ABIArgInfo getDirect() {
85 return ABIArgInfo(Direct);
Daniel Dunbar46327aa2009-02-03 06:17:37 +000086 }
Anton Korobeynikovcc6fa882009-06-06 09:36:29 +000087 static ABIArgInfo getExtend() {
88 return ABIArgInfo(Extend);
89 }
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +000090 static ABIArgInfo getIgnore() {
91 return ABIArgInfo(Ignore);
92 }
Anton Korobeynikovc4a59eb2009-06-05 22:08:42 +000093 static ABIArgInfo getCoerce(const llvm::Type *T) {
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +000094 return ABIArgInfo(Coerce, T);
95 }
Anders Carlsson0a8f8472009-09-16 15:53:40 +000096 static ABIArgInfo getIndirect(unsigned Alignment, bool ByVal = true) {
97 return ABIArgInfo(Indirect, 0, Alignment, ByVal);
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +000098 }
99 static ABIArgInfo getExpand() {
100 return ABIArgInfo(Expand);
101 }
Anton Korobeynikovc4a59eb2009-06-05 22:08:42 +0000102
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +0000103 Kind getKind() const { return TheKind; }
Daniel Dunbar46327aa2009-02-03 06:17:37 +0000104 bool isDirect() const { return TheKind == Direct; }
Anton Korobeynikovcc6fa882009-06-06 09:36:29 +0000105 bool isExtend() const { return TheKind == Extend; }
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +0000106 bool isIgnore() const { return TheKind == Ignore; }
107 bool isCoerce() const { return TheKind == Coerce; }
Daniel Dunbar11e383a2009-02-05 08:00:50 +0000108 bool isIndirect() const { return TheKind == Indirect; }
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +0000109 bool isExpand() const { return TheKind == Expand; }
Anton Korobeynikovc4a59eb2009-06-05 22:08:42 +0000110
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +0000111 // Coerce accessors
112 const llvm::Type *getCoerceToType() const {
113 assert(TheKind == Coerce && "Invalid kind!");
114 return TypeData;
115 }
Anton Korobeynikovc4a59eb2009-06-05 22:08:42 +0000116
Anders Carlsson0a8f8472009-09-16 15:53:40 +0000117 // Indirect accessors
Daniel Dunbar11e383a2009-02-05 08:00:50 +0000118 unsigned getIndirectAlign() const {
119 assert(TheKind == Indirect && "Invalid kind!");
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +0000120 return UIntData;
121 }
Daniel Dunbar6f7279b2009-02-04 23:24:38 +0000122
Anders Carlsson0a8f8472009-09-16 15:53:40 +0000123 bool getIndirectByVal() const {
124 assert(TheKind == Indirect && "Invalid kind!");
125 return BoolData;
126 }
127
Daniel Dunbar6f7279b2009-02-04 23:24:38 +0000128 void dump() const;
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +0000129 };
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();
Daniel Dunbar6bad2652009-02-03 06:51:18 +0000136
137 virtual void computeInfo(CodeGen::CGFunctionInfo &FI,
Owen Andersona1cf15f2009-07-14 23:10:40 +0000138 ASTContext &Ctx,
139 llvm::LLVMContext &VMContext) const = 0;
Daniel Dunbarb53e3e72009-02-10 21:44:36 +0000140
141 /// EmitVAArg - Emit the target dependent code to load a value of
142 /// \arg Ty from the va_list pointed to by \arg VAListAddr.
Anton Korobeynikovc4a59eb2009-06-05 22:08:42 +0000143
Daniel Dunbarb53e3e72009-02-10 21:44:36 +0000144 // FIXME: This is a gaping layering violation if we wanted to drop
145 // the ABI information any lower than CodeGen. Of course, for
146 // VAArg handling it has to be at this level; there is no way to
147 // abstract this out.
148 virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
149 CodeGen::CodeGenFunction &CGF) const = 0;
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +0000150 };
151} // end namespace clang
152
153#endif