10b57cec5SDimitry Andric //===--- APValue.cpp - Union class for APFloat/APSInt/Complex -------------===// 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 // This file implements the APValue class. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "clang/AST/APValue.h" 14e8d8bef9SDimitry Andric #include "Linkage.h" 150b57cec5SDimitry Andric #include "clang/AST/ASTContext.h" 160b57cec5SDimitry Andric #include "clang/AST/CharUnits.h" 170b57cec5SDimitry Andric #include "clang/AST/DeclCXX.h" 180b57cec5SDimitry Andric #include "clang/AST/Expr.h" 19e8d8bef9SDimitry Andric #include "clang/AST/ExprCXX.h" 200b57cec5SDimitry Andric #include "clang/AST/Type.h" 210b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 220b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 230b57cec5SDimitry Andric using namespace clang; 240b57cec5SDimitry Andric 250b57cec5SDimitry Andric /// The identity of a type_info object depends on the canonical unqualified 260b57cec5SDimitry Andric /// type only. 270b57cec5SDimitry Andric TypeInfoLValue::TypeInfoLValue(const Type *T) 280b57cec5SDimitry Andric : T(T->getCanonicalTypeUnqualified().getTypePtr()) {} 290b57cec5SDimitry Andric 300b57cec5SDimitry Andric void TypeInfoLValue::print(llvm::raw_ostream &Out, 310b57cec5SDimitry Andric const PrintingPolicy &Policy) const { 320b57cec5SDimitry Andric Out << "typeid("; 330b57cec5SDimitry Andric QualType(getType(), 0).print(Out, Policy); 340b57cec5SDimitry Andric Out << ")"; 350b57cec5SDimitry Andric } 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric static_assert( 380b57cec5SDimitry Andric 1 << llvm::PointerLikeTypeTraits<TypeInfoLValue>::NumLowBitsAvailable <= 390b57cec5SDimitry Andric alignof(Type), 400b57cec5SDimitry Andric "Type is insufficiently aligned"); 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric APValue::LValueBase::LValueBase(const ValueDecl *P, unsigned I, unsigned V) 43e8d8bef9SDimitry Andric : Ptr(P ? cast<ValueDecl>(P->getCanonicalDecl()) : nullptr), Local{I, V} {} 440b57cec5SDimitry Andric APValue::LValueBase::LValueBase(const Expr *P, unsigned I, unsigned V) 450b57cec5SDimitry Andric : Ptr(P), Local{I, V} {} 460b57cec5SDimitry Andric 47a7dea167SDimitry Andric APValue::LValueBase APValue::LValueBase::getDynamicAlloc(DynamicAllocLValue LV, 48a7dea167SDimitry Andric QualType Type) { 49a7dea167SDimitry Andric LValueBase Base; 50a7dea167SDimitry Andric Base.Ptr = LV; 51a7dea167SDimitry Andric Base.DynamicAllocType = Type.getAsOpaquePtr(); 52a7dea167SDimitry Andric return Base; 53a7dea167SDimitry Andric } 54a7dea167SDimitry Andric 550b57cec5SDimitry Andric APValue::LValueBase APValue::LValueBase::getTypeInfo(TypeInfoLValue LV, 560b57cec5SDimitry Andric QualType TypeInfo) { 570b57cec5SDimitry Andric LValueBase Base; 580b57cec5SDimitry Andric Base.Ptr = LV; 590b57cec5SDimitry Andric Base.TypeInfoType = TypeInfo.getAsOpaquePtr(); 600b57cec5SDimitry Andric return Base; 610b57cec5SDimitry Andric } 620b57cec5SDimitry Andric 63e8d8bef9SDimitry Andric QualType APValue::LValueBase::getType() const { 64e8d8bef9SDimitry Andric if (!*this) return QualType(); 65e8d8bef9SDimitry Andric if (const ValueDecl *D = dyn_cast<const ValueDecl*>()) { 66e8d8bef9SDimitry Andric // FIXME: It's unclear where we're supposed to take the type from, and 67e8d8bef9SDimitry Andric // this actually matters for arrays of unknown bound. Eg: 68e8d8bef9SDimitry Andric // 69e8d8bef9SDimitry Andric // extern int arr[]; void f() { extern int arr[3]; }; 70e8d8bef9SDimitry Andric // constexpr int *p = &arr[1]; // valid? 71e8d8bef9SDimitry Andric // 72e8d8bef9SDimitry Andric // For now, we take the most complete type we can find. 73e8d8bef9SDimitry Andric for (auto *Redecl = cast<ValueDecl>(D->getMostRecentDecl()); Redecl; 74e8d8bef9SDimitry Andric Redecl = cast_or_null<ValueDecl>(Redecl->getPreviousDecl())) { 75e8d8bef9SDimitry Andric QualType T = Redecl->getType(); 76e8d8bef9SDimitry Andric if (!T->isIncompleteArrayType()) 77e8d8bef9SDimitry Andric return T; 78e8d8bef9SDimitry Andric } 79e8d8bef9SDimitry Andric return D->getType(); 80e8d8bef9SDimitry Andric } 81e8d8bef9SDimitry Andric 82e8d8bef9SDimitry Andric if (is<TypeInfoLValue>()) 83e8d8bef9SDimitry Andric return getTypeInfoType(); 84e8d8bef9SDimitry Andric 85e8d8bef9SDimitry Andric if (is<DynamicAllocLValue>()) 86e8d8bef9SDimitry Andric return getDynamicAllocType(); 87e8d8bef9SDimitry Andric 88e8d8bef9SDimitry Andric const Expr *Base = get<const Expr*>(); 89e8d8bef9SDimitry Andric 90e8d8bef9SDimitry Andric // For a materialized temporary, the type of the temporary we materialized 91e8d8bef9SDimitry Andric // may not be the type of the expression. 92e8d8bef9SDimitry Andric if (const MaterializeTemporaryExpr *MTE = 93*0fca6ea1SDimitry Andric llvm::dyn_cast<MaterializeTemporaryExpr>(Base)) { 94e8d8bef9SDimitry Andric SmallVector<const Expr *, 2> CommaLHSs; 95e8d8bef9SDimitry Andric SmallVector<SubobjectAdjustment, 2> Adjustments; 96e8d8bef9SDimitry Andric const Expr *Temp = MTE->getSubExpr(); 97e8d8bef9SDimitry Andric const Expr *Inner = Temp->skipRValueSubobjectAdjustments(CommaLHSs, 98e8d8bef9SDimitry Andric Adjustments); 99e8d8bef9SDimitry Andric // Keep any cv-qualifiers from the reference if we generated a temporary 100e8d8bef9SDimitry Andric // for it directly. Otherwise use the type after adjustment. 101e8d8bef9SDimitry Andric if (!Adjustments.empty()) 102e8d8bef9SDimitry Andric return Inner->getType(); 103e8d8bef9SDimitry Andric } 104e8d8bef9SDimitry Andric 105e8d8bef9SDimitry Andric return Base->getType(); 106e8d8bef9SDimitry Andric } 107e8d8bef9SDimitry Andric 1080b57cec5SDimitry Andric unsigned APValue::LValueBase::getCallIndex() const { 109a7dea167SDimitry Andric return (is<TypeInfoLValue>() || is<DynamicAllocLValue>()) ? 0 110a7dea167SDimitry Andric : Local.CallIndex; 1110b57cec5SDimitry Andric } 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric unsigned APValue::LValueBase::getVersion() const { 114a7dea167SDimitry Andric return (is<TypeInfoLValue>() || is<DynamicAllocLValue>()) ? 0 : Local.Version; 1150b57cec5SDimitry Andric } 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric QualType APValue::LValueBase::getTypeInfoType() const { 1180b57cec5SDimitry Andric assert(is<TypeInfoLValue>() && "not a type_info lvalue"); 1190b57cec5SDimitry Andric return QualType::getFromOpaquePtr(TypeInfoType); 1200b57cec5SDimitry Andric } 1210b57cec5SDimitry Andric 122a7dea167SDimitry Andric QualType APValue::LValueBase::getDynamicAllocType() const { 123a7dea167SDimitry Andric assert(is<DynamicAllocLValue>() && "not a dynamic allocation lvalue"); 124a7dea167SDimitry Andric return QualType::getFromOpaquePtr(DynamicAllocType); 125a7dea167SDimitry Andric } 126a7dea167SDimitry Andric 127e8d8bef9SDimitry Andric void APValue::LValueBase::Profile(llvm::FoldingSetNodeID &ID) const { 128e8d8bef9SDimitry Andric ID.AddPointer(Ptr.getOpaqueValue()); 129e8d8bef9SDimitry Andric if (is<TypeInfoLValue>() || is<DynamicAllocLValue>()) 130e8d8bef9SDimitry Andric return; 131e8d8bef9SDimitry Andric ID.AddInteger(Local.CallIndex); 132e8d8bef9SDimitry Andric ID.AddInteger(Local.Version); 133e8d8bef9SDimitry Andric } 134e8d8bef9SDimitry Andric 1350b57cec5SDimitry Andric namespace clang { 1360b57cec5SDimitry Andric bool operator==(const APValue::LValueBase &LHS, 1370b57cec5SDimitry Andric const APValue::LValueBase &RHS) { 1380b57cec5SDimitry Andric if (LHS.Ptr != RHS.Ptr) 1390b57cec5SDimitry Andric return false; 140e8d8bef9SDimitry Andric if (LHS.is<TypeInfoLValue>() || LHS.is<DynamicAllocLValue>()) 1410b57cec5SDimitry Andric return true; 1420b57cec5SDimitry Andric return LHS.Local.CallIndex == RHS.Local.CallIndex && 1430b57cec5SDimitry Andric LHS.Local.Version == RHS.Local.Version; 1440b57cec5SDimitry Andric } 1450b57cec5SDimitry Andric } 1460b57cec5SDimitry Andric 147e8d8bef9SDimitry Andric APValue::LValuePathEntry::LValuePathEntry(BaseOrMemberType BaseOrMember) { 148e8d8bef9SDimitry Andric if (const Decl *D = BaseOrMember.getPointer()) 149e8d8bef9SDimitry Andric BaseOrMember.setPointer(D->getCanonicalDecl()); 150e8d8bef9SDimitry Andric Value = reinterpret_cast<uintptr_t>(BaseOrMember.getOpaqueValue()); 151e8d8bef9SDimitry Andric } 152e8d8bef9SDimitry Andric 153e8d8bef9SDimitry Andric void APValue::LValuePathEntry::Profile(llvm::FoldingSetNodeID &ID) const { 154e8d8bef9SDimitry Andric ID.AddInteger(Value); 155e8d8bef9SDimitry Andric } 156e8d8bef9SDimitry Andric 157e8d8bef9SDimitry Andric APValue::LValuePathSerializationHelper::LValuePathSerializationHelper( 158e8d8bef9SDimitry Andric ArrayRef<LValuePathEntry> Path, QualType ElemTy) 159bdd1243dSDimitry Andric : Ty((const void *)ElemTy.getTypePtrOrNull()), Path(Path) {} 160e8d8bef9SDimitry Andric 161e8d8bef9SDimitry Andric QualType APValue::LValuePathSerializationHelper::getType() { 162bdd1243dSDimitry Andric return QualType::getFromOpaquePtr(Ty); 163e8d8bef9SDimitry Andric } 164e8d8bef9SDimitry Andric 1650b57cec5SDimitry Andric namespace { 1660b57cec5SDimitry Andric struct LVBase { 1670b57cec5SDimitry Andric APValue::LValueBase Base; 1680b57cec5SDimitry Andric CharUnits Offset; 1690b57cec5SDimitry Andric unsigned PathLength; 1700b57cec5SDimitry Andric bool IsNullPtr : 1; 1710b57cec5SDimitry Andric bool IsOnePastTheEnd : 1; 1720b57cec5SDimitry Andric }; 1730b57cec5SDimitry Andric } 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric void *APValue::LValueBase::getOpaqueValue() const { 1760b57cec5SDimitry Andric return Ptr.getOpaqueValue(); 1770b57cec5SDimitry Andric } 1780b57cec5SDimitry Andric 1790b57cec5SDimitry Andric bool APValue::LValueBase::isNull() const { 1800b57cec5SDimitry Andric return Ptr.isNull(); 1810b57cec5SDimitry Andric } 1820b57cec5SDimitry Andric 1830b57cec5SDimitry Andric APValue::LValueBase::operator bool () const { 1840b57cec5SDimitry Andric return static_cast<bool>(Ptr); 1850b57cec5SDimitry Andric } 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric clang::APValue::LValueBase 1880b57cec5SDimitry Andric llvm::DenseMapInfo<clang::APValue::LValueBase>::getEmptyKey() { 189e8d8bef9SDimitry Andric clang::APValue::LValueBase B; 190e8d8bef9SDimitry Andric B.Ptr = DenseMapInfo<const ValueDecl*>::getEmptyKey(); 191e8d8bef9SDimitry Andric return B; 1920b57cec5SDimitry Andric } 1930b57cec5SDimitry Andric 1940b57cec5SDimitry Andric clang::APValue::LValueBase 1950b57cec5SDimitry Andric llvm::DenseMapInfo<clang::APValue::LValueBase>::getTombstoneKey() { 196e8d8bef9SDimitry Andric clang::APValue::LValueBase B; 197e8d8bef9SDimitry Andric B.Ptr = DenseMapInfo<const ValueDecl*>::getTombstoneKey(); 198e8d8bef9SDimitry Andric return B; 1990b57cec5SDimitry Andric } 2000b57cec5SDimitry Andric 2010b57cec5SDimitry Andric namespace clang { 2020b57cec5SDimitry Andric llvm::hash_code hash_value(const APValue::LValueBase &Base) { 203a7dea167SDimitry Andric if (Base.is<TypeInfoLValue>() || Base.is<DynamicAllocLValue>()) 2040b57cec5SDimitry Andric return llvm::hash_value(Base.getOpaqueValue()); 2050b57cec5SDimitry Andric return llvm::hash_combine(Base.getOpaqueValue(), Base.getCallIndex(), 2060b57cec5SDimitry Andric Base.getVersion()); 2070b57cec5SDimitry Andric } 2080b57cec5SDimitry Andric } 2090b57cec5SDimitry Andric 2100b57cec5SDimitry Andric unsigned llvm::DenseMapInfo<clang::APValue::LValueBase>::getHashValue( 2110b57cec5SDimitry Andric const clang::APValue::LValueBase &Base) { 2120b57cec5SDimitry Andric return hash_value(Base); 2130b57cec5SDimitry Andric } 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric bool llvm::DenseMapInfo<clang::APValue::LValueBase>::isEqual( 2160b57cec5SDimitry Andric const clang::APValue::LValueBase &LHS, 2170b57cec5SDimitry Andric const clang::APValue::LValueBase &RHS) { 2180b57cec5SDimitry Andric return LHS == RHS; 2190b57cec5SDimitry Andric } 2200b57cec5SDimitry Andric 2210b57cec5SDimitry Andric struct APValue::LV : LVBase { 2220b57cec5SDimitry Andric static const unsigned InlinePathSpace = 2230b57cec5SDimitry Andric (DataSize - sizeof(LVBase)) / sizeof(LValuePathEntry); 2240b57cec5SDimitry Andric 2250b57cec5SDimitry Andric /// Path - The sequence of base classes, fields and array indices to follow to 2260b57cec5SDimitry Andric /// walk from Base to the subobject. When performing GCC-style folding, there 2270b57cec5SDimitry Andric /// may not be such a path. 2280b57cec5SDimitry Andric union { 2290b57cec5SDimitry Andric LValuePathEntry Path[InlinePathSpace]; 2300b57cec5SDimitry Andric LValuePathEntry *PathPtr; 2310b57cec5SDimitry Andric }; 2320b57cec5SDimitry Andric 2330b57cec5SDimitry Andric LV() { PathLength = (unsigned)-1; } 2340b57cec5SDimitry Andric ~LV() { resizePath(0); } 2350b57cec5SDimitry Andric 2360b57cec5SDimitry Andric void resizePath(unsigned Length) { 2370b57cec5SDimitry Andric if (Length == PathLength) 2380b57cec5SDimitry Andric return; 2390b57cec5SDimitry Andric if (hasPathPtr()) 2400b57cec5SDimitry Andric delete [] PathPtr; 2410b57cec5SDimitry Andric PathLength = Length; 2420b57cec5SDimitry Andric if (hasPathPtr()) 2430b57cec5SDimitry Andric PathPtr = new LValuePathEntry[Length]; 2440b57cec5SDimitry Andric } 2450b57cec5SDimitry Andric 2460b57cec5SDimitry Andric bool hasPath() const { return PathLength != (unsigned)-1; } 2470b57cec5SDimitry Andric bool hasPathPtr() const { return hasPath() && PathLength > InlinePathSpace; } 2480b57cec5SDimitry Andric 2490b57cec5SDimitry Andric LValuePathEntry *getPath() { return hasPathPtr() ? PathPtr : Path; } 2500b57cec5SDimitry Andric const LValuePathEntry *getPath() const { 2510b57cec5SDimitry Andric return hasPathPtr() ? PathPtr : Path; 2520b57cec5SDimitry Andric } 2530b57cec5SDimitry Andric }; 2540b57cec5SDimitry Andric 2550b57cec5SDimitry Andric namespace { 2560b57cec5SDimitry Andric struct MemberPointerBase { 2570b57cec5SDimitry Andric llvm::PointerIntPair<const ValueDecl*, 1, bool> MemberAndIsDerivedMember; 2580b57cec5SDimitry Andric unsigned PathLength; 2590b57cec5SDimitry Andric }; 2600b57cec5SDimitry Andric } 2610b57cec5SDimitry Andric 2620b57cec5SDimitry Andric struct APValue::MemberPointerData : MemberPointerBase { 2630b57cec5SDimitry Andric static const unsigned InlinePathSpace = 2640b57cec5SDimitry Andric (DataSize - sizeof(MemberPointerBase)) / sizeof(const CXXRecordDecl*); 2650b57cec5SDimitry Andric typedef const CXXRecordDecl *PathElem; 2660b57cec5SDimitry Andric union { 2670b57cec5SDimitry Andric PathElem Path[InlinePathSpace]; 2680b57cec5SDimitry Andric PathElem *PathPtr; 2690b57cec5SDimitry Andric }; 2700b57cec5SDimitry Andric 2710b57cec5SDimitry Andric MemberPointerData() { PathLength = 0; } 2720b57cec5SDimitry Andric ~MemberPointerData() { resizePath(0); } 2730b57cec5SDimitry Andric 2740b57cec5SDimitry Andric void resizePath(unsigned Length) { 2750b57cec5SDimitry Andric if (Length == PathLength) 2760b57cec5SDimitry Andric return; 2770b57cec5SDimitry Andric if (hasPathPtr()) 2780b57cec5SDimitry Andric delete [] PathPtr; 2790b57cec5SDimitry Andric PathLength = Length; 2800b57cec5SDimitry Andric if (hasPathPtr()) 2810b57cec5SDimitry Andric PathPtr = new PathElem[Length]; 2820b57cec5SDimitry Andric } 2830b57cec5SDimitry Andric 2840b57cec5SDimitry Andric bool hasPathPtr() const { return PathLength > InlinePathSpace; } 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andric PathElem *getPath() { return hasPathPtr() ? PathPtr : Path; } 2870b57cec5SDimitry Andric const PathElem *getPath() const { 2880b57cec5SDimitry Andric return hasPathPtr() ? PathPtr : Path; 2890b57cec5SDimitry Andric } 2900b57cec5SDimitry Andric }; 2910b57cec5SDimitry Andric 2920b57cec5SDimitry Andric // FIXME: Reduce the malloc traffic here. 2930b57cec5SDimitry Andric 2940b57cec5SDimitry Andric APValue::Arr::Arr(unsigned NumElts, unsigned Size) : 2950b57cec5SDimitry Andric Elts(new APValue[NumElts + (NumElts != Size ? 1 : 0)]), 2960b57cec5SDimitry Andric NumElts(NumElts), ArrSize(Size) {} 2970b57cec5SDimitry Andric APValue::Arr::~Arr() { delete [] Elts; } 2980b57cec5SDimitry Andric 2990b57cec5SDimitry Andric APValue::StructData::StructData(unsigned NumBases, unsigned NumFields) : 3000b57cec5SDimitry Andric Elts(new APValue[NumBases+NumFields]), 3010b57cec5SDimitry Andric NumBases(NumBases), NumFields(NumFields) {} 3020b57cec5SDimitry Andric APValue::StructData::~StructData() { 3030b57cec5SDimitry Andric delete [] Elts; 3040b57cec5SDimitry Andric } 3050b57cec5SDimitry Andric 3060b57cec5SDimitry Andric APValue::UnionData::UnionData() : Field(nullptr), Value(new APValue) {} 3070b57cec5SDimitry Andric APValue::UnionData::~UnionData () { 3080b57cec5SDimitry Andric delete Value; 3090b57cec5SDimitry Andric } 3100b57cec5SDimitry Andric 3110b57cec5SDimitry Andric APValue::APValue(const APValue &RHS) : Kind(None) { 3120b57cec5SDimitry Andric switch (RHS.getKind()) { 3130b57cec5SDimitry Andric case None: 3140b57cec5SDimitry Andric case Indeterminate: 3150b57cec5SDimitry Andric Kind = RHS.getKind(); 3160b57cec5SDimitry Andric break; 3170b57cec5SDimitry Andric case Int: 3180b57cec5SDimitry Andric MakeInt(); 3190b57cec5SDimitry Andric setInt(RHS.getInt()); 3200b57cec5SDimitry Andric break; 3210b57cec5SDimitry Andric case Float: 3220b57cec5SDimitry Andric MakeFloat(); 3230b57cec5SDimitry Andric setFloat(RHS.getFloat()); 3240b57cec5SDimitry Andric break; 3250b57cec5SDimitry Andric case FixedPoint: { 3260b57cec5SDimitry Andric APFixedPoint FXCopy = RHS.getFixedPoint(); 3270b57cec5SDimitry Andric MakeFixedPoint(std::move(FXCopy)); 3280b57cec5SDimitry Andric break; 3290b57cec5SDimitry Andric } 3300b57cec5SDimitry Andric case Vector: 3310b57cec5SDimitry Andric MakeVector(); 332e8d8bef9SDimitry Andric setVector(((const Vec *)(const char *)&RHS.Data)->Elts, 3330b57cec5SDimitry Andric RHS.getVectorLength()); 3340b57cec5SDimitry Andric break; 3350b57cec5SDimitry Andric case ComplexInt: 3360b57cec5SDimitry Andric MakeComplexInt(); 3370b57cec5SDimitry Andric setComplexInt(RHS.getComplexIntReal(), RHS.getComplexIntImag()); 3380b57cec5SDimitry Andric break; 3390b57cec5SDimitry Andric case ComplexFloat: 3400b57cec5SDimitry Andric MakeComplexFloat(); 3410b57cec5SDimitry Andric setComplexFloat(RHS.getComplexFloatReal(), RHS.getComplexFloatImag()); 3420b57cec5SDimitry Andric break; 3430b57cec5SDimitry Andric case LValue: 3440b57cec5SDimitry Andric MakeLValue(); 3450b57cec5SDimitry Andric if (RHS.hasLValuePath()) 3460b57cec5SDimitry Andric setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), RHS.getLValuePath(), 3470b57cec5SDimitry Andric RHS.isLValueOnePastTheEnd(), RHS.isNullPointer()); 3480b57cec5SDimitry Andric else 3490b57cec5SDimitry Andric setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), NoLValuePath(), 3500b57cec5SDimitry Andric RHS.isNullPointer()); 3510b57cec5SDimitry Andric break; 3520b57cec5SDimitry Andric case Array: 3530b57cec5SDimitry Andric MakeArray(RHS.getArrayInitializedElts(), RHS.getArraySize()); 3540b57cec5SDimitry Andric for (unsigned I = 0, N = RHS.getArrayInitializedElts(); I != N; ++I) 3550b57cec5SDimitry Andric getArrayInitializedElt(I) = RHS.getArrayInitializedElt(I); 3560b57cec5SDimitry Andric if (RHS.hasArrayFiller()) 3570b57cec5SDimitry Andric getArrayFiller() = RHS.getArrayFiller(); 3580b57cec5SDimitry Andric break; 3590b57cec5SDimitry Andric case Struct: 3600b57cec5SDimitry Andric MakeStruct(RHS.getStructNumBases(), RHS.getStructNumFields()); 3610b57cec5SDimitry Andric for (unsigned I = 0, N = RHS.getStructNumBases(); I != N; ++I) 3620b57cec5SDimitry Andric getStructBase(I) = RHS.getStructBase(I); 3630b57cec5SDimitry Andric for (unsigned I = 0, N = RHS.getStructNumFields(); I != N; ++I) 3640b57cec5SDimitry Andric getStructField(I) = RHS.getStructField(I); 3650b57cec5SDimitry Andric break; 3660b57cec5SDimitry Andric case Union: 3670b57cec5SDimitry Andric MakeUnion(); 3680b57cec5SDimitry Andric setUnion(RHS.getUnionField(), RHS.getUnionValue()); 3690b57cec5SDimitry Andric break; 3700b57cec5SDimitry Andric case MemberPointer: 3710b57cec5SDimitry Andric MakeMemberPointer(RHS.getMemberPointerDecl(), 3720b57cec5SDimitry Andric RHS.isMemberPointerToDerivedMember(), 3730b57cec5SDimitry Andric RHS.getMemberPointerPath()); 3740b57cec5SDimitry Andric break; 3750b57cec5SDimitry Andric case AddrLabelDiff: 3760b57cec5SDimitry Andric MakeAddrLabelDiff(); 3770b57cec5SDimitry Andric setAddrLabelDiff(RHS.getAddrLabelDiffLHS(), RHS.getAddrLabelDiffRHS()); 3780b57cec5SDimitry Andric break; 3790b57cec5SDimitry Andric } 3800b57cec5SDimitry Andric } 3810b57cec5SDimitry Andric 382e8d8bef9SDimitry Andric APValue::APValue(APValue &&RHS) : Kind(RHS.Kind), Data(RHS.Data) { 383e8d8bef9SDimitry Andric RHS.Kind = None; 384e8d8bef9SDimitry Andric } 385e8d8bef9SDimitry Andric 386e8d8bef9SDimitry Andric APValue &APValue::operator=(const APValue &RHS) { 387e8d8bef9SDimitry Andric if (this != &RHS) 388e8d8bef9SDimitry Andric *this = APValue(RHS); 389e8d8bef9SDimitry Andric return *this; 390e8d8bef9SDimitry Andric } 391e8d8bef9SDimitry Andric 392e8d8bef9SDimitry Andric APValue &APValue::operator=(APValue &&RHS) { 3935f757f3fSDimitry Andric if (this != &RHS) { 394e8d8bef9SDimitry Andric if (Kind != None && Kind != Indeterminate) 395e8d8bef9SDimitry Andric DestroyDataAndMakeUninit(); 396e8d8bef9SDimitry Andric Kind = RHS.Kind; 397e8d8bef9SDimitry Andric Data = RHS.Data; 398e8d8bef9SDimitry Andric RHS.Kind = None; 3995f757f3fSDimitry Andric } 400e8d8bef9SDimitry Andric return *this; 401e8d8bef9SDimitry Andric } 402e8d8bef9SDimitry Andric 4030b57cec5SDimitry Andric void APValue::DestroyDataAndMakeUninit() { 4040b57cec5SDimitry Andric if (Kind == Int) 405e8d8bef9SDimitry Andric ((APSInt *)(char *)&Data)->~APSInt(); 4060b57cec5SDimitry Andric else if (Kind == Float) 407e8d8bef9SDimitry Andric ((APFloat *)(char *)&Data)->~APFloat(); 4080b57cec5SDimitry Andric else if (Kind == FixedPoint) 409e8d8bef9SDimitry Andric ((APFixedPoint *)(char *)&Data)->~APFixedPoint(); 4100b57cec5SDimitry Andric else if (Kind == Vector) 411e8d8bef9SDimitry Andric ((Vec *)(char *)&Data)->~Vec(); 4120b57cec5SDimitry Andric else if (Kind == ComplexInt) 413e8d8bef9SDimitry Andric ((ComplexAPSInt *)(char *)&Data)->~ComplexAPSInt(); 4140b57cec5SDimitry Andric else if (Kind == ComplexFloat) 415e8d8bef9SDimitry Andric ((ComplexAPFloat *)(char *)&Data)->~ComplexAPFloat(); 4160b57cec5SDimitry Andric else if (Kind == LValue) 417e8d8bef9SDimitry Andric ((LV *)(char *)&Data)->~LV(); 4180b57cec5SDimitry Andric else if (Kind == Array) 419e8d8bef9SDimitry Andric ((Arr *)(char *)&Data)->~Arr(); 4200b57cec5SDimitry Andric else if (Kind == Struct) 421e8d8bef9SDimitry Andric ((StructData *)(char *)&Data)->~StructData(); 4220b57cec5SDimitry Andric else if (Kind == Union) 423e8d8bef9SDimitry Andric ((UnionData *)(char *)&Data)->~UnionData(); 4240b57cec5SDimitry Andric else if (Kind == MemberPointer) 425e8d8bef9SDimitry Andric ((MemberPointerData *)(char *)&Data)->~MemberPointerData(); 4260b57cec5SDimitry Andric else if (Kind == AddrLabelDiff) 427e8d8bef9SDimitry Andric ((AddrLabelDiffData *)(char *)&Data)->~AddrLabelDiffData(); 4280b57cec5SDimitry Andric Kind = None; 4290b57cec5SDimitry Andric } 4300b57cec5SDimitry Andric 4310b57cec5SDimitry Andric bool APValue::needsCleanup() const { 4320b57cec5SDimitry Andric switch (getKind()) { 4330b57cec5SDimitry Andric case None: 4340b57cec5SDimitry Andric case Indeterminate: 4350b57cec5SDimitry Andric case AddrLabelDiff: 4360b57cec5SDimitry Andric return false; 4370b57cec5SDimitry Andric case Struct: 4380b57cec5SDimitry Andric case Union: 4390b57cec5SDimitry Andric case Array: 4400b57cec5SDimitry Andric case Vector: 4410b57cec5SDimitry Andric return true; 4420b57cec5SDimitry Andric case Int: 4430b57cec5SDimitry Andric return getInt().needsCleanup(); 4440b57cec5SDimitry Andric case Float: 4450b57cec5SDimitry Andric return getFloat().needsCleanup(); 4460b57cec5SDimitry Andric case FixedPoint: 4470b57cec5SDimitry Andric return getFixedPoint().getValue().needsCleanup(); 4480b57cec5SDimitry Andric case ComplexFloat: 4490b57cec5SDimitry Andric assert(getComplexFloatImag().needsCleanup() == 4500b57cec5SDimitry Andric getComplexFloatReal().needsCleanup() && 4510b57cec5SDimitry Andric "In _Complex float types, real and imaginary values always have the " 4520b57cec5SDimitry Andric "same size."); 4530b57cec5SDimitry Andric return getComplexFloatReal().needsCleanup(); 4540b57cec5SDimitry Andric case ComplexInt: 4550b57cec5SDimitry Andric assert(getComplexIntImag().needsCleanup() == 4560b57cec5SDimitry Andric getComplexIntReal().needsCleanup() && 4570b57cec5SDimitry Andric "In _Complex int types, real and imaginary values must have the " 4580b57cec5SDimitry Andric "same size."); 4590b57cec5SDimitry Andric return getComplexIntReal().needsCleanup(); 4600b57cec5SDimitry Andric case LValue: 461e8d8bef9SDimitry Andric return reinterpret_cast<const LV *>(&Data)->hasPathPtr(); 4620b57cec5SDimitry Andric case MemberPointer: 463e8d8bef9SDimitry Andric return reinterpret_cast<const MemberPointerData *>(&Data)->hasPathPtr(); 4640b57cec5SDimitry Andric } 4650b57cec5SDimitry Andric llvm_unreachable("Unknown APValue kind!"); 4660b57cec5SDimitry Andric } 4670b57cec5SDimitry Andric 4680b57cec5SDimitry Andric void APValue::swap(APValue &RHS) { 4690b57cec5SDimitry Andric std::swap(Kind, RHS.Kind); 470e8d8bef9SDimitry Andric std::swap(Data, RHS.Data); 471e8d8bef9SDimitry Andric } 472e8d8bef9SDimitry Andric 473e8d8bef9SDimitry Andric /// Profile the value of an APInt, excluding its bit-width. 474e8d8bef9SDimitry Andric static void profileIntValue(llvm::FoldingSetNodeID &ID, const llvm::APInt &V) { 475e8d8bef9SDimitry Andric for (unsigned I = 0, N = V.getBitWidth(); I < N; I += 32) 476e8d8bef9SDimitry Andric ID.AddInteger((uint32_t)V.extractBitsAsZExtValue(std::min(32u, N - I), I)); 477e8d8bef9SDimitry Andric } 478e8d8bef9SDimitry Andric 479e8d8bef9SDimitry Andric void APValue::Profile(llvm::FoldingSetNodeID &ID) const { 480e8d8bef9SDimitry Andric // Note that our profiling assumes that only APValues of the same type are 481e8d8bef9SDimitry Andric // ever compared. As a result, we don't consider collisions that could only 482e8d8bef9SDimitry Andric // happen if the types are different. (For example, structs with different 483e8d8bef9SDimitry Andric // numbers of members could profile the same.) 484e8d8bef9SDimitry Andric 485e8d8bef9SDimitry Andric ID.AddInteger(Kind); 486e8d8bef9SDimitry Andric 487e8d8bef9SDimitry Andric switch (Kind) { 488e8d8bef9SDimitry Andric case None: 489e8d8bef9SDimitry Andric case Indeterminate: 490e8d8bef9SDimitry Andric return; 491e8d8bef9SDimitry Andric 492e8d8bef9SDimitry Andric case AddrLabelDiff: 493e8d8bef9SDimitry Andric ID.AddPointer(getAddrLabelDiffLHS()->getLabel()->getCanonicalDecl()); 494e8d8bef9SDimitry Andric ID.AddPointer(getAddrLabelDiffRHS()->getLabel()->getCanonicalDecl()); 495e8d8bef9SDimitry Andric return; 496e8d8bef9SDimitry Andric 497e8d8bef9SDimitry Andric case Struct: 498e8d8bef9SDimitry Andric for (unsigned I = 0, N = getStructNumBases(); I != N; ++I) 499e8d8bef9SDimitry Andric getStructBase(I).Profile(ID); 500e8d8bef9SDimitry Andric for (unsigned I = 0, N = getStructNumFields(); I != N; ++I) 501e8d8bef9SDimitry Andric getStructField(I).Profile(ID); 502e8d8bef9SDimitry Andric return; 503e8d8bef9SDimitry Andric 504e8d8bef9SDimitry Andric case Union: 505e8d8bef9SDimitry Andric if (!getUnionField()) { 506e8d8bef9SDimitry Andric ID.AddInteger(0); 507e8d8bef9SDimitry Andric return; 508e8d8bef9SDimitry Andric } 509e8d8bef9SDimitry Andric ID.AddInteger(getUnionField()->getFieldIndex() + 1); 510e8d8bef9SDimitry Andric getUnionValue().Profile(ID); 511e8d8bef9SDimitry Andric return; 512e8d8bef9SDimitry Andric 513e8d8bef9SDimitry Andric case Array: { 514e8d8bef9SDimitry Andric if (getArraySize() == 0) 515e8d8bef9SDimitry Andric return; 516e8d8bef9SDimitry Andric 517e8d8bef9SDimitry Andric // The profile should not depend on whether the array is expanded or 518e8d8bef9SDimitry Andric // not, but we don't want to profile the array filler many times for 519e8d8bef9SDimitry Andric // a large array. So treat all equal trailing elements as the filler. 520e8d8bef9SDimitry Andric // Elements are profiled in reverse order to support this, and the 521e8d8bef9SDimitry Andric // first profiled element is followed by a count. For example: 522e8d8bef9SDimitry Andric // 523e8d8bef9SDimitry Andric // ['a', 'c', 'x', 'x', 'x'] is profiled as 524e8d8bef9SDimitry Andric // [5, 'x', 3, 'c', 'a'] 525e8d8bef9SDimitry Andric llvm::FoldingSetNodeID FillerID; 526e8d8bef9SDimitry Andric (hasArrayFiller() ? getArrayFiller() 527e8d8bef9SDimitry Andric : getArrayInitializedElt(getArrayInitializedElts() - 1)) 528e8d8bef9SDimitry Andric .Profile(FillerID); 529e8d8bef9SDimitry Andric ID.AddNodeID(FillerID); 530e8d8bef9SDimitry Andric unsigned NumFillers = getArraySize() - getArrayInitializedElts(); 531e8d8bef9SDimitry Andric unsigned N = getArrayInitializedElts(); 532e8d8bef9SDimitry Andric 533e8d8bef9SDimitry Andric // Count the number of elements equal to the last one. This loop ends 534e8d8bef9SDimitry Andric // by adding an integer indicating the number of such elements, with 535e8d8bef9SDimitry Andric // N set to the number of elements left to profile. 536e8d8bef9SDimitry Andric while (true) { 537e8d8bef9SDimitry Andric if (N == 0) { 538e8d8bef9SDimitry Andric // All elements are fillers. 539e8d8bef9SDimitry Andric assert(NumFillers == getArraySize()); 540e8d8bef9SDimitry Andric ID.AddInteger(NumFillers); 541e8d8bef9SDimitry Andric break; 542e8d8bef9SDimitry Andric } 543e8d8bef9SDimitry Andric 544e8d8bef9SDimitry Andric // No need to check if the last element is equal to the last 545e8d8bef9SDimitry Andric // element. 546e8d8bef9SDimitry Andric if (N != getArraySize()) { 547e8d8bef9SDimitry Andric llvm::FoldingSetNodeID ElemID; 548e8d8bef9SDimitry Andric getArrayInitializedElt(N - 1).Profile(ElemID); 549e8d8bef9SDimitry Andric if (ElemID != FillerID) { 550e8d8bef9SDimitry Andric ID.AddInteger(NumFillers); 551e8d8bef9SDimitry Andric ID.AddNodeID(ElemID); 552e8d8bef9SDimitry Andric --N; 553e8d8bef9SDimitry Andric break; 554e8d8bef9SDimitry Andric } 555e8d8bef9SDimitry Andric } 556e8d8bef9SDimitry Andric 557e8d8bef9SDimitry Andric // This is a filler. 558e8d8bef9SDimitry Andric ++NumFillers; 559e8d8bef9SDimitry Andric --N; 560e8d8bef9SDimitry Andric } 561e8d8bef9SDimitry Andric 562e8d8bef9SDimitry Andric // Emit the remaining elements. 563e8d8bef9SDimitry Andric for (; N != 0; --N) 564e8d8bef9SDimitry Andric getArrayInitializedElt(N - 1).Profile(ID); 565e8d8bef9SDimitry Andric return; 566e8d8bef9SDimitry Andric } 567e8d8bef9SDimitry Andric 568e8d8bef9SDimitry Andric case Vector: 569e8d8bef9SDimitry Andric for (unsigned I = 0, N = getVectorLength(); I != N; ++I) 570e8d8bef9SDimitry Andric getVectorElt(I).Profile(ID); 571e8d8bef9SDimitry Andric return; 572e8d8bef9SDimitry Andric 573e8d8bef9SDimitry Andric case Int: 574e8d8bef9SDimitry Andric profileIntValue(ID, getInt()); 575e8d8bef9SDimitry Andric return; 576e8d8bef9SDimitry Andric 577e8d8bef9SDimitry Andric case Float: 578e8d8bef9SDimitry Andric profileIntValue(ID, getFloat().bitcastToAPInt()); 579e8d8bef9SDimitry Andric return; 580e8d8bef9SDimitry Andric 581e8d8bef9SDimitry Andric case FixedPoint: 582e8d8bef9SDimitry Andric profileIntValue(ID, getFixedPoint().getValue()); 583e8d8bef9SDimitry Andric return; 584e8d8bef9SDimitry Andric 585e8d8bef9SDimitry Andric case ComplexFloat: 586e8d8bef9SDimitry Andric profileIntValue(ID, getComplexFloatReal().bitcastToAPInt()); 587e8d8bef9SDimitry Andric profileIntValue(ID, getComplexFloatImag().bitcastToAPInt()); 588e8d8bef9SDimitry Andric return; 589e8d8bef9SDimitry Andric 590e8d8bef9SDimitry Andric case ComplexInt: 591e8d8bef9SDimitry Andric profileIntValue(ID, getComplexIntReal()); 592e8d8bef9SDimitry Andric profileIntValue(ID, getComplexIntImag()); 593e8d8bef9SDimitry Andric return; 594e8d8bef9SDimitry Andric 595e8d8bef9SDimitry Andric case LValue: 596e8d8bef9SDimitry Andric getLValueBase().Profile(ID); 597e8d8bef9SDimitry Andric ID.AddInteger(getLValueOffset().getQuantity()); 598e8d8bef9SDimitry Andric ID.AddInteger((isNullPointer() ? 1 : 0) | 599e8d8bef9SDimitry Andric (isLValueOnePastTheEnd() ? 2 : 0) | 600e8d8bef9SDimitry Andric (hasLValuePath() ? 4 : 0)); 601e8d8bef9SDimitry Andric if (hasLValuePath()) { 602e8d8bef9SDimitry Andric ID.AddInteger(getLValuePath().size()); 603e8d8bef9SDimitry Andric // For uniqueness, we only need to profile the entries corresponding 604e8d8bef9SDimitry Andric // to union members, but we don't have the type here so we don't know 605e8d8bef9SDimitry Andric // how to interpret the entries. 606e8d8bef9SDimitry Andric for (LValuePathEntry E : getLValuePath()) 607e8d8bef9SDimitry Andric E.Profile(ID); 608e8d8bef9SDimitry Andric } 609e8d8bef9SDimitry Andric return; 610e8d8bef9SDimitry Andric 611e8d8bef9SDimitry Andric case MemberPointer: 612e8d8bef9SDimitry Andric ID.AddPointer(getMemberPointerDecl()); 613e8d8bef9SDimitry Andric ID.AddInteger(isMemberPointerToDerivedMember()); 614e8d8bef9SDimitry Andric for (const CXXRecordDecl *D : getMemberPointerPath()) 615e8d8bef9SDimitry Andric ID.AddPointer(D); 616e8d8bef9SDimitry Andric return; 617e8d8bef9SDimitry Andric } 618e8d8bef9SDimitry Andric 619e8d8bef9SDimitry Andric llvm_unreachable("Unknown APValue kind!"); 6200b57cec5SDimitry Andric } 6210b57cec5SDimitry Andric 6220b57cec5SDimitry Andric static double GetApproxValue(const llvm::APFloat &F) { 6230b57cec5SDimitry Andric llvm::APFloat V = F; 6240b57cec5SDimitry Andric bool ignored; 6250b57cec5SDimitry Andric V.convert(llvm::APFloat::IEEEdouble(), llvm::APFloat::rmNearestTiesToEven, 6260b57cec5SDimitry Andric &ignored); 6270b57cec5SDimitry Andric return V.convertToDouble(); 6280b57cec5SDimitry Andric } 6290b57cec5SDimitry Andric 63081ad6265SDimitry Andric static bool TryPrintAsStringLiteral(raw_ostream &Out, 63181ad6265SDimitry Andric const PrintingPolicy &Policy, 63281ad6265SDimitry Andric const ArrayType *ATy, 63381ad6265SDimitry Andric ArrayRef<APValue> Inits) { 63481ad6265SDimitry Andric if (Inits.empty()) 63581ad6265SDimitry Andric return false; 63681ad6265SDimitry Andric 63781ad6265SDimitry Andric QualType Ty = ATy->getElementType(); 63881ad6265SDimitry Andric if (!Ty->isAnyCharacterType()) 63981ad6265SDimitry Andric return false; 64081ad6265SDimitry Andric 64181ad6265SDimitry Andric // Nothing we can do about a sequence that is not null-terminated 64261cfbce3SDimitry Andric if (!Inits.back().isInt() || !Inits.back().getInt().isZero()) 64381ad6265SDimitry Andric return false; 64461cfbce3SDimitry Andric 64581ad6265SDimitry Andric Inits = Inits.drop_back(); 64681ad6265SDimitry Andric 64781ad6265SDimitry Andric llvm::SmallString<40> Buf; 64881ad6265SDimitry Andric Buf.push_back('"'); 64981ad6265SDimitry Andric 65081ad6265SDimitry Andric // Better than printing a two-digit sequence of 10 integers. 65181ad6265SDimitry Andric constexpr size_t MaxN = 36; 65281ad6265SDimitry Andric StringRef Ellipsis; 65381ad6265SDimitry Andric if (Inits.size() > MaxN && !Policy.EntireContentsOfLargeArray) { 65481ad6265SDimitry Andric Ellipsis = "[...]"; 65581ad6265SDimitry Andric Inits = 65681ad6265SDimitry Andric Inits.take_front(std::min(MaxN - Ellipsis.size() / 2, Inits.size())); 65781ad6265SDimitry Andric } 65881ad6265SDimitry Andric 65981ad6265SDimitry Andric for (auto &Val : Inits) { 66061cfbce3SDimitry Andric if (!Val.isInt()) 66161cfbce3SDimitry Andric return false; 66281ad6265SDimitry Andric int64_t Char64 = Val.getInt().getExtValue(); 66381ad6265SDimitry Andric if (!isASCII(Char64)) 66481ad6265SDimitry Andric return false; // Bye bye, see you in integers. 66581ad6265SDimitry Andric auto Ch = static_cast<unsigned char>(Char64); 66681ad6265SDimitry Andric // The diagnostic message is 'quoted' 66781ad6265SDimitry Andric StringRef Escaped = escapeCStyle<EscapeChar::SingleAndDouble>(Ch); 66881ad6265SDimitry Andric if (Escaped.empty()) { 66981ad6265SDimitry Andric if (!isPrintable(Ch)) 67081ad6265SDimitry Andric return false; 67181ad6265SDimitry Andric Buf.emplace_back(Ch); 67281ad6265SDimitry Andric } else { 67381ad6265SDimitry Andric Buf.append(Escaped); 67481ad6265SDimitry Andric } 67581ad6265SDimitry Andric } 67681ad6265SDimitry Andric 67781ad6265SDimitry Andric Buf.append(Ellipsis); 67881ad6265SDimitry Andric Buf.push_back('"'); 67981ad6265SDimitry Andric 68081ad6265SDimitry Andric if (Ty->isWideCharType()) 68181ad6265SDimitry Andric Out << 'L'; 68281ad6265SDimitry Andric else if (Ty->isChar8Type()) 68381ad6265SDimitry Andric Out << "u8"; 68481ad6265SDimitry Andric else if (Ty->isChar16Type()) 68581ad6265SDimitry Andric Out << 'u'; 68681ad6265SDimitry Andric else if (Ty->isChar32Type()) 68781ad6265SDimitry Andric Out << 'U'; 68881ad6265SDimitry Andric 68981ad6265SDimitry Andric Out << Buf; 69081ad6265SDimitry Andric return true; 69181ad6265SDimitry Andric } 69281ad6265SDimitry Andric 6930b57cec5SDimitry Andric void APValue::printPretty(raw_ostream &Out, const ASTContext &Ctx, 6940b57cec5SDimitry Andric QualType Ty) const { 695e8d8bef9SDimitry Andric printPretty(Out, Ctx.getPrintingPolicy(), Ty, &Ctx); 696e8d8bef9SDimitry Andric } 697e8d8bef9SDimitry Andric 698e8d8bef9SDimitry Andric void APValue::printPretty(raw_ostream &Out, const PrintingPolicy &Policy, 699e8d8bef9SDimitry Andric QualType Ty, const ASTContext *Ctx) const { 700e8d8bef9SDimitry Andric // There are no objects of type 'void', but values of this type can be 701e8d8bef9SDimitry Andric // returned from functions. 702e8d8bef9SDimitry Andric if (Ty->isVoidType()) { 703e8d8bef9SDimitry Andric Out << "void()"; 704e8d8bef9SDimitry Andric return; 705e8d8bef9SDimitry Andric } 706e8d8bef9SDimitry Andric 707*0fca6ea1SDimitry Andric if (const auto *AT = Ty->getAs<AtomicType>()) 708*0fca6ea1SDimitry Andric Ty = AT->getValueType(); 709*0fca6ea1SDimitry Andric 7100b57cec5SDimitry Andric switch (getKind()) { 7110b57cec5SDimitry Andric case APValue::None: 7120b57cec5SDimitry Andric Out << "<out of lifetime>"; 7130b57cec5SDimitry Andric return; 7140b57cec5SDimitry Andric case APValue::Indeterminate: 7150b57cec5SDimitry Andric Out << "<uninitialized>"; 7160b57cec5SDimitry Andric return; 7170b57cec5SDimitry Andric case APValue::Int: 7180b57cec5SDimitry Andric if (Ty->isBooleanType()) 7190b57cec5SDimitry Andric Out << (getInt().getBoolValue() ? "true" : "false"); 7200b57cec5SDimitry Andric else 7210b57cec5SDimitry Andric Out << getInt(); 7220b57cec5SDimitry Andric return; 7230b57cec5SDimitry Andric case APValue::Float: 7240b57cec5SDimitry Andric Out << GetApproxValue(getFloat()); 7250b57cec5SDimitry Andric return; 7260b57cec5SDimitry Andric case APValue::FixedPoint: 7270b57cec5SDimitry Andric Out << getFixedPoint(); 7280b57cec5SDimitry Andric return; 7290b57cec5SDimitry Andric case APValue::Vector: { 7300b57cec5SDimitry Andric Out << '{'; 731a7dea167SDimitry Andric QualType ElemTy = Ty->castAs<VectorType>()->getElementType(); 732e8d8bef9SDimitry Andric getVectorElt(0).printPretty(Out, Policy, ElemTy, Ctx); 7330b57cec5SDimitry Andric for (unsigned i = 1; i != getVectorLength(); ++i) { 7340b57cec5SDimitry Andric Out << ", "; 735e8d8bef9SDimitry Andric getVectorElt(i).printPretty(Out, Policy, ElemTy, Ctx); 7360b57cec5SDimitry Andric } 7370b57cec5SDimitry Andric Out << '}'; 7380b57cec5SDimitry Andric return; 7390b57cec5SDimitry Andric } 7400b57cec5SDimitry Andric case APValue::ComplexInt: 7410b57cec5SDimitry Andric Out << getComplexIntReal() << "+" << getComplexIntImag() << "i"; 7420b57cec5SDimitry Andric return; 7430b57cec5SDimitry Andric case APValue::ComplexFloat: 7440b57cec5SDimitry Andric Out << GetApproxValue(getComplexFloatReal()) << "+" 7450b57cec5SDimitry Andric << GetApproxValue(getComplexFloatImag()) << "i"; 7460b57cec5SDimitry Andric return; 7470b57cec5SDimitry Andric case APValue::LValue: { 7480b57cec5SDimitry Andric bool IsReference = Ty->isReferenceType(); 7490b57cec5SDimitry Andric QualType InnerTy 7500b57cec5SDimitry Andric = IsReference ? Ty.getNonReferenceType() : Ty->getPointeeType(); 7510b57cec5SDimitry Andric if (InnerTy.isNull()) 7520b57cec5SDimitry Andric InnerTy = Ty; 7530b57cec5SDimitry Andric 7540b57cec5SDimitry Andric LValueBase Base = getLValueBase(); 7550b57cec5SDimitry Andric if (!Base) { 7560b57cec5SDimitry Andric if (isNullPointer()) { 757e8d8bef9SDimitry Andric Out << (Policy.Nullptr ? "nullptr" : "0"); 7580b57cec5SDimitry Andric } else if (IsReference) { 759e8d8bef9SDimitry Andric Out << "*(" << InnerTy.stream(Policy) << "*)" 7600b57cec5SDimitry Andric << getLValueOffset().getQuantity(); 7610b57cec5SDimitry Andric } else { 762e8d8bef9SDimitry Andric Out << "(" << Ty.stream(Policy) << ")" 7630b57cec5SDimitry Andric << getLValueOffset().getQuantity(); 7640b57cec5SDimitry Andric } 7650b57cec5SDimitry Andric return; 7660b57cec5SDimitry Andric } 7670b57cec5SDimitry Andric 7680b57cec5SDimitry Andric if (!hasLValuePath()) { 7690b57cec5SDimitry Andric // No lvalue path: just print the offset. 7700b57cec5SDimitry Andric CharUnits O = getLValueOffset(); 77181ad6265SDimitry Andric CharUnits S = Ctx ? Ctx->getTypeSizeInCharsIfKnown(InnerTy).value_or( 772349cc55cSDimitry Andric CharUnits::Zero()) 773349cc55cSDimitry Andric : CharUnits::Zero(); 7740b57cec5SDimitry Andric if (!O.isZero()) { 7750b57cec5SDimitry Andric if (IsReference) 7760b57cec5SDimitry Andric Out << "*("; 777e8d8bef9SDimitry Andric if (S.isZero() || O % S) { 7780b57cec5SDimitry Andric Out << "(char*)"; 7790b57cec5SDimitry Andric S = CharUnits::One(); 7800b57cec5SDimitry Andric } 7810b57cec5SDimitry Andric Out << '&'; 782a7dea167SDimitry Andric } else if (!IsReference) { 7830b57cec5SDimitry Andric Out << '&'; 784a7dea167SDimitry Andric } 7850b57cec5SDimitry Andric 7860b57cec5SDimitry Andric if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) 7870b57cec5SDimitry Andric Out << *VD; 7880b57cec5SDimitry Andric else if (TypeInfoLValue TI = Base.dyn_cast<TypeInfoLValue>()) { 789e8d8bef9SDimitry Andric TI.print(Out, Policy); 790a7dea167SDimitry Andric } else if (DynamicAllocLValue DA = Base.dyn_cast<DynamicAllocLValue>()) { 791a7dea167SDimitry Andric Out << "{*new " 792e8d8bef9SDimitry Andric << Base.getDynamicAllocType().stream(Policy) << "#" 793a7dea167SDimitry Andric << DA.getIndex() << "}"; 7940b57cec5SDimitry Andric } else { 7950b57cec5SDimitry Andric assert(Base.get<const Expr *>() != nullptr && 7960b57cec5SDimitry Andric "Expecting non-null Expr"); 797e8d8bef9SDimitry Andric Base.get<const Expr*>()->printPretty(Out, nullptr, Policy); 7980b57cec5SDimitry Andric } 7990b57cec5SDimitry Andric 8000b57cec5SDimitry Andric if (!O.isZero()) { 8010b57cec5SDimitry Andric Out << " + " << (O / S); 8020b57cec5SDimitry Andric if (IsReference) 8030b57cec5SDimitry Andric Out << ')'; 8040b57cec5SDimitry Andric } 8050b57cec5SDimitry Andric return; 8060b57cec5SDimitry Andric } 8070b57cec5SDimitry Andric 8080b57cec5SDimitry Andric // We have an lvalue path. Print it out nicely. 8090b57cec5SDimitry Andric if (!IsReference) 8100b57cec5SDimitry Andric Out << '&'; 8110b57cec5SDimitry Andric else if (isLValueOnePastTheEnd()) 8120b57cec5SDimitry Andric Out << "*(&"; 8130b57cec5SDimitry Andric 814e8d8bef9SDimitry Andric QualType ElemTy = Base.getType(); 8150b57cec5SDimitry Andric if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) { 8160b57cec5SDimitry Andric Out << *VD; 8170b57cec5SDimitry Andric } else if (TypeInfoLValue TI = Base.dyn_cast<TypeInfoLValue>()) { 818e8d8bef9SDimitry Andric TI.print(Out, Policy); 819a7dea167SDimitry Andric } else if (DynamicAllocLValue DA = Base.dyn_cast<DynamicAllocLValue>()) { 820e8d8bef9SDimitry Andric Out << "{*new " << Base.getDynamicAllocType().stream(Policy) << "#" 821a7dea167SDimitry Andric << DA.getIndex() << "}"; 8220b57cec5SDimitry Andric } else { 8230b57cec5SDimitry Andric const Expr *E = Base.get<const Expr*>(); 8240b57cec5SDimitry Andric assert(E != nullptr && "Expecting non-null Expr"); 825e8d8bef9SDimitry Andric E->printPretty(Out, nullptr, Policy); 8260b57cec5SDimitry Andric } 8270b57cec5SDimitry Andric 8280b57cec5SDimitry Andric ArrayRef<LValuePathEntry> Path = getLValuePath(); 8290b57cec5SDimitry Andric const CXXRecordDecl *CastToBase = nullptr; 8300b57cec5SDimitry Andric for (unsigned I = 0, N = Path.size(); I != N; ++I) { 831e8d8bef9SDimitry Andric if (ElemTy->isRecordType()) { 8320b57cec5SDimitry Andric // The lvalue refers to a class type, so the next path entry is a base 8330b57cec5SDimitry Andric // or member. 8340b57cec5SDimitry Andric const Decl *BaseOrMember = Path[I].getAsBaseOrMember().getPointer(); 8350b57cec5SDimitry Andric if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(BaseOrMember)) { 8360b57cec5SDimitry Andric CastToBase = RD; 837e8d8bef9SDimitry Andric // Leave ElemTy referring to the most-derived class. The actual type 838e8d8bef9SDimitry Andric // doesn't matter except for array types. 8390b57cec5SDimitry Andric } else { 8400b57cec5SDimitry Andric const ValueDecl *VD = cast<ValueDecl>(BaseOrMember); 8410b57cec5SDimitry Andric Out << "."; 8420b57cec5SDimitry Andric if (CastToBase) 8430b57cec5SDimitry Andric Out << *CastToBase << "::"; 8440b57cec5SDimitry Andric Out << *VD; 8450b57cec5SDimitry Andric ElemTy = VD->getType(); 8460b57cec5SDimitry Andric } 8475f757f3fSDimitry Andric } else if (ElemTy->isAnyComplexType()) { 8485f757f3fSDimitry Andric // The lvalue refers to a complex type 8495f757f3fSDimitry Andric Out << (Path[I].getAsArrayIndex() == 0 ? ".real" : ".imag"); 8505f757f3fSDimitry Andric ElemTy = ElemTy->castAs<ComplexType>()->getElementType(); 8510b57cec5SDimitry Andric } else { 8520b57cec5SDimitry Andric // The lvalue must refer to an array. 8530b57cec5SDimitry Andric Out << '[' << Path[I].getAsArrayIndex() << ']'; 854e8d8bef9SDimitry Andric ElemTy = ElemTy->castAsArrayTypeUnsafe()->getElementType(); 8550b57cec5SDimitry Andric } 8560b57cec5SDimitry Andric } 8570b57cec5SDimitry Andric 8580b57cec5SDimitry Andric // Handle formatting of one-past-the-end lvalues. 8590b57cec5SDimitry Andric if (isLValueOnePastTheEnd()) { 8600b57cec5SDimitry Andric // FIXME: If CastToBase is non-0, we should prefix the output with 8610b57cec5SDimitry Andric // "(CastToBase*)". 8620b57cec5SDimitry Andric Out << " + 1"; 8630b57cec5SDimitry Andric if (IsReference) 8640b57cec5SDimitry Andric Out << ')'; 8650b57cec5SDimitry Andric } 8660b57cec5SDimitry Andric return; 8670b57cec5SDimitry Andric } 8680b57cec5SDimitry Andric case APValue::Array: { 869e8d8bef9SDimitry Andric const ArrayType *AT = Ty->castAsArrayTypeUnsafe(); 87081ad6265SDimitry Andric unsigned N = getArrayInitializedElts(); 87181ad6265SDimitry Andric if (N != 0 && TryPrintAsStringLiteral(Out, Policy, AT, 87281ad6265SDimitry Andric {&getArrayInitializedElt(0), N})) 87381ad6265SDimitry Andric return; 8740b57cec5SDimitry Andric QualType ElemTy = AT->getElementType(); 8750b57cec5SDimitry Andric Out << '{'; 87681ad6265SDimitry Andric unsigned I = 0; 87781ad6265SDimitry Andric switch (N) { 87881ad6265SDimitry Andric case 0: 87981ad6265SDimitry Andric for (; I != N; ++I) { 8800b57cec5SDimitry Andric Out << ", "; 88181ad6265SDimitry Andric if (I == 10 && !Policy.EntireContentsOfLargeArray) { 88281ad6265SDimitry Andric Out << "...}"; 88381ad6265SDimitry Andric return; 8840b57cec5SDimitry Andric } 885bdd1243dSDimitry Andric [[fallthrough]]; 88681ad6265SDimitry Andric default: 887e8d8bef9SDimitry Andric getArrayInitializedElt(I).printPretty(Out, Policy, ElemTy, Ctx); 8880b57cec5SDimitry Andric } 8890b57cec5SDimitry Andric } 8900b57cec5SDimitry Andric Out << '}'; 8910b57cec5SDimitry Andric return; 8920b57cec5SDimitry Andric } 8930b57cec5SDimitry Andric case APValue::Struct: { 8940b57cec5SDimitry Andric Out << '{'; 895a7dea167SDimitry Andric const RecordDecl *RD = Ty->castAs<RecordType>()->getDecl(); 8960b57cec5SDimitry Andric bool First = true; 8970b57cec5SDimitry Andric if (unsigned N = getStructNumBases()) { 8980b57cec5SDimitry Andric const CXXRecordDecl *CD = cast<CXXRecordDecl>(RD); 8990b57cec5SDimitry Andric CXXRecordDecl::base_class_const_iterator BI = CD->bases_begin(); 9000b57cec5SDimitry Andric for (unsigned I = 0; I != N; ++I, ++BI) { 9010b57cec5SDimitry Andric assert(BI != CD->bases_end()); 9020b57cec5SDimitry Andric if (!First) 9030b57cec5SDimitry Andric Out << ", "; 904e8d8bef9SDimitry Andric getStructBase(I).printPretty(Out, Policy, BI->getType(), Ctx); 9050b57cec5SDimitry Andric First = false; 9060b57cec5SDimitry Andric } 9070b57cec5SDimitry Andric } 9080b57cec5SDimitry Andric for (const auto *FI : RD->fields()) { 9090b57cec5SDimitry Andric if (!First) 9100b57cec5SDimitry Andric Out << ", "; 911*0fca6ea1SDimitry Andric if (FI->isUnnamedBitField()) 912*0fca6ea1SDimitry Andric continue; 9130b57cec5SDimitry Andric getStructField(FI->getFieldIndex()). 914e8d8bef9SDimitry Andric printPretty(Out, Policy, FI->getType(), Ctx); 9150b57cec5SDimitry Andric First = false; 9160b57cec5SDimitry Andric } 9170b57cec5SDimitry Andric Out << '}'; 9180b57cec5SDimitry Andric return; 9190b57cec5SDimitry Andric } 9200b57cec5SDimitry Andric case APValue::Union: 9210b57cec5SDimitry Andric Out << '{'; 9220b57cec5SDimitry Andric if (const FieldDecl *FD = getUnionField()) { 9230b57cec5SDimitry Andric Out << "." << *FD << " = "; 924e8d8bef9SDimitry Andric getUnionValue().printPretty(Out, Policy, FD->getType(), Ctx); 9250b57cec5SDimitry Andric } 9260b57cec5SDimitry Andric Out << '}'; 9270b57cec5SDimitry Andric return; 9280b57cec5SDimitry Andric case APValue::MemberPointer: 9290b57cec5SDimitry Andric // FIXME: This is not enough to unambiguously identify the member in a 9300b57cec5SDimitry Andric // multiple-inheritance scenario. 9310b57cec5SDimitry Andric if (const ValueDecl *VD = getMemberPointerDecl()) { 9320b57cec5SDimitry Andric Out << '&' << *cast<CXXRecordDecl>(VD->getDeclContext()) << "::" << *VD; 9330b57cec5SDimitry Andric return; 9340b57cec5SDimitry Andric } 9350b57cec5SDimitry Andric Out << "0"; 9360b57cec5SDimitry Andric return; 9370b57cec5SDimitry Andric case APValue::AddrLabelDiff: 9380b57cec5SDimitry Andric Out << "&&" << getAddrLabelDiffLHS()->getLabel()->getName(); 9390b57cec5SDimitry Andric Out << " - "; 9400b57cec5SDimitry Andric Out << "&&" << getAddrLabelDiffRHS()->getLabel()->getName(); 9410b57cec5SDimitry Andric return; 9420b57cec5SDimitry Andric } 9430b57cec5SDimitry Andric llvm_unreachable("Unknown APValue kind!"); 9440b57cec5SDimitry Andric } 9450b57cec5SDimitry Andric 9460b57cec5SDimitry Andric std::string APValue::getAsString(const ASTContext &Ctx, QualType Ty) const { 9470b57cec5SDimitry Andric std::string Result; 9480b57cec5SDimitry Andric llvm::raw_string_ostream Out(Result); 9490b57cec5SDimitry Andric printPretty(Out, Ctx, Ty); 9500b57cec5SDimitry Andric Out.flush(); 9510b57cec5SDimitry Andric return Result; 9520b57cec5SDimitry Andric } 9530b57cec5SDimitry Andric 9540b57cec5SDimitry Andric bool APValue::toIntegralConstant(APSInt &Result, QualType SrcTy, 9550b57cec5SDimitry Andric const ASTContext &Ctx) const { 9560b57cec5SDimitry Andric if (isInt()) { 9570b57cec5SDimitry Andric Result = getInt(); 9580b57cec5SDimitry Andric return true; 9590b57cec5SDimitry Andric } 9600b57cec5SDimitry Andric 9610b57cec5SDimitry Andric if (isLValue() && isNullPointer()) { 9620b57cec5SDimitry Andric Result = Ctx.MakeIntValue(Ctx.getTargetNullPointerValue(SrcTy), SrcTy); 9630b57cec5SDimitry Andric return true; 9640b57cec5SDimitry Andric } 9650b57cec5SDimitry Andric 9660b57cec5SDimitry Andric if (isLValue() && !getLValueBase()) { 9670b57cec5SDimitry Andric Result = Ctx.MakeIntValue(getLValueOffset().getQuantity(), SrcTy); 9680b57cec5SDimitry Andric return true; 9690b57cec5SDimitry Andric } 9700b57cec5SDimitry Andric 9710b57cec5SDimitry Andric return false; 9720b57cec5SDimitry Andric } 9730b57cec5SDimitry Andric 9740b57cec5SDimitry Andric const APValue::LValueBase APValue::getLValueBase() const { 9750b57cec5SDimitry Andric assert(isLValue() && "Invalid accessor"); 976e8d8bef9SDimitry Andric return ((const LV *)(const void *)&Data)->Base; 9770b57cec5SDimitry Andric } 9780b57cec5SDimitry Andric 9790b57cec5SDimitry Andric bool APValue::isLValueOnePastTheEnd() const { 9800b57cec5SDimitry Andric assert(isLValue() && "Invalid accessor"); 981e8d8bef9SDimitry Andric return ((const LV *)(const void *)&Data)->IsOnePastTheEnd; 9820b57cec5SDimitry Andric } 9830b57cec5SDimitry Andric 9840b57cec5SDimitry Andric CharUnits &APValue::getLValueOffset() { 9850b57cec5SDimitry Andric assert(isLValue() && "Invalid accessor"); 986e8d8bef9SDimitry Andric return ((LV *)(void *)&Data)->Offset; 9870b57cec5SDimitry Andric } 9880b57cec5SDimitry Andric 9890b57cec5SDimitry Andric bool APValue::hasLValuePath() const { 9900b57cec5SDimitry Andric assert(isLValue() && "Invalid accessor"); 991e8d8bef9SDimitry Andric return ((const LV *)(const char *)&Data)->hasPath(); 9920b57cec5SDimitry Andric } 9930b57cec5SDimitry Andric 9940b57cec5SDimitry Andric ArrayRef<APValue::LValuePathEntry> APValue::getLValuePath() const { 9950b57cec5SDimitry Andric assert(isLValue() && hasLValuePath() && "Invalid accessor"); 996e8d8bef9SDimitry Andric const LV &LVal = *((const LV *)(const char *)&Data); 997bdd1243dSDimitry Andric return llvm::ArrayRef(LVal.getPath(), LVal.PathLength); 9980b57cec5SDimitry Andric } 9990b57cec5SDimitry Andric 10000b57cec5SDimitry Andric unsigned APValue::getLValueCallIndex() const { 10010b57cec5SDimitry Andric assert(isLValue() && "Invalid accessor"); 1002e8d8bef9SDimitry Andric return ((const LV *)(const char *)&Data)->Base.getCallIndex(); 10030b57cec5SDimitry Andric } 10040b57cec5SDimitry Andric 10050b57cec5SDimitry Andric unsigned APValue::getLValueVersion() const { 10060b57cec5SDimitry Andric assert(isLValue() && "Invalid accessor"); 1007e8d8bef9SDimitry Andric return ((const LV *)(const char *)&Data)->Base.getVersion(); 10080b57cec5SDimitry Andric } 10090b57cec5SDimitry Andric 10100b57cec5SDimitry Andric bool APValue::isNullPointer() const { 10110b57cec5SDimitry Andric assert(isLValue() && "Invalid usage"); 1012e8d8bef9SDimitry Andric return ((const LV *)(const char *)&Data)->IsNullPtr; 10130b57cec5SDimitry Andric } 10140b57cec5SDimitry Andric 10150b57cec5SDimitry Andric void APValue::setLValue(LValueBase B, const CharUnits &O, NoLValuePath, 10160b57cec5SDimitry Andric bool IsNullPtr) { 10170b57cec5SDimitry Andric assert(isLValue() && "Invalid accessor"); 1018e8d8bef9SDimitry Andric LV &LVal = *((LV *)(char *)&Data); 10190b57cec5SDimitry Andric LVal.Base = B; 10200b57cec5SDimitry Andric LVal.IsOnePastTheEnd = false; 10210b57cec5SDimitry Andric LVal.Offset = O; 10220b57cec5SDimitry Andric LVal.resizePath((unsigned)-1); 10230b57cec5SDimitry Andric LVal.IsNullPtr = IsNullPtr; 10240b57cec5SDimitry Andric } 10250b57cec5SDimitry Andric 1026e8d8bef9SDimitry Andric MutableArrayRef<APValue::LValuePathEntry> 1027e8d8bef9SDimitry Andric APValue::setLValueUninit(LValueBase B, const CharUnits &O, unsigned Size, 1028e8d8bef9SDimitry Andric bool IsOnePastTheEnd, bool IsNullPtr) { 10290b57cec5SDimitry Andric assert(isLValue() && "Invalid accessor"); 1030e8d8bef9SDimitry Andric LV &LVal = *((LV *)(char *)&Data); 10310b57cec5SDimitry Andric LVal.Base = B; 10320b57cec5SDimitry Andric LVal.IsOnePastTheEnd = IsOnePastTheEnd; 10330b57cec5SDimitry Andric LVal.Offset = O; 10340b57cec5SDimitry Andric LVal.IsNullPtr = IsNullPtr; 1035e8d8bef9SDimitry Andric LVal.resizePath(Size); 1036e8d8bef9SDimitry Andric return {LVal.getPath(), Size}; 1037e8d8bef9SDimitry Andric } 1038e8d8bef9SDimitry Andric 1039e8d8bef9SDimitry Andric void APValue::setLValue(LValueBase B, const CharUnits &O, 1040e8d8bef9SDimitry Andric ArrayRef<LValuePathEntry> Path, bool IsOnePastTheEnd, 1041e8d8bef9SDimitry Andric bool IsNullPtr) { 1042e8d8bef9SDimitry Andric MutableArrayRef<APValue::LValuePathEntry> InternalPath = 1043e8d8bef9SDimitry Andric setLValueUninit(B, O, Path.size(), IsOnePastTheEnd, IsNullPtr); 1044e8d8bef9SDimitry Andric if (Path.size()) { 1045e8d8bef9SDimitry Andric memcpy(InternalPath.data(), Path.data(), 1046e8d8bef9SDimitry Andric Path.size() * sizeof(LValuePathEntry)); 1047e8d8bef9SDimitry Andric } 1048e8d8bef9SDimitry Andric } 1049e8d8bef9SDimitry Andric 1050e8d8bef9SDimitry Andric void APValue::setUnion(const FieldDecl *Field, const APValue &Value) { 1051e8d8bef9SDimitry Andric assert(isUnion() && "Invalid accessor"); 1052e8d8bef9SDimitry Andric ((UnionData *)(char *)&Data)->Field = 1053e8d8bef9SDimitry Andric Field ? Field->getCanonicalDecl() : nullptr; 1054e8d8bef9SDimitry Andric *((UnionData *)(char *)&Data)->Value = Value; 10550b57cec5SDimitry Andric } 10560b57cec5SDimitry Andric 10570b57cec5SDimitry Andric const ValueDecl *APValue::getMemberPointerDecl() const { 10580b57cec5SDimitry Andric assert(isMemberPointer() && "Invalid accessor"); 10590b57cec5SDimitry Andric const MemberPointerData &MPD = 1060e8d8bef9SDimitry Andric *((const MemberPointerData *)(const char *)&Data); 10610b57cec5SDimitry Andric return MPD.MemberAndIsDerivedMember.getPointer(); 10620b57cec5SDimitry Andric } 10630b57cec5SDimitry Andric 10640b57cec5SDimitry Andric bool APValue::isMemberPointerToDerivedMember() const { 10650b57cec5SDimitry Andric assert(isMemberPointer() && "Invalid accessor"); 10660b57cec5SDimitry Andric const MemberPointerData &MPD = 1067e8d8bef9SDimitry Andric *((const MemberPointerData *)(const char *)&Data); 10680b57cec5SDimitry Andric return MPD.MemberAndIsDerivedMember.getInt(); 10690b57cec5SDimitry Andric } 10700b57cec5SDimitry Andric 10710b57cec5SDimitry Andric ArrayRef<const CXXRecordDecl*> APValue::getMemberPointerPath() const { 10720b57cec5SDimitry Andric assert(isMemberPointer() && "Invalid accessor"); 10730b57cec5SDimitry Andric const MemberPointerData &MPD = 1074e8d8bef9SDimitry Andric *((const MemberPointerData *)(const char *)&Data); 1075bdd1243dSDimitry Andric return llvm::ArrayRef(MPD.getPath(), MPD.PathLength); 10760b57cec5SDimitry Andric } 10770b57cec5SDimitry Andric 10780b57cec5SDimitry Andric void APValue::MakeLValue() { 10790b57cec5SDimitry Andric assert(isAbsent() && "Bad state change"); 10800b57cec5SDimitry Andric static_assert(sizeof(LV) <= DataSize, "LV too big"); 1081e8d8bef9SDimitry Andric new ((void *)(char *)&Data) LV(); 10820b57cec5SDimitry Andric Kind = LValue; 10830b57cec5SDimitry Andric } 10840b57cec5SDimitry Andric 10850b57cec5SDimitry Andric void APValue::MakeArray(unsigned InitElts, unsigned Size) { 10860b57cec5SDimitry Andric assert(isAbsent() && "Bad state change"); 1087e8d8bef9SDimitry Andric new ((void *)(char *)&Data) Arr(InitElts, Size); 10880b57cec5SDimitry Andric Kind = Array; 10890b57cec5SDimitry Andric } 10900b57cec5SDimitry Andric 1091e8d8bef9SDimitry Andric MutableArrayRef<APValue::LValuePathEntry> 1092e8d8bef9SDimitry Andric setLValueUninit(APValue::LValueBase B, const CharUnits &O, unsigned Size, 1093e8d8bef9SDimitry Andric bool OnePastTheEnd, bool IsNullPtr); 1094e8d8bef9SDimitry Andric 1095e8d8bef9SDimitry Andric MutableArrayRef<const CXXRecordDecl *> 1096e8d8bef9SDimitry Andric APValue::setMemberPointerUninit(const ValueDecl *Member, bool IsDerivedMember, 1097e8d8bef9SDimitry Andric unsigned Size) { 1098e8d8bef9SDimitry Andric assert(isAbsent() && "Bad state change"); 1099e8d8bef9SDimitry Andric MemberPointerData *MPD = new ((void *)(char *)&Data) MemberPointerData; 1100e8d8bef9SDimitry Andric Kind = MemberPointer; 1101e8d8bef9SDimitry Andric MPD->MemberAndIsDerivedMember.setPointer( 1102e8d8bef9SDimitry Andric Member ? cast<ValueDecl>(Member->getCanonicalDecl()) : nullptr); 1103e8d8bef9SDimitry Andric MPD->MemberAndIsDerivedMember.setInt(IsDerivedMember); 1104e8d8bef9SDimitry Andric MPD->resizePath(Size); 1105e8d8bef9SDimitry Andric return {MPD->getPath(), MPD->PathLength}; 1106e8d8bef9SDimitry Andric } 1107e8d8bef9SDimitry Andric 11080b57cec5SDimitry Andric void APValue::MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember, 11090b57cec5SDimitry Andric ArrayRef<const CXXRecordDecl *> Path) { 1110e8d8bef9SDimitry Andric MutableArrayRef<const CXXRecordDecl *> InternalPath = 1111e8d8bef9SDimitry Andric setMemberPointerUninit(Member, IsDerivedMember, Path.size()); 1112e8d8bef9SDimitry Andric for (unsigned I = 0; I != Path.size(); ++I) 1113e8d8bef9SDimitry Andric InternalPath[I] = Path[I]->getCanonicalDecl(); 1114e8d8bef9SDimitry Andric } 1115e8d8bef9SDimitry Andric 1116e8d8bef9SDimitry Andric LinkageInfo LinkageComputer::getLVForValue(const APValue &V, 1117e8d8bef9SDimitry Andric LVComputationKind computation) { 1118e8d8bef9SDimitry Andric LinkageInfo LV = LinkageInfo::external(); 1119e8d8bef9SDimitry Andric 1120e8d8bef9SDimitry Andric auto MergeLV = [&](LinkageInfo MergeLV) { 1121e8d8bef9SDimitry Andric LV.merge(MergeLV); 11225f757f3fSDimitry Andric return LV.getLinkage() == Linkage::Internal; 1123e8d8bef9SDimitry Andric }; 1124e8d8bef9SDimitry Andric auto Merge = [&](const APValue &V) { 1125e8d8bef9SDimitry Andric return MergeLV(getLVForValue(V, computation)); 1126e8d8bef9SDimitry Andric }; 1127e8d8bef9SDimitry Andric 1128e8d8bef9SDimitry Andric switch (V.getKind()) { 1129e8d8bef9SDimitry Andric case APValue::None: 1130e8d8bef9SDimitry Andric case APValue::Indeterminate: 1131e8d8bef9SDimitry Andric case APValue::Int: 1132e8d8bef9SDimitry Andric case APValue::Float: 1133e8d8bef9SDimitry Andric case APValue::FixedPoint: 1134e8d8bef9SDimitry Andric case APValue::ComplexInt: 1135e8d8bef9SDimitry Andric case APValue::ComplexFloat: 1136e8d8bef9SDimitry Andric case APValue::Vector: 1137e8d8bef9SDimitry Andric break; 1138e8d8bef9SDimitry Andric 1139e8d8bef9SDimitry Andric case APValue::AddrLabelDiff: 1140e8d8bef9SDimitry Andric // Even for an inline function, it's not reasonable to treat a difference 1141e8d8bef9SDimitry Andric // between the addresses of labels as an external value. 1142e8d8bef9SDimitry Andric return LinkageInfo::internal(); 1143e8d8bef9SDimitry Andric 1144e8d8bef9SDimitry Andric case APValue::Struct: { 1145e8d8bef9SDimitry Andric for (unsigned I = 0, N = V.getStructNumBases(); I != N; ++I) 1146e8d8bef9SDimitry Andric if (Merge(V.getStructBase(I))) 1147e8d8bef9SDimitry Andric break; 1148e8d8bef9SDimitry Andric for (unsigned I = 0, N = V.getStructNumFields(); I != N; ++I) 1149e8d8bef9SDimitry Andric if (Merge(V.getStructField(I))) 1150e8d8bef9SDimitry Andric break; 1151e8d8bef9SDimitry Andric break; 1152e8d8bef9SDimitry Andric } 1153e8d8bef9SDimitry Andric 1154e8d8bef9SDimitry Andric case APValue::Union: 1155e8d8bef9SDimitry Andric if (V.getUnionField()) 1156e8d8bef9SDimitry Andric Merge(V.getUnionValue()); 1157e8d8bef9SDimitry Andric break; 1158e8d8bef9SDimitry Andric 1159e8d8bef9SDimitry Andric case APValue::Array: { 1160e8d8bef9SDimitry Andric for (unsigned I = 0, N = V.getArrayInitializedElts(); I != N; ++I) 1161e8d8bef9SDimitry Andric if (Merge(V.getArrayInitializedElt(I))) 1162e8d8bef9SDimitry Andric break; 1163e8d8bef9SDimitry Andric if (V.hasArrayFiller()) 1164e8d8bef9SDimitry Andric Merge(V.getArrayFiller()); 1165e8d8bef9SDimitry Andric break; 1166e8d8bef9SDimitry Andric } 1167e8d8bef9SDimitry Andric 1168e8d8bef9SDimitry Andric case APValue::LValue: { 1169e8d8bef9SDimitry Andric if (!V.getLValueBase()) { 1170e8d8bef9SDimitry Andric // Null or absolute address: this is external. 1171e8d8bef9SDimitry Andric } else if (const auto *VD = 1172e8d8bef9SDimitry Andric V.getLValueBase().dyn_cast<const ValueDecl *>()) { 1173e8d8bef9SDimitry Andric if (VD && MergeLV(getLVForDecl(VD, computation))) 1174e8d8bef9SDimitry Andric break; 1175e8d8bef9SDimitry Andric } else if (const auto TI = V.getLValueBase().dyn_cast<TypeInfoLValue>()) { 1176e8d8bef9SDimitry Andric if (MergeLV(getLVForType(*TI.getType(), computation))) 1177e8d8bef9SDimitry Andric break; 1178e8d8bef9SDimitry Andric } else if (const Expr *E = V.getLValueBase().dyn_cast<const Expr *>()) { 1179e8d8bef9SDimitry Andric // Almost all expression bases are internal. The exception is 1180e8d8bef9SDimitry Andric // lifetime-extended temporaries. 1181e8d8bef9SDimitry Andric // FIXME: These should be modeled as having the 1182e8d8bef9SDimitry Andric // LifetimeExtendedTemporaryDecl itself as the base. 1183e8d8bef9SDimitry Andric // FIXME: If we permit Objective-C object literals in template arguments, 1184e8d8bef9SDimitry Andric // they should not imply internal linkage. 1185e8d8bef9SDimitry Andric auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E); 1186e8d8bef9SDimitry Andric if (!MTE || MTE->getStorageDuration() == SD_FullExpression) 1187e8d8bef9SDimitry Andric return LinkageInfo::internal(); 1188e8d8bef9SDimitry Andric if (MergeLV(getLVForDecl(MTE->getExtendingDecl(), computation))) 1189e8d8bef9SDimitry Andric break; 1190e8d8bef9SDimitry Andric } else { 1191e8d8bef9SDimitry Andric assert(V.getLValueBase().is<DynamicAllocLValue>() && 1192e8d8bef9SDimitry Andric "unexpected LValueBase kind"); 1193e8d8bef9SDimitry Andric return LinkageInfo::internal(); 1194e8d8bef9SDimitry Andric } 1195e8d8bef9SDimitry Andric // The lvalue path doesn't matter: pointers to all subobjects always have 1196e8d8bef9SDimitry Andric // the same visibility as pointers to the complete object. 1197e8d8bef9SDimitry Andric break; 1198e8d8bef9SDimitry Andric } 1199e8d8bef9SDimitry Andric 1200e8d8bef9SDimitry Andric case APValue::MemberPointer: 1201e8d8bef9SDimitry Andric if (const NamedDecl *D = V.getMemberPointerDecl()) 1202e8d8bef9SDimitry Andric MergeLV(getLVForDecl(D, computation)); 1203e8d8bef9SDimitry Andric // Note that we could have a base-to-derived conversion here to a member of 1204e8d8bef9SDimitry Andric // a derived class with less linkage/visibility. That's covered by the 1205e8d8bef9SDimitry Andric // linkage and visibility of the value's type. 1206e8d8bef9SDimitry Andric break; 1207e8d8bef9SDimitry Andric } 1208e8d8bef9SDimitry Andric 1209e8d8bef9SDimitry Andric return LV; 12100b57cec5SDimitry Andric } 1211