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