blob: 58e5a778cf33c8ab3e69ea19cfb431feb313682d [file] [log] [blame]
Daniel Dunbar6d6b0d32009-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 Korobeynikov244360d2009-06-05 22:08:42 +000013#include "clang/AST/Type.h"
14
15#include <cassert>
16
Daniel Dunbar313321e2009-02-03 05:31:23 +000017namespace llvm {
18 class Type;
Anton Korobeynikov244360d2009-06-05 22:08:42 +000019 class Value;
Daniel Dunbar313321e2009-02-03 05:31:23 +000020}
21
Daniel Dunbar6d6b0d32009-02-03 01:05:53 +000022namespace clang {
Daniel Dunbar32931eb2009-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 Dunbare46506e2009-02-10 21:44:36 +000029 class CodeGenFunction;
Daniel Dunbar32931eb2009-02-03 06:51:18 +000030 }
31
Daniel Dunbar6d6b0d32009-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 Dunbar67dace892009-02-03 06:17:37 +000043 Direct, /// Pass the argument directly using the normal
Daniel Dunbarb8b1c672009-02-05 08:00:50 +000044 /// converted LLVM type. Complex and structure types
45 /// are passed using first class aggregates.
Anton Korobeynikov244360d2009-06-05 22:08:42 +000046
Anton Korobeynikov18adbf52009-06-06 09:36:29 +000047 Extend, /// Valid only for integer argument types. Same as 'direct'
48 /// but also emit a zero/sign extension attribute.
49
Daniel Dunbarb8b1c672009-02-05 08:00:50 +000050 Indirect, /// Pass the argument indirectly via a hidden pointer
51 /// with the specified alignment (0 indicates default
52 /// alignment).
Anton Korobeynikov244360d2009-06-05 22:08:42 +000053
Daniel Dunbar6d6b0d32009-02-03 01:05:53 +000054 Ignore, /// Ignore the argument (treat as void). Useful for
55 /// void and empty structs.
Anton Korobeynikov244360d2009-06-05 22:08:42 +000056
Daniel Dunbar6d6b0d32009-02-03 01:05:53 +000057 Coerce, /// Only valid for aggregate return types, the argument
58 /// should be accessed by coercion to a provided type.
Anton Korobeynikov244360d2009-06-05 22:08:42 +000059
Daniel Dunbar6d6b0d32009-02-03 01:05:53 +000060 Expand, /// Only valid for aggregate argument types. The
61 /// structure should be expanded into consecutive
62 /// arguments for its constituent fields. Currently
63 /// expand is only allowed on structures whose fields
64 /// are all scalar types or are themselves expandable
65 /// types.
Anton Korobeynikov244360d2009-06-05 22:08:42 +000066
Daniel Dunbar01362822009-02-03 06:30:17 +000067 KindFirst=Direct, KindLast=Expand
Daniel Dunbar6d6b0d32009-02-03 01:05:53 +000068 };
Anton Korobeynikov244360d2009-06-05 22:08:42 +000069
Daniel Dunbar6d6b0d32009-02-03 01:05:53 +000070 private:
71 Kind TheKind;
72 const llvm::Type *TypeData;
73 unsigned UIntData;
Anton Korobeynikov244360d2009-06-05 22:08:42 +000074
Daniel Dunbar6d6b0d32009-02-03 01:05:53 +000075 ABIArgInfo(Kind K, const llvm::Type *TD=0,
76 unsigned UI=0) : TheKind(K),
77 TypeData(TD),
Daniel Dunbar80453432009-02-05 01:01:30 +000078 UIntData(UI) {}
Daniel Dunbar6d6b0d32009-02-03 01:05:53 +000079 public:
Daniel Dunbar01362822009-02-03 06:30:17 +000080 ABIArgInfo() : TheKind(Direct), TypeData(0), UIntData(0) {}
Daniel Dunbar313321e2009-02-03 05:31:23 +000081
Anton Korobeynikov244360d2009-06-05 22:08:42 +000082 static ABIArgInfo getDirect() {
83 return ABIArgInfo(Direct);
Daniel Dunbar67dace892009-02-03 06:17:37 +000084 }
Anton Korobeynikov18adbf52009-06-06 09:36:29 +000085 static ABIArgInfo getExtend() {
86 return ABIArgInfo(Extend);
87 }
Daniel Dunbar6d6b0d32009-02-03 01:05:53 +000088 static ABIArgInfo getIgnore() {
89 return ABIArgInfo(Ignore);
90 }
Anton Korobeynikov244360d2009-06-05 22:08:42 +000091 static ABIArgInfo getCoerce(const llvm::Type *T) {
Daniel Dunbar6d6b0d32009-02-03 01:05:53 +000092 return ABIArgInfo(Coerce, T);
93 }
Daniel Dunbarb8b1c672009-02-05 08:00:50 +000094 static ABIArgInfo getIndirect(unsigned Alignment) {
95 return ABIArgInfo(Indirect, 0, Alignment);
Daniel Dunbar6d6b0d32009-02-03 01:05:53 +000096 }
97 static ABIArgInfo getExpand() {
98 return ABIArgInfo(Expand);
99 }
Anton Korobeynikov244360d2009-06-05 22:08:42 +0000100
Daniel Dunbar6d6b0d32009-02-03 01:05:53 +0000101 Kind getKind() const { return TheKind; }
Daniel Dunbar67dace892009-02-03 06:17:37 +0000102 bool isDirect() const { return TheKind == Direct; }
Anton Korobeynikov18adbf52009-06-06 09:36:29 +0000103 bool isExtend() const { return TheKind == Extend; }
Daniel Dunbar6d6b0d32009-02-03 01:05:53 +0000104 bool isIgnore() const { return TheKind == Ignore; }
105 bool isCoerce() const { return TheKind == Coerce; }
Daniel Dunbarb8b1c672009-02-05 08:00:50 +0000106 bool isIndirect() const { return TheKind == Indirect; }
Daniel Dunbar6d6b0d32009-02-03 01:05:53 +0000107 bool isExpand() const { return TheKind == Expand; }
Anton Korobeynikov244360d2009-06-05 22:08:42 +0000108
Daniel Dunbar6d6b0d32009-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 Korobeynikov244360d2009-06-05 22:08:42 +0000114
Daniel Dunbar6d6b0d32009-02-03 01:05:53 +0000115 // ByVal accessors
Daniel Dunbarb8b1c672009-02-05 08:00:50 +0000116 unsigned getIndirectAlign() const {
117 assert(TheKind == Indirect && "Invalid kind!");
Daniel Dunbar6d6b0d32009-02-03 01:05:53 +0000118 return UIntData;
119 }
Daniel Dunbar56e75522009-02-04 23:24:38 +0000120
121 void dump() const;
Daniel Dunbar6d6b0d32009-02-03 01:05:53 +0000122 };
123
124 /// ABIInfo - Target specific hooks for defining how a type should be
125 /// passed or returned from functions.
126 class ABIInfo {
127 public:
128 virtual ~ABIInfo();
Daniel Dunbar32931eb2009-02-03 06:51:18 +0000129
130 virtual void computeInfo(CodeGen::CGFunctionInfo &FI,
131 ASTContext &Ctx) const = 0;
Daniel Dunbare46506e2009-02-10 21:44:36 +0000132
133 /// EmitVAArg - Emit the target dependent code to load a value of
134 /// \arg Ty from the va_list pointed to by \arg VAListAddr.
Anton Korobeynikov244360d2009-06-05 22:08:42 +0000135
Daniel Dunbare46506e2009-02-10 21:44:36 +0000136 // FIXME: This is a gaping layering violation if we wanted to drop
137 // the ABI information any lower than CodeGen. Of course, for
138 // VAArg handling it has to be at this level; there is no way to
139 // abstract this out.
140 virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
141 CodeGen::CodeGenFunction &CGF) const = 0;
Daniel Dunbar6d6b0d32009-02-03 01:05:53 +0000142 };
143} // end namespace clang
144
145#endif