xref: /freebsd-src/contrib/llvm-project/clang/lib/CodeGen/CGValue.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===-- CGValue.h - LLVM CodeGen wrappers for llvm::Value* ------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // These classes implement wrappers around llvm::Value in order to
100b57cec5SDimitry Andric // fully represent the range of values for C L- and R- values.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #ifndef LLVM_CLANG_LIB_CODEGEN_CGVALUE_H
150b57cec5SDimitry Andric #define LLVM_CLANG_LIB_CODEGEN_CGVALUE_H
160b57cec5SDimitry Andric 
17*0fca6ea1SDimitry Andric #include "Address.h"
18*0fca6ea1SDimitry Andric #include "CGPointerAuthInfo.h"
19*0fca6ea1SDimitry Andric #include "CodeGenTBAA.h"
20*0fca6ea1SDimitry Andric #include "EHScopeStack.h"
210b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
220b57cec5SDimitry Andric #include "clang/AST/Type.h"
230b57cec5SDimitry Andric #include "llvm/IR/Type.h"
24*0fca6ea1SDimitry Andric #include "llvm/IR/Value.h"
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric namespace llvm {
270b57cec5SDimitry Andric   class Constant;
280b57cec5SDimitry Andric   class MDNode;
290b57cec5SDimitry Andric }
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric namespace clang {
320b57cec5SDimitry Andric namespace CodeGen {
330b57cec5SDimitry Andric class AggValueSlot;
34*0fca6ea1SDimitry Andric class CGBuilderTy;
35480093f4SDimitry Andric class CodeGenFunction;
360b57cec5SDimitry Andric struct CGBitFieldInfo;
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric /// RValue - This trivial value class is used to represent the result of an
390b57cec5SDimitry Andric /// expression that is evaluated.  It can be one of three things: either a
400b57cec5SDimitry Andric /// simple LLVM SSA value, a pair of SSA values for complex numbers, or the
410b57cec5SDimitry Andric /// address of an aggregate value in memory.
420b57cec5SDimitry Andric class RValue {
43*0fca6ea1SDimitry Andric   friend struct DominatingValue<RValue>;
440b57cec5SDimitry Andric 
45*0fca6ea1SDimitry Andric   enum FlavorEnum { Scalar, Complex, Aggregate };
460b57cec5SDimitry Andric 
47*0fca6ea1SDimitry Andric   union {
48*0fca6ea1SDimitry Andric     // Stores first and second value.
49*0fca6ea1SDimitry Andric     struct {
50*0fca6ea1SDimitry Andric       llvm::Value *first;
51*0fca6ea1SDimitry Andric       llvm::Value *second;
52*0fca6ea1SDimitry Andric     } Vals;
53*0fca6ea1SDimitry Andric 
54*0fca6ea1SDimitry Andric     // Stores aggregate address.
55*0fca6ea1SDimitry Andric     Address AggregateAddr;
56*0fca6ea1SDimitry Andric   };
57*0fca6ea1SDimitry Andric 
58*0fca6ea1SDimitry Andric   unsigned IsVolatile : 1;
59*0fca6ea1SDimitry Andric   unsigned Flavor : 2;
600b57cec5SDimitry Andric 
610b57cec5SDimitry Andric public:
62*0fca6ea1SDimitry Andric   RValue() : Vals{nullptr, nullptr}, Flavor(Scalar) {}
630b57cec5SDimitry Andric 
64*0fca6ea1SDimitry Andric   bool isScalar() const { return Flavor == Scalar; }
65*0fca6ea1SDimitry Andric   bool isComplex() const { return Flavor == Complex; }
66*0fca6ea1SDimitry Andric   bool isAggregate() const { return Flavor == Aggregate; }
67*0fca6ea1SDimitry Andric 
68*0fca6ea1SDimitry Andric   bool isVolatileQualified() const { return IsVolatile; }
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric   /// getScalarVal() - Return the Value* of this scalar value.
710b57cec5SDimitry Andric   llvm::Value *getScalarVal() const {
720b57cec5SDimitry Andric     assert(isScalar() && "Not a scalar!");
73*0fca6ea1SDimitry Andric     return Vals.first;
740b57cec5SDimitry Andric   }
750b57cec5SDimitry Andric 
760b57cec5SDimitry Andric   /// getComplexVal - Return the real/imag components of this complex value.
770b57cec5SDimitry Andric   ///
780b57cec5SDimitry Andric   std::pair<llvm::Value *, llvm::Value *> getComplexVal() const {
79*0fca6ea1SDimitry Andric     return std::make_pair(Vals.first, Vals.second);
800b57cec5SDimitry Andric   }
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric   /// getAggregateAddr() - Return the Value* of the address of the aggregate.
830b57cec5SDimitry Andric   Address getAggregateAddress() const {
840b57cec5SDimitry Andric     assert(isAggregate() && "Not an aggregate!");
85*0fca6ea1SDimitry Andric     return AggregateAddr;
860b57cec5SDimitry Andric   }
87*0fca6ea1SDimitry Andric 
88*0fca6ea1SDimitry Andric   llvm::Value *getAggregatePointer(QualType PointeeType,
89*0fca6ea1SDimitry Andric                                    CodeGenFunction &CGF) const {
90*0fca6ea1SDimitry Andric     return getAggregateAddress().getBasePointer();
910b57cec5SDimitry Andric   }
920b57cec5SDimitry Andric 
930b57cec5SDimitry Andric   static RValue getIgnored() {
940b57cec5SDimitry Andric     // FIXME: should we make this a more explicit state?
950b57cec5SDimitry Andric     return get(nullptr);
960b57cec5SDimitry Andric   }
970b57cec5SDimitry Andric 
980b57cec5SDimitry Andric   static RValue get(llvm::Value *V) {
990b57cec5SDimitry Andric     RValue ER;
100*0fca6ea1SDimitry Andric     ER.Vals.first = V;
101*0fca6ea1SDimitry Andric     ER.Flavor = Scalar;
102*0fca6ea1SDimitry Andric     ER.IsVolatile = false;
1030b57cec5SDimitry Andric     return ER;
1040b57cec5SDimitry Andric   }
105*0fca6ea1SDimitry Andric   static RValue get(Address Addr, CodeGenFunction &CGF) {
106*0fca6ea1SDimitry Andric     return RValue::get(Addr.emitRawPointer(CGF));
107*0fca6ea1SDimitry Andric   }
1080b57cec5SDimitry Andric   static RValue getComplex(llvm::Value *V1, llvm::Value *V2) {
1090b57cec5SDimitry Andric     RValue ER;
110*0fca6ea1SDimitry Andric     ER.Vals = {V1, V2};
111*0fca6ea1SDimitry Andric     ER.Flavor = Complex;
112*0fca6ea1SDimitry Andric     ER.IsVolatile = false;
1130b57cec5SDimitry Andric     return ER;
1140b57cec5SDimitry Andric   }
1150b57cec5SDimitry Andric   static RValue getComplex(const std::pair<llvm::Value *, llvm::Value *> &C) {
1160b57cec5SDimitry Andric     return getComplex(C.first, C.second);
1170b57cec5SDimitry Andric   }
1180b57cec5SDimitry Andric   // FIXME: Aggregate rvalues need to retain information about whether they are
1190b57cec5SDimitry Andric   // volatile or not.  Remove default to find all places that probably get this
1200b57cec5SDimitry Andric   // wrong.
121*0fca6ea1SDimitry Andric 
122*0fca6ea1SDimitry Andric   /// Convert an Address to an RValue. If the Address is not
123*0fca6ea1SDimitry Andric   /// signed, create an RValue using the unsigned address. Otherwise, resign the
124*0fca6ea1SDimitry Andric   /// address using the provided type.
1250b57cec5SDimitry Andric   static RValue getAggregate(Address addr, bool isVolatile = false) {
1260b57cec5SDimitry Andric     RValue ER;
127*0fca6ea1SDimitry Andric     ER.AggregateAddr = addr;
128*0fca6ea1SDimitry Andric     ER.Flavor = Aggregate;
129*0fca6ea1SDimitry Andric     ER.IsVolatile = isVolatile;
1300b57cec5SDimitry Andric     return ER;
1310b57cec5SDimitry Andric   }
1320b57cec5SDimitry Andric };
1330b57cec5SDimitry Andric 
1340b57cec5SDimitry Andric /// Does an ARC strong l-value have precise lifetime?
1350b57cec5SDimitry Andric enum ARCPreciseLifetime_t {
1360b57cec5SDimitry Andric   ARCImpreciseLifetime, ARCPreciseLifetime
1370b57cec5SDimitry Andric };
1380b57cec5SDimitry Andric 
1390b57cec5SDimitry Andric /// The source of the alignment of an l-value; an expression of
1400b57cec5SDimitry Andric /// confidence in the alignment actually matching the estimate.
1410b57cec5SDimitry Andric enum class AlignmentSource {
1420b57cec5SDimitry Andric   /// The l-value was an access to a declared entity or something
1430b57cec5SDimitry Andric   /// equivalently strong, like the address of an array allocated by a
1440b57cec5SDimitry Andric   /// language runtime.
1450b57cec5SDimitry Andric   Decl,
1460b57cec5SDimitry Andric 
1470b57cec5SDimitry Andric   /// The l-value was considered opaque, so the alignment was
1480b57cec5SDimitry Andric   /// determined from a type, but that type was an explicitly-aligned
1490b57cec5SDimitry Andric   /// typedef.
1500b57cec5SDimitry Andric   AttributedType,
1510b57cec5SDimitry Andric 
1520b57cec5SDimitry Andric   /// The l-value was considered opaque, so the alignment was
1530b57cec5SDimitry Andric   /// determined from a type.
1540b57cec5SDimitry Andric   Type
1550b57cec5SDimitry Andric };
1560b57cec5SDimitry Andric 
1570b57cec5SDimitry Andric /// Given that the base address has the given alignment source, what's
1580b57cec5SDimitry Andric /// our confidence in the alignment of the field?
1590b57cec5SDimitry Andric static inline AlignmentSource getFieldAlignmentSource(AlignmentSource Source) {
1600b57cec5SDimitry Andric   // For now, we don't distinguish fields of opaque pointers from
1610b57cec5SDimitry Andric   // top-level declarations, but maybe we should.
1620b57cec5SDimitry Andric   return AlignmentSource::Decl;
1630b57cec5SDimitry Andric }
1640b57cec5SDimitry Andric 
1650b57cec5SDimitry Andric class LValueBaseInfo {
1660b57cec5SDimitry Andric   AlignmentSource AlignSource;
1670b57cec5SDimitry Andric 
1680b57cec5SDimitry Andric public:
1690b57cec5SDimitry Andric   explicit LValueBaseInfo(AlignmentSource Source = AlignmentSource::Type)
1700b57cec5SDimitry Andric     : AlignSource(Source) {}
1710b57cec5SDimitry Andric   AlignmentSource getAlignmentSource() const { return AlignSource; }
1720b57cec5SDimitry Andric   void setAlignmentSource(AlignmentSource Source) { AlignSource = Source; }
1730b57cec5SDimitry Andric 
1740b57cec5SDimitry Andric   void mergeForCast(const LValueBaseInfo &Info) {
1750b57cec5SDimitry Andric     setAlignmentSource(Info.getAlignmentSource());
1760b57cec5SDimitry Andric   }
1770b57cec5SDimitry Andric };
1780b57cec5SDimitry Andric 
1790b57cec5SDimitry Andric /// LValue - This represents an lvalue references.  Because C/C++ allow
1800b57cec5SDimitry Andric /// bitfields, this is not a simple LLVM pointer, it may be a pointer plus a
1810b57cec5SDimitry Andric /// bitrange.
1820b57cec5SDimitry Andric class LValue {
1830b57cec5SDimitry Andric   enum {
1840b57cec5SDimitry Andric     Simple,       // This is a normal l-value, use getAddress().
1850b57cec5SDimitry Andric     VectorElt,    // This is a vector element l-value (V[i]), use getVector*
1860b57cec5SDimitry Andric     BitField,     // This is a bitfield l-value, use getBitfield*.
1870b57cec5SDimitry Andric     ExtVectorElt, // This is an extended vector subset, use getExtVectorComp
1885ffd83dbSDimitry Andric     GlobalReg,    // This is a register l-value, use getGlobalReg()
1895ffd83dbSDimitry Andric     MatrixElt     // This is a matrix element, use getVector*
1900b57cec5SDimitry Andric   } LVType;
1910b57cec5SDimitry Andric 
192*0fca6ea1SDimitry Andric   union {
193*0fca6ea1SDimitry Andric     Address Addr = Address::invalid();
1940b57cec5SDimitry Andric     llvm::Value *V;
195*0fca6ea1SDimitry Andric   };
1960b57cec5SDimitry Andric 
1970b57cec5SDimitry Andric   union {
1980b57cec5SDimitry Andric     // Index into a vector subscript: V[i]
1990b57cec5SDimitry Andric     llvm::Value *VectorIdx;
2000b57cec5SDimitry Andric 
2010b57cec5SDimitry Andric     // ExtVector element subset: V.xyx
2020b57cec5SDimitry Andric     llvm::Constant *VectorElts;
2030b57cec5SDimitry Andric 
2040b57cec5SDimitry Andric     // BitField start bit and size
2050b57cec5SDimitry Andric     const CGBitFieldInfo *BitFieldInfo;
2060b57cec5SDimitry Andric   };
2070b57cec5SDimitry Andric 
2080b57cec5SDimitry Andric   QualType Type;
2090b57cec5SDimitry Andric 
2100b57cec5SDimitry Andric   // 'const' is unused here
2110b57cec5SDimitry Andric   Qualifiers Quals;
2120b57cec5SDimitry Andric 
2130b57cec5SDimitry Andric   // objective-c's ivar
2140b57cec5SDimitry Andric   bool Ivar:1;
2150b57cec5SDimitry Andric 
2160b57cec5SDimitry Andric   // objective-c's ivar is an array
2170b57cec5SDimitry Andric   bool ObjIsArray:1;
2180b57cec5SDimitry Andric 
2190b57cec5SDimitry Andric   // LValue is non-gc'able for any reason, including being a parameter or local
2200b57cec5SDimitry Andric   // variable.
2210b57cec5SDimitry Andric   bool NonGC: 1;
2220b57cec5SDimitry Andric 
2230b57cec5SDimitry Andric   // Lvalue is a global reference of an objective-c object
2240b57cec5SDimitry Andric   bool GlobalObjCRef : 1;
2250b57cec5SDimitry Andric 
2260b57cec5SDimitry Andric   // Lvalue is a thread local reference
2270b57cec5SDimitry Andric   bool ThreadLocalRef : 1;
2280b57cec5SDimitry Andric 
2290b57cec5SDimitry Andric   // Lvalue has ARC imprecise lifetime.  We store this inverted to try
2300b57cec5SDimitry Andric   // to make the default bitfield pattern all-zeroes.
2310b57cec5SDimitry Andric   bool ImpreciseLifetime : 1;
2320b57cec5SDimitry Andric 
2330b57cec5SDimitry Andric   // This flag shows if a nontemporal load/stores should be used when accessing
2340b57cec5SDimitry Andric   // this lvalue.
2350b57cec5SDimitry Andric   bool Nontemporal : 1;
2360b57cec5SDimitry Andric 
2370b57cec5SDimitry Andric   LValueBaseInfo BaseInfo;
2380b57cec5SDimitry Andric   TBAAAccessInfo TBAAInfo;
2390b57cec5SDimitry Andric 
2400b57cec5SDimitry Andric   Expr *BaseIvarExp;
2410b57cec5SDimitry Andric 
2420b57cec5SDimitry Andric private:
243*0fca6ea1SDimitry Andric   void Initialize(QualType Type, Qualifiers Quals, Address Addr,
2440b57cec5SDimitry Andric                   LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo) {
2450b57cec5SDimitry Andric     this->Type = Type;
2460b57cec5SDimitry Andric     this->Quals = Quals;
2470b57cec5SDimitry Andric     const unsigned MaxAlign = 1U << 31;
248*0fca6ea1SDimitry Andric     CharUnits Alignment = Addr.getAlignment();
249*0fca6ea1SDimitry Andric     assert((isGlobalReg() || !Alignment.isZero() || Type->isIncompleteType()) &&
250*0fca6ea1SDimitry Andric            "initializing l-value with zero alignment!");
251*0fca6ea1SDimitry Andric     if (Alignment.getQuantity() > MaxAlign) {
252*0fca6ea1SDimitry Andric       assert(false && "Alignment exceeds allowed max!");
253*0fca6ea1SDimitry Andric       Alignment = CharUnits::fromQuantity(MaxAlign);
254*0fca6ea1SDimitry Andric     }
255*0fca6ea1SDimitry Andric     this->Addr = Addr;
2560b57cec5SDimitry Andric     this->BaseInfo = BaseInfo;
2570b57cec5SDimitry Andric     this->TBAAInfo = TBAAInfo;
2580b57cec5SDimitry Andric 
2590b57cec5SDimitry Andric     // Initialize Objective-C flags.
2600b57cec5SDimitry Andric     this->Ivar = this->ObjIsArray = this->NonGC = this->GlobalObjCRef = false;
2610b57cec5SDimitry Andric     this->ImpreciseLifetime = false;
2620b57cec5SDimitry Andric     this->Nontemporal = false;
2630b57cec5SDimitry Andric     this->ThreadLocalRef = false;
2640b57cec5SDimitry Andric     this->BaseIvarExp = nullptr;
2650b57cec5SDimitry Andric   }
2660b57cec5SDimitry Andric 
267*0fca6ea1SDimitry Andric   void initializeSimpleLValue(Address Addr, QualType Type,
268*0fca6ea1SDimitry Andric                               LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo,
269*0fca6ea1SDimitry Andric                               ASTContext &Context) {
270*0fca6ea1SDimitry Andric     Qualifiers QS = Type.getQualifiers();
271*0fca6ea1SDimitry Andric     QS.setObjCGCAttr(Context.getObjCGCAttrKind(Type));
272*0fca6ea1SDimitry Andric     LVType = Simple;
273*0fca6ea1SDimitry Andric     Initialize(Type, QS, Addr, BaseInfo, TBAAInfo);
274*0fca6ea1SDimitry Andric     assert(Addr.getBasePointer()->getType()->isPointerTy());
275*0fca6ea1SDimitry Andric   }
276*0fca6ea1SDimitry Andric 
2770b57cec5SDimitry Andric public:
2780b57cec5SDimitry Andric   bool isSimple() const { return LVType == Simple; }
2790b57cec5SDimitry Andric   bool isVectorElt() const { return LVType == VectorElt; }
2800b57cec5SDimitry Andric   bool isBitField() const { return LVType == BitField; }
2810b57cec5SDimitry Andric   bool isExtVectorElt() const { return LVType == ExtVectorElt; }
2820b57cec5SDimitry Andric   bool isGlobalReg() const { return LVType == GlobalReg; }
2835ffd83dbSDimitry Andric   bool isMatrixElt() const { return LVType == MatrixElt; }
2840b57cec5SDimitry Andric 
2850b57cec5SDimitry Andric   bool isVolatileQualified() const { return Quals.hasVolatile(); }
2860b57cec5SDimitry Andric   bool isRestrictQualified() const { return Quals.hasRestrict(); }
2870b57cec5SDimitry Andric   unsigned getVRQualifiers() const {
2880b57cec5SDimitry Andric     return Quals.getCVRQualifiers() & ~Qualifiers::Const;
2890b57cec5SDimitry Andric   }
2900b57cec5SDimitry Andric 
2910b57cec5SDimitry Andric   QualType getType() const { return Type; }
2920b57cec5SDimitry Andric 
2930b57cec5SDimitry Andric   Qualifiers::ObjCLifetime getObjCLifetime() const {
2940b57cec5SDimitry Andric     return Quals.getObjCLifetime();
2950b57cec5SDimitry Andric   }
2960b57cec5SDimitry Andric 
2970b57cec5SDimitry Andric   bool isObjCIvar() const { return Ivar; }
2980b57cec5SDimitry Andric   void setObjCIvar(bool Value) { Ivar = Value; }
2990b57cec5SDimitry Andric 
3000b57cec5SDimitry Andric   bool isObjCArray() const { return ObjIsArray; }
3010b57cec5SDimitry Andric   void setObjCArray(bool Value) { ObjIsArray = Value; }
3020b57cec5SDimitry Andric 
3030b57cec5SDimitry Andric   bool isNonGC () const { return NonGC; }
3040b57cec5SDimitry Andric   void setNonGC(bool Value) { NonGC = Value; }
3050b57cec5SDimitry Andric 
3060b57cec5SDimitry Andric   bool isGlobalObjCRef() const { return GlobalObjCRef; }
3070b57cec5SDimitry Andric   void setGlobalObjCRef(bool Value) { GlobalObjCRef = Value; }
3080b57cec5SDimitry Andric 
3090b57cec5SDimitry Andric   bool isThreadLocalRef() const { return ThreadLocalRef; }
3100b57cec5SDimitry Andric   void setThreadLocalRef(bool Value) { ThreadLocalRef = Value;}
3110b57cec5SDimitry Andric 
3120b57cec5SDimitry Andric   ARCPreciseLifetime_t isARCPreciseLifetime() const {
3130b57cec5SDimitry Andric     return ARCPreciseLifetime_t(!ImpreciseLifetime);
3140b57cec5SDimitry Andric   }
3150b57cec5SDimitry Andric   void setARCPreciseLifetime(ARCPreciseLifetime_t value) {
3160b57cec5SDimitry Andric     ImpreciseLifetime = (value == ARCImpreciseLifetime);
3170b57cec5SDimitry Andric   }
3180b57cec5SDimitry Andric   bool isNontemporal() const { return Nontemporal; }
3190b57cec5SDimitry Andric   void setNontemporal(bool Value) { Nontemporal = Value; }
3200b57cec5SDimitry Andric 
3210b57cec5SDimitry Andric   bool isObjCWeak() const {
3220b57cec5SDimitry Andric     return Quals.getObjCGCAttr() == Qualifiers::Weak;
3230b57cec5SDimitry Andric   }
3240b57cec5SDimitry Andric   bool isObjCStrong() const {
3250b57cec5SDimitry Andric     return Quals.getObjCGCAttr() == Qualifiers::Strong;
3260b57cec5SDimitry Andric   }
3270b57cec5SDimitry Andric 
3280b57cec5SDimitry Andric   bool isVolatile() const {
3290b57cec5SDimitry Andric     return Quals.hasVolatile();
3300b57cec5SDimitry Andric   }
3310b57cec5SDimitry Andric 
3320b57cec5SDimitry Andric   Expr *getBaseIvarExp() const { return BaseIvarExp; }
3330b57cec5SDimitry Andric   void setBaseIvarExp(Expr *V) { BaseIvarExp = V; }
3340b57cec5SDimitry Andric 
3350b57cec5SDimitry Andric   TBAAAccessInfo getTBAAInfo() const { return TBAAInfo; }
3360b57cec5SDimitry Andric   void setTBAAInfo(TBAAAccessInfo Info) { TBAAInfo = Info; }
3370b57cec5SDimitry Andric 
3380b57cec5SDimitry Andric   const Qualifiers &getQuals() const { return Quals; }
3390b57cec5SDimitry Andric   Qualifiers &getQuals() { return Quals; }
3400b57cec5SDimitry Andric 
3410b57cec5SDimitry Andric   LangAS getAddressSpace() const { return Quals.getAddressSpace(); }
3420b57cec5SDimitry Andric 
343*0fca6ea1SDimitry Andric   CharUnits getAlignment() const { return Addr.getAlignment(); }
344*0fca6ea1SDimitry Andric   void setAlignment(CharUnits A) { Addr.setAlignment(A); }
3450b57cec5SDimitry Andric 
3460b57cec5SDimitry Andric   LValueBaseInfo getBaseInfo() const { return BaseInfo; }
3470b57cec5SDimitry Andric   void setBaseInfo(LValueBaseInfo Info) { BaseInfo = Info; }
3480b57cec5SDimitry Andric 
349*0fca6ea1SDimitry Andric   KnownNonNull_t isKnownNonNull() const { return Addr.isKnownNonNull(); }
35006c3fb27SDimitry Andric   LValue setKnownNonNull() {
351*0fca6ea1SDimitry Andric     Addr.setKnownNonNull();
35206c3fb27SDimitry Andric     return *this;
35306c3fb27SDimitry Andric   }
35406c3fb27SDimitry Andric 
3550b57cec5SDimitry Andric   // simple lvalue
356*0fca6ea1SDimitry Andric   llvm::Value *getPointer(CodeGenFunction &CGF) const;
357*0fca6ea1SDimitry Andric   llvm::Value *emitResignedPointer(QualType PointeeTy,
358*0fca6ea1SDimitry Andric                                    CodeGenFunction &CGF) const;
359*0fca6ea1SDimitry Andric   llvm::Value *emitRawPointer(CodeGenFunction &CGF) const;
360*0fca6ea1SDimitry Andric 
361*0fca6ea1SDimitry Andric   Address getAddress() const { return Addr; }
362*0fca6ea1SDimitry Andric 
363*0fca6ea1SDimitry Andric   void setAddress(Address address) { Addr = address; }
364*0fca6ea1SDimitry Andric 
365*0fca6ea1SDimitry Andric   CGPointerAuthInfo getPointerAuthInfo() const {
366*0fca6ea1SDimitry Andric     return Addr.getPointerAuthInfo();
3670b57cec5SDimitry Andric   }
3680b57cec5SDimitry Andric 
3690b57cec5SDimitry Andric   // vector elt lvalue
3700b57cec5SDimitry Andric   Address getVectorAddress() const {
371*0fca6ea1SDimitry Andric     assert(isVectorElt());
372*0fca6ea1SDimitry Andric     return Addr;
373*0fca6ea1SDimitry Andric   }
374*0fca6ea1SDimitry Andric   llvm::Value *getRawVectorPointer(CodeGenFunction &CGF) const {
375*0fca6ea1SDimitry Andric     assert(isVectorElt());
376*0fca6ea1SDimitry Andric     return Addr.emitRawPointer(CGF);
3770b57cec5SDimitry Andric   }
3785ffd83dbSDimitry Andric   llvm::Value *getVectorPointer() const {
3795ffd83dbSDimitry Andric     assert(isVectorElt());
380*0fca6ea1SDimitry Andric     return Addr.getBasePointer();
3815ffd83dbSDimitry Andric   }
3825ffd83dbSDimitry Andric   llvm::Value *getVectorIdx() const {
3835ffd83dbSDimitry Andric     assert(isVectorElt());
3845ffd83dbSDimitry Andric     return VectorIdx;
3855ffd83dbSDimitry Andric   }
3865ffd83dbSDimitry Andric 
3875ffd83dbSDimitry Andric   Address getMatrixAddress() const {
388*0fca6ea1SDimitry Andric     assert(isMatrixElt());
389*0fca6ea1SDimitry Andric     return Addr;
3905ffd83dbSDimitry Andric   }
3915ffd83dbSDimitry Andric   llvm::Value *getMatrixPointer() const {
3925ffd83dbSDimitry Andric     assert(isMatrixElt());
393*0fca6ea1SDimitry Andric     return Addr.getBasePointer();
3945ffd83dbSDimitry Andric   }
3955ffd83dbSDimitry Andric   llvm::Value *getMatrixIdx() const {
3965ffd83dbSDimitry Andric     assert(isMatrixElt());
3975ffd83dbSDimitry Andric     return VectorIdx;
3985ffd83dbSDimitry Andric   }
3990b57cec5SDimitry Andric 
4000b57cec5SDimitry Andric   // extended vector elements.
4010b57cec5SDimitry Andric   Address getExtVectorAddress() const {
4020b57cec5SDimitry Andric     assert(isExtVectorElt());
403*0fca6ea1SDimitry Andric     return Addr;
404*0fca6ea1SDimitry Andric   }
405*0fca6ea1SDimitry Andric   llvm::Value *getRawExtVectorPointer(CodeGenFunction &CGF) const {
406*0fca6ea1SDimitry Andric     assert(isExtVectorElt());
407*0fca6ea1SDimitry Andric     return Addr.emitRawPointer(CGF);
4080b57cec5SDimitry Andric   }
4090b57cec5SDimitry Andric   llvm::Constant *getExtVectorElts() const {
4100b57cec5SDimitry Andric     assert(isExtVectorElt());
4110b57cec5SDimitry Andric     return VectorElts;
4120b57cec5SDimitry Andric   }
4130b57cec5SDimitry Andric 
4140b57cec5SDimitry Andric   // bitfield lvalue
4150b57cec5SDimitry Andric   Address getBitFieldAddress() const {
416*0fca6ea1SDimitry Andric     assert(isBitField());
417*0fca6ea1SDimitry Andric     return Addr;
4180b57cec5SDimitry Andric   }
419*0fca6ea1SDimitry Andric   llvm::Value *getRawBitFieldPointer(CodeGenFunction &CGF) const {
420*0fca6ea1SDimitry Andric     assert(isBitField());
421*0fca6ea1SDimitry Andric     return Addr.emitRawPointer(CGF);
422*0fca6ea1SDimitry Andric   }
423*0fca6ea1SDimitry Andric 
4240b57cec5SDimitry Andric   const CGBitFieldInfo &getBitFieldInfo() const {
4250b57cec5SDimitry Andric     assert(isBitField());
4260b57cec5SDimitry Andric     return *BitFieldInfo;
4270b57cec5SDimitry Andric   }
4280b57cec5SDimitry Andric 
4290b57cec5SDimitry Andric   // global register lvalue
4300b57cec5SDimitry Andric   llvm::Value *getGlobalReg() const { assert(isGlobalReg()); return V; }
4310b57cec5SDimitry Andric 
432*0fca6ea1SDimitry Andric   static LValue MakeAddr(Address Addr, QualType type, ASTContext &Context,
4330b57cec5SDimitry Andric                          LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo) {
4340b57cec5SDimitry Andric     LValue R;
4350b57cec5SDimitry Andric     R.LVType = Simple;
436*0fca6ea1SDimitry Andric     R.initializeSimpleLValue(Addr, type, BaseInfo, TBAAInfo, Context);
437*0fca6ea1SDimitry Andric     R.Addr = Addr;
438*0fca6ea1SDimitry Andric     assert(Addr.getType()->isPointerTy());
4390b57cec5SDimitry Andric     return R;
4400b57cec5SDimitry Andric   }
4410b57cec5SDimitry Andric 
4420b57cec5SDimitry Andric   static LValue MakeVectorElt(Address vecAddress, llvm::Value *Idx,
4430b57cec5SDimitry Andric                               QualType type, LValueBaseInfo BaseInfo,
4440b57cec5SDimitry Andric                               TBAAAccessInfo TBAAInfo) {
4450b57cec5SDimitry Andric     LValue R;
4460b57cec5SDimitry Andric     R.LVType = VectorElt;
4470b57cec5SDimitry Andric     R.VectorIdx = Idx;
448*0fca6ea1SDimitry Andric     R.Initialize(type, type.getQualifiers(), vecAddress, BaseInfo, TBAAInfo);
4490b57cec5SDimitry Andric     return R;
4500b57cec5SDimitry Andric   }
4510b57cec5SDimitry Andric 
452*0fca6ea1SDimitry Andric   static LValue MakeExtVectorElt(Address Addr, llvm::Constant *Elts,
4530b57cec5SDimitry Andric                                  QualType type, LValueBaseInfo BaseInfo,
4540b57cec5SDimitry Andric                                  TBAAAccessInfo TBAAInfo) {
4550b57cec5SDimitry Andric     LValue R;
4560b57cec5SDimitry Andric     R.LVType = ExtVectorElt;
4570b57cec5SDimitry Andric     R.VectorElts = Elts;
458*0fca6ea1SDimitry Andric     R.Initialize(type, type.getQualifiers(), Addr, BaseInfo, TBAAInfo);
4590b57cec5SDimitry Andric     return R;
4600b57cec5SDimitry Andric   }
4610b57cec5SDimitry Andric 
4620b57cec5SDimitry Andric   /// Create a new object to represent a bit-field access.
4630b57cec5SDimitry Andric   ///
4640b57cec5SDimitry Andric   /// \param Addr - The base address of the bit-field sequence this
4650b57cec5SDimitry Andric   /// bit-field refers to.
4660b57cec5SDimitry Andric   /// \param Info - The information describing how to perform the bit-field
4670b57cec5SDimitry Andric   /// access.
4680b57cec5SDimitry Andric   static LValue MakeBitfield(Address Addr, const CGBitFieldInfo &Info,
4690b57cec5SDimitry Andric                              QualType type, LValueBaseInfo BaseInfo,
4700b57cec5SDimitry Andric                              TBAAAccessInfo TBAAInfo) {
4710b57cec5SDimitry Andric     LValue R;
4720b57cec5SDimitry Andric     R.LVType = BitField;
4730b57cec5SDimitry Andric     R.BitFieldInfo = &Info;
474*0fca6ea1SDimitry Andric     R.Initialize(type, type.getQualifiers(), Addr, BaseInfo, TBAAInfo);
4750b57cec5SDimitry Andric     return R;
4760b57cec5SDimitry Andric   }
4770b57cec5SDimitry Andric 
4780eae32dcSDimitry Andric   static LValue MakeGlobalReg(llvm::Value *V, CharUnits alignment,
4790eae32dcSDimitry Andric                               QualType type) {
4800b57cec5SDimitry Andric     LValue R;
4810b57cec5SDimitry Andric     R.LVType = GlobalReg;
482*0fca6ea1SDimitry Andric     R.Initialize(type, type.getQualifiers(), Address::invalid(),
4830b57cec5SDimitry Andric                  LValueBaseInfo(AlignmentSource::Decl), TBAAAccessInfo());
484*0fca6ea1SDimitry Andric     R.V = V;
4850b57cec5SDimitry Andric     return R;
4860b57cec5SDimitry Andric   }
4870b57cec5SDimitry Andric 
4885ffd83dbSDimitry Andric   static LValue MakeMatrixElt(Address matAddress, llvm::Value *Idx,
4895ffd83dbSDimitry Andric                               QualType type, LValueBaseInfo BaseInfo,
4905ffd83dbSDimitry Andric                               TBAAAccessInfo TBAAInfo) {
4915ffd83dbSDimitry Andric     LValue R;
4925ffd83dbSDimitry Andric     R.LVType = MatrixElt;
4935ffd83dbSDimitry Andric     R.VectorIdx = Idx;
494*0fca6ea1SDimitry Andric     R.Initialize(type, type.getQualifiers(), matAddress, BaseInfo, TBAAInfo);
4955ffd83dbSDimitry Andric     return R;
4965ffd83dbSDimitry Andric   }
4975ffd83dbSDimitry Andric 
498*0fca6ea1SDimitry Andric   RValue asAggregateRValue() const {
499*0fca6ea1SDimitry Andric     return RValue::getAggregate(getAddress(), isVolatileQualified());
5000b57cec5SDimitry Andric   }
5010b57cec5SDimitry Andric };
5020b57cec5SDimitry Andric 
5030b57cec5SDimitry Andric /// An aggregate value slot.
5040b57cec5SDimitry Andric class AggValueSlot {
5050b57cec5SDimitry Andric   /// The address.
5060eae32dcSDimitry Andric   Address Addr;
5070b57cec5SDimitry Andric 
5080b57cec5SDimitry Andric   // Qualifiers
5090b57cec5SDimitry Andric   Qualifiers Quals;
5100b57cec5SDimitry Andric 
5110b57cec5SDimitry Andric   /// DestructedFlag - This is set to true if some external code is
5120b57cec5SDimitry Andric   /// responsible for setting up a destructor for the slot.  Otherwise
5130b57cec5SDimitry Andric   /// the code which constructs it should push the appropriate cleanup.
5140b57cec5SDimitry Andric   bool DestructedFlag : 1;
5150b57cec5SDimitry Andric 
5160b57cec5SDimitry Andric   /// ObjCGCFlag - This is set to true if writing to the memory in the
5170b57cec5SDimitry Andric   /// slot might require calling an appropriate Objective-C GC
5180b57cec5SDimitry Andric   /// barrier.  The exact interaction here is unnecessarily mysterious.
5190b57cec5SDimitry Andric   bool ObjCGCFlag : 1;
5200b57cec5SDimitry Andric 
5210b57cec5SDimitry Andric   /// ZeroedFlag - This is set to true if the memory in the slot is
5220b57cec5SDimitry Andric   /// known to be zero before the assignment into it.  This means that
5230b57cec5SDimitry Andric   /// zero fields don't need to be set.
5240b57cec5SDimitry Andric   bool ZeroedFlag : 1;
5250b57cec5SDimitry Andric 
5260b57cec5SDimitry Andric   /// AliasedFlag - This is set to true if the slot might be aliased
5270b57cec5SDimitry Andric   /// and it's not undefined behavior to access it through such an
5280b57cec5SDimitry Andric   /// alias.  Note that it's always undefined behavior to access a C++
5290b57cec5SDimitry Andric   /// object that's under construction through an alias derived from
5300b57cec5SDimitry Andric   /// outside the construction process.
5310b57cec5SDimitry Andric   ///
5320b57cec5SDimitry Andric   /// This flag controls whether calls that produce the aggregate
5330b57cec5SDimitry Andric   /// value may be evaluated directly into the slot, or whether they
5340b57cec5SDimitry Andric   /// must be evaluated into an unaliased temporary and then memcpy'ed
5350b57cec5SDimitry Andric   /// over.  Since it's invalid in general to memcpy a non-POD C++
5360b57cec5SDimitry Andric   /// object, it's important that this flag never be set when
5370b57cec5SDimitry Andric   /// evaluating an expression which constructs such an object.
5380b57cec5SDimitry Andric   bool AliasedFlag : 1;
5390b57cec5SDimitry Andric 
5400b57cec5SDimitry Andric   /// This is set to true if the tail padding of this slot might overlap
5410b57cec5SDimitry Andric   /// another object that may have already been initialized (and whose
5420b57cec5SDimitry Andric   /// value must be preserved by this initialization). If so, we may only
5430b57cec5SDimitry Andric   /// store up to the dsize of the type. Otherwise we can widen stores to
5440b57cec5SDimitry Andric   /// the size of the type.
5450b57cec5SDimitry Andric   bool OverlapFlag : 1;
5460b57cec5SDimitry Andric 
5470b57cec5SDimitry Andric   /// If is set to true, sanitizer checks are already generated for this address
5480b57cec5SDimitry Andric   /// or not required. For instance, if this address represents an object
5490b57cec5SDimitry Andric   /// created in 'new' expression, sanitizer checks for memory is made as a part
5500b57cec5SDimitry Andric   /// of 'operator new' emission and object constructor should not generate
5510b57cec5SDimitry Andric   /// them.
5520b57cec5SDimitry Andric   bool SanitizerCheckedFlag : 1;
5530b57cec5SDimitry Andric 
5540eae32dcSDimitry Andric   AggValueSlot(Address Addr, Qualifiers Quals, bool DestructedFlag,
5550eae32dcSDimitry Andric                bool ObjCGCFlag, bool ZeroedFlag, bool AliasedFlag,
5560eae32dcSDimitry Andric                bool OverlapFlag, bool SanitizerCheckedFlag)
5570eae32dcSDimitry Andric       : Addr(Addr), Quals(Quals), DestructedFlag(DestructedFlag),
5580eae32dcSDimitry Andric         ObjCGCFlag(ObjCGCFlag), ZeroedFlag(ZeroedFlag),
5590eae32dcSDimitry Andric         AliasedFlag(AliasedFlag), OverlapFlag(OverlapFlag),
5600eae32dcSDimitry Andric         SanitizerCheckedFlag(SanitizerCheckedFlag) {}
5610eae32dcSDimitry Andric 
5620b57cec5SDimitry Andric public:
5630b57cec5SDimitry Andric   enum IsAliased_t { IsNotAliased, IsAliased };
5640b57cec5SDimitry Andric   enum IsDestructed_t { IsNotDestructed, IsDestructed };
5650b57cec5SDimitry Andric   enum IsZeroed_t { IsNotZeroed, IsZeroed };
5660b57cec5SDimitry Andric   enum Overlap_t { DoesNotOverlap, MayOverlap };
5670b57cec5SDimitry Andric   enum NeedsGCBarriers_t { DoesNotNeedGCBarriers, NeedsGCBarriers };
5680b57cec5SDimitry Andric   enum IsSanitizerChecked_t { IsNotSanitizerChecked, IsSanitizerChecked };
5690b57cec5SDimitry Andric 
5700b57cec5SDimitry Andric   /// ignored - Returns an aggregate value slot indicating that the
5710b57cec5SDimitry Andric   /// aggregate value is being ignored.
5720b57cec5SDimitry Andric   static AggValueSlot ignored() {
5730b57cec5SDimitry Andric     return forAddr(Address::invalid(), Qualifiers(), IsNotDestructed,
5740b57cec5SDimitry Andric                    DoesNotNeedGCBarriers, IsNotAliased, DoesNotOverlap);
5750b57cec5SDimitry Andric   }
5760b57cec5SDimitry Andric 
5770b57cec5SDimitry Andric   /// forAddr - Make a slot for an aggregate value.
5780b57cec5SDimitry Andric   ///
5790b57cec5SDimitry Andric   /// \param quals - The qualifiers that dictate how the slot should
5800b57cec5SDimitry Andric   /// be initialied. Only 'volatile' and the Objective-C lifetime
5810b57cec5SDimitry Andric   /// qualifiers matter.
5820b57cec5SDimitry Andric   ///
5830b57cec5SDimitry Andric   /// \param isDestructed - true if something else is responsible
5840b57cec5SDimitry Andric   ///   for calling destructors on this object
5850b57cec5SDimitry Andric   /// \param needsGC - true if the slot is potentially located
5860b57cec5SDimitry Andric   ///   somewhere that ObjC GC calls should be emitted for
5870b57cec5SDimitry Andric   static AggValueSlot forAddr(Address addr,
5880b57cec5SDimitry Andric                               Qualifiers quals,
5890b57cec5SDimitry Andric                               IsDestructed_t isDestructed,
5900b57cec5SDimitry Andric                               NeedsGCBarriers_t needsGC,
5910b57cec5SDimitry Andric                               IsAliased_t isAliased,
5920b57cec5SDimitry Andric                               Overlap_t mayOverlap,
5930b57cec5SDimitry Andric                               IsZeroed_t isZeroed = IsNotZeroed,
5940b57cec5SDimitry Andric                        IsSanitizerChecked_t isChecked = IsNotSanitizerChecked) {
59506c3fb27SDimitry Andric     if (addr.isValid())
59606c3fb27SDimitry Andric       addr.setKnownNonNull();
5970eae32dcSDimitry Andric     return AggValueSlot(addr, quals, isDestructed, needsGC, isZeroed, isAliased,
5980eae32dcSDimitry Andric                         mayOverlap, isChecked);
5990b57cec5SDimitry Andric   }
6000b57cec5SDimitry Andric 
601480093f4SDimitry Andric   static AggValueSlot
602*0fca6ea1SDimitry Andric   forLValue(const LValue &LV, IsDestructed_t isDestructed,
603480093f4SDimitry Andric             NeedsGCBarriers_t needsGC, IsAliased_t isAliased,
604480093f4SDimitry Andric             Overlap_t mayOverlap, IsZeroed_t isZeroed = IsNotZeroed,
6050b57cec5SDimitry Andric             IsSanitizerChecked_t isChecked = IsNotSanitizerChecked) {
606*0fca6ea1SDimitry Andric     return forAddr(LV.getAddress(), LV.getQuals(), isDestructed, needsGC,
6070b57cec5SDimitry Andric                    isAliased, mayOverlap, isZeroed, isChecked);
6080b57cec5SDimitry Andric   }
6090b57cec5SDimitry Andric 
6100b57cec5SDimitry Andric   IsDestructed_t isExternallyDestructed() const {
6110b57cec5SDimitry Andric     return IsDestructed_t(DestructedFlag);
6120b57cec5SDimitry Andric   }
6130b57cec5SDimitry Andric   void setExternallyDestructed(bool destructed = true) {
6140b57cec5SDimitry Andric     DestructedFlag = destructed;
6150b57cec5SDimitry Andric   }
6160b57cec5SDimitry Andric 
6170b57cec5SDimitry Andric   Qualifiers getQualifiers() const { return Quals; }
6180b57cec5SDimitry Andric 
6190b57cec5SDimitry Andric   bool isVolatile() const {
6200b57cec5SDimitry Andric     return Quals.hasVolatile();
6210b57cec5SDimitry Andric   }
6220b57cec5SDimitry Andric 
6230b57cec5SDimitry Andric   void setVolatile(bool flag) {
6240b57cec5SDimitry Andric     if (flag)
6250b57cec5SDimitry Andric       Quals.addVolatile();
6260b57cec5SDimitry Andric     else
6270b57cec5SDimitry Andric       Quals.removeVolatile();
6280b57cec5SDimitry Andric   }
6290b57cec5SDimitry Andric 
6300b57cec5SDimitry Andric   Qualifiers::ObjCLifetime getObjCLifetime() const {
6310b57cec5SDimitry Andric     return Quals.getObjCLifetime();
6320b57cec5SDimitry Andric   }
6330b57cec5SDimitry Andric 
6340b57cec5SDimitry Andric   NeedsGCBarriers_t requiresGCollection() const {
6350b57cec5SDimitry Andric     return NeedsGCBarriers_t(ObjCGCFlag);
6360b57cec5SDimitry Andric   }
6370b57cec5SDimitry Andric 
638*0fca6ea1SDimitry Andric   llvm::Value *getPointer(QualType PointeeTy, CodeGenFunction &CGF) const;
639*0fca6ea1SDimitry Andric 
640*0fca6ea1SDimitry Andric   llvm::Value *emitRawPointer(CodeGenFunction &CGF) const {
641*0fca6ea1SDimitry Andric     return Addr.isValid() ? Addr.emitRawPointer(CGF) : nullptr;
6420b57cec5SDimitry Andric   }
6430b57cec5SDimitry Andric 
6440b57cec5SDimitry Andric   Address getAddress() const {
6450eae32dcSDimitry Andric     return Addr;
6460b57cec5SDimitry Andric   }
6470b57cec5SDimitry Andric 
648*0fca6ea1SDimitry Andric   bool isIgnored() const { return !Addr.isValid(); }
6490b57cec5SDimitry Andric 
6500b57cec5SDimitry Andric   CharUnits getAlignment() const {
6510eae32dcSDimitry Andric     return Addr.getAlignment();
6520b57cec5SDimitry Andric   }
6530b57cec5SDimitry Andric 
6540b57cec5SDimitry Andric   IsAliased_t isPotentiallyAliased() const {
6550b57cec5SDimitry Andric     return IsAliased_t(AliasedFlag);
6560b57cec5SDimitry Andric   }
6570b57cec5SDimitry Andric 
6580b57cec5SDimitry Andric   Overlap_t mayOverlap() const {
6590b57cec5SDimitry Andric     return Overlap_t(OverlapFlag);
6600b57cec5SDimitry Andric   }
6610b57cec5SDimitry Andric 
6620b57cec5SDimitry Andric   bool isSanitizerChecked() const {
6630b57cec5SDimitry Andric     return SanitizerCheckedFlag;
6640b57cec5SDimitry Andric   }
6650b57cec5SDimitry Andric 
6660b57cec5SDimitry Andric   RValue asRValue() const {
6670b57cec5SDimitry Andric     if (isIgnored()) {
6680b57cec5SDimitry Andric       return RValue::getIgnored();
6690b57cec5SDimitry Andric     } else {
6700b57cec5SDimitry Andric       return RValue::getAggregate(getAddress(), isVolatile());
6710b57cec5SDimitry Andric     }
6720b57cec5SDimitry Andric   }
6730b57cec5SDimitry Andric 
6740b57cec5SDimitry Andric   void setZeroed(bool V = true) { ZeroedFlag = V; }
6750b57cec5SDimitry Andric   IsZeroed_t isZeroed() const {
6760b57cec5SDimitry Andric     return IsZeroed_t(ZeroedFlag);
6770b57cec5SDimitry Andric   }
6780b57cec5SDimitry Andric 
6790b57cec5SDimitry Andric   /// Get the preferred size to use when storing a value to this slot. This
6800b57cec5SDimitry Andric   /// is the type size unless that might overlap another object, in which
6810b57cec5SDimitry Andric   /// case it's the dsize.
6820b57cec5SDimitry Andric   CharUnits getPreferredSize(ASTContext &Ctx, QualType Type) const {
683e8d8bef9SDimitry Andric     return mayOverlap() ? Ctx.getTypeInfoDataSizeInChars(Type).Width
6840b57cec5SDimitry Andric                         : Ctx.getTypeSizeInChars(Type);
6850b57cec5SDimitry Andric   }
6860b57cec5SDimitry Andric };
6870b57cec5SDimitry Andric 
6880b57cec5SDimitry Andric }  // end namespace CodeGen
6890b57cec5SDimitry Andric }  // end namespace clang
6900b57cec5SDimitry Andric 
6910b57cec5SDimitry Andric #endif
692