blob: 85524acbe1f7a0b1e1724aa895c6d36d4cfdba2e [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"
Chris Lattner958c53c2010-06-29 19:21:36 +000014#include "llvm/Type.h"
Anton Korobeynikovc4a59eb2009-06-05 22:08:42 +000015
Daniel Dunbar88c2fa92009-02-03 05:31:23 +000016namespace llvm {
Anton Korobeynikovc4a59eb2009-06-05 22:08:42 +000017 class Value;
Benjamin Kramerf21efe92009-08-11 17:46:57 +000018 class LLVMContext;
Daniel Dunbar88c2fa92009-02-03 05:31:23 +000019}
20
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +000021namespace clang {
Daniel Dunbar6bad2652009-02-03 06:51:18 +000022 class ASTContext;
23
24 // FIXME: This is a layering issue if we want to move ABIInfo
25 // down. Fortunately CGFunctionInfo has no real tie to CodeGen.
26 namespace CodeGen {
27 class CGFunctionInfo;
Daniel Dunbarb53e3e72009-02-10 21:44:36 +000028 class CodeGenFunction;
Daniel Dunbar6bad2652009-02-03 06:51:18 +000029 }
30
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +000031 /* FIXME: All of this stuff should be part of the target interface
32 somehow. It is currently here because it is not clear how to factor
33 the targets to support this, since the Targets currently live in a
34 layer below types n'stuff.
35 */
36
37 /// ABIArgInfo - Helper class to encapsulate information about how a
38 /// specific C type should be passed to or returned from a function.
39 class ABIArgInfo {
40 public:
41 enum Kind {
Daniel Dunbar46327aa2009-02-03 06:17:37 +000042 Direct, /// Pass the argument directly using the normal
Daniel Dunbar11e383a2009-02-05 08:00:50 +000043 /// converted LLVM type. Complex and structure types
44 /// are passed using first class aggregates.
Anton Korobeynikovc4a59eb2009-06-05 22:08:42 +000045
Anton Korobeynikovcc6fa882009-06-06 09:36:29 +000046 Extend, /// Valid only for integer argument types. Same as 'direct'
47 /// but also emit a zero/sign extension attribute.
48
Daniel Dunbar11e383a2009-02-05 08:00:50 +000049 Indirect, /// Pass the argument indirectly via a hidden pointer
50 /// with the specified alignment (0 indicates default
51 /// alignment).
Anton Korobeynikovc4a59eb2009-06-05 22:08:42 +000052
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +000053 Ignore, /// Ignore the argument (treat as void). Useful for
54 /// void and empty structs.
Anton Korobeynikovc4a59eb2009-06-05 22:08:42 +000055
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +000056 Coerce, /// Only valid for aggregate return types, the argument
57 /// should be accessed by coercion to a provided type.
Anton Korobeynikovc4a59eb2009-06-05 22:08:42 +000058
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +000059 Expand, /// Only valid for aggregate argument types. The
60 /// structure should be expanded into consecutive
61 /// arguments for its constituent fields. Currently
62 /// expand is only allowed on structures whose fields
63 /// are all scalar types or are themselves expandable
64 /// types.
Anton Korobeynikovc4a59eb2009-06-05 22:08:42 +000065
Daniel Dunbar0bcc5212009-02-03 06:30:17 +000066 KindFirst=Direct, KindLast=Expand
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +000067 };
Anton Korobeynikovc4a59eb2009-06-05 22:08:42 +000068
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +000069 private:
70 Kind TheKind;
Chris Lattner958c53c2010-06-29 19:21:36 +000071 llvm::PATypeHolder TypeData;
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +000072 unsigned UIntData;
Anders Carlsson0a8f8472009-09-16 15:53:40 +000073 bool BoolData;
Anton Korobeynikovc4a59eb2009-06-05 22:08:42 +000074
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +000075 ABIArgInfo(Kind K, const llvm::Type *TD=0,
Anders Carlsson0a8f8472009-09-16 15:53:40 +000076 unsigned UI=0, bool B = false)
77 : TheKind(K), TypeData(TD), UIntData(UI), BoolData(B) {}
78
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +000079 public:
Daniel Dunbar0bcc5212009-02-03 06:30:17 +000080 ABIArgInfo() : TheKind(Direct), TypeData(0), UIntData(0) {}
Daniel Dunbar88c2fa92009-02-03 05:31:23 +000081
Anton Korobeynikovc4a59eb2009-06-05 22:08:42 +000082 static ABIArgInfo getDirect() {
83 return ABIArgInfo(Direct);
Daniel Dunbar46327aa2009-02-03 06:17:37 +000084 }
Anton Korobeynikovcc6fa882009-06-06 09:36:29 +000085 static ABIArgInfo getExtend() {
86 return ABIArgInfo(Extend);
87 }
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +000088 static ABIArgInfo getIgnore() {
89 return ABIArgInfo(Ignore);
90 }
Anton Korobeynikovc4a59eb2009-06-05 22:08:42 +000091 static ABIArgInfo getCoerce(const llvm::Type *T) {
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +000092 return ABIArgInfo(Coerce, T);
93 }
Anders Carlsson0a8f8472009-09-16 15:53:40 +000094 static ABIArgInfo getIndirect(unsigned Alignment, bool ByVal = true) {
95 return ABIArgInfo(Indirect, 0, Alignment, ByVal);
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +000096 }
97 static ABIArgInfo getExpand() {
98 return ABIArgInfo(Expand);
99 }
Anton Korobeynikovc4a59eb2009-06-05 22:08:42 +0000100
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +0000101 Kind getKind() const { return TheKind; }
Daniel Dunbar46327aa2009-02-03 06:17:37 +0000102 bool isDirect() const { return TheKind == Direct; }
Anton Korobeynikovcc6fa882009-06-06 09:36:29 +0000103 bool isExtend() const { return TheKind == Extend; }
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +0000104 bool isIgnore() const { return TheKind == Ignore; }
105 bool isCoerce() const { return TheKind == Coerce; }
Daniel Dunbar11e383a2009-02-05 08:00:50 +0000106 bool isIndirect() const { return TheKind == Indirect; }
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +0000107 bool isExpand() const { return TheKind == Expand; }
Anton Korobeynikovc4a59eb2009-06-05 22:08:42 +0000108
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +0000109 // Coerce accessors
110 const llvm::Type *getCoerceToType() const {
111 assert(TheKind == Coerce && "Invalid kind!");
112 return TypeData;
113 }
Anton Korobeynikovc4a59eb2009-06-05 22:08:42 +0000114
Anders Carlsson0a8f8472009-09-16 15:53:40 +0000115 // Indirect accessors
Daniel Dunbar11e383a2009-02-05 08:00:50 +0000116 unsigned getIndirectAlign() const {
117 assert(TheKind == Indirect && "Invalid kind!");
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +0000118 return UIntData;
119 }
Daniel Dunbar6f7279b2009-02-04 23:24:38 +0000120
Anders Carlsson0a8f8472009-09-16 15:53:40 +0000121 bool getIndirectByVal() const {
122 assert(TheKind == Indirect && "Invalid kind!");
123 return BoolData;
124 }
125
Daniel Dunbar6f7279b2009-02-04 23:24:38 +0000126 void dump() const;
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +0000127 };
128
129 /// ABIInfo - Target specific hooks for defining how a type should be
130 /// passed or returned from functions.
131 class ABIInfo {
132 public:
133 virtual ~ABIInfo();
Daniel Dunbar6bad2652009-02-03 06:51:18 +0000134
135 virtual void computeInfo(CodeGen::CGFunctionInfo &FI,
Owen Andersona1cf15f2009-07-14 23:10:40 +0000136 ASTContext &Ctx,
Chris Lattner8640cd62010-06-29 01:08:48 +0000137 llvm::LLVMContext &VMContext,
138 // This is the preferred type for argument lowering
139 // which can be used to generate better IR.
140 const llvm::Type *const *PrefTypes = 0,
141 unsigned NumPrefTypes = 0) const = 0;
Daniel Dunbarb53e3e72009-02-10 21:44:36 +0000142
143 /// EmitVAArg - Emit the target dependent code to load a value of
144 /// \arg Ty from the va_list pointed to by \arg VAListAddr.
Anton Korobeynikovc4a59eb2009-06-05 22:08:42 +0000145
Daniel Dunbarb53e3e72009-02-10 21:44:36 +0000146 // FIXME: This is a gaping layering violation if we wanted to drop
147 // the ABI information any lower than CodeGen. Of course, for
148 // VAArg handling it has to be at this level; there is no way to
149 // abstract this out.
150 virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
151 CodeGen::CodeGenFunction &CGF) const = 0;
Daniel Dunbar9eb5c6d2009-02-03 01:05:53 +0000152 };
153} // end namespace clang
154
155#endif