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