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