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
24namespace llvm {
25 class Constant;
26 class MDNode;
27}
28
29namespace clang {
30namespace 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.
39class 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
53public:
54 bool isScalar() const { return V1.getInt() == Scalar; }
55 bool isComplex() const { return V1.getInt() == Complex; }
56 bool isAggregate() const { return V1.getInt() == Aggregate; }
57
58 bool isVolatileQualified() const { return V2.getInt(); }
59
60 /// getScalarVal() - Return the Value* of this scalar value.
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 ///
68 std::pair<llvm::Value *, llvm::Value *> getComplexVal() const {
69 return std::make_pair(x: V1.getPointer(), y: V2.getPointer());
70 }
71
72 /// getAggregateAddr() - Return the Value* of the address of the aggregate.
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(Quantity: align));
78 }
79 llvm::Value *getAggregatePointer() const {
80 assert(isAggregate() && "Not an aggregate!");
81 return V1.getPointer();
82 }
83
84 static RValue getIgnored() {
85 // FIXME: should we make this a more explicit state?
86 return get(V: nullptr);
87 }
88
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 }
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 }
104 static RValue getComplex(const std::pair<llvm::Value *, llvm::Value *> &C) {
105 return getComplex(V1: C.first, V2: 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?
124enum 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.
130enum 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?
148static 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
154class LValueBaseInfo {
155 AlignmentSource AlignSource;
156
157public:
158 explicit LValueBaseInfo(AlignmentSource Source = AlignmentSource::Type)
159 : AlignSource(Source) {}
160 AlignmentSource getAlignmentSource() const { return AlignSource; }
161 void setAlignmentSource(AlignmentSource Source) { AlignSource = Source; }
162
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.
171class 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 // The pointer is known not to be null.
229 bool IsKnownNonNull : 1;
230
231 LValueBaseInfo BaseInfo;
232 TBAAAccessInfo TBAAInfo;
233
234 Expr *BaseIvarExp;
235
236private:
237 void Initialize(QualType Type, Qualifiers Quals, CharUnits Alignment,
238 LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo) {
239 assert((!Alignment.isZero() || Type->isIncompleteType()) &&
240 "initializing l-value with zero alignment!");
241 if (isGlobalReg())
242 assert(ElementType == nullptr && "Global reg does not store elem type");
243 else
244 assert(ElementType != nullptr && "Must have elem type");
245
246 this->Type = Type;
247 this->Quals = Quals;
248 const unsigned MaxAlign = 1U << 31;
249 this->Alignment = Alignment.getQuantity() <= MaxAlign
250 ? Alignment.getQuantity()
251 : MaxAlign;
252 assert(this->Alignment == Alignment.getQuantity() &&
253 "Alignment exceeds allowed max!");
254 this->BaseInfo = BaseInfo;
255 this->TBAAInfo = TBAAInfo;
256
257 // Initialize Objective-C flags.
258 this->Ivar = this->ObjIsArray = this->NonGC = this->GlobalObjCRef = false;
259 this->ImpreciseLifetime = false;
260 this->Nontemporal = false;
261 this->ThreadLocalRef = false;
262 this->BaseIvarExp = nullptr;
263 }
264
265public:
266 bool isSimple() const { return LVType == Simple; }
267 bool isVectorElt() const { return LVType == VectorElt; }
268 bool isBitField() const { return LVType == BitField; }
269 bool isExtVectorElt() const { return LVType == ExtVectorElt; }
270 bool isGlobalReg() const { return LVType == GlobalReg; }
271 bool isMatrixElt() const { return LVType == MatrixElt; }
272
273 bool isVolatileQualified() const { return Quals.hasVolatile(); }
274 bool isRestrictQualified() const { return Quals.hasRestrict(); }
275 unsigned getVRQualifiers() const {
276 return Quals.getCVRQualifiers() & ~Qualifiers::Const;
277 }
278
279 QualType getType() const { return Type; }
280
281 Qualifiers::ObjCLifetime getObjCLifetime() const {
282 return Quals.getObjCLifetime();
283 }
284
285 bool isObjCIvar() const { return Ivar; }
286 void setObjCIvar(bool Value) { Ivar = Value; }
287
288 bool isObjCArray() const { return ObjIsArray; }
289 void setObjCArray(bool Value) { ObjIsArray = Value; }
290
291 bool isNonGC () const { return NonGC; }
292 void setNonGC(bool Value) { NonGC = Value; }
293
294 bool isGlobalObjCRef() const { return GlobalObjCRef; }
295 void setGlobalObjCRef(bool Value) { GlobalObjCRef = Value; }
296
297 bool isThreadLocalRef() const { return ThreadLocalRef; }
298 void setThreadLocalRef(bool Value) { ThreadLocalRef = Value;}
299
300 ARCPreciseLifetime_t isARCPreciseLifetime() const {
301 return ARCPreciseLifetime_t(!ImpreciseLifetime);
302 }
303 void setARCPreciseLifetime(ARCPreciseLifetime_t value) {
304 ImpreciseLifetime = (value == ARCImpreciseLifetime);
305 }
306 bool isNontemporal() const { return Nontemporal; }
307 void setNontemporal(bool Value) { Nontemporal = Value; }
308
309 bool isObjCWeak() const {
310 return Quals.getObjCGCAttr() == Qualifiers::Weak;
311 }
312 bool isObjCStrong() const {
313 return Quals.getObjCGCAttr() == Qualifiers::Strong;
314 }
315
316 bool isVolatile() const {
317 return Quals.hasVolatile();
318 }
319
320 Expr *getBaseIvarExp() const { return BaseIvarExp; }
321 void setBaseIvarExp(Expr *V) { BaseIvarExp = V; }
322
323 TBAAAccessInfo getTBAAInfo() const { return TBAAInfo; }
324 void setTBAAInfo(TBAAAccessInfo Info) { TBAAInfo = Info; }
325
326 const Qualifiers &getQuals() const { return Quals; }
327 Qualifiers &getQuals() { return Quals; }
328
329 LangAS getAddressSpace() const { return Quals.getAddressSpace(); }
330
331 CharUnits getAlignment() const { return CharUnits::fromQuantity(Quantity: Alignment); }
332 void setAlignment(CharUnits A) { Alignment = A.getQuantity(); }
333
334 LValueBaseInfo getBaseInfo() const { return BaseInfo; }
335 void setBaseInfo(LValueBaseInfo Info) { BaseInfo = Info; }
336
337 KnownNonNull_t isKnownNonNull() const {
338 return (KnownNonNull_t)IsKnownNonNull;
339 }
340 LValue setKnownNonNull() {
341 IsKnownNonNull = true;
342 return *this;
343 }
344
345 // simple lvalue
346 llvm::Value *getPointer(CodeGenFunction &CGF) const {
347 assert(isSimple());
348 return V;
349 }
350 Address getAddress(CodeGenFunction &CGF) const {
351 return Address(getPointer(CGF), ElementType, getAlignment(),
352 isKnownNonNull());
353 }
354 void setAddress(Address address) {
355 assert(isSimple());
356 V = address.getPointer();
357 ElementType = address.getElementType();
358 Alignment = address.getAlignment().getQuantity();
359 IsKnownNonNull = address.isKnownNonNull();
360 }
361
362 // vector elt lvalue
363 Address getVectorAddress() const {
364 return Address(getVectorPointer(), ElementType, getAlignment(),
365 (KnownNonNull_t)isKnownNonNull());
366 }
367 llvm::Value *getVectorPointer() const {
368 assert(isVectorElt());
369 return V;
370 }
371 llvm::Value *getVectorIdx() const {
372 assert(isVectorElt());
373 return VectorIdx;
374 }
375
376 Address getMatrixAddress() const {
377 return Address(getMatrixPointer(), ElementType, getAlignment(),
378 (KnownNonNull_t)isKnownNonNull());
379 }
380 llvm::Value *getMatrixPointer() const {
381 assert(isMatrixElt());
382 return V;
383 }
384 llvm::Value *getMatrixIdx() const {
385 assert(isMatrixElt());
386 return VectorIdx;
387 }
388
389 // extended vector elements.
390 Address getExtVectorAddress() const {
391 return Address(getExtVectorPointer(), ElementType, getAlignment(),
392 (KnownNonNull_t)isKnownNonNull());
393 }
394 llvm::Value *getExtVectorPointer() const {
395 assert(isExtVectorElt());
396 return V;
397 }
398 llvm::Constant *getExtVectorElts() const {
399 assert(isExtVectorElt());
400 return VectorElts;
401 }
402
403 // bitfield lvalue
404 Address getBitFieldAddress() const {
405 return Address(getBitFieldPointer(), ElementType, getAlignment(),
406 (KnownNonNull_t)isKnownNonNull());
407 }
408 llvm::Value *getBitFieldPointer() const { assert(isBitField()); return V; }
409 const CGBitFieldInfo &getBitFieldInfo() const {
410 assert(isBitField());
411 return *BitFieldInfo;
412 }
413
414 // global register lvalue
415 llvm::Value *getGlobalReg() const { assert(isGlobalReg()); return V; }
416
417 static LValue MakeAddr(Address address, QualType type, ASTContext &Context,
418 LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo) {
419 Qualifiers qs = type.getQualifiers();
420 qs.setObjCGCAttr(Context.getObjCGCAttrKind(Ty: type));
421
422 LValue R;
423 R.LVType = Simple;
424 assert(address.getPointer()->getType()->isPointerTy());
425 R.V = address.getPointer();
426 R.ElementType = address.getElementType();
427 R.IsKnownNonNull = address.isKnownNonNull();
428 R.Initialize(Type: type, Quals: qs, Alignment: address.getAlignment(), BaseInfo, TBAAInfo);
429 return R;
430 }
431
432 static LValue MakeVectorElt(Address vecAddress, llvm::Value *Idx,
433 QualType type, LValueBaseInfo BaseInfo,
434 TBAAAccessInfo TBAAInfo) {
435 LValue R;
436 R.LVType = VectorElt;
437 R.V = vecAddress.getPointer();
438 R.ElementType = vecAddress.getElementType();
439 R.VectorIdx = Idx;
440 R.IsKnownNonNull = vecAddress.isKnownNonNull();
441 R.Initialize(Type: type, Quals: type.getQualifiers(), Alignment: vecAddress.getAlignment(),
442 BaseInfo, TBAAInfo);
443 return R;
444 }
445
446 static LValue MakeExtVectorElt(Address vecAddress, llvm::Constant *Elts,
447 QualType type, LValueBaseInfo BaseInfo,
448 TBAAAccessInfo TBAAInfo) {
449 LValue R;
450 R.LVType = ExtVectorElt;
451 R.V = vecAddress.getPointer();
452 R.ElementType = vecAddress.getElementType();
453 R.VectorElts = Elts;
454 R.IsKnownNonNull = vecAddress.isKnownNonNull();
455 R.Initialize(Type: type, Quals: type.getQualifiers(), Alignment: vecAddress.getAlignment(),
456 BaseInfo, TBAAInfo);
457 return R;
458 }
459
460 /// Create a new object to represent a bit-field access.
461 ///
462 /// \param Addr - The base address of the bit-field sequence this
463 /// bit-field refers to.
464 /// \param Info - The information describing how to perform the bit-field
465 /// access.
466 static LValue MakeBitfield(Address Addr, const CGBitFieldInfo &Info,
467 QualType type, LValueBaseInfo BaseInfo,
468 TBAAAccessInfo TBAAInfo) {
469 LValue R;
470 R.LVType = BitField;
471 R.V = Addr.getPointer();
472 R.ElementType = Addr.getElementType();
473 R.BitFieldInfo = &Info;
474 R.IsKnownNonNull = Addr.isKnownNonNull();
475 R.Initialize(Type: type, Quals: type.getQualifiers(), Alignment: Addr.getAlignment(), BaseInfo,
476 TBAAInfo);
477 return R;
478 }
479
480 static LValue MakeGlobalReg(llvm::Value *V, CharUnits alignment,
481 QualType type) {
482 LValue R;
483 R.LVType = GlobalReg;
484 R.V = V;
485 R.ElementType = nullptr;
486 R.IsKnownNonNull = true;
487 R.Initialize(Type: type, Quals: type.getQualifiers(), Alignment: alignment,
488 BaseInfo: LValueBaseInfo(AlignmentSource::Decl), TBAAInfo: TBAAAccessInfo());
489 return R;
490 }
491
492 static LValue MakeMatrixElt(Address matAddress, llvm::Value *Idx,
493 QualType type, LValueBaseInfo BaseInfo,
494 TBAAAccessInfo TBAAInfo) {
495 LValue R;
496 R.LVType = MatrixElt;
497 R.V = matAddress.getPointer();
498 R.ElementType = matAddress.getElementType();
499 R.VectorIdx = Idx;
500 R.IsKnownNonNull = matAddress.isKnownNonNull();
501 R.Initialize(Type: type, Quals: type.getQualifiers(), Alignment: matAddress.getAlignment(),
502 BaseInfo, TBAAInfo);
503 return R;
504 }
505
506 RValue asAggregateRValue(CodeGenFunction &CGF) const {
507 return RValue::getAggregate(addr: getAddress(CGF), isVolatile: isVolatileQualified());
508 }
509};
510
511/// An aggregate value slot.
512class AggValueSlot {
513 /// The address.
514 Address Addr;
515
516 // Qualifiers
517 Qualifiers Quals;
518
519 /// DestructedFlag - This is set to true if some external code is
520 /// responsible for setting up a destructor for the slot. Otherwise
521 /// the code which constructs it should push the appropriate cleanup.
522 bool DestructedFlag : 1;
523
524 /// ObjCGCFlag - This is set to true if writing to the memory in the
525 /// slot might require calling an appropriate Objective-C GC
526 /// barrier. The exact interaction here is unnecessarily mysterious.
527 bool ObjCGCFlag : 1;
528
529 /// ZeroedFlag - This is set to true if the memory in the slot is
530 /// known to be zero before the assignment into it. This means that
531 /// zero fields don't need to be set.
532 bool ZeroedFlag : 1;
533
534 /// AliasedFlag - This is set to true if the slot might be aliased
535 /// and it's not undefined behavior to access it through such an
536 /// alias. Note that it's always undefined behavior to access a C++
537 /// object that's under construction through an alias derived from
538 /// outside the construction process.
539 ///
540 /// This flag controls whether calls that produce the aggregate
541 /// value may be evaluated directly into the slot, or whether they
542 /// must be evaluated into an unaliased temporary and then memcpy'ed
543 /// over. Since it's invalid in general to memcpy a non-POD C++
544 /// object, it's important that this flag never be set when
545 /// evaluating an expression which constructs such an object.
546 bool AliasedFlag : 1;
547
548 /// This is set to true if the tail padding of this slot might overlap
549 /// another object that may have already been initialized (and whose
550 /// value must be preserved by this initialization). If so, we may only
551 /// store up to the dsize of the type. Otherwise we can widen stores to
552 /// the size of the type.
553 bool OverlapFlag : 1;
554
555 /// If is set to true, sanitizer checks are already generated for this address
556 /// or not required. For instance, if this address represents an object
557 /// created in 'new' expression, sanitizer checks for memory is made as a part
558 /// of 'operator new' emission and object constructor should not generate
559 /// them.
560 bool SanitizerCheckedFlag : 1;
561
562 AggValueSlot(Address Addr, Qualifiers Quals, bool DestructedFlag,
563 bool ObjCGCFlag, bool ZeroedFlag, bool AliasedFlag,
564 bool OverlapFlag, bool SanitizerCheckedFlag)
565 : Addr(Addr), Quals(Quals), DestructedFlag(DestructedFlag),
566 ObjCGCFlag(ObjCGCFlag), ZeroedFlag(ZeroedFlag),
567 AliasedFlag(AliasedFlag), OverlapFlag(OverlapFlag),
568 SanitizerCheckedFlag(SanitizerCheckedFlag) {}
569
570public:
571 enum IsAliased_t { IsNotAliased, IsAliased };
572 enum IsDestructed_t { IsNotDestructed, IsDestructed };
573 enum IsZeroed_t { IsNotZeroed, IsZeroed };
574 enum Overlap_t { DoesNotOverlap, MayOverlap };
575 enum NeedsGCBarriers_t { DoesNotNeedGCBarriers, NeedsGCBarriers };
576 enum IsSanitizerChecked_t { IsNotSanitizerChecked, IsSanitizerChecked };
577
578 /// ignored - Returns an aggregate value slot indicating that the
579 /// aggregate value is being ignored.
580 static AggValueSlot ignored() {
581 return forAddr(addr: Address::invalid(), quals: Qualifiers(), isDestructed: IsNotDestructed,
582 needsGC: DoesNotNeedGCBarriers, isAliased: IsNotAliased, mayOverlap: DoesNotOverlap);
583 }
584
585 /// forAddr - Make a slot for an aggregate value.
586 ///
587 /// \param quals - The qualifiers that dictate how the slot should
588 /// be initialied. Only 'volatile' and the Objective-C lifetime
589 /// qualifiers matter.
590 ///
591 /// \param isDestructed - true if something else is responsible
592 /// for calling destructors on this object
593 /// \param needsGC - true if the slot is potentially located
594 /// somewhere that ObjC GC calls should be emitted for
595 static AggValueSlot forAddr(Address addr,
596 Qualifiers quals,
597 IsDestructed_t isDestructed,
598 NeedsGCBarriers_t needsGC,
599 IsAliased_t isAliased,
600 Overlap_t mayOverlap,
601 IsZeroed_t isZeroed = IsNotZeroed,
602 IsSanitizerChecked_t isChecked = IsNotSanitizerChecked) {
603 if (addr.isValid())
604 addr.setKnownNonNull();
605 return AggValueSlot(addr, quals, isDestructed, needsGC, isZeroed, isAliased,
606 mayOverlap, isChecked);
607 }
608
609 static AggValueSlot
610 forLValue(const LValue &LV, CodeGenFunction &CGF, IsDestructed_t isDestructed,
611 NeedsGCBarriers_t needsGC, IsAliased_t isAliased,
612 Overlap_t mayOverlap, IsZeroed_t isZeroed = IsNotZeroed,
613 IsSanitizerChecked_t isChecked = IsNotSanitizerChecked) {
614 return forAddr(addr: LV.getAddress(CGF), quals: LV.getQuals(), isDestructed, needsGC,
615 isAliased, mayOverlap, isZeroed, isChecked);
616 }
617
618 IsDestructed_t isExternallyDestructed() const {
619 return IsDestructed_t(DestructedFlag);
620 }
621 void setExternallyDestructed(bool destructed = true) {
622 DestructedFlag = destructed;
623 }
624
625 Qualifiers getQualifiers() const { return Quals; }
626
627 bool isVolatile() const {
628 return Quals.hasVolatile();
629 }
630
631 void setVolatile(bool flag) {
632 if (flag)
633 Quals.addVolatile();
634 else
635 Quals.removeVolatile();
636 }
637
638 Qualifiers::ObjCLifetime getObjCLifetime() const {
639 return Quals.getObjCLifetime();
640 }
641
642 NeedsGCBarriers_t requiresGCollection() const {
643 return NeedsGCBarriers_t(ObjCGCFlag);
644 }
645
646 llvm::Value *getPointer() const {
647 return Addr.getPointer();
648 }
649
650 Address getAddress() const {
651 return Addr;
652 }
653
654 bool isIgnored() const {
655 return !Addr.isValid();
656 }
657
658 CharUnits getAlignment() const {
659 return Addr.getAlignment();
660 }
661
662 IsAliased_t isPotentiallyAliased() const {
663 return IsAliased_t(AliasedFlag);
664 }
665
666 Overlap_t mayOverlap() const {
667 return Overlap_t(OverlapFlag);
668 }
669
670 bool isSanitizerChecked() const {
671 return SanitizerCheckedFlag;
672 }
673
674 RValue asRValue() const {
675 if (isIgnored()) {
676 return RValue::getIgnored();
677 } else {
678 return RValue::getAggregate(addr: getAddress(), isVolatile: isVolatile());
679 }
680 }
681
682 void setZeroed(bool V = true) { ZeroedFlag = V; }
683 IsZeroed_t isZeroed() const {
684 return IsZeroed_t(ZeroedFlag);
685 }
686
687 /// Get the preferred size to use when storing a value to this slot. This
688 /// is the type size unless that might overlap another object, in which
689 /// case it's the dsize.
690 CharUnits getPreferredSize(ASTContext &Ctx, QualType Type) const {
691 return mayOverlap() ? Ctx.getTypeInfoDataSizeInChars(T: Type).Width
692 : Ctx.getTypeSizeInChars(T: Type);
693 }
694};
695
696} // end namespace CodeGen
697} // end namespace clang
698
699#endif
700

source code of clang/lib/CodeGen/CGValue.h