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