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