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.
TypeInfoLValue(const Type * T)270b57cec5SDimitry Andric TypeInfoLValue::TypeInfoLValue(const Type *T)
280b57cec5SDimitry Andric     : T(T->getCanonicalTypeUnqualified().getTypePtr()) {}
290b57cec5SDimitry Andric 
print(llvm::raw_ostream & Out,const PrintingPolicy & Policy) const300b57cec5SDimitry 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 
LValueBase(const ValueDecl * P,unsigned I,unsigned V)420b57cec5SDimitry Andric APValue::LValueBase::LValueBase(const ValueDecl *P, unsigned I, unsigned V)
43e8d8bef9SDimitry Andric     : Ptr(P ? cast<ValueDecl>(P->getCanonicalDecl()) : nullptr), Local{I, V} {}
LValueBase(const Expr * P,unsigned I,unsigned V)440b57cec5SDimitry Andric APValue::LValueBase::LValueBase(const Expr *P, unsigned I, unsigned V)
450b57cec5SDimitry Andric     : Ptr(P), Local{I, V} {}
460b57cec5SDimitry Andric 
getDynamicAlloc(DynamicAllocLValue LV,QualType Type)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 
getTypeInfo(TypeInfoLValue LV,QualType TypeInfo)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 
getType() const63e8d8bef9SDimitry 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 =
93e8d8bef9SDimitry Andric           clang::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 
getCallIndex() const1080b57cec5SDimitry Andric unsigned APValue::LValueBase::getCallIndex() const {
109a7dea167SDimitry Andric   return (is<TypeInfoLValue>() || is<DynamicAllocLValue>()) ? 0
110a7dea167SDimitry Andric                                                             : Local.CallIndex;
1110b57cec5SDimitry Andric }
1120b57cec5SDimitry Andric 
getVersion() const1130b57cec5SDimitry Andric unsigned APValue::LValueBase::getVersion() const {
114a7dea167SDimitry Andric   return (is<TypeInfoLValue>() || is<DynamicAllocLValue>()) ? 0 : Local.Version;
1150b57cec5SDimitry Andric }
1160b57cec5SDimitry Andric 
getTypeInfoType() const1170b57cec5SDimitry 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 
getDynamicAllocType() const122a7dea167SDimitry 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 
Profile(llvm::FoldingSetNodeID & ID) const127e8d8bef9SDimitry 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 {
operator ==(const APValue::LValueBase & LHS,const APValue::LValueBase & RHS)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 
LValuePathEntry(BaseOrMemberType BaseOrMember)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 
Profile(llvm::FoldingSetNodeID & ID) const153e8d8bef9SDimitry Andric void APValue::LValuePathEntry::Profile(llvm::FoldingSetNodeID &ID) const {
154e8d8bef9SDimitry Andric   ID.AddInteger(Value);
155e8d8bef9SDimitry Andric }
156e8d8bef9SDimitry Andric 
LValuePathSerializationHelper(ArrayRef<LValuePathEntry> Path,QualType ElemTy)157e8d8bef9SDimitry Andric APValue::LValuePathSerializationHelper::LValuePathSerializationHelper(
158e8d8bef9SDimitry Andric     ArrayRef<LValuePathEntry> Path, QualType ElemTy)
159bdd1243dSDimitry Andric     : Ty((const void *)ElemTy.getTypePtrOrNull()), Path(Path) {}
160e8d8bef9SDimitry Andric 
getType()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 
getOpaqueValue() const1750b57cec5SDimitry Andric void *APValue::LValueBase::getOpaqueValue() const {
1760b57cec5SDimitry Andric   return Ptr.getOpaqueValue();
1770b57cec5SDimitry Andric }
1780b57cec5SDimitry Andric 
isNull() const1790b57cec5SDimitry Andric bool APValue::LValueBase::isNull() const {
1800b57cec5SDimitry Andric   return Ptr.isNull();
1810b57cec5SDimitry Andric }
1820b57cec5SDimitry Andric 
operator bool() const1830b57cec5SDimitry Andric APValue::LValueBase::operator bool () const {
1840b57cec5SDimitry Andric   return static_cast<bool>(Ptr);
1850b57cec5SDimitry Andric }
1860b57cec5SDimitry Andric 
1870b57cec5SDimitry Andric clang::APValue::LValueBase
getEmptyKey()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
getTombstoneKey()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 {
hash_value(const APValue::LValueBase & Base)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 
getHashValue(const clang::APValue::LValueBase & Base)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 
isEqual(const clang::APValue::LValueBase & LHS,const clang::APValue::LValueBase & RHS)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 
LVAPValue::LV2330b57cec5SDimitry Andric   LV() { PathLength = (unsigned)-1; }
~LVAPValue::LV2340b57cec5SDimitry Andric   ~LV() { resizePath(0); }
2350b57cec5SDimitry Andric 
resizePathAPValue::LV2360b57cec5SDimitry 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 
hasPathAPValue::LV2460b57cec5SDimitry Andric   bool hasPath() const { return PathLength != (unsigned)-1; }
hasPathPtrAPValue::LV2470b57cec5SDimitry Andric   bool hasPathPtr() const { return hasPath() && PathLength > InlinePathSpace; }
2480b57cec5SDimitry Andric 
getPathAPValue::LV2490b57cec5SDimitry Andric   LValuePathEntry *getPath() { return hasPathPtr() ? PathPtr : Path; }
getPathAPValue::LV2500b57cec5SDimitry 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 
MemberPointerDataAPValue::MemberPointerData2710b57cec5SDimitry Andric   MemberPointerData() { PathLength = 0; }
~MemberPointerDataAPValue::MemberPointerData2720b57cec5SDimitry Andric   ~MemberPointerData() { resizePath(0); }
2730b57cec5SDimitry Andric 
resizePathAPValue::MemberPointerData2740b57cec5SDimitry 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 
hasPathPtrAPValue::MemberPointerData2840b57cec5SDimitry Andric   bool hasPathPtr() const { return PathLength > InlinePathSpace; }
2850b57cec5SDimitry Andric 
getPathAPValue::MemberPointerData2860b57cec5SDimitry Andric   PathElem *getPath() { return hasPathPtr() ? PathPtr : Path; }
getPathAPValue::MemberPointerData2870b57cec5SDimitry 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 
Arr(unsigned NumElts,unsigned Size)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) {}
~Arr()2970b57cec5SDimitry Andric APValue::Arr::~Arr() { delete [] Elts; }
2980b57cec5SDimitry Andric 
StructData(unsigned NumBases,unsigned NumFields)2990b57cec5SDimitry Andric APValue::StructData::StructData(unsigned NumBases, unsigned NumFields) :
3000b57cec5SDimitry Andric   Elts(new APValue[NumBases+NumFields]),
3010b57cec5SDimitry Andric   NumBases(NumBases), NumFields(NumFields) {}
~StructData()3020b57cec5SDimitry Andric APValue::StructData::~StructData() {
3030b57cec5SDimitry Andric   delete [] Elts;
3040b57cec5SDimitry Andric }
3050b57cec5SDimitry Andric 
UnionData()3060b57cec5SDimitry Andric APValue::UnionData::UnionData() : Field(nullptr), Value(new APValue) {}
~UnionData()3070b57cec5SDimitry Andric APValue::UnionData::~UnionData () {
3080b57cec5SDimitry Andric   delete Value;
3090b57cec5SDimitry Andric }
3100b57cec5SDimitry Andric 
APValue(const APValue & RHS)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 
APValue(APValue && RHS)382e8d8bef9SDimitry Andric APValue::APValue(APValue &&RHS) : Kind(RHS.Kind), Data(RHS.Data) {
383e8d8bef9SDimitry Andric   RHS.Kind = None;
384e8d8bef9SDimitry Andric }
385e8d8bef9SDimitry Andric 
operator =(const APValue & RHS)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 
operator =(APValue && RHS)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 
DestroyDataAndMakeUninit()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 
needsCleanup() const4310b57cec5SDimitry 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 
swap(APValue & RHS)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.
profileIntValue(llvm::FoldingSetNodeID & ID,const llvm::APInt & V)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 
Profile(llvm::FoldingSetNodeID & ID) const479e8d8bef9SDimitry 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 
GetApproxValue(const llvm::APFloat & F)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 
TryPrintAsStringLiteral(raw_ostream & Out,const PrintingPolicy & Policy,const ArrayType * ATy,ArrayRef<APValue> Inits)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 
printPretty(raw_ostream & Out,const ASTContext & Ctx,QualType Ty) const6930b57cec5SDimitry 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 
printPretty(raw_ostream & Out,const PrintingPolicy & Policy,QualType Ty,const ASTContext * Ctx) const698e8d8bef9SDimitry 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 
7070b57cec5SDimitry Andric   switch (getKind()) {
7080b57cec5SDimitry Andric   case APValue::None:
7090b57cec5SDimitry Andric     Out << "<out of lifetime>";
7100b57cec5SDimitry Andric     return;
7110b57cec5SDimitry Andric   case APValue::Indeterminate:
7120b57cec5SDimitry Andric     Out << "<uninitialized>";
7130b57cec5SDimitry Andric     return;
7140b57cec5SDimitry Andric   case APValue::Int:
7150b57cec5SDimitry Andric     if (Ty->isBooleanType())
7160b57cec5SDimitry Andric       Out << (getInt().getBoolValue() ? "true" : "false");
7170b57cec5SDimitry Andric     else
7180b57cec5SDimitry Andric       Out << getInt();
7190b57cec5SDimitry Andric     return;
7200b57cec5SDimitry Andric   case APValue::Float:
7210b57cec5SDimitry Andric     Out << GetApproxValue(getFloat());
7220b57cec5SDimitry Andric     return;
7230b57cec5SDimitry Andric   case APValue::FixedPoint:
7240b57cec5SDimitry Andric     Out << getFixedPoint();
7250b57cec5SDimitry Andric     return;
7260b57cec5SDimitry Andric   case APValue::Vector: {
7270b57cec5SDimitry Andric     Out << '{';
728a7dea167SDimitry Andric     QualType ElemTy = Ty->castAs<VectorType>()->getElementType();
729e8d8bef9SDimitry Andric     getVectorElt(0).printPretty(Out, Policy, ElemTy, Ctx);
7300b57cec5SDimitry Andric     for (unsigned i = 1; i != getVectorLength(); ++i) {
7310b57cec5SDimitry Andric       Out << ", ";
732e8d8bef9SDimitry Andric       getVectorElt(i).printPretty(Out, Policy, ElemTy, Ctx);
7330b57cec5SDimitry Andric     }
7340b57cec5SDimitry Andric     Out << '}';
7350b57cec5SDimitry Andric     return;
7360b57cec5SDimitry Andric   }
7370b57cec5SDimitry Andric   case APValue::ComplexInt:
7380b57cec5SDimitry Andric     Out << getComplexIntReal() << "+" << getComplexIntImag() << "i";
7390b57cec5SDimitry Andric     return;
7400b57cec5SDimitry Andric   case APValue::ComplexFloat:
7410b57cec5SDimitry Andric     Out << GetApproxValue(getComplexFloatReal()) << "+"
7420b57cec5SDimitry Andric         << GetApproxValue(getComplexFloatImag()) << "i";
7430b57cec5SDimitry Andric     return;
7440b57cec5SDimitry Andric   case APValue::LValue: {
7450b57cec5SDimitry Andric     bool IsReference = Ty->isReferenceType();
7460b57cec5SDimitry Andric     QualType InnerTy
7470b57cec5SDimitry Andric       = IsReference ? Ty.getNonReferenceType() : Ty->getPointeeType();
7480b57cec5SDimitry Andric     if (InnerTy.isNull())
7490b57cec5SDimitry Andric       InnerTy = Ty;
7500b57cec5SDimitry Andric 
7510b57cec5SDimitry Andric     LValueBase Base = getLValueBase();
7520b57cec5SDimitry Andric     if (!Base) {
7530b57cec5SDimitry Andric       if (isNullPointer()) {
754e8d8bef9SDimitry Andric         Out << (Policy.Nullptr ? "nullptr" : "0");
7550b57cec5SDimitry Andric       } else if (IsReference) {
756e8d8bef9SDimitry Andric         Out << "*(" << InnerTy.stream(Policy) << "*)"
7570b57cec5SDimitry Andric             << getLValueOffset().getQuantity();
7580b57cec5SDimitry Andric       } else {
759e8d8bef9SDimitry Andric         Out << "(" << Ty.stream(Policy) << ")"
7600b57cec5SDimitry Andric             << getLValueOffset().getQuantity();
7610b57cec5SDimitry Andric       }
7620b57cec5SDimitry Andric       return;
7630b57cec5SDimitry Andric     }
7640b57cec5SDimitry Andric 
7650b57cec5SDimitry Andric     if (!hasLValuePath()) {
7660b57cec5SDimitry Andric       // No lvalue path: just print the offset.
7670b57cec5SDimitry Andric       CharUnits O = getLValueOffset();
76881ad6265SDimitry Andric       CharUnits S = Ctx ? Ctx->getTypeSizeInCharsIfKnown(InnerTy).value_or(
769349cc55cSDimitry Andric                               CharUnits::Zero())
770349cc55cSDimitry Andric                         : CharUnits::Zero();
7710b57cec5SDimitry Andric       if (!O.isZero()) {
7720b57cec5SDimitry Andric         if (IsReference)
7730b57cec5SDimitry Andric           Out << "*(";
774e8d8bef9SDimitry Andric         if (S.isZero() || O % S) {
7750b57cec5SDimitry Andric           Out << "(char*)";
7760b57cec5SDimitry Andric           S = CharUnits::One();
7770b57cec5SDimitry Andric         }
7780b57cec5SDimitry Andric         Out << '&';
779a7dea167SDimitry Andric       } else if (!IsReference) {
7800b57cec5SDimitry Andric         Out << '&';
781a7dea167SDimitry Andric       }
7820b57cec5SDimitry Andric 
7830b57cec5SDimitry Andric       if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>())
7840b57cec5SDimitry Andric         Out << *VD;
7850b57cec5SDimitry Andric       else if (TypeInfoLValue TI = Base.dyn_cast<TypeInfoLValue>()) {
786e8d8bef9SDimitry Andric         TI.print(Out, Policy);
787a7dea167SDimitry Andric       } else if (DynamicAllocLValue DA = Base.dyn_cast<DynamicAllocLValue>()) {
788a7dea167SDimitry Andric         Out << "{*new "
789e8d8bef9SDimitry Andric             << Base.getDynamicAllocType().stream(Policy) << "#"
790a7dea167SDimitry Andric             << DA.getIndex() << "}";
7910b57cec5SDimitry Andric       } else {
7920b57cec5SDimitry Andric         assert(Base.get<const Expr *>() != nullptr &&
7930b57cec5SDimitry Andric                "Expecting non-null Expr");
794e8d8bef9SDimitry Andric         Base.get<const Expr*>()->printPretty(Out, nullptr, Policy);
7950b57cec5SDimitry Andric       }
7960b57cec5SDimitry Andric 
7970b57cec5SDimitry Andric       if (!O.isZero()) {
7980b57cec5SDimitry Andric         Out << " + " << (O / S);
7990b57cec5SDimitry Andric         if (IsReference)
8000b57cec5SDimitry Andric           Out << ')';
8010b57cec5SDimitry Andric       }
8020b57cec5SDimitry Andric       return;
8030b57cec5SDimitry Andric     }
8040b57cec5SDimitry Andric 
8050b57cec5SDimitry Andric     // We have an lvalue path. Print it out nicely.
8060b57cec5SDimitry Andric     if (!IsReference)
8070b57cec5SDimitry Andric       Out << '&';
8080b57cec5SDimitry Andric     else if (isLValueOnePastTheEnd())
8090b57cec5SDimitry Andric       Out << "*(&";
8100b57cec5SDimitry Andric 
811e8d8bef9SDimitry Andric     QualType ElemTy = Base.getType();
8120b57cec5SDimitry Andric     if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) {
8130b57cec5SDimitry Andric       Out << *VD;
8140b57cec5SDimitry Andric     } else if (TypeInfoLValue TI = Base.dyn_cast<TypeInfoLValue>()) {
815e8d8bef9SDimitry Andric       TI.print(Out, Policy);
816a7dea167SDimitry Andric     } else if (DynamicAllocLValue DA = Base.dyn_cast<DynamicAllocLValue>()) {
817e8d8bef9SDimitry Andric       Out << "{*new " << Base.getDynamicAllocType().stream(Policy) << "#"
818a7dea167SDimitry Andric           << DA.getIndex() << "}";
8190b57cec5SDimitry Andric     } else {
8200b57cec5SDimitry Andric       const Expr *E = Base.get<const Expr*>();
8210b57cec5SDimitry Andric       assert(E != nullptr && "Expecting non-null Expr");
822e8d8bef9SDimitry Andric       E->printPretty(Out, nullptr, Policy);
8230b57cec5SDimitry Andric     }
8240b57cec5SDimitry Andric 
8250b57cec5SDimitry Andric     ArrayRef<LValuePathEntry> Path = getLValuePath();
8260b57cec5SDimitry Andric     const CXXRecordDecl *CastToBase = nullptr;
8270b57cec5SDimitry Andric     for (unsigned I = 0, N = Path.size(); I != N; ++I) {
828e8d8bef9SDimitry Andric       if (ElemTy->isRecordType()) {
8290b57cec5SDimitry Andric         // The lvalue refers to a class type, so the next path entry is a base
8300b57cec5SDimitry Andric         // or member.
8310b57cec5SDimitry Andric         const Decl *BaseOrMember = Path[I].getAsBaseOrMember().getPointer();
8320b57cec5SDimitry Andric         if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(BaseOrMember)) {
8330b57cec5SDimitry Andric           CastToBase = RD;
834e8d8bef9SDimitry Andric           // Leave ElemTy referring to the most-derived class. The actual type
835e8d8bef9SDimitry Andric           // doesn't matter except for array types.
8360b57cec5SDimitry Andric         } else {
8370b57cec5SDimitry Andric           const ValueDecl *VD = cast<ValueDecl>(BaseOrMember);
8380b57cec5SDimitry Andric           Out << ".";
8390b57cec5SDimitry Andric           if (CastToBase)
8400b57cec5SDimitry Andric             Out << *CastToBase << "::";
8410b57cec5SDimitry Andric           Out << *VD;
8420b57cec5SDimitry Andric           ElemTy = VD->getType();
8430b57cec5SDimitry Andric         }
8445f757f3fSDimitry Andric       } else if (ElemTy->isAnyComplexType()) {
8455f757f3fSDimitry Andric         // The lvalue refers to a complex type
8465f757f3fSDimitry Andric         Out << (Path[I].getAsArrayIndex() == 0 ? ".real" : ".imag");
8475f757f3fSDimitry Andric         ElemTy = ElemTy->castAs<ComplexType>()->getElementType();
8480b57cec5SDimitry Andric       } else {
8490b57cec5SDimitry Andric         // The lvalue must refer to an array.
8500b57cec5SDimitry Andric         Out << '[' << Path[I].getAsArrayIndex() << ']';
851e8d8bef9SDimitry Andric         ElemTy = ElemTy->castAsArrayTypeUnsafe()->getElementType();
8520b57cec5SDimitry Andric       }
8530b57cec5SDimitry Andric     }
8540b57cec5SDimitry Andric 
8550b57cec5SDimitry Andric     // Handle formatting of one-past-the-end lvalues.
8560b57cec5SDimitry Andric     if (isLValueOnePastTheEnd()) {
8570b57cec5SDimitry Andric       // FIXME: If CastToBase is non-0, we should prefix the output with
8580b57cec5SDimitry Andric       // "(CastToBase*)".
8590b57cec5SDimitry Andric       Out << " + 1";
8600b57cec5SDimitry Andric       if (IsReference)
8610b57cec5SDimitry Andric         Out << ')';
8620b57cec5SDimitry Andric     }
8630b57cec5SDimitry Andric     return;
8640b57cec5SDimitry Andric   }
8650b57cec5SDimitry Andric   case APValue::Array: {
866e8d8bef9SDimitry Andric     const ArrayType *AT = Ty->castAsArrayTypeUnsafe();
86781ad6265SDimitry Andric     unsigned N = getArrayInitializedElts();
86881ad6265SDimitry Andric     if (N != 0 && TryPrintAsStringLiteral(Out, Policy, AT,
86981ad6265SDimitry Andric                                           {&getArrayInitializedElt(0), N}))
87081ad6265SDimitry Andric       return;
8710b57cec5SDimitry Andric     QualType ElemTy = AT->getElementType();
8720b57cec5SDimitry Andric     Out << '{';
87381ad6265SDimitry Andric     unsigned I = 0;
87481ad6265SDimitry Andric     switch (N) {
87581ad6265SDimitry Andric     case 0:
87681ad6265SDimitry Andric       for (; I != N; ++I) {
8770b57cec5SDimitry Andric         Out << ", ";
87881ad6265SDimitry Andric         if (I == 10 && !Policy.EntireContentsOfLargeArray) {
87981ad6265SDimitry Andric           Out << "...}";
88081ad6265SDimitry Andric           return;
8810b57cec5SDimitry Andric         }
882bdd1243dSDimitry Andric         [[fallthrough]];
88381ad6265SDimitry Andric       default:
884e8d8bef9SDimitry Andric         getArrayInitializedElt(I).printPretty(Out, Policy, ElemTy, Ctx);
8850b57cec5SDimitry Andric       }
8860b57cec5SDimitry Andric     }
8870b57cec5SDimitry Andric     Out << '}';
8880b57cec5SDimitry Andric     return;
8890b57cec5SDimitry Andric   }
8900b57cec5SDimitry Andric   case APValue::Struct: {
8910b57cec5SDimitry Andric     Out << '{';
892a7dea167SDimitry Andric     const RecordDecl *RD = Ty->castAs<RecordType>()->getDecl();
8930b57cec5SDimitry Andric     bool First = true;
8940b57cec5SDimitry Andric     if (unsigned N = getStructNumBases()) {
8950b57cec5SDimitry Andric       const CXXRecordDecl *CD = cast<CXXRecordDecl>(RD);
8960b57cec5SDimitry Andric       CXXRecordDecl::base_class_const_iterator BI = CD->bases_begin();
8970b57cec5SDimitry Andric       for (unsigned I = 0; I != N; ++I, ++BI) {
8980b57cec5SDimitry Andric         assert(BI != CD->bases_end());
8990b57cec5SDimitry Andric         if (!First)
9000b57cec5SDimitry Andric           Out << ", ";
901e8d8bef9SDimitry Andric         getStructBase(I).printPretty(Out, Policy, BI->getType(), Ctx);
9020b57cec5SDimitry Andric         First = false;
9030b57cec5SDimitry Andric       }
9040b57cec5SDimitry Andric     }
9050b57cec5SDimitry Andric     for (const auto *FI : RD->fields()) {
9060b57cec5SDimitry Andric       if (!First)
9070b57cec5SDimitry Andric         Out << ", ";
9080b57cec5SDimitry Andric       if (FI->isUnnamedBitfield()) continue;
9090b57cec5SDimitry Andric       getStructField(FI->getFieldIndex()).
910e8d8bef9SDimitry Andric         printPretty(Out, Policy, FI->getType(), Ctx);
9110b57cec5SDimitry Andric       First = false;
9120b57cec5SDimitry Andric     }
9130b57cec5SDimitry Andric     Out << '}';
9140b57cec5SDimitry Andric     return;
9150b57cec5SDimitry Andric   }
9160b57cec5SDimitry Andric   case APValue::Union:
9170b57cec5SDimitry Andric     Out << '{';
9180b57cec5SDimitry Andric     if (const FieldDecl *FD = getUnionField()) {
9190b57cec5SDimitry Andric       Out << "." << *FD << " = ";
920e8d8bef9SDimitry Andric       getUnionValue().printPretty(Out, Policy, FD->getType(), Ctx);
9210b57cec5SDimitry Andric     }
9220b57cec5SDimitry Andric     Out << '}';
9230b57cec5SDimitry Andric     return;
9240b57cec5SDimitry Andric   case APValue::MemberPointer:
9250b57cec5SDimitry Andric     // FIXME: This is not enough to unambiguously identify the member in a
9260b57cec5SDimitry Andric     // multiple-inheritance scenario.
9270b57cec5SDimitry Andric     if (const ValueDecl *VD = getMemberPointerDecl()) {
9280b57cec5SDimitry Andric       Out << '&' << *cast<CXXRecordDecl>(VD->getDeclContext()) << "::" << *VD;
9290b57cec5SDimitry Andric       return;
9300b57cec5SDimitry Andric     }
9310b57cec5SDimitry Andric     Out << "0";
9320b57cec5SDimitry Andric     return;
9330b57cec5SDimitry Andric   case APValue::AddrLabelDiff:
9340b57cec5SDimitry Andric     Out << "&&" << getAddrLabelDiffLHS()->getLabel()->getName();
9350b57cec5SDimitry Andric     Out << " - ";
9360b57cec5SDimitry Andric     Out << "&&" << getAddrLabelDiffRHS()->getLabel()->getName();
9370b57cec5SDimitry Andric     return;
9380b57cec5SDimitry Andric   }
9390b57cec5SDimitry Andric   llvm_unreachable("Unknown APValue kind!");
9400b57cec5SDimitry Andric }
9410b57cec5SDimitry Andric 
getAsString(const ASTContext & Ctx,QualType Ty) const9420b57cec5SDimitry Andric std::string APValue::getAsString(const ASTContext &Ctx, QualType Ty) const {
9430b57cec5SDimitry Andric   std::string Result;
9440b57cec5SDimitry Andric   llvm::raw_string_ostream Out(Result);
9450b57cec5SDimitry Andric   printPretty(Out, Ctx, Ty);
9460b57cec5SDimitry Andric   Out.flush();
9470b57cec5SDimitry Andric   return Result;
9480b57cec5SDimitry Andric }
9490b57cec5SDimitry Andric 
toIntegralConstant(APSInt & Result,QualType SrcTy,const ASTContext & Ctx) const9500b57cec5SDimitry Andric bool APValue::toIntegralConstant(APSInt &Result, QualType SrcTy,
9510b57cec5SDimitry Andric                                  const ASTContext &Ctx) const {
9520b57cec5SDimitry Andric   if (isInt()) {
9530b57cec5SDimitry Andric     Result = getInt();
9540b57cec5SDimitry Andric     return true;
9550b57cec5SDimitry Andric   }
9560b57cec5SDimitry Andric 
9570b57cec5SDimitry Andric   if (isLValue() && isNullPointer()) {
9580b57cec5SDimitry Andric     Result = Ctx.MakeIntValue(Ctx.getTargetNullPointerValue(SrcTy), SrcTy);
9590b57cec5SDimitry Andric     return true;
9600b57cec5SDimitry Andric   }
9610b57cec5SDimitry Andric 
9620b57cec5SDimitry Andric   if (isLValue() && !getLValueBase()) {
9630b57cec5SDimitry Andric     Result = Ctx.MakeIntValue(getLValueOffset().getQuantity(), SrcTy);
9640b57cec5SDimitry Andric     return true;
9650b57cec5SDimitry Andric   }
9660b57cec5SDimitry Andric 
9670b57cec5SDimitry Andric   return false;
9680b57cec5SDimitry Andric }
9690b57cec5SDimitry Andric 
getLValueBase() const9700b57cec5SDimitry Andric const APValue::LValueBase APValue::getLValueBase() const {
9710b57cec5SDimitry Andric   assert(isLValue() && "Invalid accessor");
972e8d8bef9SDimitry Andric   return ((const LV *)(const void *)&Data)->Base;
9730b57cec5SDimitry Andric }
9740b57cec5SDimitry Andric 
isLValueOnePastTheEnd() const9750b57cec5SDimitry Andric bool APValue::isLValueOnePastTheEnd() const {
9760b57cec5SDimitry Andric   assert(isLValue() && "Invalid accessor");
977e8d8bef9SDimitry Andric   return ((const LV *)(const void *)&Data)->IsOnePastTheEnd;
9780b57cec5SDimitry Andric }
9790b57cec5SDimitry Andric 
getLValueOffset()9800b57cec5SDimitry Andric CharUnits &APValue::getLValueOffset() {
9810b57cec5SDimitry Andric   assert(isLValue() && "Invalid accessor");
982e8d8bef9SDimitry Andric   return ((LV *)(void *)&Data)->Offset;
9830b57cec5SDimitry Andric }
9840b57cec5SDimitry Andric 
hasLValuePath() const9850b57cec5SDimitry Andric bool APValue::hasLValuePath() const {
9860b57cec5SDimitry Andric   assert(isLValue() && "Invalid accessor");
987e8d8bef9SDimitry Andric   return ((const LV *)(const char *)&Data)->hasPath();
9880b57cec5SDimitry Andric }
9890b57cec5SDimitry Andric 
getLValuePath() const9900b57cec5SDimitry Andric ArrayRef<APValue::LValuePathEntry> APValue::getLValuePath() const {
9910b57cec5SDimitry Andric   assert(isLValue() && hasLValuePath() && "Invalid accessor");
992e8d8bef9SDimitry Andric   const LV &LVal = *((const LV *)(const char *)&Data);
993bdd1243dSDimitry Andric   return llvm::ArrayRef(LVal.getPath(), LVal.PathLength);
9940b57cec5SDimitry Andric }
9950b57cec5SDimitry Andric 
getLValueCallIndex() const9960b57cec5SDimitry Andric unsigned APValue::getLValueCallIndex() const {
9970b57cec5SDimitry Andric   assert(isLValue() && "Invalid accessor");
998e8d8bef9SDimitry Andric   return ((const LV *)(const char *)&Data)->Base.getCallIndex();
9990b57cec5SDimitry Andric }
10000b57cec5SDimitry Andric 
getLValueVersion() const10010b57cec5SDimitry Andric unsigned APValue::getLValueVersion() const {
10020b57cec5SDimitry Andric   assert(isLValue() && "Invalid accessor");
1003e8d8bef9SDimitry Andric   return ((const LV *)(const char *)&Data)->Base.getVersion();
10040b57cec5SDimitry Andric }
10050b57cec5SDimitry Andric 
isNullPointer() const10060b57cec5SDimitry Andric bool APValue::isNullPointer() const {
10070b57cec5SDimitry Andric   assert(isLValue() && "Invalid usage");
1008e8d8bef9SDimitry Andric   return ((const LV *)(const char *)&Data)->IsNullPtr;
10090b57cec5SDimitry Andric }
10100b57cec5SDimitry Andric 
setLValue(LValueBase B,const CharUnits & O,NoLValuePath,bool IsNullPtr)10110b57cec5SDimitry Andric void APValue::setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
10120b57cec5SDimitry Andric                         bool IsNullPtr) {
10130b57cec5SDimitry Andric   assert(isLValue() && "Invalid accessor");
1014e8d8bef9SDimitry Andric   LV &LVal = *((LV *)(char *)&Data);
10150b57cec5SDimitry Andric   LVal.Base = B;
10160b57cec5SDimitry Andric   LVal.IsOnePastTheEnd = false;
10170b57cec5SDimitry Andric   LVal.Offset = O;
10180b57cec5SDimitry Andric   LVal.resizePath((unsigned)-1);
10190b57cec5SDimitry Andric   LVal.IsNullPtr = IsNullPtr;
10200b57cec5SDimitry Andric }
10210b57cec5SDimitry Andric 
1022e8d8bef9SDimitry Andric MutableArrayRef<APValue::LValuePathEntry>
setLValueUninit(LValueBase B,const CharUnits & O,unsigned Size,bool IsOnePastTheEnd,bool IsNullPtr)1023e8d8bef9SDimitry Andric APValue::setLValueUninit(LValueBase B, const CharUnits &O, unsigned Size,
1024e8d8bef9SDimitry Andric                          bool IsOnePastTheEnd, bool IsNullPtr) {
10250b57cec5SDimitry Andric   assert(isLValue() && "Invalid accessor");
1026e8d8bef9SDimitry Andric   LV &LVal = *((LV *)(char *)&Data);
10270b57cec5SDimitry Andric   LVal.Base = B;
10280b57cec5SDimitry Andric   LVal.IsOnePastTheEnd = IsOnePastTheEnd;
10290b57cec5SDimitry Andric   LVal.Offset = O;
10300b57cec5SDimitry Andric   LVal.IsNullPtr = IsNullPtr;
1031e8d8bef9SDimitry Andric   LVal.resizePath(Size);
1032e8d8bef9SDimitry Andric   return {LVal.getPath(), Size};
1033e8d8bef9SDimitry Andric }
1034e8d8bef9SDimitry Andric 
setLValue(LValueBase B,const CharUnits & O,ArrayRef<LValuePathEntry> Path,bool IsOnePastTheEnd,bool IsNullPtr)1035e8d8bef9SDimitry Andric void APValue::setLValue(LValueBase B, const CharUnits &O,
1036e8d8bef9SDimitry Andric                         ArrayRef<LValuePathEntry> Path, bool IsOnePastTheEnd,
1037e8d8bef9SDimitry Andric                         bool IsNullPtr) {
1038e8d8bef9SDimitry Andric   MutableArrayRef<APValue::LValuePathEntry> InternalPath =
1039e8d8bef9SDimitry Andric       setLValueUninit(B, O, Path.size(), IsOnePastTheEnd, IsNullPtr);
1040e8d8bef9SDimitry Andric   if (Path.size()) {
1041e8d8bef9SDimitry Andric     memcpy(InternalPath.data(), Path.data(),
1042e8d8bef9SDimitry Andric            Path.size() * sizeof(LValuePathEntry));
1043e8d8bef9SDimitry Andric   }
1044e8d8bef9SDimitry Andric }
1045e8d8bef9SDimitry Andric 
setUnion(const FieldDecl * Field,const APValue & Value)1046e8d8bef9SDimitry Andric void APValue::setUnion(const FieldDecl *Field, const APValue &Value) {
1047e8d8bef9SDimitry Andric   assert(isUnion() && "Invalid accessor");
1048e8d8bef9SDimitry Andric   ((UnionData *)(char *)&Data)->Field =
1049e8d8bef9SDimitry Andric       Field ? Field->getCanonicalDecl() : nullptr;
1050e8d8bef9SDimitry Andric   *((UnionData *)(char *)&Data)->Value = Value;
10510b57cec5SDimitry Andric }
10520b57cec5SDimitry Andric 
getMemberPointerDecl() const10530b57cec5SDimitry Andric const ValueDecl *APValue::getMemberPointerDecl() const {
10540b57cec5SDimitry Andric   assert(isMemberPointer() && "Invalid accessor");
10550b57cec5SDimitry Andric   const MemberPointerData &MPD =
1056e8d8bef9SDimitry Andric       *((const MemberPointerData *)(const char *)&Data);
10570b57cec5SDimitry Andric   return MPD.MemberAndIsDerivedMember.getPointer();
10580b57cec5SDimitry Andric }
10590b57cec5SDimitry Andric 
isMemberPointerToDerivedMember() const10600b57cec5SDimitry Andric bool APValue::isMemberPointerToDerivedMember() const {
10610b57cec5SDimitry Andric   assert(isMemberPointer() && "Invalid accessor");
10620b57cec5SDimitry Andric   const MemberPointerData &MPD =
1063e8d8bef9SDimitry Andric       *((const MemberPointerData *)(const char *)&Data);
10640b57cec5SDimitry Andric   return MPD.MemberAndIsDerivedMember.getInt();
10650b57cec5SDimitry Andric }
10660b57cec5SDimitry Andric 
getMemberPointerPath() const10670b57cec5SDimitry Andric ArrayRef<const CXXRecordDecl*> APValue::getMemberPointerPath() const {
10680b57cec5SDimitry Andric   assert(isMemberPointer() && "Invalid accessor");
10690b57cec5SDimitry Andric   const MemberPointerData &MPD =
1070e8d8bef9SDimitry Andric       *((const MemberPointerData *)(const char *)&Data);
1071bdd1243dSDimitry Andric   return llvm::ArrayRef(MPD.getPath(), MPD.PathLength);
10720b57cec5SDimitry Andric }
10730b57cec5SDimitry Andric 
MakeLValue()10740b57cec5SDimitry Andric void APValue::MakeLValue() {
10750b57cec5SDimitry Andric   assert(isAbsent() && "Bad state change");
10760b57cec5SDimitry Andric   static_assert(sizeof(LV) <= DataSize, "LV too big");
1077e8d8bef9SDimitry Andric   new ((void *)(char *)&Data) LV();
10780b57cec5SDimitry Andric   Kind = LValue;
10790b57cec5SDimitry Andric }
10800b57cec5SDimitry Andric 
MakeArray(unsigned InitElts,unsigned Size)10810b57cec5SDimitry Andric void APValue::MakeArray(unsigned InitElts, unsigned Size) {
10820b57cec5SDimitry Andric   assert(isAbsent() && "Bad state change");
1083e8d8bef9SDimitry Andric   new ((void *)(char *)&Data) Arr(InitElts, Size);
10840b57cec5SDimitry Andric   Kind = Array;
10850b57cec5SDimitry Andric }
10860b57cec5SDimitry Andric 
1087e8d8bef9SDimitry Andric MutableArrayRef<APValue::LValuePathEntry>
1088e8d8bef9SDimitry Andric setLValueUninit(APValue::LValueBase B, const CharUnits &O, unsigned Size,
1089e8d8bef9SDimitry Andric                 bool OnePastTheEnd, bool IsNullPtr);
1090e8d8bef9SDimitry Andric 
1091e8d8bef9SDimitry Andric MutableArrayRef<const CXXRecordDecl *>
setMemberPointerUninit(const ValueDecl * Member,bool IsDerivedMember,unsigned Size)1092e8d8bef9SDimitry Andric APValue::setMemberPointerUninit(const ValueDecl *Member, bool IsDerivedMember,
1093e8d8bef9SDimitry Andric                                 unsigned Size) {
1094e8d8bef9SDimitry Andric   assert(isAbsent() && "Bad state change");
1095e8d8bef9SDimitry Andric   MemberPointerData *MPD = new ((void *)(char *)&Data) MemberPointerData;
1096e8d8bef9SDimitry Andric   Kind = MemberPointer;
1097e8d8bef9SDimitry Andric   MPD->MemberAndIsDerivedMember.setPointer(
1098e8d8bef9SDimitry Andric       Member ? cast<ValueDecl>(Member->getCanonicalDecl()) : nullptr);
1099e8d8bef9SDimitry Andric   MPD->MemberAndIsDerivedMember.setInt(IsDerivedMember);
1100e8d8bef9SDimitry Andric   MPD->resizePath(Size);
1101e8d8bef9SDimitry Andric   return {MPD->getPath(), MPD->PathLength};
1102e8d8bef9SDimitry Andric }
1103e8d8bef9SDimitry Andric 
MakeMemberPointer(const ValueDecl * Member,bool IsDerivedMember,ArrayRef<const CXXRecordDecl * > Path)11040b57cec5SDimitry Andric void APValue::MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
11050b57cec5SDimitry Andric                                 ArrayRef<const CXXRecordDecl *> Path) {
1106e8d8bef9SDimitry Andric   MutableArrayRef<const CXXRecordDecl *> InternalPath =
1107e8d8bef9SDimitry Andric       setMemberPointerUninit(Member, IsDerivedMember, Path.size());
1108e8d8bef9SDimitry Andric   for (unsigned I = 0; I != Path.size(); ++I)
1109e8d8bef9SDimitry Andric     InternalPath[I] = Path[I]->getCanonicalDecl();
1110e8d8bef9SDimitry Andric }
1111e8d8bef9SDimitry Andric 
getLVForValue(const APValue & V,LVComputationKind computation)1112e8d8bef9SDimitry Andric LinkageInfo LinkageComputer::getLVForValue(const APValue &V,
1113e8d8bef9SDimitry Andric                                            LVComputationKind computation) {
1114e8d8bef9SDimitry Andric   LinkageInfo LV = LinkageInfo::external();
1115e8d8bef9SDimitry Andric 
1116e8d8bef9SDimitry Andric   auto MergeLV = [&](LinkageInfo MergeLV) {
1117e8d8bef9SDimitry Andric     LV.merge(MergeLV);
11185f757f3fSDimitry Andric     return LV.getLinkage() == Linkage::Internal;
1119e8d8bef9SDimitry Andric   };
1120e8d8bef9SDimitry Andric   auto Merge = [&](const APValue &V) {
1121e8d8bef9SDimitry Andric     return MergeLV(getLVForValue(V, computation));
1122e8d8bef9SDimitry Andric   };
1123e8d8bef9SDimitry Andric 
1124e8d8bef9SDimitry Andric   switch (V.getKind()) {
1125e8d8bef9SDimitry Andric   case APValue::None:
1126e8d8bef9SDimitry Andric   case APValue::Indeterminate:
1127e8d8bef9SDimitry Andric   case APValue::Int:
1128e8d8bef9SDimitry Andric   case APValue::Float:
1129e8d8bef9SDimitry Andric   case APValue::FixedPoint:
1130e8d8bef9SDimitry Andric   case APValue::ComplexInt:
1131e8d8bef9SDimitry Andric   case APValue::ComplexFloat:
1132e8d8bef9SDimitry Andric   case APValue::Vector:
1133e8d8bef9SDimitry Andric     break;
1134e8d8bef9SDimitry Andric 
1135e8d8bef9SDimitry Andric   case APValue::AddrLabelDiff:
1136e8d8bef9SDimitry Andric     // Even for an inline function, it's not reasonable to treat a difference
1137e8d8bef9SDimitry Andric     // between the addresses of labels as an external value.
1138e8d8bef9SDimitry Andric     return LinkageInfo::internal();
1139e8d8bef9SDimitry Andric 
1140e8d8bef9SDimitry Andric   case APValue::Struct: {
1141e8d8bef9SDimitry Andric     for (unsigned I = 0, N = V.getStructNumBases(); I != N; ++I)
1142e8d8bef9SDimitry Andric       if (Merge(V.getStructBase(I)))
1143e8d8bef9SDimitry Andric         break;
1144e8d8bef9SDimitry Andric     for (unsigned I = 0, N = V.getStructNumFields(); I != N; ++I)
1145e8d8bef9SDimitry Andric       if (Merge(V.getStructField(I)))
1146e8d8bef9SDimitry Andric         break;
1147e8d8bef9SDimitry Andric     break;
1148e8d8bef9SDimitry Andric   }
1149e8d8bef9SDimitry Andric 
1150e8d8bef9SDimitry Andric   case APValue::Union:
1151e8d8bef9SDimitry Andric     if (V.getUnionField())
1152e8d8bef9SDimitry Andric       Merge(V.getUnionValue());
1153e8d8bef9SDimitry Andric     break;
1154e8d8bef9SDimitry Andric 
1155e8d8bef9SDimitry Andric   case APValue::Array: {
1156e8d8bef9SDimitry Andric     for (unsigned I = 0, N = V.getArrayInitializedElts(); I != N; ++I)
1157e8d8bef9SDimitry Andric       if (Merge(V.getArrayInitializedElt(I)))
1158e8d8bef9SDimitry Andric         break;
1159e8d8bef9SDimitry Andric     if (V.hasArrayFiller())
1160e8d8bef9SDimitry Andric       Merge(V.getArrayFiller());
1161e8d8bef9SDimitry Andric     break;
1162e8d8bef9SDimitry Andric   }
1163e8d8bef9SDimitry Andric 
1164e8d8bef9SDimitry Andric   case APValue::LValue: {
1165e8d8bef9SDimitry Andric     if (!V.getLValueBase()) {
1166e8d8bef9SDimitry Andric       // Null or absolute address: this is external.
1167e8d8bef9SDimitry Andric     } else if (const auto *VD =
1168e8d8bef9SDimitry Andric                    V.getLValueBase().dyn_cast<const ValueDecl *>()) {
1169e8d8bef9SDimitry Andric       if (VD && MergeLV(getLVForDecl(VD, computation)))
1170e8d8bef9SDimitry Andric         break;
1171e8d8bef9SDimitry Andric     } else if (const auto TI = V.getLValueBase().dyn_cast<TypeInfoLValue>()) {
1172e8d8bef9SDimitry Andric       if (MergeLV(getLVForType(*TI.getType(), computation)))
1173e8d8bef9SDimitry Andric         break;
1174e8d8bef9SDimitry Andric     } else if (const Expr *E = V.getLValueBase().dyn_cast<const Expr *>()) {
1175e8d8bef9SDimitry Andric       // Almost all expression bases are internal. The exception is
1176e8d8bef9SDimitry Andric       // lifetime-extended temporaries.
1177e8d8bef9SDimitry Andric       // FIXME: These should be modeled as having the
1178e8d8bef9SDimitry Andric       // LifetimeExtendedTemporaryDecl itself as the base.
1179e8d8bef9SDimitry Andric       // FIXME: If we permit Objective-C object literals in template arguments,
1180e8d8bef9SDimitry Andric       // they should not imply internal linkage.
1181e8d8bef9SDimitry Andric       auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E);
1182e8d8bef9SDimitry Andric       if (!MTE || MTE->getStorageDuration() == SD_FullExpression)
1183e8d8bef9SDimitry Andric         return LinkageInfo::internal();
1184e8d8bef9SDimitry Andric       if (MergeLV(getLVForDecl(MTE->getExtendingDecl(), computation)))
1185e8d8bef9SDimitry Andric         break;
1186e8d8bef9SDimitry Andric     } else {
1187e8d8bef9SDimitry Andric       assert(V.getLValueBase().is<DynamicAllocLValue>() &&
1188e8d8bef9SDimitry Andric              "unexpected LValueBase kind");
1189e8d8bef9SDimitry Andric       return LinkageInfo::internal();
1190e8d8bef9SDimitry Andric     }
1191e8d8bef9SDimitry Andric     // The lvalue path doesn't matter: pointers to all subobjects always have
1192e8d8bef9SDimitry Andric     // the same visibility as pointers to the complete object.
1193e8d8bef9SDimitry Andric     break;
1194e8d8bef9SDimitry Andric   }
1195e8d8bef9SDimitry Andric 
1196e8d8bef9SDimitry Andric   case APValue::MemberPointer:
1197e8d8bef9SDimitry Andric     if (const NamedDecl *D = V.getMemberPointerDecl())
1198e8d8bef9SDimitry Andric       MergeLV(getLVForDecl(D, computation));
1199e8d8bef9SDimitry Andric     // Note that we could have a base-to-derived conversion here to a member of
1200e8d8bef9SDimitry Andric     // a derived class with less linkage/visibility. That's covered by the
1201e8d8bef9SDimitry Andric     // linkage and visibility of the value's type.
1202e8d8bef9SDimitry Andric     break;
1203e8d8bef9SDimitry Andric   }
1204e8d8bef9SDimitry Andric 
1205e8d8bef9SDimitry Andric   return LV;
12060b57cec5SDimitry Andric }
1207