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 ObjCKVCRefExpr;
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   bool isScalar() const { return Flavor == Scalar; }
45   bool isComplex() const { return Flavor == Complex; }
46   bool isAggregate() const { return Flavor == Aggregate; }
47 
48   bool isVolatileQualified() const { return Volatile; }
49 
50   /// getScalar() - Return the Value* of this scalar value.
51   llvm::Value *getScalarVal() const {
52     assert(isScalar() && "Not a scalar!");
53     return V1;
54   }
55 
56   /// getComplexVal - Return the real/imag components of this complex value.
57   ///
58   std::pair<llvm::Value *, llvm::Value *> getComplexVal() const {
59     return std::pair<llvm::Value *, llvm::Value *>(V1, V2);
60   }
61 
62   /// getAggregateAddr() - Return the Value* of the address of the aggregate.
63   llvm::Value *getAggregateAddr() const {
64     assert(isAggregate() && "Not an aggregate!");
65     return V1;
66   }
67 
68   static RValue get(llvm::Value *V) {
69     RValue ER;
70     ER.V1 = V;
71     ER.Flavor = Scalar;
72     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   static RValue getComplex(const std::pair<llvm::Value *, llvm::Value *> &C) {
84     RValue ER;
85     ER.V1 = C.first;
86     ER.V2 = C.second;
87     ER.Flavor = Complex;
88     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   static RValue getAggregate(llvm::Value *V, bool Vol = false) {
95     RValue ER;
96     ER.V1 = V;
97     ER.Flavor = Aggregate;
98     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 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   enum ObjCType {
122     None = 0,     // object with no gc attribute.
123     Weak,         // __weak object expression
124     Strong        // __strong object expression
125   };
126 
127   llvm::Value *V;
128 
129   union {
130     // Index into a vector subscript: V[i]
131     llvm::Value *VectorIdx;
132 
133     // ExtVector element subset: V.xyx
134     llvm::Constant *VectorElts;
135 
136     // BitField start bit and size
137     struct {
138       unsigned short StartBit;
139       unsigned short Size;
140       bool IsSigned;
141     } BitfieldData;
142 
143     // Obj-C property reference expression
144     const ObjCPropertyRefExpr *PropertyRefExpr;
145     // ObjC 'implicit' property reference expression
146     const ObjCKVCRefExpr *KVCRefExpr;
147   };
148 
149   bool Volatile:1;
150   // FIXME: set but never used, what effect should it have?
151   bool Restrict:1;
152 
153   // objective-c's ivar
154   bool Ivar:1;
155 
156   // LValue is non-gc'able for any reason, including being a parameter or local
157   // variable.
158   bool NonGC: 1;
159 
160   // Lvalue is a global reference of an objective-c object
161   bool GlobalObjCRef : 1;
162 
163   // objective-c's gc attributes
164   unsigned ObjCType : 2;
165 
166   // address space
167   unsigned AddressSpace;
168 
169 private:
170   static void SetQualifiers(unsigned Qualifiers, LValue& R) {
171     R.Volatile = (Qualifiers&QualType::Volatile)!=0;
172     R.Restrict = (Qualifiers&QualType::Restrict)!=0;
173     // FIXME: Convenient place to set objc flags to 0. This should really be
174     // done in a user-defined constructor instead.
175     R.ObjCType = None;
176     R.Ivar = R.NonGC = R.GlobalObjCRef = false;
177   }
178 
179 public:
180   bool isSimple() const { return LVType == Simple; }
181   bool isVectorElt() const { return LVType == VectorElt; }
182   bool isBitfield() const { return LVType == BitField; }
183   bool isExtVectorElt() const { return LVType == ExtVectorElt; }
184   bool isPropertyRef() const { return LVType == PropertyRef; }
185   bool isKVCRef() const { return LVType == KVCRef; }
186 
187   bool isVolatileQualified() const { return Volatile; }
188   bool isRestrictQualified() const { return Restrict; }
189   unsigned getQualifiers() const {
190     return (Volatile ? QualType::Volatile : 0) |
191            (Restrict ? QualType::Restrict : 0);
192   }
193 
194   bool isObjCIvar() const { return Ivar; }
195   bool isNonGC () const { return NonGC; }
196   bool isGlobalObjCRef() const { return GlobalObjCRef; }
197   bool isObjCWeak() const { return ObjCType == Weak; }
198   bool isObjCStrong() const { return ObjCType == Strong; }
199 
200   unsigned getAddressSpace() const { return AddressSpace; }
201 
202   static void SetObjCIvar(LValue& R, bool iValue) {
203     R.Ivar = iValue;
204   }
205 
206   static void SetGlobalObjCRef(LValue& R, bool iValue) {
207     R.GlobalObjCRef = iValue;
208   }
209 
210   static void SetObjCNonGC(LValue& R, bool iValue) {
211     R.NonGC = iValue;
212   }
213   static void SetObjCType(QualType::GCAttrTypes GCAttrs, LValue& R) {
214     if (GCAttrs == QualType::Weak)
215       R.ObjCType = Weak;
216     else if (GCAttrs == QualType::Strong)
217       R.ObjCType = Strong;
218     else
219      R.ObjCType = None;
220   }
221 
222   // simple lvalue
223   llvm::Value *getAddress() const { assert(isSimple()); return V; }
224   // vector elt lvalue
225   llvm::Value *getVectorAddr() const { assert(isVectorElt()); return V; }
226   llvm::Value *getVectorIdx() const { assert(isVectorElt()); return VectorIdx; }
227   // extended vector elements.
228   llvm::Value *getExtVectorAddr() const { assert(isExtVectorElt()); return V; }
229   llvm::Constant *getExtVectorElts() const {
230     assert(isExtVectorElt());
231     return VectorElts;
232   }
233   // bitfield lvalue
234   llvm::Value *getBitfieldAddr() const { assert(isBitfield()); return V; }
235   unsigned short getBitfieldStartBit() const {
236     assert(isBitfield());
237     return BitfieldData.StartBit;
238   }
239   unsigned short getBitfieldSize() const {
240     assert(isBitfield());
241     return BitfieldData.Size;
242   }
243   bool isBitfieldSigned() const {
244     assert(isBitfield());
245     return BitfieldData.IsSigned;
246   }
247   // property ref lvalue
248   const ObjCPropertyRefExpr *getPropertyRefExpr() const {
249     assert(isPropertyRef());
250     return PropertyRefExpr;
251   }
252 
253   // 'implicit' property ref lvalue
254   const ObjCKVCRefExpr *getKVCRefExpr() const {
255     assert(isKVCRef());
256     return KVCRefExpr;
257   }
258 
259   static LValue MakeAddr(llvm::Value *V, unsigned Qualifiers,
260                          QualType::GCAttrTypes GCAttrs = QualType::GCNone,
261                          unsigned AddressSpace = 0) {
262     LValue R;
263     R.LVType = Simple;
264     R.V = V;
265     SetQualifiers(Qualifiers,R);
266     R.AddressSpace = AddressSpace;
267     SetObjCType(GCAttrs, R);
268     return R;
269   }
270 
271   static LValue MakeVectorElt(llvm::Value *Vec, llvm::Value *Idx,
272                               unsigned Qualifiers) {
273     LValue R;
274     R.LVType = VectorElt;
275     R.V = Vec;
276     R.VectorIdx = Idx;
277     SetQualifiers(Qualifiers,R);
278     return R;
279   }
280 
281   static LValue MakeExtVectorElt(llvm::Value *Vec, llvm::Constant *Elts,
282                                  unsigned Qualifiers) {
283     LValue R;
284     R.LVType = ExtVectorElt;
285     R.V = Vec;
286     R.VectorElts = Elts;
287     SetQualifiers(Qualifiers,R);
288     return R;
289   }
290 
291   static LValue MakeBitfield(llvm::Value *V, unsigned short StartBit,
292                              unsigned short Size, bool IsSigned,
293                              unsigned Qualifiers) {
294     LValue R;
295     R.LVType = BitField;
296     R.V = V;
297     R.BitfieldData.StartBit = StartBit;
298     R.BitfieldData.Size = Size;
299     R.BitfieldData.IsSigned = IsSigned;
300     SetQualifiers(Qualifiers,R);
301     return R;
302   }
303 
304   // FIXME: It is probably bad that we aren't emitting the target when we build
305   // the lvalue. However, this complicates the code a bit, and I haven't figured
306   // out how to make it go wrong yet.
307   static LValue MakePropertyRef(const ObjCPropertyRefExpr *E,
308                                 unsigned Qualifiers) {
309     LValue R;
310     R.LVType = PropertyRef;
311     R.PropertyRefExpr = E;
312     SetQualifiers(Qualifiers,R);
313     return R;
314   }
315 
316   static LValue MakeKVCRef(const ObjCKVCRefExpr *E, unsigned Qualifiers) {
317     LValue R;
318     R.LVType = KVCRef;
319     R.KVCRefExpr = E;
320     SetQualifiers(Qualifiers,R);
321     return R;
322   }
323 };
324 
325 }  // end namespace CodeGen
326 }  // end namespace clang
327 
328 #endif
329