CGValue.h revision 07ed93f378a8868c9a7c04ca7ae685b85c55e5ea
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/ASTContext.h"
19#include "clang/AST/Type.h"
20
21namespace llvm {
22  class Constant;
23  class Value;
24}
25
26namespace clang {
27  class ObjCPropertyRefExpr;
28  class ObjCImplicitSetterGetterRefExpr;
29  class CXXConstructExpr;
30
31namespace CodeGen {
32  class CGBitFieldInfo;
33
34/// RValue - This trivial value class is used to represent the result of an
35/// expression that is evaluated.  It can be one of three things: either a
36/// simple LLVM SSA value, a pair of SSA values for complex numbers, or the
37/// address of an aggregate value in memory.
38class RValue {
39  enum Flavor { Scalar, Complex, Aggregate };
40
41  // Stores first value and flavor.
42  llvm::PointerIntPair<llvm::Value *, 2, Flavor> V1;
43  // Stores second value and volatility.
44  llvm::PointerIntPair<llvm::Value *, 1, bool> V2;
45
46public:
47  bool isScalar() const { return V1.getInt() == Scalar; }
48  bool isComplex() const { return V1.getInt() == Complex; }
49  bool isAggregate() const { return V1.getInt() == Aggregate; }
50
51  bool isVolatileQualified() const { return V2.getInt(); }
52
53  /// getScalarVal() - Return the Value* of this scalar value.
54  llvm::Value *getScalarVal() const {
55    assert(isScalar() && "Not a scalar!");
56    return V1.getPointer();
57  }
58
59  /// getComplexVal - Return the real/imag components of this complex value.
60  ///
61  std::pair<llvm::Value *, llvm::Value *> getComplexVal() const {
62    return std::make_pair(V1.getPointer(), V2.getPointer());
63  }
64
65  /// getAggregateAddr() - Return the Value* of the address of the aggregate.
66  llvm::Value *getAggregateAddr() const {
67    assert(isAggregate() && "Not an aggregate!");
68    return V1.getPointer();
69  }
70
71  static RValue get(llvm::Value *V) {
72    RValue ER;
73    ER.V1.setPointer(V);
74    ER.V1.setInt(Scalar);
75    ER.V2.setInt(false);
76    return ER;
77  }
78  static RValue getComplex(llvm::Value *V1, llvm::Value *V2) {
79    RValue ER;
80    ER.V1.setPointer(V1);
81    ER.V2.setPointer(V2);
82    ER.V1.setInt(Complex);
83    ER.V2.setInt(false);
84    return ER;
85  }
86  static RValue getComplex(const std::pair<llvm::Value *, llvm::Value *> &C) {
87    return getComplex(C.first, C.second);
88  }
89  // FIXME: Aggregate rvalues need to retain information about whether they are
90  // volatile or not.  Remove default to find all places that probably get this
91  // wrong.
92  static RValue getAggregate(llvm::Value *V, bool Volatile = false) {
93    RValue ER;
94    ER.V1.setPointer(V);
95    ER.V1.setInt(Aggregate);
96    ER.V2.setInt(Volatile);
97    return ER;
98  }
99};
100
101
102/// LValue - This represents an lvalue references.  Because C/C++ allow
103/// bitfields, this is not a simple LLVM pointer, it may be a pointer plus a
104/// bitrange.
105class LValue {
106  // FIXME: alignment?
107
108  enum {
109    Simple,       // This is a normal l-value, use getAddress().
110    VectorElt,    // This is a vector element l-value (V[i]), use getVector*
111    BitField,     // This is a bitfield l-value, use getBitfield*.
112    ExtVectorElt, // This is an extended vector subset, use getExtVectorComp
113    PropertyRef,  // This is an Objective-C property reference, use
114                  // getPropertyRefExpr
115    KVCRef        // This is an objective-c 'implicit' property ref,
116                  // use getKVCRefExpr
117  } LVType;
118
119  llvm::Value *V;
120
121  union {
122    // Index into a vector subscript: V[i]
123    llvm::Value *VectorIdx;
124
125    // ExtVector element subset: V.xyx
126    llvm::Constant *VectorElts;
127
128    // BitField start bit and size
129    const CGBitFieldInfo *BitFieldInfo;
130
131    // Obj-C property reference expression
132    const ObjCPropertyRefExpr *PropertyRefExpr;
133
134    // ObjC 'implicit' property reference expression
135    const ObjCImplicitSetterGetterRefExpr *KVCRefExpr;
136  };
137
138  // 'const' is unused here
139  Qualifiers Quals;
140
141  /// The alignment to use when accessing this lvalue.
142  unsigned short Alignment;
143
144  // objective-c's ivar
145  bool Ivar:1;
146
147  // objective-c's ivar is an array
148  bool ObjIsArray:1;
149
150  // LValue is non-gc'able for any reason, including being a parameter or local
151  // variable.
152  bool NonGC: 1;
153
154  // Lvalue is a global reference of an objective-c object
155  bool GlobalObjCRef : 1;
156
157  // Lvalue is a thread local reference
158  bool ThreadLocalRef : 1;
159
160  Expr *BaseIvarExp;
161
162  /// TBAAInfo - TBAA information to attach to dereferences of this LValue.
163  llvm::MDNode *TBAAInfo;
164
165private:
166  void Initialize(Qualifiers Quals, unsigned Alignment = 0,
167                  llvm::MDNode *TBAAInfo = 0) {
168    this->Quals = Quals;
169    this->Alignment = Alignment;
170    assert(this->Alignment == Alignment && "Alignment exceeds allowed max!");
171
172    // Initialize Objective-C flags.
173    this->Ivar = this->ObjIsArray = this->NonGC = this->GlobalObjCRef = false;
174    this->ThreadLocalRef = false;
175    this->BaseIvarExp = 0;
176    this->TBAAInfo = TBAAInfo;
177  }
178
179public:
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 Quals.hasVolatile(); }
188  bool isRestrictQualified() const { return Quals.hasRestrict(); }
189  unsigned getVRQualifiers() const {
190    return Quals.getCVRQualifiers() & ~Qualifiers::Const;
191  }
192
193  bool isObjCIvar() const { return Ivar; }
194  void setObjCIvar(bool Value) { Ivar = Value; }
195
196  bool isObjCArray() const { return ObjIsArray; }
197  void setObjCArray(bool Value) { ObjIsArray = Value; }
198
199  bool isNonGC () const { return NonGC; }
200  void setNonGC(bool Value) { NonGC = Value; }
201
202  bool isGlobalObjCRef() const { return GlobalObjCRef; }
203  void setGlobalObjCRef(bool Value) { GlobalObjCRef = Value; }
204
205  bool isThreadLocalRef() const { return ThreadLocalRef; }
206  void setThreadLocalRef(bool Value) { ThreadLocalRef = Value;}
207
208  bool isObjCWeak() const {
209    return Quals.getObjCGCAttr() == Qualifiers::Weak;
210  }
211  bool isObjCStrong() const {
212    return Quals.getObjCGCAttr() == Qualifiers::Strong;
213  }
214
215  Expr *getBaseIvarExp() const { return BaseIvarExp; }
216  void setBaseIvarExp(Expr *V) { BaseIvarExp = V; }
217
218  llvm::MDNode *getTBAAInfo() const { return TBAAInfo; }
219  void setTBAAInfo(llvm::MDNode *N) { TBAAInfo = N; }
220
221  const Qualifiers &getQuals() const { return Quals; }
222  Qualifiers &getQuals() { return Quals; }
223
224  unsigned getAddressSpace() const { return Quals.getAddressSpace(); }
225
226  unsigned getAlignment() const { return Alignment; }
227
228  // simple lvalue
229  llvm::Value *getAddress() const { assert(isSimple()); return V; }
230
231  // vector elt lvalue
232  llvm::Value *getVectorAddr() const { assert(isVectorElt()); return V; }
233  llvm::Value *getVectorIdx() const { assert(isVectorElt()); return VectorIdx; }
234
235  // extended vector elements.
236  llvm::Value *getExtVectorAddr() const { assert(isExtVectorElt()); return V; }
237  llvm::Constant *getExtVectorElts() const {
238    assert(isExtVectorElt());
239    return VectorElts;
240  }
241
242  // bitfield lvalue
243  llvm::Value *getBitFieldBaseAddr() const {
244    assert(isBitField());
245    return V;
246  }
247  const CGBitFieldInfo &getBitFieldInfo() const {
248    assert(isBitField());
249    return *BitFieldInfo;
250  }
251
252  // property ref lvalue
253  const ObjCPropertyRefExpr *getPropertyRefExpr() const {
254    assert(isPropertyRef());
255    return PropertyRefExpr;
256  }
257
258  // 'implicit' property ref lvalue
259  const ObjCImplicitSetterGetterRefExpr *getKVCRefExpr() const {
260    assert(isKVCRef());
261    return KVCRefExpr;
262  }
263
264  static LValue MakeAddr(llvm::Value *V, QualType T, unsigned Alignment,
265                         ASTContext &Context,
266                         llvm::MDNode *TBAAInfo = 0) {
267    Qualifiers Quals = Context.getCanonicalType(T).getQualifiers();
268    Quals.setObjCGCAttr(Context.getObjCGCAttrKind(T));
269
270    LValue R;
271    R.LVType = Simple;
272    R.V = V;
273    R.Initialize(Quals, Alignment, TBAAInfo);
274    return R;
275  }
276
277  static LValue MakeVectorElt(llvm::Value *Vec, llvm::Value *Idx,
278                              unsigned CVR) {
279    LValue R;
280    R.LVType = VectorElt;
281    R.V = Vec;
282    R.VectorIdx = Idx;
283    R.Initialize(Qualifiers::fromCVRMask(CVR));
284    return R;
285  }
286
287  static LValue MakeExtVectorElt(llvm::Value *Vec, llvm::Constant *Elts,
288                                 unsigned CVR) {
289    LValue R;
290    R.LVType = ExtVectorElt;
291    R.V = Vec;
292    R.VectorElts = Elts;
293    R.Initialize(Qualifiers::fromCVRMask(CVR));
294    return R;
295  }
296
297  /// \brief Create a new object to represent a bit-field access.
298  ///
299  /// \param BaseValue - The base address of the structure containing the
300  /// bit-field.
301  /// \param Info - The information describing how to perform the bit-field
302  /// access.
303  static LValue MakeBitfield(llvm::Value *BaseValue, const CGBitFieldInfo &Info,
304                             unsigned CVR) {
305    LValue R;
306    R.LVType = BitField;
307    R.V = BaseValue;
308    R.BitFieldInfo = &Info;
309    R.Initialize(Qualifiers::fromCVRMask(CVR));
310    return R;
311  }
312
313  // FIXME: It is probably bad that we aren't emitting the target when we build
314  // the lvalue. However, this complicates the code a bit, and I haven't figured
315  // out how to make it go wrong yet.
316  static LValue MakePropertyRef(const ObjCPropertyRefExpr *E,
317                                unsigned CVR) {
318    LValue R;
319    R.LVType = PropertyRef;
320    R.PropertyRefExpr = E;
321    R.Initialize(Qualifiers::fromCVRMask(CVR));
322    return R;
323  }
324
325  static LValue MakeKVCRef(const ObjCImplicitSetterGetterRefExpr *E,
326                           unsigned CVR) {
327    LValue R;
328    R.LVType = KVCRef;
329    R.KVCRefExpr = E;
330    R.Initialize(Qualifiers::fromCVRMask(CVR));
331    return R;
332  }
333};
334
335/// An aggregate value slot.
336class AggValueSlot {
337  /// The address.
338  llvm::Value *Addr;
339  CXXConstructExpr *CtorExpr;
340
341  // Associated flags.
342  bool VolatileFlag : 1;
343  bool LifetimeFlag : 1;
344  bool RequiresGCollection : 1;
345
346public:
347  /// ignored - Returns an aggregate value slot indicating that the
348  /// aggregate value is being ignored.
349  static AggValueSlot ignored() {
350    AggValueSlot AV;
351    AV.Addr = 0;
352    AV.CtorExpr = 0;
353    AV.VolatileFlag = AV.LifetimeFlag = AV.RequiresGCollection = 0;
354    return AV;
355  }
356
357  /// forAddr - Make a slot for an aggregate value.
358  ///
359  /// \param Volatile - true if the slot should be volatile-initialized
360  /// \param LifetimeExternallyManaged - true if the slot's lifetime
361  ///   is being externally managed; false if a destructor should be
362  ///   registered for any temporaries evaluated into the slot
363  /// \param RequiresGCollection - true if the slot is located
364  ///   somewhere that ObjC GC calls should be emitted for
365  static AggValueSlot forAddr(llvm::Value *Addr, bool Volatile,
366                              bool LifetimeExternallyManaged,
367                              bool RequiresGCollection=false) {
368    AggValueSlot AV;
369    AV.Addr = Addr;
370    AV.CtorExpr = 0;
371    AV.VolatileFlag = Volatile;
372    AV.LifetimeFlag = LifetimeExternallyManaged;
373    AV.RequiresGCollection = RequiresGCollection;
374    return AV;
375  }
376
377  static AggValueSlot forLValue(LValue LV, bool LifetimeExternallyManaged,
378                                bool RequiresGCollection=false) {
379    return forAddr(LV.getAddress(), LV.isVolatileQualified(),
380                   LifetimeExternallyManaged, RequiresGCollection);
381  }
382
383  void setCtorExpr(CXXConstructExpr *E) { CtorExpr = E; }
384  CXXConstructExpr *getCtorExpr() const { return CtorExpr; }
385
386  bool isLifetimeExternallyManaged() const {
387    return LifetimeFlag;
388  }
389  void setLifetimeExternallyManaged() {
390    LifetimeFlag = true;
391  }
392
393  bool isVolatile() const {
394    return VolatileFlag;
395  }
396
397  bool requiresGCollection() const {
398    return RequiresGCollection;
399  }
400
401  llvm::Value *getAddr() const {
402    return Addr;
403  }
404
405  bool isIgnored() const {
406    return Addr == 0;
407  }
408
409  RValue asRValue() const {
410    return RValue::getAggregate(getAddr(), isVolatile());
411  }
412
413};
414
415}  // end namespace CodeGen
416}  // end namespace clang
417
418#endif
419