blob: bc9a15fe9f77453c8e0201d4c8c713753012d370 [file] [log] [blame]
Daniel Dunbar2eecaab2008-08-23 03:10:25 +00001//===-- CGValue.h - LLVM CodeGen wrappers for llvm::Value* ------*- 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// These classes implement wrappers around llvm::Value in order to
11// fully represent the range of values for C L- and R- values.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef CLANG_CODEGEN_CGVALUE_H
16#define CLANG_CODEGEN_CGVALUE_H
17
18#include "clang/AST/Type.h"
19
20namespace clang {
Daniel Dunbar85c59ed2008-08-29 08:11:39 +000021 class ObjCPropertyRefExpr;
22
Daniel Dunbar2eecaab2008-08-23 03:10:25 +000023namespace CodeGen {
24
25/// RValue - This trivial value class is used to represent the result of an
26/// expression that is evaluated. It can be one of three things: either a
27/// simple LLVM SSA value, a pair of SSA values for complex numbers, or the
28/// address of an aggregate value in memory.
29class RValue {
30 llvm::Value *V1, *V2;
31 // TODO: Encode this into the low bit of pointer for more efficient
32 // return-by-value.
33 enum { Scalar, Complex, Aggregate } Flavor;
34
35 // FIXME: Aggregate rvalues need to retain information about whether they are
36 // volatile or not.
37public:
38
39 bool isScalar() const { return Flavor == Scalar; }
40 bool isComplex() const { return Flavor == Complex; }
41 bool isAggregate() const { return Flavor == Aggregate; }
42
43 /// getScalar() - Return the Value* of this scalar value.
44 llvm::Value *getScalarVal() const {
45 assert(isScalar() && "Not a scalar!");
46 return V1;
47 }
48
49 /// getComplexVal - Return the real/imag components of this complex value.
50 ///
51 std::pair<llvm::Value *, llvm::Value *> getComplexVal() const {
52 return std::pair<llvm::Value *, llvm::Value *>(V1, V2);
53 }
54
55 /// getAggregateAddr() - Return the Value* of the address of the aggregate.
56 llvm::Value *getAggregateAddr() const {
57 assert(isAggregate() && "Not an aggregate!");
58 return V1;
59 }
60
61 static RValue get(llvm::Value *V) {
62 RValue ER;
63 ER.V1 = V;
64 ER.Flavor = Scalar;
65 return ER;
66 }
67 static RValue getComplex(llvm::Value *V1, llvm::Value *V2) {
68 RValue ER;
69 ER.V1 = V1;
70 ER.V2 = V2;
71 ER.Flavor = Complex;
72 return ER;
73 }
74 static RValue getComplex(const std::pair<llvm::Value *, llvm::Value *> &C) {
75 RValue ER;
76 ER.V1 = C.first;
77 ER.V2 = C.second;
78 ER.Flavor = Complex;
79 return ER;
80 }
81 static RValue getAggregate(llvm::Value *V) {
82 RValue ER;
83 ER.V1 = V;
84 ER.Flavor = Aggregate;
85 return ER;
86 }
87};
88
89
90/// LValue - This represents an lvalue references. Because C/C++ allow
91/// bitfields, this is not a simple LLVM pointer, it may be a pointer plus a
92/// bitrange.
93class LValue {
94 // FIXME: alignment?
95
96 enum {
97 Simple, // This is a normal l-value, use getAddress().
98 VectorElt, // This is a vector element l-value (V[i]), use getVector*
99 BitField, // This is a bitfield l-value, use getBitfield*.
Daniel Dunbar85c59ed2008-08-29 08:11:39 +0000100 ExtVectorElt, // This is an extended vector subset, use getExtVectorComp
101 PropertyRef // This is an Objective-C property reference, use
102 // getPropertyRefExpr
Daniel Dunbar2eecaab2008-08-23 03:10:25 +0000103 } LVType;
104
105 llvm::Value *V;
106
107 union {
108 // Index into a vector subscript: V[i]
109 llvm::Value *VectorIdx;
110
111 // ExtVector element subset: V.xyx
112 llvm::Constant *VectorElts;
113
114 // BitField start bit and size
115 struct {
116 unsigned short StartBit;
117 unsigned short Size;
118 bool IsSigned;
119 } BitfieldData;
Daniel Dunbar85c59ed2008-08-29 08:11:39 +0000120
121 // Obj-C property reference expression
122 const ObjCPropertyRefExpr *PropertyRefExpr;
Daniel Dunbar2eecaab2008-08-23 03:10:25 +0000123 };
124
125 bool Volatile:1;
126 // FIXME: set but never used, what effect should it have?
127 bool Restrict:1;
128
129private:
130 static void SetQualifiers(unsigned Qualifiers, LValue& R) {
131 R.Volatile = (Qualifiers&QualType::Volatile)!=0;
132 R.Restrict = (Qualifiers&QualType::Restrict)!=0;
133 }
134
135public:
136 bool isSimple() const { return LVType == Simple; }
137 bool isVectorElt() const { return LVType == VectorElt; }
138 bool isBitfield() const { return LVType == BitField; }
139 bool isExtVectorElt() const { return LVType == ExtVectorElt; }
Daniel Dunbar85c59ed2008-08-29 08:11:39 +0000140 bool isPropertyRef() const { return LVType == PropertyRef; }
141
Daniel Dunbar2eecaab2008-08-23 03:10:25 +0000142 bool isVolatileQualified() const { return Volatile; }
143 bool isRestrictQualified() const { return Restrict; }
144
145 // simple lvalue
146 llvm::Value *getAddress() const { assert(isSimple()); return V; }
147 // vector elt lvalue
148 llvm::Value *getVectorAddr() const { assert(isVectorElt()); return V; }
149 llvm::Value *getVectorIdx() const { assert(isVectorElt()); return VectorIdx; }
150 // extended vector elements.
151 llvm::Value *getExtVectorAddr() const { assert(isExtVectorElt()); return V; }
152 llvm::Constant *getExtVectorElts() const {
153 assert(isExtVectorElt());
154 return VectorElts;
155 }
156 // bitfield lvalue
157 llvm::Value *getBitfieldAddr() const { assert(isBitfield()); return V; }
158 unsigned short getBitfieldStartBit() const {
159 assert(isBitfield());
160 return BitfieldData.StartBit;
161 }
162 unsigned short getBitfieldSize() const {
163 assert(isBitfield());
164 return BitfieldData.Size;
165 }
166 bool isBitfieldSigned() const {
167 assert(isBitfield());
168 return BitfieldData.IsSigned;
169 }
Daniel Dunbar85c59ed2008-08-29 08:11:39 +0000170 // property ref lvalue
171 const ObjCPropertyRefExpr *getPropertyRefExpr() const {
172 assert(isPropertyRef());
173 return PropertyRefExpr;
174 }
Daniel Dunbar2eecaab2008-08-23 03:10:25 +0000175
176 static LValue MakeAddr(llvm::Value *V, unsigned Qualifiers) {
177 LValue R;
178 R.LVType = Simple;
179 R.V = V;
180 SetQualifiers(Qualifiers,R);
181 return R;
182 }
183
184 static LValue MakeVectorElt(llvm::Value *Vec, llvm::Value *Idx,
185 unsigned Qualifiers) {
186 LValue R;
187 R.LVType = VectorElt;
188 R.V = Vec;
189 R.VectorIdx = Idx;
190 SetQualifiers(Qualifiers,R);
191 return R;
192 }
193
194 static LValue MakeExtVectorElt(llvm::Value *Vec, llvm::Constant *Elts,
195 unsigned Qualifiers) {
196 LValue R;
197 R.LVType = ExtVectorElt;
198 R.V = Vec;
199 R.VectorElts = Elts;
200 SetQualifiers(Qualifiers,R);
201 return R;
202 }
203
204 static LValue MakeBitfield(llvm::Value *V, unsigned short StartBit,
205 unsigned short Size, bool IsSigned,
206 unsigned Qualifiers) {
207 LValue R;
208 R.LVType = BitField;
209 R.V = V;
210 R.BitfieldData.StartBit = StartBit;
211 R.BitfieldData.Size = Size;
212 R.BitfieldData.IsSigned = IsSigned;
213 SetQualifiers(Qualifiers,R);
214 return R;
215 }
Daniel Dunbar85c59ed2008-08-29 08:11:39 +0000216
217 static LValue MakePropertyRef(const ObjCPropertyRefExpr *E,
218 unsigned Qualifiers) {
219 LValue R;
220 R.LVType = PropertyRef;
221 R.PropertyRefExpr = E;
222 SetQualifiers(Qualifiers,R);
223 return R;
224 }
Daniel Dunbar2eecaab2008-08-23 03:10:25 +0000225};
226
227} // end namespace CodeGen
228} // end namespace clang
229
230#endif