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