CGValue.h revision 226633
1234353Sdim//===-- CGValue.h - LLVM CodeGen wrappers for llvm::Value* ------*- C++ -*-===//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10224145Sdim// These classes implement wrappers around llvm::Value in order to
11193323Sed// fully represent the range of values for C L- and R- values.
12193323Sed//
13193323Sed//===----------------------------------------------------------------------===//
14193323Sed
15249423Sdim#ifndef CLANG_CODEGEN_CGVALUE_H
16218893Sdim#define CLANG_CODEGEN_CGVALUE_H
17249423Sdim
18249423Sdim#include "clang/AST/ASTContext.h"
19249423Sdim#include "clang/AST/Type.h"
20249423Sdim
21243830Sdimnamespace llvm {
22249423Sdim  class Constant;
23224145Sdim  class Value;
24224145Sdim}
25224145Sdim
26224145Sdimnamespace clang {
27224145Sdim  class ObjCPropertyRefExpr;
28193323Sed
29193323Sednamespace CodeGen {
30194710Sed  class CGBitFieldInfo;
31194710Sed
32194710Sed/// RValue - This trivial value class is used to represent the result of an
33194710Sed/// expression that is evaluated.  It can be one of three things: either a
34199989Srdivacky/// simple LLVM SSA value, a pair of SSA values for complex numbers, or the
35263508Sdim/// address of an aggregate value in memory.
36199989Srdivackyclass RValue {
37218893Sdim  enum Flavor { Scalar, Complex, Aggregate };
38243830Sdim
39243830Sdim  // Stores first value and flavor.
40243830Sdim  llvm::PointerIntPair<llvm::Value *, 2, Flavor> V1;
41263508Sdim  // Stores second value and volatility.
42263508Sdim  llvm::PointerIntPair<llvm::Value *, 1, bool> V2;
43263508Sdim
44263508Sdimpublic:
45263508Sdim  bool isScalar() const { return V1.getInt() == Scalar; }
46218893Sdim  bool isComplex() const { return V1.getInt() == Complex; }
47263508Sdim  bool isAggregate() const { return V1.getInt() == Aggregate; }
48263508Sdim
49263508Sdim  bool isVolatileQualified() const { return V2.getInt(); }
50263508Sdim
51263508Sdim  /// getScalarVal() - Return the Value* of this scalar value.
52263508Sdim  llvm::Value *getScalarVal() const {
53263508Sdim    assert(isScalar() && "Not a scalar!");
54263508Sdim    return V1.getPointer();
55263508Sdim  }
56263508Sdim
57263508Sdim  /// getComplexVal - Return the real/imag components of this complex value.
58263508Sdim  ///
59263508Sdim  std::pair<llvm::Value *, llvm::Value *> getComplexVal() const {
60263508Sdim    return std::make_pair(V1.getPointer(), V2.getPointer());
61263508Sdim  }
62263508Sdim
63263508Sdim  /// getAggregateAddr() - Return the Value* of the address of the aggregate.
64263508Sdim  llvm::Value *getAggregateAddr() const {
65263508Sdim    assert(isAggregate() && "Not an aggregate!");
66263508Sdim    return V1.getPointer();
67263508Sdim  }
68263508Sdim
69263508Sdim  static RValue get(llvm::Value *V) {
70263508Sdim    RValue ER;
71263508Sdim    ER.V1.setPointer(V);
72263508Sdim    ER.V1.setInt(Scalar);
73263508Sdim    ER.V2.setInt(false);
74263508Sdim    return ER;
75263508Sdim  }
76263508Sdim  static RValue getComplex(llvm::Value *V1, llvm::Value *V2) {
77224145Sdim    RValue ER;
78249423Sdim    ER.V1.setPointer(V1);
79224145Sdim    ER.V2.setPointer(V2);
80218893Sdim    ER.V1.setInt(Complex);
81263508Sdim    ER.V2.setInt(false);
82193323Sed    return ER;
83224145Sdim  }
84218893Sdim  static RValue getComplex(const std::pair<llvm::Value *, llvm::Value *> &C) {
85249423Sdim    return getComplex(C.first, C.second);
86193323Sed  }
87249423Sdim  // FIXME: Aggregate rvalues need to retain information about whether they are
88249423Sdim  // volatile or not.  Remove default to find all places that probably get this
89249423Sdim  // wrong.
90249423Sdim  static RValue getAggregate(llvm::Value *V, bool Volatile = false) {
91249423Sdim    RValue ER;
92249423Sdim    ER.V1.setPointer(V);
93249423Sdim    ER.V1.setInt(Aggregate);
94249423Sdim    ER.V2.setInt(Volatile);
95249423Sdim    return ER;
96263508Sdim  }
97249423Sdim};
98249423Sdim
99263508Sdim
100249423Sdim/// LValue - This represents an lvalue references.  Because C/C++ allow
101249423Sdim/// bitfields, this is not a simple LLVM pointer, it may be a pointer plus a
102249423Sdim/// bitrange.
103263508Sdimclass LValue {
104249423Sdim  enum {
105249423Sdim    Simple,       // This is a normal l-value, use getAddress().
106249423Sdim    VectorElt,    // This is a vector element l-value (V[i]), use getVector*
107249423Sdim    BitField,     // This is a bitfield l-value, use getBitfield*.
108249423Sdim    ExtVectorElt, // This is an extended vector subset, use getExtVectorComp
109249423Sdim    PropertyRef   // This is an Objective-C property reference, use
110249423Sdim                  // getPropertyRefExpr
111249423Sdim  } LVType;
112249423Sdim
113249423Sdim  llvm::Value *V;
114249423Sdim
115249423Sdim  union {
116249423Sdim    // Index into a vector subscript: V[i]
117249423Sdim    llvm::Value *VectorIdx;
118249423Sdim
119249423Sdim    // ExtVector element subset: V.xyx
120249423Sdim    llvm::Constant *VectorElts;
121249423Sdim
122249423Sdim    // BitField start bit and size
123249423Sdim    const CGBitFieldInfo *BitFieldInfo;
124249423Sdim
125249423Sdim    // Obj-C property reference expression
126249423Sdim    const ObjCPropertyRefExpr *PropertyRefExpr;
127249423Sdim  };
128263508Sdim
129249423Sdim  QualType Type;
130263508Sdim
131251662Sdim  // 'const' is unused here
132263508Sdim  Qualifiers Quals;
133263508Sdim
134249423Sdim  /// The alignment to use when accessing this lvalue.
135249423Sdim  unsigned short Alignment;
136249423Sdim
137249423Sdim  // objective-c's ivar
138249423Sdim  bool Ivar:1;
139249423Sdim
140249423Sdim  // objective-c's ivar is an array
141249423Sdim  bool ObjIsArray:1;
142249423Sdim
143249423Sdim  // LValue is non-gc'able for any reason, including being a parameter or local
144249423Sdim  // variable.
145249423Sdim  bool NonGC: 1;
146249423Sdim
147249423Sdim  // Lvalue is a global reference of an objective-c object
148249423Sdim  bool GlobalObjCRef : 1;
149249423Sdim
150249423Sdim  // Lvalue is a thread local reference
151249423Sdim  bool ThreadLocalRef : 1;
152249423Sdim
153249423Sdim  Expr *BaseIvarExp;
154249423Sdim
155249423Sdim  /// TBAAInfo - TBAA information to attach to dereferences of this LValue.
156249423Sdim  llvm::MDNode *TBAAInfo;
157263508Sdim
158263508Sdimprivate:
159263508Sdim  void Initialize(QualType Type, Qualifiers Quals, unsigned Alignment = 0,
160263508Sdim                  llvm::MDNode *TBAAInfo = 0) {
161263508Sdim    this->Type = Type;
162263508Sdim    this->Quals = Quals;
163263508Sdim    this->Alignment = Alignment;
164193323Sed    assert(this->Alignment == Alignment && "Alignment exceeds allowed max!");
165224145Sdim
166224145Sdim    // Initialize Objective-C flags.
167224145Sdim    this->Ivar = this->ObjIsArray = this->NonGC = this->GlobalObjCRef = false;
168249423Sdim    this->ThreadLocalRef = false;
169249423Sdim    this->BaseIvarExp = 0;
170224145Sdim    this->TBAAInfo = TBAAInfo;
171224145Sdim  }
172249423Sdim
173224145Sdimpublic:
174224145Sdim  bool isSimple() const { return LVType == Simple; }
175218893Sdim  bool isVectorElt() const { return LVType == VectorElt; }
176224145Sdim  bool isBitField() const { return LVType == BitField; }
177204961Srdivacky  bool isExtVectorElt() const { return LVType == ExtVectorElt; }
178224145Sdim  bool isPropertyRef() const { return LVType == PropertyRef; }
179224145Sdim
180224145Sdim  bool isVolatileQualified() const { return Quals.hasVolatile(); }
181263508Sdim  bool isRestrictQualified() const { return Quals.hasRestrict(); }
182193323Sed  unsigned getVRQualifiers() const {
183239462Sdim    return Quals.getCVRQualifiers() & ~Qualifiers::Const;
184239462Sdim  }
185239462Sdim
186224145Sdim  QualType getType() const { return Type; }
187224145Sdim
188193323Sed  Qualifiers::ObjCLifetime getObjCLifetime() const {
189249423Sdim    return Quals.getObjCLifetime();
190249423Sdim  }
191234353Sdim
192234353Sdim  bool isObjCIvar() const { return Ivar; }
193224145Sdim  void setObjCIvar(bool Value) { Ivar = Value; }
194198090Srdivacky
195193323Sed  bool isObjCArray() const { return ObjIsArray; }
196193323Sed  void setObjCArray(bool Value) { ObjIsArray = Value; }
197193323Sed
198263508Sdim  bool isNonGC () const { return NonGC; }
199263508Sdim  void setNonGC(bool Value) { NonGC = Value; }
200263508Sdim
201263508Sdim  bool isGlobalObjCRef() const { return GlobalObjCRef; }
202263508Sdim  void setGlobalObjCRef(bool Value) { GlobalObjCRef = Value; }
203224145Sdim
204234353Sdim  bool isThreadLocalRef() const { return ThreadLocalRef; }
205218893Sdim  void setThreadLocalRef(bool Value) { ThreadLocalRef = Value;}
206198090Srdivacky
207198396Srdivacky  bool isObjCWeak() const {
208198396Srdivacky    return Quals.getObjCGCAttr() == Qualifiers::Weak;
209218893Sdim  }
210263508Sdim  bool isObjCStrong() const {
211263508Sdim    return Quals.getObjCGCAttr() == Qualifiers::Strong;
212263508Sdim  }
213263508Sdim
214263508Sdim  bool isVolatile() const {
215263508Sdim    return Quals.hasVolatile();
216263508Sdim  }
217263508Sdim
218263508Sdim  Expr *getBaseIvarExp() const { return BaseIvarExp; }
219263508Sdim  void setBaseIvarExp(Expr *V) { BaseIvarExp = V; }
220263508Sdim
221263508Sdim  llvm::MDNode *getTBAAInfo() const { return TBAAInfo; }
222263508Sdim  void setTBAAInfo(llvm::MDNode *N) { TBAAInfo = N; }
223263508Sdim
224263508Sdim  const Qualifiers &getQuals() const { return Quals; }
225263508Sdim  Qualifiers &getQuals() { return Quals; }
226263508Sdim
227263508Sdim  unsigned getAddressSpace() const { return Quals.getAddressSpace(); }
228263508Sdim
229263508Sdim  unsigned getAlignment() const { return Alignment; }
230263508Sdim
231263508Sdim  // simple lvalue
232263508Sdim  llvm::Value *getAddress() const { assert(isSimple()); return V; }
233263508Sdim  void setAddress(llvm::Value *address) {
234263508Sdim    assert(isSimple());
235263508Sdim    V = address;
236249423Sdim  }
237263508Sdim
238263508Sdim  // vector elt lvalue
239263508Sdim  llvm::Value *getVectorAddr() const { assert(isVectorElt()); return V; }
240263508Sdim  llvm::Value *getVectorIdx() const { assert(isVectorElt()); return VectorIdx; }
241263508Sdim
242263508Sdim  // extended vector elements.
243263508Sdim  llvm::Value *getExtVectorAddr() const { assert(isExtVectorElt()); return V; }
244263508Sdim  llvm::Constant *getExtVectorElts() const {
245263508Sdim    assert(isExtVectorElt());
246263508Sdim    return VectorElts;
247263508Sdim  }
248263508Sdim
249249423Sdim  // bitfield lvalue
250249423Sdim  llvm::Value *getBitFieldBaseAddr() const {
251249423Sdim    assert(isBitField());
252249423Sdim    return V;
253249423Sdim  }
254193323Sed  const CGBitFieldInfo &getBitFieldInfo() const {
255198090Srdivacky    assert(isBitField());
256198090Srdivacky    return *BitFieldInfo;
257198090Srdivacky  }
258207618Srdivacky
259207618Srdivacky  // property ref lvalue
260198090Srdivacky  llvm::Value *getPropertyRefBaseAddr() const {
261198090Srdivacky    assert(isPropertyRef());
262198090Srdivacky    return V;
263203954Srdivacky  }
264203954Srdivacky  const ObjCPropertyRefExpr *getPropertyRefExpr() const {
265219077Sdim    assert(isPropertyRef());
266219077Sdim    return PropertyRefExpr;
267219077Sdim  }
268198090Srdivacky
269198090Srdivacky  static LValue MakeAddr(llvm::Value *address, QualType type,
270198090Srdivacky                         unsigned alignment, ASTContext &Context,
271198090Srdivacky                         llvm::MDNode *TBAAInfo = 0) {
272198090Srdivacky    Qualifiers qs = type.getQualifiers();
273198090Srdivacky    qs.setObjCGCAttr(Context.getObjCGCAttrKind(type));
274198090Srdivacky
275198090Srdivacky    LValue R;
276198090Srdivacky    R.LVType = Simple;
277198090Srdivacky    R.V = address;
278198090Srdivacky    R.Initialize(type, qs, alignment, TBAAInfo);
279198090Srdivacky    return R;
280198090Srdivacky  }
281198090Srdivacky
282198090Srdivacky  static LValue MakeVectorElt(llvm::Value *Vec, llvm::Value *Idx,
283198090Srdivacky                              QualType type) {
284198090Srdivacky    LValue R;
285198090Srdivacky    R.LVType = VectorElt;
286198090Srdivacky    R.V = Vec;
287198090Srdivacky    R.VectorIdx = Idx;
288198090Srdivacky    R.Initialize(type, type.getQualifiers());
289198090Srdivacky    return R;
290198090Srdivacky  }
291198090Srdivacky
292198090Srdivacky  static LValue MakeExtVectorElt(llvm::Value *Vec, llvm::Constant *Elts,
293198090Srdivacky                                 QualType type) {
294198090Srdivacky    LValue R;
295198090Srdivacky    R.LVType = ExtVectorElt;
296198090Srdivacky    R.V = Vec;
297198090Srdivacky    R.VectorElts = Elts;
298218893Sdim    R.Initialize(type, type.getQualifiers());
299198090Srdivacky    return R;
300198090Srdivacky  }
301198090Srdivacky
302198090Srdivacky  /// \brief Create a new object to represent a bit-field access.
303198090Srdivacky  ///
304198090Srdivacky  /// \param BaseValue - The base address of the structure containing the
305198090Srdivacky  /// bit-field.
306198090Srdivacky  /// \param Info - The information describing how to perform the bit-field
307198090Srdivacky  /// access.
308199481Srdivacky  static LValue MakeBitfield(llvm::Value *BaseValue,
309218893Sdim                             const CGBitFieldInfo &Info,
310239462Sdim                             QualType type) {
311218893Sdim    LValue R;
312218893Sdim    R.LVType = BitField;
313263508Sdim    R.V = BaseValue;
314263508Sdim    R.BitFieldInfo = &Info;
315263508Sdim    R.Initialize(type, type.getQualifiers());
316263508Sdim    return R;
317263508Sdim  }
318199481Srdivacky
319199481Srdivacky  // FIXME: It is probably bad that we aren't emitting the target when we build
320224145Sdim  // the lvalue. However, this complicates the code a bit, and I haven't figured
321199481Srdivacky  // out how to make it go wrong yet.
322263508Sdim  static LValue MakePropertyRef(const ObjCPropertyRefExpr *E,
323199481Srdivacky                                llvm::Value *Base) {
324199481Srdivacky    LValue R;
325    R.LVType = PropertyRef;
326    R.V = Base;
327    R.PropertyRefExpr = E;
328    R.Initialize(QualType(), Qualifiers());
329    return R;
330  }
331};
332
333/// An aggregate value slot.
334class AggValueSlot {
335  /// The address.
336  llvm::Value *Addr;
337
338  // Qualifiers
339  Qualifiers Quals;
340
341  /// DestructedFlag - This is set to true if some external code is
342  /// responsible for setting up a destructor for the slot.  Otherwise
343  /// the code which constructs it should push the appropriate cleanup.
344  bool DestructedFlag : 1;
345
346  /// ObjCGCFlag - This is set to true if writing to the memory in the
347  /// slot might require calling an appropriate Objective-C GC
348  /// barrier.  The exact interaction here is unnecessarily mysterious.
349  bool ObjCGCFlag : 1;
350
351  /// ZeroedFlag - This is set to true if the memory in the slot is
352  /// known to be zero before the assignment into it.  This means that
353  /// zero fields don't need to be set.
354  bool ZeroedFlag : 1;
355
356  /// AliasedFlag - This is set to true if the slot might be aliased
357  /// and it's not undefined behavior to access it through such an
358  /// alias.  Note that it's always undefined behavior to access a C++
359  /// object that's under construction through an alias derived from
360  /// outside the construction process.
361  ///
362  /// This flag controls whether calls that produce the aggregate
363  /// value may be evaluated directly into the slot, or whether they
364  /// must be evaluated into an unaliased temporary and then memcpy'ed
365  /// over.  Since it's invalid in general to memcpy a non-POD C++
366  /// object, it's important that this flag never be set when
367  /// evaluating an expression which constructs such an object.
368  bool AliasedFlag : 1;
369
370public:
371  enum IsAliased_t { IsNotAliased, IsAliased };
372  enum IsDestructed_t { IsNotDestructed, IsDestructed };
373  enum IsZeroed_t { IsNotZeroed, IsZeroed };
374  enum NeedsGCBarriers_t { DoesNotNeedGCBarriers, NeedsGCBarriers };
375
376  /// ignored - Returns an aggregate value slot indicating that the
377  /// aggregate value is being ignored.
378  static AggValueSlot ignored() {
379    AggValueSlot AV;
380    AV.Addr = 0;
381    AV.Quals = Qualifiers();
382    AV.DestructedFlag = AV.ObjCGCFlag = AV.ZeroedFlag = AV.AliasedFlag = false;
383    return AV;
384  }
385
386  /// forAddr - Make a slot for an aggregate value.
387  ///
388  /// \param quals - The qualifiers that dictate how the slot should
389  /// be initialied. Only 'volatile' and the Objective-C lifetime
390  /// qualifiers matter.
391  ///
392  /// \param isDestructed - true if something else is responsible
393  ///   for calling destructors on this object
394  /// \param needsGC - true if the slot is potentially located
395  ///   somewhere that ObjC GC calls should be emitted for
396  static AggValueSlot forAddr(llvm::Value *addr, Qualifiers quals,
397                              IsDestructed_t isDestructed,
398                              NeedsGCBarriers_t needsGC,
399                              IsAliased_t isAliased,
400                              IsZeroed_t isZeroed = IsNotZeroed) {
401    AggValueSlot AV;
402    AV.Addr = addr;
403    AV.Quals = quals;
404    AV.DestructedFlag = isDestructed;
405    AV.ObjCGCFlag = needsGC;
406    AV.ZeroedFlag = isZeroed;
407    AV.AliasedFlag = isAliased;
408    return AV;
409  }
410
411  static AggValueSlot forLValue(LValue LV, IsDestructed_t isDestructed,
412                                NeedsGCBarriers_t needsGC,
413                                IsAliased_t isAliased,
414                                IsZeroed_t isZeroed = IsNotZeroed) {
415    return forAddr(LV.getAddress(), LV.getQuals(),
416                   isDestructed, needsGC, isAliased, isZeroed);
417  }
418
419  IsDestructed_t isExternallyDestructed() const {
420    return IsDestructed_t(DestructedFlag);
421  }
422  void setExternallyDestructed(bool destructed = true) {
423    DestructedFlag = destructed;
424  }
425
426  Qualifiers getQualifiers() const { return Quals; }
427
428  bool isVolatile() const {
429    return Quals.hasVolatile();
430  }
431
432  Qualifiers::ObjCLifetime getObjCLifetime() const {
433    return Quals.getObjCLifetime();
434  }
435
436  NeedsGCBarriers_t requiresGCollection() const {
437    return NeedsGCBarriers_t(ObjCGCFlag);
438  }
439
440  llvm::Value *getAddr() const {
441    return Addr;
442  }
443
444  bool isIgnored() const {
445    return Addr == 0;
446  }
447
448  IsAliased_t isPotentiallyAliased() const {
449    return IsAliased_t(AliasedFlag);
450  }
451
452  RValue asRValue() const {
453    return RValue::getAggregate(getAddr(), isVolatile());
454  }
455
456  void setZeroed(bool V = true) { ZeroedFlag = V; }
457  IsZeroed_t isZeroed() const {
458    return IsZeroed_t(ZeroedFlag);
459  }
460};
461
462}  // end namespace CodeGen
463}  // end namespace clang
464
465#endif
466