xref: /minix3/external/bsd/llvm/dist/clang/lib/CodeGen/CGValue.h (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
1*f4a2713aSLionel Sambuc //===-- CGValue.h - LLVM CodeGen wrappers for llvm::Value* ------*- C++ -*-===//
2*f4a2713aSLionel Sambuc //
3*f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4*f4a2713aSLionel Sambuc //
5*f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6*f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7*f4a2713aSLionel Sambuc //
8*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9*f4a2713aSLionel Sambuc //
10*f4a2713aSLionel Sambuc // These classes implement wrappers around llvm::Value in order to
11*f4a2713aSLionel Sambuc // fully represent the range of values for C L- and R- values.
12*f4a2713aSLionel Sambuc //
13*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
14*f4a2713aSLionel Sambuc 
15*f4a2713aSLionel Sambuc #ifndef CLANG_CODEGEN_CGVALUE_H
16*f4a2713aSLionel Sambuc #define CLANG_CODEGEN_CGVALUE_H
17*f4a2713aSLionel Sambuc 
18*f4a2713aSLionel Sambuc #include "clang/AST/ASTContext.h"
19*f4a2713aSLionel Sambuc #include "clang/AST/CharUnits.h"
20*f4a2713aSLionel Sambuc #include "clang/AST/Type.h"
21*f4a2713aSLionel Sambuc #include "llvm/IR/Value.h"
22*f4a2713aSLionel Sambuc 
23*f4a2713aSLionel Sambuc namespace llvm {
24*f4a2713aSLionel Sambuc   class Constant;
25*f4a2713aSLionel Sambuc   class MDNode;
26*f4a2713aSLionel Sambuc }
27*f4a2713aSLionel Sambuc 
28*f4a2713aSLionel Sambuc namespace clang {
29*f4a2713aSLionel Sambuc namespace CodeGen {
30*f4a2713aSLionel Sambuc   class AggValueSlot;
31*f4a2713aSLionel Sambuc   struct CGBitFieldInfo;
32*f4a2713aSLionel Sambuc 
33*f4a2713aSLionel Sambuc /// RValue - This trivial value class is used to represent the result of an
34*f4a2713aSLionel Sambuc /// expression that is evaluated.  It can be one of three things: either a
35*f4a2713aSLionel Sambuc /// simple LLVM SSA value, a pair of SSA values for complex numbers, or the
36*f4a2713aSLionel Sambuc /// address of an aggregate value in memory.
37*f4a2713aSLionel Sambuc class RValue {
38*f4a2713aSLionel Sambuc   enum Flavor { Scalar, Complex, Aggregate };
39*f4a2713aSLionel Sambuc 
40*f4a2713aSLionel Sambuc   // Stores first value and flavor.
41*f4a2713aSLionel Sambuc   llvm::PointerIntPair<llvm::Value *, 2, Flavor> V1;
42*f4a2713aSLionel Sambuc   // Stores second value and volatility.
43*f4a2713aSLionel Sambuc   llvm::PointerIntPair<llvm::Value *, 1, bool> V2;
44*f4a2713aSLionel Sambuc 
45*f4a2713aSLionel Sambuc public:
46*f4a2713aSLionel Sambuc   bool isScalar() const { return V1.getInt() == Scalar; }
47*f4a2713aSLionel Sambuc   bool isComplex() const { return V1.getInt() == Complex; }
48*f4a2713aSLionel Sambuc   bool isAggregate() const { return V1.getInt() == Aggregate; }
49*f4a2713aSLionel Sambuc 
50*f4a2713aSLionel Sambuc   bool isVolatileQualified() const { return V2.getInt(); }
51*f4a2713aSLionel Sambuc 
52*f4a2713aSLionel Sambuc   /// getScalarVal() - Return the Value* of this scalar value.
53*f4a2713aSLionel Sambuc   llvm::Value *getScalarVal() const {
54*f4a2713aSLionel Sambuc     assert(isScalar() && "Not a scalar!");
55*f4a2713aSLionel Sambuc     return V1.getPointer();
56*f4a2713aSLionel Sambuc   }
57*f4a2713aSLionel Sambuc 
58*f4a2713aSLionel Sambuc   /// getComplexVal - Return the real/imag components of this complex value.
59*f4a2713aSLionel Sambuc   ///
60*f4a2713aSLionel Sambuc   std::pair<llvm::Value *, llvm::Value *> getComplexVal() const {
61*f4a2713aSLionel Sambuc     return std::make_pair(V1.getPointer(), V2.getPointer());
62*f4a2713aSLionel Sambuc   }
63*f4a2713aSLionel Sambuc 
64*f4a2713aSLionel Sambuc   /// getAggregateAddr() - Return the Value* of the address of the aggregate.
65*f4a2713aSLionel Sambuc   llvm::Value *getAggregateAddr() const {
66*f4a2713aSLionel Sambuc     assert(isAggregate() && "Not an aggregate!");
67*f4a2713aSLionel Sambuc     return V1.getPointer();
68*f4a2713aSLionel Sambuc   }
69*f4a2713aSLionel Sambuc 
70*f4a2713aSLionel Sambuc   static RValue get(llvm::Value *V) {
71*f4a2713aSLionel Sambuc     RValue ER;
72*f4a2713aSLionel Sambuc     ER.V1.setPointer(V);
73*f4a2713aSLionel Sambuc     ER.V1.setInt(Scalar);
74*f4a2713aSLionel Sambuc     ER.V2.setInt(false);
75*f4a2713aSLionel Sambuc     return ER;
76*f4a2713aSLionel Sambuc   }
77*f4a2713aSLionel Sambuc   static RValue getComplex(llvm::Value *V1, llvm::Value *V2) {
78*f4a2713aSLionel Sambuc     RValue ER;
79*f4a2713aSLionel Sambuc     ER.V1.setPointer(V1);
80*f4a2713aSLionel Sambuc     ER.V2.setPointer(V2);
81*f4a2713aSLionel Sambuc     ER.V1.setInt(Complex);
82*f4a2713aSLionel Sambuc     ER.V2.setInt(false);
83*f4a2713aSLionel Sambuc     return ER;
84*f4a2713aSLionel Sambuc   }
85*f4a2713aSLionel Sambuc   static RValue getComplex(const std::pair<llvm::Value *, llvm::Value *> &C) {
86*f4a2713aSLionel Sambuc     return getComplex(C.first, C.second);
87*f4a2713aSLionel Sambuc   }
88*f4a2713aSLionel Sambuc   // FIXME: Aggregate rvalues need to retain information about whether they are
89*f4a2713aSLionel Sambuc   // volatile or not.  Remove default to find all places that probably get this
90*f4a2713aSLionel Sambuc   // wrong.
91*f4a2713aSLionel Sambuc   static RValue getAggregate(llvm::Value *V, bool Volatile = false) {
92*f4a2713aSLionel Sambuc     RValue ER;
93*f4a2713aSLionel Sambuc     ER.V1.setPointer(V);
94*f4a2713aSLionel Sambuc     ER.V1.setInt(Aggregate);
95*f4a2713aSLionel Sambuc     ER.V2.setInt(Volatile);
96*f4a2713aSLionel Sambuc     return ER;
97*f4a2713aSLionel Sambuc   }
98*f4a2713aSLionel Sambuc };
99*f4a2713aSLionel Sambuc 
100*f4a2713aSLionel Sambuc /// Does an ARC strong l-value have precise lifetime?
101*f4a2713aSLionel Sambuc enum ARCPreciseLifetime_t {
102*f4a2713aSLionel Sambuc   ARCImpreciseLifetime, ARCPreciseLifetime
103*f4a2713aSLionel Sambuc };
104*f4a2713aSLionel Sambuc 
105*f4a2713aSLionel Sambuc /// LValue - This represents an lvalue references.  Because C/C++ allow
106*f4a2713aSLionel Sambuc /// bitfields, this is not a simple LLVM pointer, it may be a pointer plus a
107*f4a2713aSLionel Sambuc /// bitrange.
108*f4a2713aSLionel Sambuc class LValue {
109*f4a2713aSLionel Sambuc   enum {
110*f4a2713aSLionel Sambuc     Simple,       // This is a normal l-value, use getAddress().
111*f4a2713aSLionel Sambuc     VectorElt,    // This is a vector element l-value (V[i]), use getVector*
112*f4a2713aSLionel Sambuc     BitField,     // This is a bitfield l-value, use getBitfield*.
113*f4a2713aSLionel Sambuc     ExtVectorElt  // This is an extended vector subset, use getExtVectorComp
114*f4a2713aSLionel Sambuc   } LVType;
115*f4a2713aSLionel Sambuc 
116*f4a2713aSLionel Sambuc   llvm::Value *V;
117*f4a2713aSLionel Sambuc 
118*f4a2713aSLionel Sambuc   union {
119*f4a2713aSLionel Sambuc     // Index into a vector subscript: V[i]
120*f4a2713aSLionel Sambuc     llvm::Value *VectorIdx;
121*f4a2713aSLionel Sambuc 
122*f4a2713aSLionel Sambuc     // ExtVector element subset: V.xyx
123*f4a2713aSLionel Sambuc     llvm::Constant *VectorElts;
124*f4a2713aSLionel Sambuc 
125*f4a2713aSLionel Sambuc     // BitField start bit and size
126*f4a2713aSLionel Sambuc     const CGBitFieldInfo *BitFieldInfo;
127*f4a2713aSLionel Sambuc   };
128*f4a2713aSLionel Sambuc 
129*f4a2713aSLionel Sambuc   QualType Type;
130*f4a2713aSLionel Sambuc 
131*f4a2713aSLionel Sambuc   // 'const' is unused here
132*f4a2713aSLionel Sambuc   Qualifiers Quals;
133*f4a2713aSLionel Sambuc 
134*f4a2713aSLionel Sambuc   // The alignment to use when accessing this lvalue.  (For vector elements,
135*f4a2713aSLionel Sambuc   // this is the alignment of the whole vector.)
136*f4a2713aSLionel Sambuc   int64_t Alignment;
137*f4a2713aSLionel Sambuc 
138*f4a2713aSLionel Sambuc   // objective-c's ivar
139*f4a2713aSLionel Sambuc   bool Ivar:1;
140*f4a2713aSLionel Sambuc 
141*f4a2713aSLionel Sambuc   // objective-c's ivar is an array
142*f4a2713aSLionel Sambuc   bool ObjIsArray:1;
143*f4a2713aSLionel Sambuc 
144*f4a2713aSLionel Sambuc   // LValue is non-gc'able for any reason, including being a parameter or local
145*f4a2713aSLionel Sambuc   // variable.
146*f4a2713aSLionel Sambuc   bool NonGC: 1;
147*f4a2713aSLionel Sambuc 
148*f4a2713aSLionel Sambuc   // Lvalue is a global reference of an objective-c object
149*f4a2713aSLionel Sambuc   bool GlobalObjCRef : 1;
150*f4a2713aSLionel Sambuc 
151*f4a2713aSLionel Sambuc   // Lvalue is a thread local reference
152*f4a2713aSLionel Sambuc   bool ThreadLocalRef : 1;
153*f4a2713aSLionel Sambuc 
154*f4a2713aSLionel Sambuc   // Lvalue has ARC imprecise lifetime.  We store this inverted to try
155*f4a2713aSLionel Sambuc   // to make the default bitfield pattern all-zeroes.
156*f4a2713aSLionel Sambuc   bool ImpreciseLifetime : 1;
157*f4a2713aSLionel Sambuc 
158*f4a2713aSLionel Sambuc   Expr *BaseIvarExp;
159*f4a2713aSLionel Sambuc 
160*f4a2713aSLionel Sambuc   /// Used by struct-path-aware TBAA.
161*f4a2713aSLionel Sambuc   QualType TBAABaseType;
162*f4a2713aSLionel Sambuc   /// Offset relative to the base type.
163*f4a2713aSLionel Sambuc   uint64_t TBAAOffset;
164*f4a2713aSLionel Sambuc 
165*f4a2713aSLionel Sambuc   /// TBAAInfo - TBAA information to attach to dereferences of this LValue.
166*f4a2713aSLionel Sambuc   llvm::MDNode *TBAAInfo;
167*f4a2713aSLionel Sambuc 
168*f4a2713aSLionel Sambuc private:
169*f4a2713aSLionel Sambuc   void Initialize(QualType Type, Qualifiers Quals,
170*f4a2713aSLionel Sambuc                   CharUnits Alignment,
171*f4a2713aSLionel Sambuc                   llvm::MDNode *TBAAInfo = 0) {
172*f4a2713aSLionel Sambuc     this->Type = Type;
173*f4a2713aSLionel Sambuc     this->Quals = Quals;
174*f4a2713aSLionel Sambuc     this->Alignment = Alignment.getQuantity();
175*f4a2713aSLionel Sambuc     assert(this->Alignment == Alignment.getQuantity() &&
176*f4a2713aSLionel Sambuc            "Alignment exceeds allowed max!");
177*f4a2713aSLionel Sambuc 
178*f4a2713aSLionel Sambuc     // Initialize Objective-C flags.
179*f4a2713aSLionel Sambuc     this->Ivar = this->ObjIsArray = this->NonGC = this->GlobalObjCRef = false;
180*f4a2713aSLionel Sambuc     this->ImpreciseLifetime = false;
181*f4a2713aSLionel Sambuc     this->ThreadLocalRef = false;
182*f4a2713aSLionel Sambuc     this->BaseIvarExp = 0;
183*f4a2713aSLionel Sambuc 
184*f4a2713aSLionel Sambuc     // Initialize fields for TBAA.
185*f4a2713aSLionel Sambuc     this->TBAABaseType = Type;
186*f4a2713aSLionel Sambuc     this->TBAAOffset = 0;
187*f4a2713aSLionel Sambuc     this->TBAAInfo = TBAAInfo;
188*f4a2713aSLionel Sambuc   }
189*f4a2713aSLionel Sambuc 
190*f4a2713aSLionel Sambuc public:
191*f4a2713aSLionel Sambuc   bool isSimple() const { return LVType == Simple; }
192*f4a2713aSLionel Sambuc   bool isVectorElt() const { return LVType == VectorElt; }
193*f4a2713aSLionel Sambuc   bool isBitField() const { return LVType == BitField; }
194*f4a2713aSLionel Sambuc   bool isExtVectorElt() const { return LVType == ExtVectorElt; }
195*f4a2713aSLionel Sambuc 
196*f4a2713aSLionel Sambuc   bool isVolatileQualified() const { return Quals.hasVolatile(); }
197*f4a2713aSLionel Sambuc   bool isRestrictQualified() const { return Quals.hasRestrict(); }
198*f4a2713aSLionel Sambuc   unsigned getVRQualifiers() const {
199*f4a2713aSLionel Sambuc     return Quals.getCVRQualifiers() & ~Qualifiers::Const;
200*f4a2713aSLionel Sambuc   }
201*f4a2713aSLionel Sambuc 
202*f4a2713aSLionel Sambuc   QualType getType() const { return Type; }
203*f4a2713aSLionel Sambuc 
204*f4a2713aSLionel Sambuc   Qualifiers::ObjCLifetime getObjCLifetime() const {
205*f4a2713aSLionel Sambuc     return Quals.getObjCLifetime();
206*f4a2713aSLionel Sambuc   }
207*f4a2713aSLionel Sambuc 
208*f4a2713aSLionel Sambuc   bool isObjCIvar() const { return Ivar; }
209*f4a2713aSLionel Sambuc   void setObjCIvar(bool Value) { Ivar = Value; }
210*f4a2713aSLionel Sambuc 
211*f4a2713aSLionel Sambuc   bool isObjCArray() const { return ObjIsArray; }
212*f4a2713aSLionel Sambuc   void setObjCArray(bool Value) { ObjIsArray = Value; }
213*f4a2713aSLionel Sambuc 
214*f4a2713aSLionel Sambuc   bool isNonGC () const { return NonGC; }
215*f4a2713aSLionel Sambuc   void setNonGC(bool Value) { NonGC = Value; }
216*f4a2713aSLionel Sambuc 
217*f4a2713aSLionel Sambuc   bool isGlobalObjCRef() const { return GlobalObjCRef; }
218*f4a2713aSLionel Sambuc   void setGlobalObjCRef(bool Value) { GlobalObjCRef = Value; }
219*f4a2713aSLionel Sambuc 
220*f4a2713aSLionel Sambuc   bool isThreadLocalRef() const { return ThreadLocalRef; }
221*f4a2713aSLionel Sambuc   void setThreadLocalRef(bool Value) { ThreadLocalRef = Value;}
222*f4a2713aSLionel Sambuc 
223*f4a2713aSLionel Sambuc   ARCPreciseLifetime_t isARCPreciseLifetime() const {
224*f4a2713aSLionel Sambuc     return ARCPreciseLifetime_t(!ImpreciseLifetime);
225*f4a2713aSLionel Sambuc   }
226*f4a2713aSLionel Sambuc   void setARCPreciseLifetime(ARCPreciseLifetime_t value) {
227*f4a2713aSLionel Sambuc     ImpreciseLifetime = (value == ARCImpreciseLifetime);
228*f4a2713aSLionel Sambuc   }
229*f4a2713aSLionel Sambuc 
230*f4a2713aSLionel Sambuc   bool isObjCWeak() const {
231*f4a2713aSLionel Sambuc     return Quals.getObjCGCAttr() == Qualifiers::Weak;
232*f4a2713aSLionel Sambuc   }
233*f4a2713aSLionel Sambuc   bool isObjCStrong() const {
234*f4a2713aSLionel Sambuc     return Quals.getObjCGCAttr() == Qualifiers::Strong;
235*f4a2713aSLionel Sambuc   }
236*f4a2713aSLionel Sambuc 
237*f4a2713aSLionel Sambuc   bool isVolatile() const {
238*f4a2713aSLionel Sambuc     return Quals.hasVolatile();
239*f4a2713aSLionel Sambuc   }
240*f4a2713aSLionel Sambuc 
241*f4a2713aSLionel Sambuc   Expr *getBaseIvarExp() const { return BaseIvarExp; }
242*f4a2713aSLionel Sambuc   void setBaseIvarExp(Expr *V) { BaseIvarExp = V; }
243*f4a2713aSLionel Sambuc 
244*f4a2713aSLionel Sambuc   QualType getTBAABaseType() const { return TBAABaseType; }
245*f4a2713aSLionel Sambuc   void setTBAABaseType(QualType T) { TBAABaseType = T; }
246*f4a2713aSLionel Sambuc 
247*f4a2713aSLionel Sambuc   uint64_t getTBAAOffset() const { return TBAAOffset; }
248*f4a2713aSLionel Sambuc   void setTBAAOffset(uint64_t O) { TBAAOffset = O; }
249*f4a2713aSLionel Sambuc 
250*f4a2713aSLionel Sambuc   llvm::MDNode *getTBAAInfo() const { return TBAAInfo; }
251*f4a2713aSLionel Sambuc   void setTBAAInfo(llvm::MDNode *N) { TBAAInfo = N; }
252*f4a2713aSLionel Sambuc 
253*f4a2713aSLionel Sambuc   const Qualifiers &getQuals() const { return Quals; }
254*f4a2713aSLionel Sambuc   Qualifiers &getQuals() { return Quals; }
255*f4a2713aSLionel Sambuc 
256*f4a2713aSLionel Sambuc   unsigned getAddressSpace() const { return Quals.getAddressSpace(); }
257*f4a2713aSLionel Sambuc 
258*f4a2713aSLionel Sambuc   CharUnits getAlignment() const { return CharUnits::fromQuantity(Alignment); }
259*f4a2713aSLionel Sambuc   void setAlignment(CharUnits A) { Alignment = A.getQuantity(); }
260*f4a2713aSLionel Sambuc 
261*f4a2713aSLionel Sambuc   // simple lvalue
262*f4a2713aSLionel Sambuc   llvm::Value *getAddress() const { assert(isSimple()); return V; }
263*f4a2713aSLionel Sambuc   void setAddress(llvm::Value *address) {
264*f4a2713aSLionel Sambuc     assert(isSimple());
265*f4a2713aSLionel Sambuc     V = address;
266*f4a2713aSLionel Sambuc   }
267*f4a2713aSLionel Sambuc 
268*f4a2713aSLionel Sambuc   // vector elt lvalue
269*f4a2713aSLionel Sambuc   llvm::Value *getVectorAddr() const { assert(isVectorElt()); return V; }
270*f4a2713aSLionel Sambuc   llvm::Value *getVectorIdx() const { assert(isVectorElt()); return VectorIdx; }
271*f4a2713aSLionel Sambuc 
272*f4a2713aSLionel Sambuc   // extended vector elements.
273*f4a2713aSLionel Sambuc   llvm::Value *getExtVectorAddr() const { assert(isExtVectorElt()); return V; }
274*f4a2713aSLionel Sambuc   llvm::Constant *getExtVectorElts() const {
275*f4a2713aSLionel Sambuc     assert(isExtVectorElt());
276*f4a2713aSLionel Sambuc     return VectorElts;
277*f4a2713aSLionel Sambuc   }
278*f4a2713aSLionel Sambuc 
279*f4a2713aSLionel Sambuc   // bitfield lvalue
280*f4a2713aSLionel Sambuc   llvm::Value *getBitFieldAddr() const {
281*f4a2713aSLionel Sambuc     assert(isBitField());
282*f4a2713aSLionel Sambuc     return V;
283*f4a2713aSLionel Sambuc   }
284*f4a2713aSLionel Sambuc   const CGBitFieldInfo &getBitFieldInfo() const {
285*f4a2713aSLionel Sambuc     assert(isBitField());
286*f4a2713aSLionel Sambuc     return *BitFieldInfo;
287*f4a2713aSLionel Sambuc   }
288*f4a2713aSLionel Sambuc 
289*f4a2713aSLionel Sambuc   static LValue MakeAddr(llvm::Value *address, QualType type,
290*f4a2713aSLionel Sambuc                          CharUnits alignment, ASTContext &Context,
291*f4a2713aSLionel Sambuc                          llvm::MDNode *TBAAInfo = 0) {
292*f4a2713aSLionel Sambuc     Qualifiers qs = type.getQualifiers();
293*f4a2713aSLionel Sambuc     qs.setObjCGCAttr(Context.getObjCGCAttrKind(type));
294*f4a2713aSLionel Sambuc 
295*f4a2713aSLionel Sambuc     LValue R;
296*f4a2713aSLionel Sambuc     R.LVType = Simple;
297*f4a2713aSLionel Sambuc     R.V = address;
298*f4a2713aSLionel Sambuc     R.Initialize(type, qs, alignment, TBAAInfo);
299*f4a2713aSLionel Sambuc     return R;
300*f4a2713aSLionel Sambuc   }
301*f4a2713aSLionel Sambuc 
302*f4a2713aSLionel Sambuc   static LValue MakeVectorElt(llvm::Value *Vec, llvm::Value *Idx,
303*f4a2713aSLionel Sambuc                               QualType type, CharUnits Alignment) {
304*f4a2713aSLionel Sambuc     LValue R;
305*f4a2713aSLionel Sambuc     R.LVType = VectorElt;
306*f4a2713aSLionel Sambuc     R.V = Vec;
307*f4a2713aSLionel Sambuc     R.VectorIdx = Idx;
308*f4a2713aSLionel Sambuc     R.Initialize(type, type.getQualifiers(), Alignment);
309*f4a2713aSLionel Sambuc     return R;
310*f4a2713aSLionel Sambuc   }
311*f4a2713aSLionel Sambuc 
312*f4a2713aSLionel Sambuc   static LValue MakeExtVectorElt(llvm::Value *Vec, llvm::Constant *Elts,
313*f4a2713aSLionel Sambuc                                  QualType type, CharUnits Alignment) {
314*f4a2713aSLionel Sambuc     LValue R;
315*f4a2713aSLionel Sambuc     R.LVType = ExtVectorElt;
316*f4a2713aSLionel Sambuc     R.V = Vec;
317*f4a2713aSLionel Sambuc     R.VectorElts = Elts;
318*f4a2713aSLionel Sambuc     R.Initialize(type, type.getQualifiers(), Alignment);
319*f4a2713aSLionel Sambuc     return R;
320*f4a2713aSLionel Sambuc   }
321*f4a2713aSLionel Sambuc 
322*f4a2713aSLionel Sambuc   /// \brief Create a new object to represent a bit-field access.
323*f4a2713aSLionel Sambuc   ///
324*f4a2713aSLionel Sambuc   /// \param Addr - The base address of the bit-field sequence this
325*f4a2713aSLionel Sambuc   /// bit-field refers to.
326*f4a2713aSLionel Sambuc   /// \param Info - The information describing how to perform the bit-field
327*f4a2713aSLionel Sambuc   /// access.
328*f4a2713aSLionel Sambuc   static LValue MakeBitfield(llvm::Value *Addr,
329*f4a2713aSLionel Sambuc                              const CGBitFieldInfo &Info,
330*f4a2713aSLionel Sambuc                              QualType type, CharUnits Alignment) {
331*f4a2713aSLionel Sambuc     LValue R;
332*f4a2713aSLionel Sambuc     R.LVType = BitField;
333*f4a2713aSLionel Sambuc     R.V = Addr;
334*f4a2713aSLionel Sambuc     R.BitFieldInfo = &Info;
335*f4a2713aSLionel Sambuc     R.Initialize(type, type.getQualifiers(), Alignment);
336*f4a2713aSLionel Sambuc     return R;
337*f4a2713aSLionel Sambuc   }
338*f4a2713aSLionel Sambuc 
339*f4a2713aSLionel Sambuc   RValue asAggregateRValue() const {
340*f4a2713aSLionel Sambuc     // FIMXE: Alignment
341*f4a2713aSLionel Sambuc     return RValue::getAggregate(getAddress(), isVolatileQualified());
342*f4a2713aSLionel Sambuc   }
343*f4a2713aSLionel Sambuc };
344*f4a2713aSLionel Sambuc 
345*f4a2713aSLionel Sambuc /// An aggregate value slot.
346*f4a2713aSLionel Sambuc class AggValueSlot {
347*f4a2713aSLionel Sambuc   /// The address.
348*f4a2713aSLionel Sambuc   llvm::Value *Addr;
349*f4a2713aSLionel Sambuc 
350*f4a2713aSLionel Sambuc   // Qualifiers
351*f4a2713aSLionel Sambuc   Qualifiers Quals;
352*f4a2713aSLionel Sambuc 
353*f4a2713aSLionel Sambuc   unsigned short Alignment;
354*f4a2713aSLionel Sambuc 
355*f4a2713aSLionel Sambuc   /// DestructedFlag - This is set to true if some external code is
356*f4a2713aSLionel Sambuc   /// responsible for setting up a destructor for the slot.  Otherwise
357*f4a2713aSLionel Sambuc   /// the code which constructs it should push the appropriate cleanup.
358*f4a2713aSLionel Sambuc   bool DestructedFlag : 1;
359*f4a2713aSLionel Sambuc 
360*f4a2713aSLionel Sambuc   /// ObjCGCFlag - This is set to true if writing to the memory in the
361*f4a2713aSLionel Sambuc   /// slot might require calling an appropriate Objective-C GC
362*f4a2713aSLionel Sambuc   /// barrier.  The exact interaction here is unnecessarily mysterious.
363*f4a2713aSLionel Sambuc   bool ObjCGCFlag : 1;
364*f4a2713aSLionel Sambuc 
365*f4a2713aSLionel Sambuc   /// ZeroedFlag - This is set to true if the memory in the slot is
366*f4a2713aSLionel Sambuc   /// known to be zero before the assignment into it.  This means that
367*f4a2713aSLionel Sambuc   /// zero fields don't need to be set.
368*f4a2713aSLionel Sambuc   bool ZeroedFlag : 1;
369*f4a2713aSLionel Sambuc 
370*f4a2713aSLionel Sambuc   /// AliasedFlag - This is set to true if the slot might be aliased
371*f4a2713aSLionel Sambuc   /// and it's not undefined behavior to access it through such an
372*f4a2713aSLionel Sambuc   /// alias.  Note that it's always undefined behavior to access a C++
373*f4a2713aSLionel Sambuc   /// object that's under construction through an alias derived from
374*f4a2713aSLionel Sambuc   /// outside the construction process.
375*f4a2713aSLionel Sambuc   ///
376*f4a2713aSLionel Sambuc   /// This flag controls whether calls that produce the aggregate
377*f4a2713aSLionel Sambuc   /// value may be evaluated directly into the slot, or whether they
378*f4a2713aSLionel Sambuc   /// must be evaluated into an unaliased temporary and then memcpy'ed
379*f4a2713aSLionel Sambuc   /// over.  Since it's invalid in general to memcpy a non-POD C++
380*f4a2713aSLionel Sambuc   /// object, it's important that this flag never be set when
381*f4a2713aSLionel Sambuc   /// evaluating an expression which constructs such an object.
382*f4a2713aSLionel Sambuc   bool AliasedFlag : 1;
383*f4a2713aSLionel Sambuc 
384*f4a2713aSLionel Sambuc public:
385*f4a2713aSLionel Sambuc   enum IsAliased_t { IsNotAliased, IsAliased };
386*f4a2713aSLionel Sambuc   enum IsDestructed_t { IsNotDestructed, IsDestructed };
387*f4a2713aSLionel Sambuc   enum IsZeroed_t { IsNotZeroed, IsZeroed };
388*f4a2713aSLionel Sambuc   enum NeedsGCBarriers_t { DoesNotNeedGCBarriers, NeedsGCBarriers };
389*f4a2713aSLionel Sambuc 
390*f4a2713aSLionel Sambuc   /// ignored - Returns an aggregate value slot indicating that the
391*f4a2713aSLionel Sambuc   /// aggregate value is being ignored.
392*f4a2713aSLionel Sambuc   static AggValueSlot ignored() {
393*f4a2713aSLionel Sambuc     return forAddr(0, CharUnits(), Qualifiers(), IsNotDestructed,
394*f4a2713aSLionel Sambuc                    DoesNotNeedGCBarriers, IsNotAliased);
395*f4a2713aSLionel Sambuc   }
396*f4a2713aSLionel Sambuc 
397*f4a2713aSLionel Sambuc   /// forAddr - Make a slot for an aggregate value.
398*f4a2713aSLionel Sambuc   ///
399*f4a2713aSLionel Sambuc   /// \param quals - The qualifiers that dictate how the slot should
400*f4a2713aSLionel Sambuc   /// be initialied. Only 'volatile' and the Objective-C lifetime
401*f4a2713aSLionel Sambuc   /// qualifiers matter.
402*f4a2713aSLionel Sambuc   ///
403*f4a2713aSLionel Sambuc   /// \param isDestructed - true if something else is responsible
404*f4a2713aSLionel Sambuc   ///   for calling destructors on this object
405*f4a2713aSLionel Sambuc   /// \param needsGC - true if the slot is potentially located
406*f4a2713aSLionel Sambuc   ///   somewhere that ObjC GC calls should be emitted for
407*f4a2713aSLionel Sambuc   static AggValueSlot forAddr(llvm::Value *addr, CharUnits align,
408*f4a2713aSLionel Sambuc                               Qualifiers quals,
409*f4a2713aSLionel Sambuc                               IsDestructed_t isDestructed,
410*f4a2713aSLionel Sambuc                               NeedsGCBarriers_t needsGC,
411*f4a2713aSLionel Sambuc                               IsAliased_t isAliased,
412*f4a2713aSLionel Sambuc                               IsZeroed_t isZeroed = IsNotZeroed) {
413*f4a2713aSLionel Sambuc     AggValueSlot AV;
414*f4a2713aSLionel Sambuc     AV.Addr = addr;
415*f4a2713aSLionel Sambuc     AV.Alignment = align.getQuantity();
416*f4a2713aSLionel Sambuc     AV.Quals = quals;
417*f4a2713aSLionel Sambuc     AV.DestructedFlag = isDestructed;
418*f4a2713aSLionel Sambuc     AV.ObjCGCFlag = needsGC;
419*f4a2713aSLionel Sambuc     AV.ZeroedFlag = isZeroed;
420*f4a2713aSLionel Sambuc     AV.AliasedFlag = isAliased;
421*f4a2713aSLionel Sambuc     return AV;
422*f4a2713aSLionel Sambuc   }
423*f4a2713aSLionel Sambuc 
424*f4a2713aSLionel Sambuc   static AggValueSlot forLValue(const LValue &LV,
425*f4a2713aSLionel Sambuc                                 IsDestructed_t isDestructed,
426*f4a2713aSLionel Sambuc                                 NeedsGCBarriers_t needsGC,
427*f4a2713aSLionel Sambuc                                 IsAliased_t isAliased,
428*f4a2713aSLionel Sambuc                                 IsZeroed_t isZeroed = IsNotZeroed) {
429*f4a2713aSLionel Sambuc     return forAddr(LV.getAddress(), LV.getAlignment(),
430*f4a2713aSLionel Sambuc                    LV.getQuals(), isDestructed, needsGC, isAliased, isZeroed);
431*f4a2713aSLionel Sambuc   }
432*f4a2713aSLionel Sambuc 
433*f4a2713aSLionel Sambuc   IsDestructed_t isExternallyDestructed() const {
434*f4a2713aSLionel Sambuc     return IsDestructed_t(DestructedFlag);
435*f4a2713aSLionel Sambuc   }
436*f4a2713aSLionel Sambuc   void setExternallyDestructed(bool destructed = true) {
437*f4a2713aSLionel Sambuc     DestructedFlag = destructed;
438*f4a2713aSLionel Sambuc   }
439*f4a2713aSLionel Sambuc 
440*f4a2713aSLionel Sambuc   Qualifiers getQualifiers() const { return Quals; }
441*f4a2713aSLionel Sambuc 
442*f4a2713aSLionel Sambuc   bool isVolatile() const {
443*f4a2713aSLionel Sambuc     return Quals.hasVolatile();
444*f4a2713aSLionel Sambuc   }
445*f4a2713aSLionel Sambuc 
446*f4a2713aSLionel Sambuc   void setVolatile(bool flag) {
447*f4a2713aSLionel Sambuc     Quals.setVolatile(flag);
448*f4a2713aSLionel Sambuc   }
449*f4a2713aSLionel Sambuc 
450*f4a2713aSLionel Sambuc   Qualifiers::ObjCLifetime getObjCLifetime() const {
451*f4a2713aSLionel Sambuc     return Quals.getObjCLifetime();
452*f4a2713aSLionel Sambuc   }
453*f4a2713aSLionel Sambuc 
454*f4a2713aSLionel Sambuc   NeedsGCBarriers_t requiresGCollection() const {
455*f4a2713aSLionel Sambuc     return NeedsGCBarriers_t(ObjCGCFlag);
456*f4a2713aSLionel Sambuc   }
457*f4a2713aSLionel Sambuc 
458*f4a2713aSLionel Sambuc   llvm::Value *getAddr() const {
459*f4a2713aSLionel Sambuc     return Addr;
460*f4a2713aSLionel Sambuc   }
461*f4a2713aSLionel Sambuc 
462*f4a2713aSLionel Sambuc   bool isIgnored() const {
463*f4a2713aSLionel Sambuc     return Addr == 0;
464*f4a2713aSLionel Sambuc   }
465*f4a2713aSLionel Sambuc 
466*f4a2713aSLionel Sambuc   CharUnits getAlignment() const {
467*f4a2713aSLionel Sambuc     return CharUnits::fromQuantity(Alignment);
468*f4a2713aSLionel Sambuc   }
469*f4a2713aSLionel Sambuc 
470*f4a2713aSLionel Sambuc   IsAliased_t isPotentiallyAliased() const {
471*f4a2713aSLionel Sambuc     return IsAliased_t(AliasedFlag);
472*f4a2713aSLionel Sambuc   }
473*f4a2713aSLionel Sambuc 
474*f4a2713aSLionel Sambuc   // FIXME: Alignment?
475*f4a2713aSLionel Sambuc   RValue asRValue() const {
476*f4a2713aSLionel Sambuc     return RValue::getAggregate(getAddr(), isVolatile());
477*f4a2713aSLionel Sambuc   }
478*f4a2713aSLionel Sambuc 
479*f4a2713aSLionel Sambuc   void setZeroed(bool V = true) { ZeroedFlag = V; }
480*f4a2713aSLionel Sambuc   IsZeroed_t isZeroed() const {
481*f4a2713aSLionel Sambuc     return IsZeroed_t(ZeroedFlag);
482*f4a2713aSLionel Sambuc   }
483*f4a2713aSLionel Sambuc };
484*f4a2713aSLionel Sambuc 
485*f4a2713aSLionel Sambuc }  // end namespace CodeGen
486*f4a2713aSLionel Sambuc }  // end namespace clang
487*f4a2713aSLionel Sambuc 
488*f4a2713aSLionel Sambuc #endif
489