 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
47.8% |
11 / 23 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
100.0% |
23 / 23 |
| |
|
Line Coverage: |
100.0% |
118 / 118 |
| |
 |
|
 |
1 : //===-- 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 :
20 : namespace llvm {
21 : class Constant;
22 : class Value;
23 : }
24 :
25 : namespace clang {
26 : class ObjCPropertyRefExpr;
27 : class ObjCImplicitSetterGetterRefExpr;
28 :
29 : namespace CodeGen {
30 :
31 : /// RValue - This trivial value class is used to represent the result of an
32 : /// expression that is evaluated. It can be one of three things: either a
33 : /// simple LLVM SSA value, a pair of SSA values for complex numbers, or the
34 : /// address of an aggregate value in memory.
35 : class RValue {
36 : llvm::Value *V1, *V2;
37 : // TODO: Encode this into the low bit of pointer for more efficient
38 : // return-by-value.
39 : enum { Scalar, Complex, Aggregate } Flavor;
40 :
41 : bool Volatile:1;
42 : public:
43 :
44 17650: bool isScalar() const { return Flavor == Scalar; }
45 83: bool isComplex() const { return Flavor == Complex; }
46 524: bool isAggregate() const { return Flavor == Aggregate; }
47 :
48 202: bool isVolatileQualified() const { return Volatile; }
49 :
50 : /// getScalarVal() - Return the Value* of this scalar value.
51 11681: llvm::Value *getScalarVal() const {
11681: branch 1 taken
0: branch 2 not taken
52 11681: assert(isScalar() && "Not a scalar!");
53 11681: return V1;
54 : }
55 :
56 : /// getComplexVal - Return the real/imag components of this complex value.
57 : ///
58 33: std::pair<llvm::Value *, llvm::Value *> getComplexVal() const {
59 33: return std::pair<llvm::Value *, llvm::Value *>(V1, V2);
60 : }
61 :
62 : /// getAggregateAddr() - Return the Value* of the address of the aggregate.
63 270: llvm::Value *getAggregateAddr() const {
0: branch 2 not taken
64 270: assert(isAggregate() && "Not an aggregate!");
65 270: return V1;
66 : }
67 :
68 17637: static RValue get(llvm::Value *V) {
69 : RValue ER;
70 17637: ER.V1 = V;
71 17637: ER.Flavor = Scalar;
72 17637: ER.Volatile = false;
73 : return ER;
74 : }
75 : static RValue getComplex(llvm::Value *V1, llvm::Value *V2) {
76 : RValue ER;
77 : ER.V1 = V1;
78 : ER.V2 = V2;
79 : ER.Flavor = Complex;
80 : ER.Volatile = false;
81 : return ER;
82 : }
83 79: static RValue getComplex(const std::pair<llvm::Value *, llvm::Value *> &C) {
84 : RValue ER;
85 79: ER.V1 = C.first;
86 79: ER.V2 = C.second;
87 79: ER.Flavor = Complex;
88 79: ER.Volatile = false;
89 : return ER;
90 : }
91 : // FIXME: Aggregate rvalues need to retain information about whether they are
92 : // volatile or not. Remove default to find all places that probably get this
93 : // wrong.
94 554: static RValue getAggregate(llvm::Value *V, bool Vol = false) {
95 : RValue ER;
96 554: ER.V1 = V;
97 554: ER.Flavor = Aggregate;
98 554: ER.Volatile = Vol;
99 : return ER;
100 : }
101 : };
102 :
103 :
104 : /// LValue - This represents an lvalue references. Because C/C++ allow
105 : /// bitfields, this is not a simple LLVM pointer, it may be a pointer plus a
106 : /// bitrange.
107 8481: class LValue {
108 : // FIXME: alignment?
109 :
110 : enum {
111 : Simple, // This is a normal l-value, use getAddress().
112 : VectorElt, // This is a vector element l-value (V[i]), use getVector*
113 : BitField, // This is a bitfield l-value, use getBitfield*.
114 : ExtVectorElt, // This is an extended vector subset, use getExtVectorComp
115 : PropertyRef, // This is an Objective-C property reference, use
116 : // getPropertyRefExpr
117 : KVCRef // This is an objective-c 'implicit' property ref,
118 : // use getKVCRefExpr
119 : } LVType;
120 :
121 : llvm::Value *V;
122 :
123 : union {
124 : // Index into a vector subscript: V[i]
125 : llvm::Value *VectorIdx;
126 :
127 : // ExtVector element subset: V.xyx
128 : llvm::Constant *VectorElts;
129 :
130 : // BitField start bit and size
131 : struct {
132 : unsigned short StartBit;
133 : unsigned short Size;
134 : bool IsSigned;
135 : } BitfieldData;
136 :
137 : // Obj-C property reference expression
138 : const ObjCPropertyRefExpr *PropertyRefExpr;
139 : // ObjC 'implicit' property reference expression
140 : const ObjCImplicitSetterGetterRefExpr *KVCRefExpr;
141 : };
142 :
143 : // 'const' is unused here
144 : Qualifiers Quals;
145 :
146 : // objective-c's ivar
147 : bool Ivar:1;
148 :
149 : // objective-c's ivar is an array
150 : bool ObjIsArray:1;
151 :
152 : // LValue is non-gc'able for any reason, including being a parameter or local
153 : // variable.
154 : bool NonGC: 1;
155 :
156 : // Lvalue is a global reference of an objective-c object
157 : bool GlobalObjCRef : 1;
158 :
159 : Expr *BaseIvarExp;
160 : private:
161 8425: void SetQualifiers(Qualifiers Quals) {
162 8425: this->Quals = Quals;
163 :
164 : // FIXME: Convenient place to set objc flags to 0. This should really be
165 : // done in a user-defined constructor instead.
166 8425: this->Ivar = this->ObjIsArray = this->NonGC = this->GlobalObjCRef = false;
167 8425: this->BaseIvarExp = 0;
168 8425: }
169 :
170 : public:
171 16221: bool isSimple() const { return LVType == Simple; }
172 194: bool isVectorElt() const { return LVType == VectorElt; }
173 2965: bool isBitfield() const { return LVType == BitField; }
174 310: bool isExtVectorElt() const { return LVType == ExtVectorElt; }
175 180: bool isPropertyRef() const { return LVType == PropertyRef; }
176 63: bool isKVCRef() const { return LVType == KVCRef; }
177 :
178 5647: bool isVolatileQualified() const { return Quals.hasVolatile(); }
179 : bool isRestrictQualified() const { return Quals.hasRestrict(); }
180 56: unsigned getVRQualifiers() const {
181 56: return Quals.getCVRQualifiers() & ~Qualifiers::Const;
182 : }
183 :
184 197: bool isObjCIvar() const { return Ivar; }
185 71: bool isObjCArray() const { return ObjIsArray; }
186 493: bool isNonGC () const { return NonGC; }
187 131: bool isGlobalObjCRef() const { return GlobalObjCRef; }
188 5048: bool isObjCWeak() const { return Quals.getObjCGCAttr() == Qualifiers::Weak; }
189 1440: bool isObjCStrong() const { return Quals.getObjCGCAttr() == Qualifiers::Strong; }
190 :
191 72: Expr *getBaseIvarExp() const { return BaseIvarExp; }
192 135: void setBaseIvarExp(Expr *V) { BaseIvarExp = V; }
193 :
194 : unsigned getAddressSpace() const { return Quals.getAddressSpace(); }
195 :
196 158: static void SetObjCIvar(LValue& R, bool iValue) {
197 158: R.Ivar = iValue;
198 158: }
199 585: static void SetObjCArray(LValue& R, bool iValue) {
200 585: R.ObjIsArray = iValue;
201 585: }
202 175: static void SetGlobalObjCRef(LValue& R, bool iValue) {
203 175: R.GlobalObjCRef = iValue;
204 175: }
205 :
206 4490: static void SetObjCNonGC(LValue& R, bool iValue) {
207 4490: R.NonGC = iValue;
208 4490: }
209 :
210 : // simple lvalue
0: branch 1 not taken
9560: branch 2 taken
211 9560: llvm::Value *getAddress() const { assert(isSimple()); return V; }
212 : // vector elt lvalue
213 7: llvm::Value *getVectorAddr() const { assert(isVectorElt()); return V; }
0: branch 1 not taken
4: branch 2 taken
214 4: llvm::Value *getVectorIdx() const { assert(isVectorElt()); return VectorIdx; }
215 : // extended vector elements.
0: branch 1 not taken
64: branch 2 taken
216 64: llvm::Value *getExtVectorAddr() const { assert(isExtVectorElt()); return V; }
217 56: llvm::Constant *getExtVectorElts() const {
0: branch 1 not taken
56: branch 2 taken
218 56: assert(isExtVectorElt());
219 56: return VectorElts;
220 : }
221 : // bitfield lvalue
0: branch 1 not taken
130: branch 2 taken
222 130: llvm::Value *getBitfieldAddr() const { assert(isBitfield()); return V; }
223 130: unsigned short getBitfieldStartBit() const {
0: branch 1 not taken
130: branch 2 taken
224 130: assert(isBitfield());
225 130: return BitfieldData.StartBit;
226 : }
227 130: unsigned short getBitfieldSize() const {
0: branch 1 not taken
130: branch 2 taken
228 130: assert(isBitfield());
229 130: return BitfieldData.Size;
230 : }
231 119: bool isBitfieldSigned() const {
0: branch 1 not taken
119: branch 2 taken
232 119: assert(isBitfield());
233 119: return BitfieldData.IsSigned;
234 : }
235 : // property ref lvalue
236 65: const ObjCPropertyRefExpr *getPropertyRefExpr() const {
0: branch 1 not taken
65: branch 2 taken
237 65: assert(isPropertyRef());
238 65: return PropertyRefExpr;
239 : }
240 :
241 : // 'implicit' property ref lvalue
242 15: const ObjCImplicitSetterGetterRefExpr *getKVCRefExpr() const {
0: branch 1 not taken
15: branch 2 taken
243 15: assert(isKVCRef());
244 15: return KVCRefExpr;
245 : }
246 :
247 8174: static LValue MakeAddr(llvm::Value *V, Qualifiers Quals) {
248 8174: LValue R;
249 8174: R.LVType = Simple;
250 8174: R.V = V;
251 8174: R.SetQualifiers(Quals);
252 : return R;
253 : }
254 :
255 : static LValue MakeVectorElt(llvm::Value *Vec, llvm::Value *Idx,
256 4: unsigned CVR) {
257 4: LValue R;
258 4: R.LVType = VectorElt;
259 4: R.V = Vec;
260 4: R.VectorIdx = Idx;
261 4: R.SetQualifiers(Qualifiers::fromCVRMask(CVR));
262 : return R;
263 : }
264 :
265 : static LValue MakeExtVectorElt(llvm::Value *Vec, llvm::Constant *Elts,
266 56: unsigned CVR) {
267 56: LValue R;
268 56: R.LVType = ExtVectorElt;
269 56: R.V = Vec;
270 56: R.VectorElts = Elts;
271 56: R.SetQualifiers(Qualifiers::fromCVRMask(CVR));
272 : return R;
273 : }
274 :
275 : static LValue MakeBitfield(llvm::Value *V, unsigned short StartBit,
276 : unsigned short Size, bool IsSigned,
277 120: unsigned CVR) {
278 120: LValue R;
279 120: R.LVType = BitField;
280 120: R.V = V;
281 120: R.BitfieldData.StartBit = StartBit;
282 120: R.BitfieldData.Size = Size;
283 120: R.BitfieldData.IsSigned = IsSigned;
284 120: R.SetQualifiers(Qualifiers::fromCVRMask(CVR));
285 : return R;
286 : }
287 :
288 : // FIXME: It is probably bad that we aren't emitting the target when we build
289 : // the lvalue. However, this complicates the code a bit, and I haven't figured
290 : // out how to make it go wrong yet.
291 : static LValue MakePropertyRef(const ObjCPropertyRefExpr *E,
292 56: unsigned CVR) {
293 56: LValue R;
294 56: R.LVType = PropertyRef;
295 56: R.PropertyRefExpr = E;
296 56: R.SetQualifiers(Qualifiers::fromCVRMask(CVR));
297 : return R;
298 : }
299 :
300 : static LValue MakeKVCRef(const ObjCImplicitSetterGetterRefExpr *E,
301 15: unsigned CVR) {
302 15: LValue R;
303 15: R.LVType = KVCRef;
304 15: R.KVCRefExpr = E;
305 15: R.SetQualifiers(Qualifiers::fromCVRMask(CVR));
306 : return R;
307 : }
308 : };
309 :
310 : } // end namespace CodeGen
311 : } // end namespace clang
312 :
313 : #endif
Generated: 2010-02-10 01:31 by zcov