17330f729Sjoerg //===--- APValue.cpp - Union class for APFloat/APSInt/Complex -------------===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg //
97330f729Sjoerg // This file implements the APValue class.
107330f729Sjoerg //
117330f729Sjoerg //===----------------------------------------------------------------------===//
127330f729Sjoerg
137330f729Sjoerg #include "clang/AST/APValue.h"
14*e038c9c4Sjoerg #include "Linkage.h"
157330f729Sjoerg #include "clang/AST/ASTContext.h"
167330f729Sjoerg #include "clang/AST/CharUnits.h"
177330f729Sjoerg #include "clang/AST/DeclCXX.h"
187330f729Sjoerg #include "clang/AST/Expr.h"
19*e038c9c4Sjoerg #include "clang/AST/ExprCXX.h"
207330f729Sjoerg #include "clang/AST/Type.h"
217330f729Sjoerg #include "llvm/Support/ErrorHandling.h"
227330f729Sjoerg #include "llvm/Support/raw_ostream.h"
237330f729Sjoerg using namespace clang;
247330f729Sjoerg
257330f729Sjoerg /// The identity of a type_info object depends on the canonical unqualified
267330f729Sjoerg /// type only.
TypeInfoLValue(const Type * T)277330f729Sjoerg TypeInfoLValue::TypeInfoLValue(const Type *T)
287330f729Sjoerg : T(T->getCanonicalTypeUnqualified().getTypePtr()) {}
297330f729Sjoerg
print(llvm::raw_ostream & Out,const PrintingPolicy & Policy) const307330f729Sjoerg void TypeInfoLValue::print(llvm::raw_ostream &Out,
317330f729Sjoerg const PrintingPolicy &Policy) const {
327330f729Sjoerg Out << "typeid(";
337330f729Sjoerg QualType(getType(), 0).print(Out, Policy);
347330f729Sjoerg Out << ")";
357330f729Sjoerg }
367330f729Sjoerg
377330f729Sjoerg static_assert(
387330f729Sjoerg 1 << llvm::PointerLikeTypeTraits<TypeInfoLValue>::NumLowBitsAvailable <=
397330f729Sjoerg alignof(Type),
407330f729Sjoerg "Type is insufficiently aligned");
417330f729Sjoerg
LValueBase(const ValueDecl * P,unsigned I,unsigned V)427330f729Sjoerg APValue::LValueBase::LValueBase(const ValueDecl *P, unsigned I, unsigned V)
43*e038c9c4Sjoerg : Ptr(P ? cast<ValueDecl>(P->getCanonicalDecl()) : nullptr), Local{I, V} {}
LValueBase(const Expr * P,unsigned I,unsigned V)447330f729Sjoerg APValue::LValueBase::LValueBase(const Expr *P, unsigned I, unsigned V)
457330f729Sjoerg : Ptr(P), Local{I, V} {}
467330f729Sjoerg
getDynamicAlloc(DynamicAllocLValue LV,QualType Type)477330f729Sjoerg APValue::LValueBase APValue::LValueBase::getDynamicAlloc(DynamicAllocLValue LV,
487330f729Sjoerg QualType Type) {
497330f729Sjoerg LValueBase Base;
507330f729Sjoerg Base.Ptr = LV;
517330f729Sjoerg Base.DynamicAllocType = Type.getAsOpaquePtr();
527330f729Sjoerg return Base;
537330f729Sjoerg }
547330f729Sjoerg
getTypeInfo(TypeInfoLValue LV,QualType TypeInfo)557330f729Sjoerg APValue::LValueBase APValue::LValueBase::getTypeInfo(TypeInfoLValue LV,
567330f729Sjoerg QualType TypeInfo) {
577330f729Sjoerg LValueBase Base;
587330f729Sjoerg Base.Ptr = LV;
597330f729Sjoerg Base.TypeInfoType = TypeInfo.getAsOpaquePtr();
607330f729Sjoerg return Base;
617330f729Sjoerg }
627330f729Sjoerg
getType() const63*e038c9c4Sjoerg QualType APValue::LValueBase::getType() const {
64*e038c9c4Sjoerg if (!*this) return QualType();
65*e038c9c4Sjoerg if (const ValueDecl *D = dyn_cast<const ValueDecl*>()) {
66*e038c9c4Sjoerg // FIXME: It's unclear where we're supposed to take the type from, and
67*e038c9c4Sjoerg // this actually matters for arrays of unknown bound. Eg:
68*e038c9c4Sjoerg //
69*e038c9c4Sjoerg // extern int arr[]; void f() { extern int arr[3]; };
70*e038c9c4Sjoerg // constexpr int *p = &arr[1]; // valid?
71*e038c9c4Sjoerg //
72*e038c9c4Sjoerg // For now, we take the most complete type we can find.
73*e038c9c4Sjoerg for (auto *Redecl = cast<ValueDecl>(D->getMostRecentDecl()); Redecl;
74*e038c9c4Sjoerg Redecl = cast_or_null<ValueDecl>(Redecl->getPreviousDecl())) {
75*e038c9c4Sjoerg QualType T = Redecl->getType();
76*e038c9c4Sjoerg if (!T->isIncompleteArrayType())
77*e038c9c4Sjoerg return T;
78*e038c9c4Sjoerg }
79*e038c9c4Sjoerg return D->getType();
80*e038c9c4Sjoerg }
81*e038c9c4Sjoerg
82*e038c9c4Sjoerg if (is<TypeInfoLValue>())
83*e038c9c4Sjoerg return getTypeInfoType();
84*e038c9c4Sjoerg
85*e038c9c4Sjoerg if (is<DynamicAllocLValue>())
86*e038c9c4Sjoerg return getDynamicAllocType();
87*e038c9c4Sjoerg
88*e038c9c4Sjoerg const Expr *Base = get<const Expr*>();
89*e038c9c4Sjoerg
90*e038c9c4Sjoerg // For a materialized temporary, the type of the temporary we materialized
91*e038c9c4Sjoerg // may not be the type of the expression.
92*e038c9c4Sjoerg if (const MaterializeTemporaryExpr *MTE =
93*e038c9c4Sjoerg clang::dyn_cast<MaterializeTemporaryExpr>(Base)) {
94*e038c9c4Sjoerg SmallVector<const Expr *, 2> CommaLHSs;
95*e038c9c4Sjoerg SmallVector<SubobjectAdjustment, 2> Adjustments;
96*e038c9c4Sjoerg const Expr *Temp = MTE->getSubExpr();
97*e038c9c4Sjoerg const Expr *Inner = Temp->skipRValueSubobjectAdjustments(CommaLHSs,
98*e038c9c4Sjoerg Adjustments);
99*e038c9c4Sjoerg // Keep any cv-qualifiers from the reference if we generated a temporary
100*e038c9c4Sjoerg // for it directly. Otherwise use the type after adjustment.
101*e038c9c4Sjoerg if (!Adjustments.empty())
102*e038c9c4Sjoerg return Inner->getType();
103*e038c9c4Sjoerg }
104*e038c9c4Sjoerg
105*e038c9c4Sjoerg return Base->getType();
106*e038c9c4Sjoerg }
107*e038c9c4Sjoerg
getCallIndex() const1087330f729Sjoerg unsigned APValue::LValueBase::getCallIndex() const {
1097330f729Sjoerg return (is<TypeInfoLValue>() || is<DynamicAllocLValue>()) ? 0
1107330f729Sjoerg : Local.CallIndex;
1117330f729Sjoerg }
1127330f729Sjoerg
getVersion() const1137330f729Sjoerg unsigned APValue::LValueBase::getVersion() const {
1147330f729Sjoerg return (is<TypeInfoLValue>() || is<DynamicAllocLValue>()) ? 0 : Local.Version;
1157330f729Sjoerg }
1167330f729Sjoerg
getTypeInfoType() const1177330f729Sjoerg QualType APValue::LValueBase::getTypeInfoType() const {
1187330f729Sjoerg assert(is<TypeInfoLValue>() && "not a type_info lvalue");
1197330f729Sjoerg return QualType::getFromOpaquePtr(TypeInfoType);
1207330f729Sjoerg }
1217330f729Sjoerg
getDynamicAllocType() const1227330f729Sjoerg QualType APValue::LValueBase::getDynamicAllocType() const {
1237330f729Sjoerg assert(is<DynamicAllocLValue>() && "not a dynamic allocation lvalue");
1247330f729Sjoerg return QualType::getFromOpaquePtr(DynamicAllocType);
1257330f729Sjoerg }
1267330f729Sjoerg
Profile(llvm::FoldingSetNodeID & ID) const127*e038c9c4Sjoerg void APValue::LValueBase::Profile(llvm::FoldingSetNodeID &ID) const {
128*e038c9c4Sjoerg ID.AddPointer(Ptr.getOpaqueValue());
129*e038c9c4Sjoerg if (is<TypeInfoLValue>() || is<DynamicAllocLValue>())
130*e038c9c4Sjoerg return;
131*e038c9c4Sjoerg ID.AddInteger(Local.CallIndex);
132*e038c9c4Sjoerg ID.AddInteger(Local.Version);
133*e038c9c4Sjoerg }
134*e038c9c4Sjoerg
1357330f729Sjoerg namespace clang {
operator ==(const APValue::LValueBase & LHS,const APValue::LValueBase & RHS)1367330f729Sjoerg bool operator==(const APValue::LValueBase &LHS,
1377330f729Sjoerg const APValue::LValueBase &RHS) {
1387330f729Sjoerg if (LHS.Ptr != RHS.Ptr)
1397330f729Sjoerg return false;
140*e038c9c4Sjoerg if (LHS.is<TypeInfoLValue>() || LHS.is<DynamicAllocLValue>())
1417330f729Sjoerg return true;
1427330f729Sjoerg return LHS.Local.CallIndex == RHS.Local.CallIndex &&
1437330f729Sjoerg LHS.Local.Version == RHS.Local.Version;
1447330f729Sjoerg }
1457330f729Sjoerg }
1467330f729Sjoerg
LValuePathEntry(BaseOrMemberType BaseOrMember)147*e038c9c4Sjoerg APValue::LValuePathEntry::LValuePathEntry(BaseOrMemberType BaseOrMember) {
148*e038c9c4Sjoerg if (const Decl *D = BaseOrMember.getPointer())
149*e038c9c4Sjoerg BaseOrMember.setPointer(D->getCanonicalDecl());
150*e038c9c4Sjoerg Value = reinterpret_cast<uintptr_t>(BaseOrMember.getOpaqueValue());
151*e038c9c4Sjoerg }
152*e038c9c4Sjoerg
Profile(llvm::FoldingSetNodeID & ID) const153*e038c9c4Sjoerg void APValue::LValuePathEntry::Profile(llvm::FoldingSetNodeID &ID) const {
154*e038c9c4Sjoerg ID.AddInteger(Value);
155*e038c9c4Sjoerg }
156*e038c9c4Sjoerg
LValuePathSerializationHelper(ArrayRef<LValuePathEntry> Path,QualType ElemTy)157*e038c9c4Sjoerg APValue::LValuePathSerializationHelper::LValuePathSerializationHelper(
158*e038c9c4Sjoerg ArrayRef<LValuePathEntry> Path, QualType ElemTy)
159*e038c9c4Sjoerg : ElemTy((const void *)ElemTy.getTypePtrOrNull()), Path(Path) {}
160*e038c9c4Sjoerg
getType()161*e038c9c4Sjoerg QualType APValue::LValuePathSerializationHelper::getType() {
162*e038c9c4Sjoerg return QualType::getFromOpaquePtr(ElemTy);
163*e038c9c4Sjoerg }
164*e038c9c4Sjoerg
1657330f729Sjoerg namespace {
1667330f729Sjoerg struct LVBase {
1677330f729Sjoerg APValue::LValueBase Base;
1687330f729Sjoerg CharUnits Offset;
1697330f729Sjoerg unsigned PathLength;
1707330f729Sjoerg bool IsNullPtr : 1;
1717330f729Sjoerg bool IsOnePastTheEnd : 1;
1727330f729Sjoerg };
1737330f729Sjoerg }
1747330f729Sjoerg
getOpaqueValue() const1757330f729Sjoerg void *APValue::LValueBase::getOpaqueValue() const {
1767330f729Sjoerg return Ptr.getOpaqueValue();
1777330f729Sjoerg }
1787330f729Sjoerg
isNull() const1797330f729Sjoerg bool APValue::LValueBase::isNull() const {
1807330f729Sjoerg return Ptr.isNull();
1817330f729Sjoerg }
1827330f729Sjoerg
operator bool() const1837330f729Sjoerg APValue::LValueBase::operator bool () const {
1847330f729Sjoerg return static_cast<bool>(Ptr);
1857330f729Sjoerg }
1867330f729Sjoerg
1877330f729Sjoerg clang::APValue::LValueBase
getEmptyKey()1887330f729Sjoerg llvm::DenseMapInfo<clang::APValue::LValueBase>::getEmptyKey() {
189*e038c9c4Sjoerg clang::APValue::LValueBase B;
190*e038c9c4Sjoerg B.Ptr = DenseMapInfo<const ValueDecl*>::getEmptyKey();
191*e038c9c4Sjoerg return B;
1927330f729Sjoerg }
1937330f729Sjoerg
1947330f729Sjoerg clang::APValue::LValueBase
getTombstoneKey()1957330f729Sjoerg llvm::DenseMapInfo<clang::APValue::LValueBase>::getTombstoneKey() {
196*e038c9c4Sjoerg clang::APValue::LValueBase B;
197*e038c9c4Sjoerg B.Ptr = DenseMapInfo<const ValueDecl*>::getTombstoneKey();
198*e038c9c4Sjoerg return B;
1997330f729Sjoerg }
2007330f729Sjoerg
2017330f729Sjoerg namespace clang {
hash_value(const APValue::LValueBase & Base)2027330f729Sjoerg llvm::hash_code hash_value(const APValue::LValueBase &Base) {
2037330f729Sjoerg if (Base.is<TypeInfoLValue>() || Base.is<DynamicAllocLValue>())
2047330f729Sjoerg return llvm::hash_value(Base.getOpaqueValue());
2057330f729Sjoerg return llvm::hash_combine(Base.getOpaqueValue(), Base.getCallIndex(),
2067330f729Sjoerg Base.getVersion());
2077330f729Sjoerg }
2087330f729Sjoerg }
2097330f729Sjoerg
getHashValue(const clang::APValue::LValueBase & Base)2107330f729Sjoerg unsigned llvm::DenseMapInfo<clang::APValue::LValueBase>::getHashValue(
2117330f729Sjoerg const clang::APValue::LValueBase &Base) {
2127330f729Sjoerg return hash_value(Base);
2137330f729Sjoerg }
2147330f729Sjoerg
isEqual(const clang::APValue::LValueBase & LHS,const clang::APValue::LValueBase & RHS)2157330f729Sjoerg bool llvm::DenseMapInfo<clang::APValue::LValueBase>::isEqual(
2167330f729Sjoerg const clang::APValue::LValueBase &LHS,
2177330f729Sjoerg const clang::APValue::LValueBase &RHS) {
2187330f729Sjoerg return LHS == RHS;
2197330f729Sjoerg }
2207330f729Sjoerg
2217330f729Sjoerg struct APValue::LV : LVBase {
2227330f729Sjoerg static const unsigned InlinePathSpace =
2237330f729Sjoerg (DataSize - sizeof(LVBase)) / sizeof(LValuePathEntry);
2247330f729Sjoerg
2257330f729Sjoerg /// Path - The sequence of base classes, fields and array indices to follow to
2267330f729Sjoerg /// walk from Base to the subobject. When performing GCC-style folding, there
2277330f729Sjoerg /// may not be such a path.
2287330f729Sjoerg union {
2297330f729Sjoerg LValuePathEntry Path[InlinePathSpace];
2307330f729Sjoerg LValuePathEntry *PathPtr;
2317330f729Sjoerg };
2327330f729Sjoerg
LVAPValue::LV2337330f729Sjoerg LV() { PathLength = (unsigned)-1; }
~LVAPValue::LV2347330f729Sjoerg ~LV() { resizePath(0); }
2357330f729Sjoerg
resizePathAPValue::LV2367330f729Sjoerg void resizePath(unsigned Length) {
2377330f729Sjoerg if (Length == PathLength)
2387330f729Sjoerg return;
2397330f729Sjoerg if (hasPathPtr())
2407330f729Sjoerg delete [] PathPtr;
2417330f729Sjoerg PathLength = Length;
2427330f729Sjoerg if (hasPathPtr())
2437330f729Sjoerg PathPtr = new LValuePathEntry[Length];
2447330f729Sjoerg }
2457330f729Sjoerg
hasPathAPValue::LV2467330f729Sjoerg bool hasPath() const { return PathLength != (unsigned)-1; }
hasPathPtrAPValue::LV2477330f729Sjoerg bool hasPathPtr() const { return hasPath() && PathLength > InlinePathSpace; }
2487330f729Sjoerg
getPathAPValue::LV2497330f729Sjoerg LValuePathEntry *getPath() { return hasPathPtr() ? PathPtr : Path; }
getPathAPValue::LV2507330f729Sjoerg const LValuePathEntry *getPath() const {
2517330f729Sjoerg return hasPathPtr() ? PathPtr : Path;
2527330f729Sjoerg }
2537330f729Sjoerg };
2547330f729Sjoerg
2557330f729Sjoerg namespace {
2567330f729Sjoerg struct MemberPointerBase {
2577330f729Sjoerg llvm::PointerIntPair<const ValueDecl*, 1, bool> MemberAndIsDerivedMember;
2587330f729Sjoerg unsigned PathLength;
2597330f729Sjoerg };
2607330f729Sjoerg }
2617330f729Sjoerg
2627330f729Sjoerg struct APValue::MemberPointerData : MemberPointerBase {
2637330f729Sjoerg static const unsigned InlinePathSpace =
2647330f729Sjoerg (DataSize - sizeof(MemberPointerBase)) / sizeof(const CXXRecordDecl*);
2657330f729Sjoerg typedef const CXXRecordDecl *PathElem;
2667330f729Sjoerg union {
2677330f729Sjoerg PathElem Path[InlinePathSpace];
2687330f729Sjoerg PathElem *PathPtr;
2697330f729Sjoerg };
2707330f729Sjoerg
MemberPointerDataAPValue::MemberPointerData2717330f729Sjoerg MemberPointerData() { PathLength = 0; }
~MemberPointerDataAPValue::MemberPointerData2727330f729Sjoerg ~MemberPointerData() { resizePath(0); }
2737330f729Sjoerg
resizePathAPValue::MemberPointerData2747330f729Sjoerg void resizePath(unsigned Length) {
2757330f729Sjoerg if (Length == PathLength)
2767330f729Sjoerg return;
2777330f729Sjoerg if (hasPathPtr())
2787330f729Sjoerg delete [] PathPtr;
2797330f729Sjoerg PathLength = Length;
2807330f729Sjoerg if (hasPathPtr())
2817330f729Sjoerg PathPtr = new PathElem[Length];
2827330f729Sjoerg }
2837330f729Sjoerg
hasPathPtrAPValue::MemberPointerData2847330f729Sjoerg bool hasPathPtr() const { return PathLength > InlinePathSpace; }
2857330f729Sjoerg
getPathAPValue::MemberPointerData2867330f729Sjoerg PathElem *getPath() { return hasPathPtr() ? PathPtr : Path; }
getPathAPValue::MemberPointerData2877330f729Sjoerg const PathElem *getPath() const {
2887330f729Sjoerg return hasPathPtr() ? PathPtr : Path;
2897330f729Sjoerg }
2907330f729Sjoerg };
2917330f729Sjoerg
2927330f729Sjoerg // FIXME: Reduce the malloc traffic here.
2937330f729Sjoerg
Arr(unsigned NumElts,unsigned Size)2947330f729Sjoerg APValue::Arr::Arr(unsigned NumElts, unsigned Size) :
2957330f729Sjoerg Elts(new APValue[NumElts + (NumElts != Size ? 1 : 0)]),
2967330f729Sjoerg NumElts(NumElts), ArrSize(Size) {}
~Arr()2977330f729Sjoerg APValue::Arr::~Arr() { delete [] Elts; }
2987330f729Sjoerg
StructData(unsigned NumBases,unsigned NumFields)2997330f729Sjoerg APValue::StructData::StructData(unsigned NumBases, unsigned NumFields) :
3007330f729Sjoerg Elts(new APValue[NumBases+NumFields]),
3017330f729Sjoerg NumBases(NumBases), NumFields(NumFields) {}
~StructData()3027330f729Sjoerg APValue::StructData::~StructData() {
3037330f729Sjoerg delete [] Elts;
3047330f729Sjoerg }
3057330f729Sjoerg
UnionData()3067330f729Sjoerg APValue::UnionData::UnionData() : Field(nullptr), Value(new APValue) {}
~UnionData()3077330f729Sjoerg APValue::UnionData::~UnionData () {
3087330f729Sjoerg delete Value;
3097330f729Sjoerg }
3107330f729Sjoerg
APValue(const APValue & RHS)3117330f729Sjoerg APValue::APValue(const APValue &RHS) : Kind(None) {
3127330f729Sjoerg switch (RHS.getKind()) {
3137330f729Sjoerg case None:
3147330f729Sjoerg case Indeterminate:
3157330f729Sjoerg Kind = RHS.getKind();
3167330f729Sjoerg break;
3177330f729Sjoerg case Int:
3187330f729Sjoerg MakeInt();
3197330f729Sjoerg setInt(RHS.getInt());
3207330f729Sjoerg break;
3217330f729Sjoerg case Float:
3227330f729Sjoerg MakeFloat();
3237330f729Sjoerg setFloat(RHS.getFloat());
3247330f729Sjoerg break;
3257330f729Sjoerg case FixedPoint: {
3267330f729Sjoerg APFixedPoint FXCopy = RHS.getFixedPoint();
3277330f729Sjoerg MakeFixedPoint(std::move(FXCopy));
3287330f729Sjoerg break;
3297330f729Sjoerg }
3307330f729Sjoerg case Vector:
3317330f729Sjoerg MakeVector();
332*e038c9c4Sjoerg setVector(((const Vec *)(const char *)&RHS.Data)->Elts,
3337330f729Sjoerg RHS.getVectorLength());
3347330f729Sjoerg break;
3357330f729Sjoerg case ComplexInt:
3367330f729Sjoerg MakeComplexInt();
3377330f729Sjoerg setComplexInt(RHS.getComplexIntReal(), RHS.getComplexIntImag());
3387330f729Sjoerg break;
3397330f729Sjoerg case ComplexFloat:
3407330f729Sjoerg MakeComplexFloat();
3417330f729Sjoerg setComplexFloat(RHS.getComplexFloatReal(), RHS.getComplexFloatImag());
3427330f729Sjoerg break;
3437330f729Sjoerg case LValue:
3447330f729Sjoerg MakeLValue();
3457330f729Sjoerg if (RHS.hasLValuePath())
3467330f729Sjoerg setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), RHS.getLValuePath(),
3477330f729Sjoerg RHS.isLValueOnePastTheEnd(), RHS.isNullPointer());
3487330f729Sjoerg else
3497330f729Sjoerg setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), NoLValuePath(),
3507330f729Sjoerg RHS.isNullPointer());
3517330f729Sjoerg break;
3527330f729Sjoerg case Array:
3537330f729Sjoerg MakeArray(RHS.getArrayInitializedElts(), RHS.getArraySize());
3547330f729Sjoerg for (unsigned I = 0, N = RHS.getArrayInitializedElts(); I != N; ++I)
3557330f729Sjoerg getArrayInitializedElt(I) = RHS.getArrayInitializedElt(I);
3567330f729Sjoerg if (RHS.hasArrayFiller())
3577330f729Sjoerg getArrayFiller() = RHS.getArrayFiller();
3587330f729Sjoerg break;
3597330f729Sjoerg case Struct:
3607330f729Sjoerg MakeStruct(RHS.getStructNumBases(), RHS.getStructNumFields());
3617330f729Sjoerg for (unsigned I = 0, N = RHS.getStructNumBases(); I != N; ++I)
3627330f729Sjoerg getStructBase(I) = RHS.getStructBase(I);
3637330f729Sjoerg for (unsigned I = 0, N = RHS.getStructNumFields(); I != N; ++I)
3647330f729Sjoerg getStructField(I) = RHS.getStructField(I);
3657330f729Sjoerg break;
3667330f729Sjoerg case Union:
3677330f729Sjoerg MakeUnion();
3687330f729Sjoerg setUnion(RHS.getUnionField(), RHS.getUnionValue());
3697330f729Sjoerg break;
3707330f729Sjoerg case MemberPointer:
3717330f729Sjoerg MakeMemberPointer(RHS.getMemberPointerDecl(),
3727330f729Sjoerg RHS.isMemberPointerToDerivedMember(),
3737330f729Sjoerg RHS.getMemberPointerPath());
3747330f729Sjoerg break;
3757330f729Sjoerg case AddrLabelDiff:
3767330f729Sjoerg MakeAddrLabelDiff();
3777330f729Sjoerg setAddrLabelDiff(RHS.getAddrLabelDiffLHS(), RHS.getAddrLabelDiffRHS());
3787330f729Sjoerg break;
3797330f729Sjoerg }
3807330f729Sjoerg }
3817330f729Sjoerg
APValue(APValue && RHS)382*e038c9c4Sjoerg APValue::APValue(APValue &&RHS) : Kind(RHS.Kind), Data(RHS.Data) {
383*e038c9c4Sjoerg RHS.Kind = None;
384*e038c9c4Sjoerg }
385*e038c9c4Sjoerg
operator =(const APValue & RHS)386*e038c9c4Sjoerg APValue &APValue::operator=(const APValue &RHS) {
387*e038c9c4Sjoerg if (this != &RHS)
388*e038c9c4Sjoerg *this = APValue(RHS);
389*e038c9c4Sjoerg return *this;
390*e038c9c4Sjoerg }
391*e038c9c4Sjoerg
operator =(APValue && RHS)392*e038c9c4Sjoerg APValue &APValue::operator=(APValue &&RHS) {
393*e038c9c4Sjoerg if (Kind != None && Kind != Indeterminate)
394*e038c9c4Sjoerg DestroyDataAndMakeUninit();
395*e038c9c4Sjoerg Kind = RHS.Kind;
396*e038c9c4Sjoerg Data = RHS.Data;
397*e038c9c4Sjoerg RHS.Kind = None;
398*e038c9c4Sjoerg return *this;
399*e038c9c4Sjoerg }
400*e038c9c4Sjoerg
DestroyDataAndMakeUninit()4017330f729Sjoerg void APValue::DestroyDataAndMakeUninit() {
4027330f729Sjoerg if (Kind == Int)
403*e038c9c4Sjoerg ((APSInt *)(char *)&Data)->~APSInt();
4047330f729Sjoerg else if (Kind == Float)
405*e038c9c4Sjoerg ((APFloat *)(char *)&Data)->~APFloat();
4067330f729Sjoerg else if (Kind == FixedPoint)
407*e038c9c4Sjoerg ((APFixedPoint *)(char *)&Data)->~APFixedPoint();
4087330f729Sjoerg else if (Kind == Vector)
409*e038c9c4Sjoerg ((Vec *)(char *)&Data)->~Vec();
4107330f729Sjoerg else if (Kind == ComplexInt)
411*e038c9c4Sjoerg ((ComplexAPSInt *)(char *)&Data)->~ComplexAPSInt();
4127330f729Sjoerg else if (Kind == ComplexFloat)
413*e038c9c4Sjoerg ((ComplexAPFloat *)(char *)&Data)->~ComplexAPFloat();
4147330f729Sjoerg else if (Kind == LValue)
415*e038c9c4Sjoerg ((LV *)(char *)&Data)->~LV();
4167330f729Sjoerg else if (Kind == Array)
417*e038c9c4Sjoerg ((Arr *)(char *)&Data)->~Arr();
4187330f729Sjoerg else if (Kind == Struct)
419*e038c9c4Sjoerg ((StructData *)(char *)&Data)->~StructData();
4207330f729Sjoerg else if (Kind == Union)
421*e038c9c4Sjoerg ((UnionData *)(char *)&Data)->~UnionData();
4227330f729Sjoerg else if (Kind == MemberPointer)
423*e038c9c4Sjoerg ((MemberPointerData *)(char *)&Data)->~MemberPointerData();
4247330f729Sjoerg else if (Kind == AddrLabelDiff)
425*e038c9c4Sjoerg ((AddrLabelDiffData *)(char *)&Data)->~AddrLabelDiffData();
4267330f729Sjoerg Kind = None;
4277330f729Sjoerg }
4287330f729Sjoerg
needsCleanup() const4297330f729Sjoerg bool APValue::needsCleanup() const {
4307330f729Sjoerg switch (getKind()) {
4317330f729Sjoerg case None:
4327330f729Sjoerg case Indeterminate:
4337330f729Sjoerg case AddrLabelDiff:
4347330f729Sjoerg return false;
4357330f729Sjoerg case Struct:
4367330f729Sjoerg case Union:
4377330f729Sjoerg case Array:
4387330f729Sjoerg case Vector:
4397330f729Sjoerg return true;
4407330f729Sjoerg case Int:
4417330f729Sjoerg return getInt().needsCleanup();
4427330f729Sjoerg case Float:
4437330f729Sjoerg return getFloat().needsCleanup();
4447330f729Sjoerg case FixedPoint:
4457330f729Sjoerg return getFixedPoint().getValue().needsCleanup();
4467330f729Sjoerg case ComplexFloat:
4477330f729Sjoerg assert(getComplexFloatImag().needsCleanup() ==
4487330f729Sjoerg getComplexFloatReal().needsCleanup() &&
4497330f729Sjoerg "In _Complex float types, real and imaginary values always have the "
4507330f729Sjoerg "same size.");
4517330f729Sjoerg return getComplexFloatReal().needsCleanup();
4527330f729Sjoerg case ComplexInt:
4537330f729Sjoerg assert(getComplexIntImag().needsCleanup() ==
4547330f729Sjoerg getComplexIntReal().needsCleanup() &&
4557330f729Sjoerg "In _Complex int types, real and imaginary values must have the "
4567330f729Sjoerg "same size.");
4577330f729Sjoerg return getComplexIntReal().needsCleanup();
4587330f729Sjoerg case LValue:
459*e038c9c4Sjoerg return reinterpret_cast<const LV *>(&Data)->hasPathPtr();
4607330f729Sjoerg case MemberPointer:
461*e038c9c4Sjoerg return reinterpret_cast<const MemberPointerData *>(&Data)->hasPathPtr();
4627330f729Sjoerg }
4637330f729Sjoerg llvm_unreachable("Unknown APValue kind!");
4647330f729Sjoerg }
4657330f729Sjoerg
swap(APValue & RHS)4667330f729Sjoerg void APValue::swap(APValue &RHS) {
4677330f729Sjoerg std::swap(Kind, RHS.Kind);
468*e038c9c4Sjoerg std::swap(Data, RHS.Data);
4697330f729Sjoerg }
4707330f729Sjoerg
471*e038c9c4Sjoerg /// Profile the value of an APInt, excluding its bit-width.
profileIntValue(llvm::FoldingSetNodeID & ID,const llvm::APInt & V)472*e038c9c4Sjoerg static void profileIntValue(llvm::FoldingSetNodeID &ID, const llvm::APInt &V) {
473*e038c9c4Sjoerg for (unsigned I = 0, N = V.getBitWidth(); I < N; I += 32)
474*e038c9c4Sjoerg ID.AddInteger((uint32_t)V.extractBitsAsZExtValue(std::min(32u, N - I), I));
475*e038c9c4Sjoerg }
476*e038c9c4Sjoerg
Profile(llvm::FoldingSetNodeID & ID) const477*e038c9c4Sjoerg void APValue::Profile(llvm::FoldingSetNodeID &ID) const {
478*e038c9c4Sjoerg // Note that our profiling assumes that only APValues of the same type are
479*e038c9c4Sjoerg // ever compared. As a result, we don't consider collisions that could only
480*e038c9c4Sjoerg // happen if the types are different. (For example, structs with different
481*e038c9c4Sjoerg // numbers of members could profile the same.)
482*e038c9c4Sjoerg
483*e038c9c4Sjoerg ID.AddInteger(Kind);
484*e038c9c4Sjoerg
485*e038c9c4Sjoerg switch (Kind) {
486*e038c9c4Sjoerg case None:
487*e038c9c4Sjoerg case Indeterminate:
488*e038c9c4Sjoerg return;
489*e038c9c4Sjoerg
490*e038c9c4Sjoerg case AddrLabelDiff:
491*e038c9c4Sjoerg ID.AddPointer(getAddrLabelDiffLHS()->getLabel()->getCanonicalDecl());
492*e038c9c4Sjoerg ID.AddPointer(getAddrLabelDiffRHS()->getLabel()->getCanonicalDecl());
493*e038c9c4Sjoerg return;
494*e038c9c4Sjoerg
495*e038c9c4Sjoerg case Struct:
496*e038c9c4Sjoerg for (unsigned I = 0, N = getStructNumBases(); I != N; ++I)
497*e038c9c4Sjoerg getStructBase(I).Profile(ID);
498*e038c9c4Sjoerg for (unsigned I = 0, N = getStructNumFields(); I != N; ++I)
499*e038c9c4Sjoerg getStructField(I).Profile(ID);
500*e038c9c4Sjoerg return;
501*e038c9c4Sjoerg
502*e038c9c4Sjoerg case Union:
503*e038c9c4Sjoerg if (!getUnionField()) {
504*e038c9c4Sjoerg ID.AddInteger(0);
505*e038c9c4Sjoerg return;
506*e038c9c4Sjoerg }
507*e038c9c4Sjoerg ID.AddInteger(getUnionField()->getFieldIndex() + 1);
508*e038c9c4Sjoerg getUnionValue().Profile(ID);
509*e038c9c4Sjoerg return;
510*e038c9c4Sjoerg
511*e038c9c4Sjoerg case Array: {
512*e038c9c4Sjoerg if (getArraySize() == 0)
513*e038c9c4Sjoerg return;
514*e038c9c4Sjoerg
515*e038c9c4Sjoerg // The profile should not depend on whether the array is expanded or
516*e038c9c4Sjoerg // not, but we don't want to profile the array filler many times for
517*e038c9c4Sjoerg // a large array. So treat all equal trailing elements as the filler.
518*e038c9c4Sjoerg // Elements are profiled in reverse order to support this, and the
519*e038c9c4Sjoerg // first profiled element is followed by a count. For example:
520*e038c9c4Sjoerg //
521*e038c9c4Sjoerg // ['a', 'c', 'x', 'x', 'x'] is profiled as
522*e038c9c4Sjoerg // [5, 'x', 3, 'c', 'a']
523*e038c9c4Sjoerg llvm::FoldingSetNodeID FillerID;
524*e038c9c4Sjoerg (hasArrayFiller() ? getArrayFiller()
525*e038c9c4Sjoerg : getArrayInitializedElt(getArrayInitializedElts() - 1))
526*e038c9c4Sjoerg .Profile(FillerID);
527*e038c9c4Sjoerg ID.AddNodeID(FillerID);
528*e038c9c4Sjoerg unsigned NumFillers = getArraySize() - getArrayInitializedElts();
529*e038c9c4Sjoerg unsigned N = getArrayInitializedElts();
530*e038c9c4Sjoerg
531*e038c9c4Sjoerg // Count the number of elements equal to the last one. This loop ends
532*e038c9c4Sjoerg // by adding an integer indicating the number of such elements, with
533*e038c9c4Sjoerg // N set to the number of elements left to profile.
534*e038c9c4Sjoerg while (true) {
535*e038c9c4Sjoerg if (N == 0) {
536*e038c9c4Sjoerg // All elements are fillers.
537*e038c9c4Sjoerg assert(NumFillers == getArraySize());
538*e038c9c4Sjoerg ID.AddInteger(NumFillers);
539*e038c9c4Sjoerg break;
540*e038c9c4Sjoerg }
541*e038c9c4Sjoerg
542*e038c9c4Sjoerg // No need to check if the last element is equal to the last
543*e038c9c4Sjoerg // element.
544*e038c9c4Sjoerg if (N != getArraySize()) {
545*e038c9c4Sjoerg llvm::FoldingSetNodeID ElemID;
546*e038c9c4Sjoerg getArrayInitializedElt(N - 1).Profile(ElemID);
547*e038c9c4Sjoerg if (ElemID != FillerID) {
548*e038c9c4Sjoerg ID.AddInteger(NumFillers);
549*e038c9c4Sjoerg ID.AddNodeID(ElemID);
550*e038c9c4Sjoerg --N;
551*e038c9c4Sjoerg break;
552*e038c9c4Sjoerg }
553*e038c9c4Sjoerg }
554*e038c9c4Sjoerg
555*e038c9c4Sjoerg // This is a filler.
556*e038c9c4Sjoerg ++NumFillers;
557*e038c9c4Sjoerg --N;
558*e038c9c4Sjoerg }
559*e038c9c4Sjoerg
560*e038c9c4Sjoerg // Emit the remaining elements.
561*e038c9c4Sjoerg for (; N != 0; --N)
562*e038c9c4Sjoerg getArrayInitializedElt(N - 1).Profile(ID);
563*e038c9c4Sjoerg return;
564*e038c9c4Sjoerg }
565*e038c9c4Sjoerg
566*e038c9c4Sjoerg case Vector:
567*e038c9c4Sjoerg for (unsigned I = 0, N = getVectorLength(); I != N; ++I)
568*e038c9c4Sjoerg getVectorElt(I).Profile(ID);
569*e038c9c4Sjoerg return;
570*e038c9c4Sjoerg
571*e038c9c4Sjoerg case Int:
572*e038c9c4Sjoerg profileIntValue(ID, getInt());
573*e038c9c4Sjoerg return;
574*e038c9c4Sjoerg
575*e038c9c4Sjoerg case Float:
576*e038c9c4Sjoerg profileIntValue(ID, getFloat().bitcastToAPInt());
577*e038c9c4Sjoerg return;
578*e038c9c4Sjoerg
579*e038c9c4Sjoerg case FixedPoint:
580*e038c9c4Sjoerg profileIntValue(ID, getFixedPoint().getValue());
581*e038c9c4Sjoerg return;
582*e038c9c4Sjoerg
583*e038c9c4Sjoerg case ComplexFloat:
584*e038c9c4Sjoerg profileIntValue(ID, getComplexFloatReal().bitcastToAPInt());
585*e038c9c4Sjoerg profileIntValue(ID, getComplexFloatImag().bitcastToAPInt());
586*e038c9c4Sjoerg return;
587*e038c9c4Sjoerg
588*e038c9c4Sjoerg case ComplexInt:
589*e038c9c4Sjoerg profileIntValue(ID, getComplexIntReal());
590*e038c9c4Sjoerg profileIntValue(ID, getComplexIntImag());
591*e038c9c4Sjoerg return;
592*e038c9c4Sjoerg
593*e038c9c4Sjoerg case LValue:
594*e038c9c4Sjoerg getLValueBase().Profile(ID);
595*e038c9c4Sjoerg ID.AddInteger(getLValueOffset().getQuantity());
596*e038c9c4Sjoerg ID.AddInteger((isNullPointer() ? 1 : 0) |
597*e038c9c4Sjoerg (isLValueOnePastTheEnd() ? 2 : 0) |
598*e038c9c4Sjoerg (hasLValuePath() ? 4 : 0));
599*e038c9c4Sjoerg if (hasLValuePath()) {
600*e038c9c4Sjoerg ID.AddInteger(getLValuePath().size());
601*e038c9c4Sjoerg // For uniqueness, we only need to profile the entries corresponding
602*e038c9c4Sjoerg // to union members, but we don't have the type here so we don't know
603*e038c9c4Sjoerg // how to interpret the entries.
604*e038c9c4Sjoerg for (LValuePathEntry E : getLValuePath())
605*e038c9c4Sjoerg E.Profile(ID);
606*e038c9c4Sjoerg }
607*e038c9c4Sjoerg return;
608*e038c9c4Sjoerg
609*e038c9c4Sjoerg case MemberPointer:
610*e038c9c4Sjoerg ID.AddPointer(getMemberPointerDecl());
611*e038c9c4Sjoerg ID.AddInteger(isMemberPointerToDerivedMember());
612*e038c9c4Sjoerg for (const CXXRecordDecl *D : getMemberPointerPath())
613*e038c9c4Sjoerg ID.AddPointer(D);
614*e038c9c4Sjoerg return;
615*e038c9c4Sjoerg }
616*e038c9c4Sjoerg
617*e038c9c4Sjoerg llvm_unreachable("Unknown APValue kind!");
6187330f729Sjoerg }
6197330f729Sjoerg
GetApproxValue(const llvm::APFloat & F)6207330f729Sjoerg static double GetApproxValue(const llvm::APFloat &F) {
6217330f729Sjoerg llvm::APFloat V = F;
6227330f729Sjoerg bool ignored;
6237330f729Sjoerg V.convert(llvm::APFloat::IEEEdouble(), llvm::APFloat::rmNearestTiesToEven,
6247330f729Sjoerg &ignored);
6257330f729Sjoerg return V.convertToDouble();
6267330f729Sjoerg }
6277330f729Sjoerg
printPretty(raw_ostream & Out,const ASTContext & Ctx,QualType Ty) const6287330f729Sjoerg void APValue::printPretty(raw_ostream &Out, const ASTContext &Ctx,
6297330f729Sjoerg QualType Ty) const {
630*e038c9c4Sjoerg printPretty(Out, Ctx.getPrintingPolicy(), Ty, &Ctx);
631*e038c9c4Sjoerg }
632*e038c9c4Sjoerg
printPretty(raw_ostream & Out,const PrintingPolicy & Policy,QualType Ty,const ASTContext * Ctx) const633*e038c9c4Sjoerg void APValue::printPretty(raw_ostream &Out, const PrintingPolicy &Policy,
634*e038c9c4Sjoerg QualType Ty, const ASTContext *Ctx) const {
635*e038c9c4Sjoerg // There are no objects of type 'void', but values of this type can be
636*e038c9c4Sjoerg // returned from functions.
637*e038c9c4Sjoerg if (Ty->isVoidType()) {
638*e038c9c4Sjoerg Out << "void()";
639*e038c9c4Sjoerg return;
640*e038c9c4Sjoerg }
641*e038c9c4Sjoerg
6427330f729Sjoerg switch (getKind()) {
6437330f729Sjoerg case APValue::None:
6447330f729Sjoerg Out << "<out of lifetime>";
6457330f729Sjoerg return;
6467330f729Sjoerg case APValue::Indeterminate:
6477330f729Sjoerg Out << "<uninitialized>";
6487330f729Sjoerg return;
6497330f729Sjoerg case APValue::Int:
6507330f729Sjoerg if (Ty->isBooleanType())
6517330f729Sjoerg Out << (getInt().getBoolValue() ? "true" : "false");
6527330f729Sjoerg else
6537330f729Sjoerg Out << getInt();
6547330f729Sjoerg return;
6557330f729Sjoerg case APValue::Float:
6567330f729Sjoerg Out << GetApproxValue(getFloat());
6577330f729Sjoerg return;
6587330f729Sjoerg case APValue::FixedPoint:
6597330f729Sjoerg Out << getFixedPoint();
6607330f729Sjoerg return;
6617330f729Sjoerg case APValue::Vector: {
6627330f729Sjoerg Out << '{';
6637330f729Sjoerg QualType ElemTy = Ty->castAs<VectorType>()->getElementType();
664*e038c9c4Sjoerg getVectorElt(0).printPretty(Out, Policy, ElemTy, Ctx);
6657330f729Sjoerg for (unsigned i = 1; i != getVectorLength(); ++i) {
6667330f729Sjoerg Out << ", ";
667*e038c9c4Sjoerg getVectorElt(i).printPretty(Out, Policy, ElemTy, Ctx);
6687330f729Sjoerg }
6697330f729Sjoerg Out << '}';
6707330f729Sjoerg return;
6717330f729Sjoerg }
6727330f729Sjoerg case APValue::ComplexInt:
6737330f729Sjoerg Out << getComplexIntReal() << "+" << getComplexIntImag() << "i";
6747330f729Sjoerg return;
6757330f729Sjoerg case APValue::ComplexFloat:
6767330f729Sjoerg Out << GetApproxValue(getComplexFloatReal()) << "+"
6777330f729Sjoerg << GetApproxValue(getComplexFloatImag()) << "i";
6787330f729Sjoerg return;
6797330f729Sjoerg case APValue::LValue: {
6807330f729Sjoerg bool IsReference = Ty->isReferenceType();
6817330f729Sjoerg QualType InnerTy
6827330f729Sjoerg = IsReference ? Ty.getNonReferenceType() : Ty->getPointeeType();
6837330f729Sjoerg if (InnerTy.isNull())
6847330f729Sjoerg InnerTy = Ty;
6857330f729Sjoerg
6867330f729Sjoerg LValueBase Base = getLValueBase();
6877330f729Sjoerg if (!Base) {
6887330f729Sjoerg if (isNullPointer()) {
689*e038c9c4Sjoerg Out << (Policy.Nullptr ? "nullptr" : "0");
6907330f729Sjoerg } else if (IsReference) {
691*e038c9c4Sjoerg Out << "*(" << InnerTy.stream(Policy) << "*)"
6927330f729Sjoerg << getLValueOffset().getQuantity();
6937330f729Sjoerg } else {
694*e038c9c4Sjoerg Out << "(" << Ty.stream(Policy) << ")"
6957330f729Sjoerg << getLValueOffset().getQuantity();
6967330f729Sjoerg }
6977330f729Sjoerg return;
6987330f729Sjoerg }
6997330f729Sjoerg
7007330f729Sjoerg if (!hasLValuePath()) {
7017330f729Sjoerg // No lvalue path: just print the offset.
7027330f729Sjoerg CharUnits O = getLValueOffset();
703*e038c9c4Sjoerg CharUnits S = Ctx ? Ctx->getTypeSizeInChars(InnerTy) : CharUnits::Zero();
7047330f729Sjoerg if (!O.isZero()) {
7057330f729Sjoerg if (IsReference)
7067330f729Sjoerg Out << "*(";
707*e038c9c4Sjoerg if (S.isZero() || O % S) {
7087330f729Sjoerg Out << "(char*)";
7097330f729Sjoerg S = CharUnits::One();
7107330f729Sjoerg }
7117330f729Sjoerg Out << '&';
7127330f729Sjoerg } else if (!IsReference) {
7137330f729Sjoerg Out << '&';
7147330f729Sjoerg }
7157330f729Sjoerg
7167330f729Sjoerg if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>())
7177330f729Sjoerg Out << *VD;
7187330f729Sjoerg else if (TypeInfoLValue TI = Base.dyn_cast<TypeInfoLValue>()) {
719*e038c9c4Sjoerg TI.print(Out, Policy);
7207330f729Sjoerg } else if (DynamicAllocLValue DA = Base.dyn_cast<DynamicAllocLValue>()) {
7217330f729Sjoerg Out << "{*new "
722*e038c9c4Sjoerg << Base.getDynamicAllocType().stream(Policy) << "#"
7237330f729Sjoerg << DA.getIndex() << "}";
7247330f729Sjoerg } else {
7257330f729Sjoerg assert(Base.get<const Expr *>() != nullptr &&
7267330f729Sjoerg "Expecting non-null Expr");
727*e038c9c4Sjoerg Base.get<const Expr*>()->printPretty(Out, nullptr, Policy);
7287330f729Sjoerg }
7297330f729Sjoerg
7307330f729Sjoerg if (!O.isZero()) {
7317330f729Sjoerg Out << " + " << (O / S);
7327330f729Sjoerg if (IsReference)
7337330f729Sjoerg Out << ')';
7347330f729Sjoerg }
7357330f729Sjoerg return;
7367330f729Sjoerg }
7377330f729Sjoerg
7387330f729Sjoerg // We have an lvalue path. Print it out nicely.
7397330f729Sjoerg if (!IsReference)
7407330f729Sjoerg Out << '&';
7417330f729Sjoerg else if (isLValueOnePastTheEnd())
7427330f729Sjoerg Out << "*(&";
7437330f729Sjoerg
744*e038c9c4Sjoerg QualType ElemTy = Base.getType();
7457330f729Sjoerg if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) {
7467330f729Sjoerg Out << *VD;
7477330f729Sjoerg } else if (TypeInfoLValue TI = Base.dyn_cast<TypeInfoLValue>()) {
748*e038c9c4Sjoerg TI.print(Out, Policy);
7497330f729Sjoerg } else if (DynamicAllocLValue DA = Base.dyn_cast<DynamicAllocLValue>()) {
750*e038c9c4Sjoerg Out << "{*new " << Base.getDynamicAllocType().stream(Policy) << "#"
7517330f729Sjoerg << DA.getIndex() << "}";
7527330f729Sjoerg } else {
7537330f729Sjoerg const Expr *E = Base.get<const Expr*>();
7547330f729Sjoerg assert(E != nullptr && "Expecting non-null Expr");
755*e038c9c4Sjoerg E->printPretty(Out, nullptr, Policy);
7567330f729Sjoerg }
7577330f729Sjoerg
7587330f729Sjoerg ArrayRef<LValuePathEntry> Path = getLValuePath();
7597330f729Sjoerg const CXXRecordDecl *CastToBase = nullptr;
7607330f729Sjoerg for (unsigned I = 0, N = Path.size(); I != N; ++I) {
761*e038c9c4Sjoerg if (ElemTy->isRecordType()) {
7627330f729Sjoerg // The lvalue refers to a class type, so the next path entry is a base
7637330f729Sjoerg // or member.
7647330f729Sjoerg const Decl *BaseOrMember = Path[I].getAsBaseOrMember().getPointer();
7657330f729Sjoerg if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(BaseOrMember)) {
7667330f729Sjoerg CastToBase = RD;
767*e038c9c4Sjoerg // Leave ElemTy referring to the most-derived class. The actual type
768*e038c9c4Sjoerg // doesn't matter except for array types.
7697330f729Sjoerg } else {
7707330f729Sjoerg const ValueDecl *VD = cast<ValueDecl>(BaseOrMember);
7717330f729Sjoerg Out << ".";
7727330f729Sjoerg if (CastToBase)
7737330f729Sjoerg Out << *CastToBase << "::";
7747330f729Sjoerg Out << *VD;
7757330f729Sjoerg ElemTy = VD->getType();
7767330f729Sjoerg }
7777330f729Sjoerg } else {
7787330f729Sjoerg // The lvalue must refer to an array.
7797330f729Sjoerg Out << '[' << Path[I].getAsArrayIndex() << ']';
780*e038c9c4Sjoerg ElemTy = ElemTy->castAsArrayTypeUnsafe()->getElementType();
7817330f729Sjoerg }
7827330f729Sjoerg }
7837330f729Sjoerg
7847330f729Sjoerg // Handle formatting of one-past-the-end lvalues.
7857330f729Sjoerg if (isLValueOnePastTheEnd()) {
7867330f729Sjoerg // FIXME: If CastToBase is non-0, we should prefix the output with
7877330f729Sjoerg // "(CastToBase*)".
7887330f729Sjoerg Out << " + 1";
7897330f729Sjoerg if (IsReference)
7907330f729Sjoerg Out << ')';
7917330f729Sjoerg }
7927330f729Sjoerg return;
7937330f729Sjoerg }
7947330f729Sjoerg case APValue::Array: {
795*e038c9c4Sjoerg const ArrayType *AT = Ty->castAsArrayTypeUnsafe();
7967330f729Sjoerg QualType ElemTy = AT->getElementType();
7977330f729Sjoerg Out << '{';
7987330f729Sjoerg if (unsigned N = getArrayInitializedElts()) {
799*e038c9c4Sjoerg getArrayInitializedElt(0).printPretty(Out, Policy, ElemTy, Ctx);
8007330f729Sjoerg for (unsigned I = 1; I != N; ++I) {
8017330f729Sjoerg Out << ", ";
8027330f729Sjoerg if (I == 10) {
8037330f729Sjoerg // Avoid printing out the entire contents of large arrays.
8047330f729Sjoerg Out << "...";
8057330f729Sjoerg break;
8067330f729Sjoerg }
807*e038c9c4Sjoerg getArrayInitializedElt(I).printPretty(Out, Policy, ElemTy, Ctx);
8087330f729Sjoerg }
8097330f729Sjoerg }
8107330f729Sjoerg Out << '}';
8117330f729Sjoerg return;
8127330f729Sjoerg }
8137330f729Sjoerg case APValue::Struct: {
8147330f729Sjoerg Out << '{';
8157330f729Sjoerg const RecordDecl *RD = Ty->castAs<RecordType>()->getDecl();
8167330f729Sjoerg bool First = true;
8177330f729Sjoerg if (unsigned N = getStructNumBases()) {
8187330f729Sjoerg const CXXRecordDecl *CD = cast<CXXRecordDecl>(RD);
8197330f729Sjoerg CXXRecordDecl::base_class_const_iterator BI = CD->bases_begin();
8207330f729Sjoerg for (unsigned I = 0; I != N; ++I, ++BI) {
8217330f729Sjoerg assert(BI != CD->bases_end());
8227330f729Sjoerg if (!First)
8237330f729Sjoerg Out << ", ";
824*e038c9c4Sjoerg getStructBase(I).printPretty(Out, Policy, BI->getType(), Ctx);
8257330f729Sjoerg First = false;
8267330f729Sjoerg }
8277330f729Sjoerg }
8287330f729Sjoerg for (const auto *FI : RD->fields()) {
8297330f729Sjoerg if (!First)
8307330f729Sjoerg Out << ", ";
8317330f729Sjoerg if (FI->isUnnamedBitfield()) continue;
8327330f729Sjoerg getStructField(FI->getFieldIndex()).
833*e038c9c4Sjoerg printPretty(Out, Policy, FI->getType(), Ctx);
8347330f729Sjoerg First = false;
8357330f729Sjoerg }
8367330f729Sjoerg Out << '}';
8377330f729Sjoerg return;
8387330f729Sjoerg }
8397330f729Sjoerg case APValue::Union:
8407330f729Sjoerg Out << '{';
8417330f729Sjoerg if (const FieldDecl *FD = getUnionField()) {
8427330f729Sjoerg Out << "." << *FD << " = ";
843*e038c9c4Sjoerg getUnionValue().printPretty(Out, Policy, FD->getType(), Ctx);
8447330f729Sjoerg }
8457330f729Sjoerg Out << '}';
8467330f729Sjoerg return;
8477330f729Sjoerg case APValue::MemberPointer:
8487330f729Sjoerg // FIXME: This is not enough to unambiguously identify the member in a
8497330f729Sjoerg // multiple-inheritance scenario.
8507330f729Sjoerg if (const ValueDecl *VD = getMemberPointerDecl()) {
8517330f729Sjoerg Out << '&' << *cast<CXXRecordDecl>(VD->getDeclContext()) << "::" << *VD;
8527330f729Sjoerg return;
8537330f729Sjoerg }
8547330f729Sjoerg Out << "0";
8557330f729Sjoerg return;
8567330f729Sjoerg case APValue::AddrLabelDiff:
8577330f729Sjoerg Out << "&&" << getAddrLabelDiffLHS()->getLabel()->getName();
8587330f729Sjoerg Out << " - ";
8597330f729Sjoerg Out << "&&" << getAddrLabelDiffRHS()->getLabel()->getName();
8607330f729Sjoerg return;
8617330f729Sjoerg }
8627330f729Sjoerg llvm_unreachable("Unknown APValue kind!");
8637330f729Sjoerg }
8647330f729Sjoerg
getAsString(const ASTContext & Ctx,QualType Ty) const8657330f729Sjoerg std::string APValue::getAsString(const ASTContext &Ctx, QualType Ty) const {
8667330f729Sjoerg std::string Result;
8677330f729Sjoerg llvm::raw_string_ostream Out(Result);
8687330f729Sjoerg printPretty(Out, Ctx, Ty);
8697330f729Sjoerg Out.flush();
8707330f729Sjoerg return Result;
8717330f729Sjoerg }
8727330f729Sjoerg
toIntegralConstant(APSInt & Result,QualType SrcTy,const ASTContext & Ctx) const8737330f729Sjoerg bool APValue::toIntegralConstant(APSInt &Result, QualType SrcTy,
8747330f729Sjoerg const ASTContext &Ctx) const {
8757330f729Sjoerg if (isInt()) {
8767330f729Sjoerg Result = getInt();
8777330f729Sjoerg return true;
8787330f729Sjoerg }
8797330f729Sjoerg
8807330f729Sjoerg if (isLValue() && isNullPointer()) {
8817330f729Sjoerg Result = Ctx.MakeIntValue(Ctx.getTargetNullPointerValue(SrcTy), SrcTy);
8827330f729Sjoerg return true;
8837330f729Sjoerg }
8847330f729Sjoerg
8857330f729Sjoerg if (isLValue() && !getLValueBase()) {
8867330f729Sjoerg Result = Ctx.MakeIntValue(getLValueOffset().getQuantity(), SrcTy);
8877330f729Sjoerg return true;
8887330f729Sjoerg }
8897330f729Sjoerg
8907330f729Sjoerg return false;
8917330f729Sjoerg }
8927330f729Sjoerg
getLValueBase() const8937330f729Sjoerg const APValue::LValueBase APValue::getLValueBase() const {
8947330f729Sjoerg assert(isLValue() && "Invalid accessor");
895*e038c9c4Sjoerg return ((const LV *)(const void *)&Data)->Base;
8967330f729Sjoerg }
8977330f729Sjoerg
isLValueOnePastTheEnd() const8987330f729Sjoerg bool APValue::isLValueOnePastTheEnd() const {
8997330f729Sjoerg assert(isLValue() && "Invalid accessor");
900*e038c9c4Sjoerg return ((const LV *)(const void *)&Data)->IsOnePastTheEnd;
9017330f729Sjoerg }
9027330f729Sjoerg
getLValueOffset()9037330f729Sjoerg CharUnits &APValue::getLValueOffset() {
9047330f729Sjoerg assert(isLValue() && "Invalid accessor");
905*e038c9c4Sjoerg return ((LV *)(void *)&Data)->Offset;
9067330f729Sjoerg }
9077330f729Sjoerg
hasLValuePath() const9087330f729Sjoerg bool APValue::hasLValuePath() const {
9097330f729Sjoerg assert(isLValue() && "Invalid accessor");
910*e038c9c4Sjoerg return ((const LV *)(const char *)&Data)->hasPath();
9117330f729Sjoerg }
9127330f729Sjoerg
getLValuePath() const9137330f729Sjoerg ArrayRef<APValue::LValuePathEntry> APValue::getLValuePath() const {
9147330f729Sjoerg assert(isLValue() && hasLValuePath() && "Invalid accessor");
915*e038c9c4Sjoerg const LV &LVal = *((const LV *)(const char *)&Data);
9167330f729Sjoerg return llvm::makeArrayRef(LVal.getPath(), LVal.PathLength);
9177330f729Sjoerg }
9187330f729Sjoerg
getLValueCallIndex() const9197330f729Sjoerg unsigned APValue::getLValueCallIndex() const {
9207330f729Sjoerg assert(isLValue() && "Invalid accessor");
921*e038c9c4Sjoerg return ((const LV *)(const char *)&Data)->Base.getCallIndex();
9227330f729Sjoerg }
9237330f729Sjoerg
getLValueVersion() const9247330f729Sjoerg unsigned APValue::getLValueVersion() const {
9257330f729Sjoerg assert(isLValue() && "Invalid accessor");
926*e038c9c4Sjoerg return ((const LV *)(const char *)&Data)->Base.getVersion();
9277330f729Sjoerg }
9287330f729Sjoerg
isNullPointer() const9297330f729Sjoerg bool APValue::isNullPointer() const {
9307330f729Sjoerg assert(isLValue() && "Invalid usage");
931*e038c9c4Sjoerg return ((const LV *)(const char *)&Data)->IsNullPtr;
9327330f729Sjoerg }
9337330f729Sjoerg
setLValue(LValueBase B,const CharUnits & O,NoLValuePath,bool IsNullPtr)9347330f729Sjoerg void APValue::setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
9357330f729Sjoerg bool IsNullPtr) {
9367330f729Sjoerg assert(isLValue() && "Invalid accessor");
937*e038c9c4Sjoerg LV &LVal = *((LV *)(char *)&Data);
9387330f729Sjoerg LVal.Base = B;
9397330f729Sjoerg LVal.IsOnePastTheEnd = false;
9407330f729Sjoerg LVal.Offset = O;
9417330f729Sjoerg LVal.resizePath((unsigned)-1);
9427330f729Sjoerg LVal.IsNullPtr = IsNullPtr;
9437330f729Sjoerg }
9447330f729Sjoerg
945*e038c9c4Sjoerg MutableArrayRef<APValue::LValuePathEntry>
setLValueUninit(LValueBase B,const CharUnits & O,unsigned Size,bool IsOnePastTheEnd,bool IsNullPtr)946*e038c9c4Sjoerg APValue::setLValueUninit(LValueBase B, const CharUnits &O, unsigned Size,
947*e038c9c4Sjoerg bool IsOnePastTheEnd, bool IsNullPtr) {
9487330f729Sjoerg assert(isLValue() && "Invalid accessor");
949*e038c9c4Sjoerg LV &LVal = *((LV *)(char *)&Data);
9507330f729Sjoerg LVal.Base = B;
9517330f729Sjoerg LVal.IsOnePastTheEnd = IsOnePastTheEnd;
9527330f729Sjoerg LVal.Offset = O;
9537330f729Sjoerg LVal.IsNullPtr = IsNullPtr;
954*e038c9c4Sjoerg LVal.resizePath(Size);
955*e038c9c4Sjoerg return {LVal.getPath(), Size};
956*e038c9c4Sjoerg }
957*e038c9c4Sjoerg
setLValue(LValueBase B,const CharUnits & O,ArrayRef<LValuePathEntry> Path,bool IsOnePastTheEnd,bool IsNullPtr)958*e038c9c4Sjoerg void APValue::setLValue(LValueBase B, const CharUnits &O,
959*e038c9c4Sjoerg ArrayRef<LValuePathEntry> Path, bool IsOnePastTheEnd,
960*e038c9c4Sjoerg bool IsNullPtr) {
961*e038c9c4Sjoerg MutableArrayRef<APValue::LValuePathEntry> InternalPath =
962*e038c9c4Sjoerg setLValueUninit(B, O, Path.size(), IsOnePastTheEnd, IsNullPtr);
963*e038c9c4Sjoerg if (Path.size()) {
964*e038c9c4Sjoerg memcpy(InternalPath.data(), Path.data(),
965*e038c9c4Sjoerg Path.size() * sizeof(LValuePathEntry));
966*e038c9c4Sjoerg }
967*e038c9c4Sjoerg }
968*e038c9c4Sjoerg
setUnion(const FieldDecl * Field,const APValue & Value)969*e038c9c4Sjoerg void APValue::setUnion(const FieldDecl *Field, const APValue &Value) {
970*e038c9c4Sjoerg assert(isUnion() && "Invalid accessor");
971*e038c9c4Sjoerg ((UnionData *)(char *)&Data)->Field =
972*e038c9c4Sjoerg Field ? Field->getCanonicalDecl() : nullptr;
973*e038c9c4Sjoerg *((UnionData *)(char *)&Data)->Value = Value;
9747330f729Sjoerg }
9757330f729Sjoerg
getMemberPointerDecl() const9767330f729Sjoerg const ValueDecl *APValue::getMemberPointerDecl() const {
9777330f729Sjoerg assert(isMemberPointer() && "Invalid accessor");
9787330f729Sjoerg const MemberPointerData &MPD =
979*e038c9c4Sjoerg *((const MemberPointerData *)(const char *)&Data);
9807330f729Sjoerg return MPD.MemberAndIsDerivedMember.getPointer();
9817330f729Sjoerg }
9827330f729Sjoerg
isMemberPointerToDerivedMember() const9837330f729Sjoerg bool APValue::isMemberPointerToDerivedMember() const {
9847330f729Sjoerg assert(isMemberPointer() && "Invalid accessor");
9857330f729Sjoerg const MemberPointerData &MPD =
986*e038c9c4Sjoerg *((const MemberPointerData *)(const char *)&Data);
9877330f729Sjoerg return MPD.MemberAndIsDerivedMember.getInt();
9887330f729Sjoerg }
9897330f729Sjoerg
getMemberPointerPath() const9907330f729Sjoerg ArrayRef<const CXXRecordDecl*> APValue::getMemberPointerPath() const {
9917330f729Sjoerg assert(isMemberPointer() && "Invalid accessor");
9927330f729Sjoerg const MemberPointerData &MPD =
993*e038c9c4Sjoerg *((const MemberPointerData *)(const char *)&Data);
9947330f729Sjoerg return llvm::makeArrayRef(MPD.getPath(), MPD.PathLength);
9957330f729Sjoerg }
9967330f729Sjoerg
MakeLValue()9977330f729Sjoerg void APValue::MakeLValue() {
9987330f729Sjoerg assert(isAbsent() && "Bad state change");
9997330f729Sjoerg static_assert(sizeof(LV) <= DataSize, "LV too big");
1000*e038c9c4Sjoerg new ((void *)(char *)&Data) LV();
10017330f729Sjoerg Kind = LValue;
10027330f729Sjoerg }
10037330f729Sjoerg
MakeArray(unsigned InitElts,unsigned Size)10047330f729Sjoerg void APValue::MakeArray(unsigned InitElts, unsigned Size) {
10057330f729Sjoerg assert(isAbsent() && "Bad state change");
1006*e038c9c4Sjoerg new ((void *)(char *)&Data) Arr(InitElts, Size);
10077330f729Sjoerg Kind = Array;
10087330f729Sjoerg }
10097330f729Sjoerg
1010*e038c9c4Sjoerg MutableArrayRef<APValue::LValuePathEntry>
1011*e038c9c4Sjoerg setLValueUninit(APValue::LValueBase B, const CharUnits &O, unsigned Size,
1012*e038c9c4Sjoerg bool OnePastTheEnd, bool IsNullPtr);
1013*e038c9c4Sjoerg
1014*e038c9c4Sjoerg MutableArrayRef<const CXXRecordDecl *>
setMemberPointerUninit(const ValueDecl * Member,bool IsDerivedMember,unsigned Size)1015*e038c9c4Sjoerg APValue::setMemberPointerUninit(const ValueDecl *Member, bool IsDerivedMember,
1016*e038c9c4Sjoerg unsigned Size) {
1017*e038c9c4Sjoerg assert(isAbsent() && "Bad state change");
1018*e038c9c4Sjoerg MemberPointerData *MPD = new ((void *)(char *)&Data) MemberPointerData;
1019*e038c9c4Sjoerg Kind = MemberPointer;
1020*e038c9c4Sjoerg MPD->MemberAndIsDerivedMember.setPointer(
1021*e038c9c4Sjoerg Member ? cast<ValueDecl>(Member->getCanonicalDecl()) : nullptr);
1022*e038c9c4Sjoerg MPD->MemberAndIsDerivedMember.setInt(IsDerivedMember);
1023*e038c9c4Sjoerg MPD->resizePath(Size);
1024*e038c9c4Sjoerg return {MPD->getPath(), MPD->PathLength};
1025*e038c9c4Sjoerg }
1026*e038c9c4Sjoerg
MakeMemberPointer(const ValueDecl * Member,bool IsDerivedMember,ArrayRef<const CXXRecordDecl * > Path)10277330f729Sjoerg void APValue::MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
10287330f729Sjoerg ArrayRef<const CXXRecordDecl *> Path) {
1029*e038c9c4Sjoerg MutableArrayRef<const CXXRecordDecl *> InternalPath =
1030*e038c9c4Sjoerg setMemberPointerUninit(Member, IsDerivedMember, Path.size());
1031*e038c9c4Sjoerg for (unsigned I = 0; I != Path.size(); ++I)
1032*e038c9c4Sjoerg InternalPath[I] = Path[I]->getCanonicalDecl();
1033*e038c9c4Sjoerg }
1034*e038c9c4Sjoerg
getLVForValue(const APValue & V,LVComputationKind computation)1035*e038c9c4Sjoerg LinkageInfo LinkageComputer::getLVForValue(const APValue &V,
1036*e038c9c4Sjoerg LVComputationKind computation) {
1037*e038c9c4Sjoerg LinkageInfo LV = LinkageInfo::external();
1038*e038c9c4Sjoerg
1039*e038c9c4Sjoerg auto MergeLV = [&](LinkageInfo MergeLV) {
1040*e038c9c4Sjoerg LV.merge(MergeLV);
1041*e038c9c4Sjoerg return LV.getLinkage() == InternalLinkage;
1042*e038c9c4Sjoerg };
1043*e038c9c4Sjoerg auto Merge = [&](const APValue &V) {
1044*e038c9c4Sjoerg return MergeLV(getLVForValue(V, computation));
1045*e038c9c4Sjoerg };
1046*e038c9c4Sjoerg
1047*e038c9c4Sjoerg switch (V.getKind()) {
1048*e038c9c4Sjoerg case APValue::None:
1049*e038c9c4Sjoerg case APValue::Indeterminate:
1050*e038c9c4Sjoerg case APValue::Int:
1051*e038c9c4Sjoerg case APValue::Float:
1052*e038c9c4Sjoerg case APValue::FixedPoint:
1053*e038c9c4Sjoerg case APValue::ComplexInt:
1054*e038c9c4Sjoerg case APValue::ComplexFloat:
1055*e038c9c4Sjoerg case APValue::Vector:
1056*e038c9c4Sjoerg break;
1057*e038c9c4Sjoerg
1058*e038c9c4Sjoerg case APValue::AddrLabelDiff:
1059*e038c9c4Sjoerg // Even for an inline function, it's not reasonable to treat a difference
1060*e038c9c4Sjoerg // between the addresses of labels as an external value.
1061*e038c9c4Sjoerg return LinkageInfo::internal();
1062*e038c9c4Sjoerg
1063*e038c9c4Sjoerg case APValue::Struct: {
1064*e038c9c4Sjoerg for (unsigned I = 0, N = V.getStructNumBases(); I != N; ++I)
1065*e038c9c4Sjoerg if (Merge(V.getStructBase(I)))
1066*e038c9c4Sjoerg break;
1067*e038c9c4Sjoerg for (unsigned I = 0, N = V.getStructNumFields(); I != N; ++I)
1068*e038c9c4Sjoerg if (Merge(V.getStructField(I)))
1069*e038c9c4Sjoerg break;
1070*e038c9c4Sjoerg break;
1071*e038c9c4Sjoerg }
1072*e038c9c4Sjoerg
1073*e038c9c4Sjoerg case APValue::Union:
1074*e038c9c4Sjoerg if (V.getUnionField())
1075*e038c9c4Sjoerg Merge(V.getUnionValue());
1076*e038c9c4Sjoerg break;
1077*e038c9c4Sjoerg
1078*e038c9c4Sjoerg case APValue::Array: {
1079*e038c9c4Sjoerg for (unsigned I = 0, N = V.getArrayInitializedElts(); I != N; ++I)
1080*e038c9c4Sjoerg if (Merge(V.getArrayInitializedElt(I)))
1081*e038c9c4Sjoerg break;
1082*e038c9c4Sjoerg if (V.hasArrayFiller())
1083*e038c9c4Sjoerg Merge(V.getArrayFiller());
1084*e038c9c4Sjoerg break;
1085*e038c9c4Sjoerg }
1086*e038c9c4Sjoerg
1087*e038c9c4Sjoerg case APValue::LValue: {
1088*e038c9c4Sjoerg if (!V.getLValueBase()) {
1089*e038c9c4Sjoerg // Null or absolute address: this is external.
1090*e038c9c4Sjoerg } else if (const auto *VD =
1091*e038c9c4Sjoerg V.getLValueBase().dyn_cast<const ValueDecl *>()) {
1092*e038c9c4Sjoerg if (VD && MergeLV(getLVForDecl(VD, computation)))
1093*e038c9c4Sjoerg break;
1094*e038c9c4Sjoerg } else if (const auto TI = V.getLValueBase().dyn_cast<TypeInfoLValue>()) {
1095*e038c9c4Sjoerg if (MergeLV(getLVForType(*TI.getType(), computation)))
1096*e038c9c4Sjoerg break;
1097*e038c9c4Sjoerg } else if (const Expr *E = V.getLValueBase().dyn_cast<const Expr *>()) {
1098*e038c9c4Sjoerg // Almost all expression bases are internal. The exception is
1099*e038c9c4Sjoerg // lifetime-extended temporaries.
1100*e038c9c4Sjoerg // FIXME: These should be modeled as having the
1101*e038c9c4Sjoerg // LifetimeExtendedTemporaryDecl itself as the base.
1102*e038c9c4Sjoerg // FIXME: If we permit Objective-C object literals in template arguments,
1103*e038c9c4Sjoerg // they should not imply internal linkage.
1104*e038c9c4Sjoerg auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E);
1105*e038c9c4Sjoerg if (!MTE || MTE->getStorageDuration() == SD_FullExpression)
1106*e038c9c4Sjoerg return LinkageInfo::internal();
1107*e038c9c4Sjoerg if (MergeLV(getLVForDecl(MTE->getExtendingDecl(), computation)))
1108*e038c9c4Sjoerg break;
1109*e038c9c4Sjoerg } else {
1110*e038c9c4Sjoerg assert(V.getLValueBase().is<DynamicAllocLValue>() &&
1111*e038c9c4Sjoerg "unexpected LValueBase kind");
1112*e038c9c4Sjoerg return LinkageInfo::internal();
1113*e038c9c4Sjoerg }
1114*e038c9c4Sjoerg // The lvalue path doesn't matter: pointers to all subobjects always have
1115*e038c9c4Sjoerg // the same visibility as pointers to the complete object.
1116*e038c9c4Sjoerg break;
1117*e038c9c4Sjoerg }
1118*e038c9c4Sjoerg
1119*e038c9c4Sjoerg case APValue::MemberPointer:
1120*e038c9c4Sjoerg if (const NamedDecl *D = V.getMemberPointerDecl())
1121*e038c9c4Sjoerg MergeLV(getLVForDecl(D, computation));
1122*e038c9c4Sjoerg // Note that we could have a base-to-derived conversion here to a member of
1123*e038c9c4Sjoerg // a derived class with less linkage/visibility. That's covered by the
1124*e038c9c4Sjoerg // linkage and visibility of the value's type.
1125*e038c9c4Sjoerg break;
1126*e038c9c4Sjoerg }
1127*e038c9c4Sjoerg
1128*e038c9c4Sjoerg return LV;
11297330f729Sjoerg }
1130