blob: 44af0c476aa55e545656c7b4b0b0c256ec7d3b07 [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
Anton Korobeynikov73628192009-06-05 22:08:42 +000013#include "clang/AST/Type.h"
14
15#include <cassert>
16
Daniel Dunbare92e0ab2009-02-03 05:31:23 +000017namespace llvm {
18 class Type;
Anton Korobeynikov73628192009-06-05 22:08:42 +000019 class Value;
Daniel Dunbare92e0ab2009-02-03 05:31:23 +000020}
21
Daniel Dunbard283e632009-02-03 01:05:53 +000022namespace clang {
Daniel Dunbar749e36b2009-02-03 06:51:18 +000023 class ASTContext;
24
25 // FIXME: This is a layering issue if we want to move ABIInfo
26 // down. Fortunately CGFunctionInfo has no real tie to CodeGen.
27 namespace CodeGen {
28 class CGFunctionInfo;
Daniel Dunbar003327a2009-02-10 21:44:36 +000029 class CodeGenFunction;
Daniel Dunbar749e36b2009-02-03 06:51:18 +000030 }
31
Daniel Dunbard283e632009-02-03 01:05:53 +000032 /* FIXME: All of this stuff should be part of the target interface
33 somehow. It is currently here because it is not clear how to factor
34 the targets to support this, since the Targets currently live in a
35 layer below types n'stuff.
36 */
37
38 /// ABIArgInfo - Helper class to encapsulate information about how a
39 /// specific C type should be passed to or returned from a function.
40 class ABIArgInfo {
41 public:
42 enum Kind {
Daniel Dunbarb1a60c02009-02-03 06:17:37 +000043 Direct, /// Pass the argument directly using the normal
Daniel Dunbar88dde9b2009-02-05 08:00:50 +000044 /// converted LLVM type. Complex and structure types
45 /// are passed using first class aggregates.
Anton Korobeynikov73628192009-06-05 22:08:42 +000046
Daniel Dunbar88dde9b2009-02-05 08:00:50 +000047 Indirect, /// Pass the argument indirectly via a hidden pointer
48 /// with the specified alignment (0 indicates default
49 /// alignment).
Anton Korobeynikov73628192009-06-05 22:08:42 +000050
Daniel Dunbard283e632009-02-03 01:05:53 +000051 Ignore, /// Ignore the argument (treat as void). Useful for
52 /// void and empty structs.
Anton Korobeynikov73628192009-06-05 22:08:42 +000053
Daniel Dunbard283e632009-02-03 01:05:53 +000054 Coerce, /// Only valid for aggregate return types, the argument
55 /// should be accessed by coercion to a provided type.
Anton Korobeynikov73628192009-06-05 22:08:42 +000056
Daniel Dunbard283e632009-02-03 01:05:53 +000057 Expand, /// Only valid for aggregate argument types. The
58 /// structure should be expanded into consecutive
59 /// arguments for its constituent fields. Currently
60 /// expand is only allowed on structures whose fields
61 /// are all scalar types or are themselves expandable
62 /// types.
Anton Korobeynikov73628192009-06-05 22:08:42 +000063
Daniel Dunbareec02622009-02-03 06:30:17 +000064 KindFirst=Direct, KindLast=Expand
Daniel Dunbard283e632009-02-03 01:05:53 +000065 };
Anton Korobeynikov73628192009-06-05 22:08:42 +000066
Daniel Dunbard283e632009-02-03 01:05:53 +000067 private:
68 Kind TheKind;
69 const llvm::Type *TypeData;
70 unsigned UIntData;
Anton Korobeynikov73628192009-06-05 22:08:42 +000071
Daniel Dunbard283e632009-02-03 01:05:53 +000072 ABIArgInfo(Kind K, const llvm::Type *TD=0,
73 unsigned UI=0) : TheKind(K),
74 TypeData(TD),
Daniel Dunbare6d233a2009-02-05 01:01:30 +000075 UIntData(UI) {}
Daniel Dunbard283e632009-02-03 01:05:53 +000076 public:
Daniel Dunbareec02622009-02-03 06:30:17 +000077 ABIArgInfo() : TheKind(Direct), TypeData(0), UIntData(0) {}
Daniel Dunbare92e0ab2009-02-03 05:31:23 +000078
Anton Korobeynikov73628192009-06-05 22:08:42 +000079 static ABIArgInfo getDirect() {
80 return ABIArgInfo(Direct);
Daniel Dunbarb1a60c02009-02-03 06:17:37 +000081 }
Daniel Dunbard283e632009-02-03 01:05:53 +000082 static ABIArgInfo getIgnore() {
83 return ABIArgInfo(Ignore);
84 }
Anton Korobeynikov73628192009-06-05 22:08:42 +000085 static ABIArgInfo getCoerce(const llvm::Type *T) {
Daniel Dunbard283e632009-02-03 01:05:53 +000086 return ABIArgInfo(Coerce, T);
87 }
Daniel Dunbar88dde9b2009-02-05 08:00:50 +000088 static ABIArgInfo getIndirect(unsigned Alignment) {
89 return ABIArgInfo(Indirect, 0, Alignment);
Daniel Dunbard283e632009-02-03 01:05:53 +000090 }
91 static ABIArgInfo getExpand() {
92 return ABIArgInfo(Expand);
93 }
Anton Korobeynikov73628192009-06-05 22:08:42 +000094
Daniel Dunbard283e632009-02-03 01:05:53 +000095 Kind getKind() const { return TheKind; }
Daniel Dunbarb1a60c02009-02-03 06:17:37 +000096 bool isDirect() const { return TheKind == Direct; }
Daniel Dunbard283e632009-02-03 01:05:53 +000097 bool isIgnore() const { return TheKind == Ignore; }
98 bool isCoerce() const { return TheKind == Coerce; }
Daniel Dunbar88dde9b2009-02-05 08:00:50 +000099 bool isIndirect() const { return TheKind == Indirect; }
Daniel Dunbard283e632009-02-03 01:05:53 +0000100 bool isExpand() const { return TheKind == Expand; }
Anton Korobeynikov73628192009-06-05 22:08:42 +0000101
Daniel Dunbard283e632009-02-03 01:05:53 +0000102 // Coerce accessors
103 const llvm::Type *getCoerceToType() const {
104 assert(TheKind == Coerce && "Invalid kind!");
105 return TypeData;
106 }
Anton Korobeynikov73628192009-06-05 22:08:42 +0000107
Daniel Dunbard283e632009-02-03 01:05:53 +0000108 // ByVal accessors
Daniel Dunbar88dde9b2009-02-05 08:00:50 +0000109 unsigned getIndirectAlign() const {
110 assert(TheKind == Indirect && "Invalid kind!");
Daniel Dunbard283e632009-02-03 01:05:53 +0000111 return UIntData;
112 }
Daniel Dunbar9f4874e2009-02-04 23:24:38 +0000113
114 void dump() const;
Daniel Dunbard283e632009-02-03 01:05:53 +0000115 };
116
117 /// ABIInfo - Target specific hooks for defining how a type should be
118 /// passed or returned from functions.
119 class ABIInfo {
120 public:
121 virtual ~ABIInfo();
Daniel Dunbar749e36b2009-02-03 06:51:18 +0000122
123 virtual void computeInfo(CodeGen::CGFunctionInfo &FI,
124 ASTContext &Ctx) const = 0;
Daniel Dunbar003327a2009-02-10 21:44:36 +0000125
126 /// EmitVAArg - Emit the target dependent code to load a value of
127 /// \arg Ty from the va_list pointed to by \arg VAListAddr.
Anton Korobeynikov73628192009-06-05 22:08:42 +0000128
Daniel Dunbar003327a2009-02-10 21:44:36 +0000129 // FIXME: This is a gaping layering violation if we wanted to drop
130 // the ABI information any lower than CodeGen. Of course, for
131 // VAArg handling it has to be at this level; there is no way to
132 // abstract this out.
133 virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
134 CodeGen::CodeGenFunction &CGF) const = 0;
Daniel Dunbard283e632009-02-03 01:05:53 +0000135 };
136} // end namespace clang
137
138#endif