blob: 23edaa3c03e5650725e75515be2b82451659f7dd [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;
Owen Andersonbdc004c2009-08-05 23:18:46 +000020 struct LLVMContext;
Daniel Dunbare92e0ab2009-02-03 05:31:23 +000021}
22
Daniel Dunbard283e632009-02-03 01:05:53 +000023namespace clang {
Daniel Dunbar749e36b2009-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 Dunbar003327a2009-02-10 21:44:36 +000030 class CodeGenFunction;
Daniel Dunbar749e36b2009-02-03 06:51:18 +000031 }
32
Daniel Dunbard283e632009-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 Dunbarb1a60c02009-02-03 06:17:37 +000044 Direct, /// Pass the argument directly using the normal
Daniel Dunbar88dde9b2009-02-05 08:00:50 +000045 /// converted LLVM type. Complex and structure types
46 /// are passed using first class aggregates.
Anton Korobeynikov73628192009-06-05 22:08:42 +000047
Anton Korobeynikov2ce305d2009-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 Dunbar88dde9b2009-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 Korobeynikov73628192009-06-05 22:08:42 +000054
Daniel Dunbard283e632009-02-03 01:05:53 +000055 Ignore, /// Ignore the argument (treat as void). Useful for
56 /// void and empty structs.
Anton Korobeynikov73628192009-06-05 22:08:42 +000057
Daniel Dunbard283e632009-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 Korobeynikov73628192009-06-05 22:08:42 +000060
Daniel Dunbard283e632009-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 Korobeynikov73628192009-06-05 22:08:42 +000067
Daniel Dunbareec02622009-02-03 06:30:17 +000068 KindFirst=Direct, KindLast=Expand
Daniel Dunbard283e632009-02-03 01:05:53 +000069 };
Anton Korobeynikov73628192009-06-05 22:08:42 +000070
Daniel Dunbard283e632009-02-03 01:05:53 +000071 private:
72 Kind TheKind;
73 const llvm::Type *TypeData;
74 unsigned UIntData;
Anton Korobeynikov73628192009-06-05 22:08:42 +000075
Daniel Dunbard283e632009-02-03 01:05:53 +000076 ABIArgInfo(Kind K, const llvm::Type *TD=0,
77 unsigned UI=0) : TheKind(K),
78 TypeData(TD),
Daniel Dunbare6d233a2009-02-05 01:01:30 +000079 UIntData(UI) {}
Daniel Dunbard283e632009-02-03 01:05:53 +000080 public:
Daniel Dunbareec02622009-02-03 06:30:17 +000081 ABIArgInfo() : TheKind(Direct), TypeData(0), UIntData(0) {}
Daniel Dunbare92e0ab2009-02-03 05:31:23 +000082
Anton Korobeynikov73628192009-06-05 22:08:42 +000083 static ABIArgInfo getDirect() {
84 return ABIArgInfo(Direct);
Daniel Dunbarb1a60c02009-02-03 06:17:37 +000085 }
Anton Korobeynikov2ce305d2009-06-06 09:36:29 +000086 static ABIArgInfo getExtend() {
87 return ABIArgInfo(Extend);
88 }
Daniel Dunbard283e632009-02-03 01:05:53 +000089 static ABIArgInfo getIgnore() {
90 return ABIArgInfo(Ignore);
91 }
Anton Korobeynikov73628192009-06-05 22:08:42 +000092 static ABIArgInfo getCoerce(const llvm::Type *T) {
Daniel Dunbard283e632009-02-03 01:05:53 +000093 return ABIArgInfo(Coerce, T);
94 }
Daniel Dunbar88dde9b2009-02-05 08:00:50 +000095 static ABIArgInfo getIndirect(unsigned Alignment) {
96 return ABIArgInfo(Indirect, 0, Alignment);
Daniel Dunbard283e632009-02-03 01:05:53 +000097 }
98 static ABIArgInfo getExpand() {
99 return ABIArgInfo(Expand);
100 }
Anton Korobeynikov73628192009-06-05 22:08:42 +0000101
Daniel Dunbard283e632009-02-03 01:05:53 +0000102 Kind getKind() const { return TheKind; }
Daniel Dunbarb1a60c02009-02-03 06:17:37 +0000103 bool isDirect() const { return TheKind == Direct; }
Anton Korobeynikov2ce305d2009-06-06 09:36:29 +0000104 bool isExtend() const { return TheKind == Extend; }
Daniel Dunbard283e632009-02-03 01:05:53 +0000105 bool isIgnore() const { return TheKind == Ignore; }
106 bool isCoerce() const { return TheKind == Coerce; }
Daniel Dunbar88dde9b2009-02-05 08:00:50 +0000107 bool isIndirect() const { return TheKind == Indirect; }
Daniel Dunbard283e632009-02-03 01:05:53 +0000108 bool isExpand() const { return TheKind == Expand; }
Anton Korobeynikov73628192009-06-05 22:08:42 +0000109
Daniel Dunbard283e632009-02-03 01:05:53 +0000110 // Coerce accessors
111 const llvm::Type *getCoerceToType() const {
112 assert(TheKind == Coerce && "Invalid kind!");
113 return TypeData;
114 }
Anton Korobeynikov73628192009-06-05 22:08:42 +0000115
Daniel Dunbard283e632009-02-03 01:05:53 +0000116 // ByVal accessors
Daniel Dunbar88dde9b2009-02-05 08:00:50 +0000117 unsigned getIndirectAlign() const {
118 assert(TheKind == Indirect && "Invalid kind!");
Daniel Dunbard283e632009-02-03 01:05:53 +0000119 return UIntData;
120 }
Daniel Dunbar9f4874e2009-02-04 23:24:38 +0000121
122 void dump() const;
Daniel Dunbard283e632009-02-03 01:05:53 +0000123 };
124
125 /// ABIInfo - Target specific hooks for defining how a type should be
126 /// passed or returned from functions.
127 class ABIInfo {
128 public:
129 virtual ~ABIInfo();
Daniel Dunbar749e36b2009-02-03 06:51:18 +0000130
131 virtual void computeInfo(CodeGen::CGFunctionInfo &FI,
Owen Anderson73e7f802009-07-14 23:10:40 +0000132 ASTContext &Ctx,
133 llvm::LLVMContext &VMContext) const = 0;
Daniel Dunbar003327a2009-02-10 21:44:36 +0000134
135 /// EmitVAArg - Emit the target dependent code to load a value of
136 /// \arg Ty from the va_list pointed to by \arg VAListAddr.
Anton Korobeynikov73628192009-06-05 22:08:42 +0000137
Daniel Dunbar003327a2009-02-10 21:44:36 +0000138 // FIXME: This is a gaping layering violation if we wanted to drop
139 // the ABI information any lower than CodeGen. Of course, for
140 // VAArg handling it has to be at this level; there is no way to
141 // abstract this out.
142 virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
143 CodeGen::CodeGenFunction &CGF) const = 0;
Daniel Dunbard283e632009-02-03 01:05:53 +0000144 };
145} // end namespace clang
146
147#endif