blob: e0917f77e0e4f932ede71ed9f55f054f8004900a [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
Daniel Dunbare92e0ab2009-02-03 05:31:23 +000013namespace llvm {
14 class Type;
15}
16
Daniel Dunbard283e632009-02-03 01:05:53 +000017namespace clang {
18 /* FIXME: All of this stuff should be part of the target interface
19 somehow. It is currently here because it is not clear how to factor
20 the targets to support this, since the Targets currently live in a
21 layer below types n'stuff.
22 */
23
24 /// ABIArgInfo - Helper class to encapsulate information about how a
25 /// specific C type should be passed to or returned from a function.
26 class ABIArgInfo {
27 public:
28 enum Kind {
29 Default,
30 StructRet, /// Only valid for return values. The return value
31 /// should be passed through a pointer to a caller
32 /// allocated location passed as an implicit first
33 /// argument to the function.
34
35 Ignore, /// Ignore the argument (treat as void). Useful for
36 /// void and empty structs.
37
38 Coerce, /// Only valid for aggregate return types, the argument
39 /// should be accessed by coercion to a provided type.
40
41 ByVal, /// Only valid for aggregate argument types. The
42 /// structure should be passed "byval" with the
43 /// specified alignment (0 indicates default
44 /// alignment).
45
46 Expand, /// Only valid for aggregate argument types. The
47 /// structure should be expanded into consecutive
48 /// arguments for its constituent fields. Currently
49 /// expand is only allowed on structures whose fields
50 /// are all scalar types or are themselves expandable
51 /// types.
52
53 KindFirst=Default, KindLast=Expand
54 };
55
56 private:
57 Kind TheKind;
58 const llvm::Type *TypeData;
59 unsigned UIntData;
60
61 ABIArgInfo(Kind K, const llvm::Type *TD=0,
62 unsigned UI=0) : TheKind(K),
63 TypeData(TD),
64 UIntData(0) {}
65 public:
Daniel Dunbare92e0ab2009-02-03 05:31:23 +000066 ABIArgInfo() : TheKind(Default), TypeData(0), UIntData(0) {}
67
Daniel Dunbard283e632009-02-03 01:05:53 +000068 static ABIArgInfo getDefault() {
69 return ABIArgInfo(Default);
70 }
71 static ABIArgInfo getStructRet() {
72 return ABIArgInfo(StructRet);
73 }
74 static ABIArgInfo getIgnore() {
75 return ABIArgInfo(Ignore);
76 }
77 static ABIArgInfo getCoerce(const llvm::Type *T) {
78 return ABIArgInfo(Coerce, T);
79 }
80 static ABIArgInfo getByVal(unsigned Alignment) {
81 return ABIArgInfo(ByVal, 0, Alignment);
82 }
83 static ABIArgInfo getExpand() {
84 return ABIArgInfo(Expand);
85 }
86
87 Kind getKind() const { return TheKind; }
88 bool isDefault() const { return TheKind == Default; }
89 bool isStructRet() const { return TheKind == StructRet; }
90 bool isIgnore() const { return TheKind == Ignore; }
91 bool isCoerce() const { return TheKind == Coerce; }
92 bool isByVal() const { return TheKind == ByVal; }
93 bool isExpand() const { return TheKind == Expand; }
94
95 // Coerce accessors
96 const llvm::Type *getCoerceToType() const {
97 assert(TheKind == Coerce && "Invalid kind!");
98 return TypeData;
99 }
100
101 // ByVal accessors
102 unsigned getByValAlignment() const {
103 assert(TheKind == ByVal && "Invalid kind!");
104 return UIntData;
105 }
106 };
107
108 /// ABIInfo - Target specific hooks for defining how a type should be
109 /// passed or returned from functions.
110 class ABIInfo {
111 public:
112 virtual ~ABIInfo();
113
114 virtual ABIArgInfo classifyReturnType(QualType RetTy,
115 ASTContext &Context) const = 0;
116
117 virtual ABIArgInfo classifyArgumentType(QualType Ty,
118 ASTContext &Context) const = 0;
119 };
120} // end namespace clang
121
122#endif