xref: /llvm-project/clang/lib/AST/APValue.cpp (revision ee0ce302c5eb4f26738f334f2fd8b165fa65dfca)
1 //===--- APValue.cpp - Union class for APFloat/APSInt/Complex -------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 //  This file implements the APValue class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "clang/AST/APValue.h"
14 #include "clang/AST/ASTContext.h"
15 #include "clang/AST/CharUnits.h"
16 #include "clang/AST/DeclCXX.h"
17 #include "clang/AST/Expr.h"
18 #include "clang/AST/Type.h"
19 #include "llvm/Support/ErrorHandling.h"
20 #include "llvm/Support/raw_ostream.h"
21 using namespace clang;
22 
23 /// The identity of a type_info object depends on the canonical unqualified
24 /// type only.
25 TypeInfoLValue::TypeInfoLValue(const Type *T)
26     : T(T->getCanonicalTypeUnqualified().getTypePtr()) {}
27 
28 void TypeInfoLValue::print(llvm::raw_ostream &Out,
29                            const PrintingPolicy &Policy) const {
30   Out << "typeid(";
31   QualType(getType(), 0).print(Out, Policy);
32   Out << ")";
33 }
34 
35 static_assert(
36     1 << llvm::PointerLikeTypeTraits<TypeInfoLValue>::NumLowBitsAvailable <=
37         alignof(const Type *),
38     "Type is insufficiently aligned");
39 
40 APValue::LValueBase::LValueBase(const ValueDecl *P, unsigned I, unsigned V)
41     : Ptr(P), Local{I, V} {}
42 APValue::LValueBase::LValueBase(const Expr *P, unsigned I, unsigned V)
43     : Ptr(P), Local{I, V} {}
44 
45 APValue::LValueBase APValue::LValueBase::getTypeInfo(TypeInfoLValue LV,
46                                                      QualType TypeInfo) {
47   LValueBase Base;
48   Base.Ptr = LV;
49   Base.TypeInfoType = TypeInfo.getAsOpaquePtr();
50   return Base;
51 }
52 
53 unsigned APValue::LValueBase::getCallIndex() const {
54   return is<TypeInfoLValue>() ? 0 : Local.CallIndex;
55 }
56 
57 unsigned APValue::LValueBase::getVersion() const {
58   return is<TypeInfoLValue>() ? 0 : Local.Version;
59 }
60 
61 QualType APValue::LValueBase::getTypeInfoType() const {
62   assert(is<TypeInfoLValue>() && "not a type_info lvalue");
63   return QualType::getFromOpaquePtr(TypeInfoType);
64 }
65 
66 namespace clang {
67 bool operator==(const APValue::LValueBase &LHS,
68                 const APValue::LValueBase &RHS) {
69   if (LHS.Ptr != RHS.Ptr)
70     return false;
71   if (LHS.is<TypeInfoLValue>())
72     return true;
73   return LHS.Local.CallIndex == RHS.Local.CallIndex &&
74          LHS.Local.Version == RHS.Local.Version;
75 }
76 }
77 
78 namespace {
79   struct LVBase {
80     APValue::LValueBase Base;
81     CharUnits Offset;
82     unsigned PathLength;
83     bool IsNullPtr : 1;
84     bool IsOnePastTheEnd : 1;
85   };
86 }
87 
88 void *APValue::LValueBase::getOpaqueValue() const {
89   return Ptr.getOpaqueValue();
90 }
91 
92 bool APValue::LValueBase::isNull() const {
93   return Ptr.isNull();
94 }
95 
96 APValue::LValueBase::operator bool () const {
97   return static_cast<bool>(Ptr);
98 }
99 
100 clang::APValue::LValueBase
101 llvm::DenseMapInfo<clang::APValue::LValueBase>::getEmptyKey() {
102   return clang::APValue::LValueBase(
103       DenseMapInfo<const ValueDecl*>::getEmptyKey());
104 }
105 
106 clang::APValue::LValueBase
107 llvm::DenseMapInfo<clang::APValue::LValueBase>::getTombstoneKey() {
108   return clang::APValue::LValueBase(
109       DenseMapInfo<const ValueDecl*>::getTombstoneKey());
110 }
111 
112 namespace clang {
113 llvm::hash_code hash_value(const APValue::LValueBase &Base) {
114   if (Base.is<TypeInfoLValue>())
115     return llvm::hash_value(Base.getOpaqueValue());
116   return llvm::hash_combine(Base.getOpaqueValue(), Base.getCallIndex(),
117                             Base.getVersion());
118 }
119 }
120 
121 unsigned llvm::DenseMapInfo<clang::APValue::LValueBase>::getHashValue(
122     const clang::APValue::LValueBase &Base) {
123   return hash_value(Base);
124 }
125 
126 bool llvm::DenseMapInfo<clang::APValue::LValueBase>::isEqual(
127     const clang::APValue::LValueBase &LHS,
128     const clang::APValue::LValueBase &RHS) {
129   return LHS == RHS;
130 }
131 
132 struct APValue::LV : LVBase {
133   static const unsigned InlinePathSpace =
134       (DataSize - sizeof(LVBase)) / sizeof(LValuePathEntry);
135 
136   /// Path - The sequence of base classes, fields and array indices to follow to
137   /// walk from Base to the subobject. When performing GCC-style folding, there
138   /// may not be such a path.
139   union {
140     LValuePathEntry Path[InlinePathSpace];
141     LValuePathEntry *PathPtr;
142   };
143 
144   LV() { PathLength = (unsigned)-1; }
145   ~LV() { resizePath(0); }
146 
147   void resizePath(unsigned Length) {
148     if (Length == PathLength)
149       return;
150     if (hasPathPtr())
151       delete [] PathPtr;
152     PathLength = Length;
153     if (hasPathPtr())
154       PathPtr = new LValuePathEntry[Length];
155   }
156 
157   bool hasPath() const { return PathLength != (unsigned)-1; }
158   bool hasPathPtr() const { return hasPath() && PathLength > InlinePathSpace; }
159 
160   LValuePathEntry *getPath() { return hasPathPtr() ? PathPtr : Path; }
161   const LValuePathEntry *getPath() const {
162     return hasPathPtr() ? PathPtr : Path;
163   }
164 };
165 
166 namespace {
167   struct MemberPointerBase {
168     llvm::PointerIntPair<const ValueDecl*, 1, bool> MemberAndIsDerivedMember;
169     unsigned PathLength;
170   };
171 }
172 
173 struct APValue::MemberPointerData : MemberPointerBase {
174   static const unsigned InlinePathSpace =
175       (DataSize - sizeof(MemberPointerBase)) / sizeof(const CXXRecordDecl*);
176   typedef const CXXRecordDecl *PathElem;
177   union {
178     PathElem Path[InlinePathSpace];
179     PathElem *PathPtr;
180   };
181 
182   MemberPointerData() { PathLength = 0; }
183   ~MemberPointerData() { resizePath(0); }
184 
185   void resizePath(unsigned Length) {
186     if (Length == PathLength)
187       return;
188     if (hasPathPtr())
189       delete [] PathPtr;
190     PathLength = Length;
191     if (hasPathPtr())
192       PathPtr = new PathElem[Length];
193   }
194 
195   bool hasPathPtr() const { return PathLength > InlinePathSpace; }
196 
197   PathElem *getPath() { return hasPathPtr() ? PathPtr : Path; }
198   const PathElem *getPath() const {
199     return hasPathPtr() ? PathPtr : Path;
200   }
201 };
202 
203 // FIXME: Reduce the malloc traffic here.
204 
205 APValue::Arr::Arr(unsigned NumElts, unsigned Size) :
206   Elts(new APValue[NumElts + (NumElts != Size ? 1 : 0)]),
207   NumElts(NumElts), ArrSize(Size) {}
208 APValue::Arr::~Arr() { delete [] Elts; }
209 
210 APValue::StructData::StructData(unsigned NumBases, unsigned NumFields) :
211   Elts(new APValue[NumBases+NumFields]),
212   NumBases(NumBases), NumFields(NumFields) {}
213 APValue::StructData::~StructData() {
214   delete [] Elts;
215 }
216 
217 APValue::UnionData::UnionData() : Field(nullptr), Value(new APValue) {}
218 APValue::UnionData::~UnionData () {
219   delete Value;
220 }
221 
222 APValue::APValue(const APValue &RHS) : Kind(Uninitialized) {
223   switch (RHS.getKind()) {
224   case Uninitialized:
225     break;
226   case Int:
227     MakeInt();
228     setInt(RHS.getInt());
229     break;
230   case Float:
231     MakeFloat();
232     setFloat(RHS.getFloat());
233     break;
234   case FixedPoint: {
235     APFixedPoint FXCopy = RHS.getFixedPoint();
236     MakeFixedPoint(std::move(FXCopy));
237     break;
238   }
239   case Vector:
240     MakeVector();
241     setVector(((const Vec *)(const char *)RHS.Data.buffer)->Elts,
242               RHS.getVectorLength());
243     break;
244   case ComplexInt:
245     MakeComplexInt();
246     setComplexInt(RHS.getComplexIntReal(), RHS.getComplexIntImag());
247     break;
248   case ComplexFloat:
249     MakeComplexFloat();
250     setComplexFloat(RHS.getComplexFloatReal(), RHS.getComplexFloatImag());
251     break;
252   case LValue:
253     MakeLValue();
254     if (RHS.hasLValuePath())
255       setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), RHS.getLValuePath(),
256                 RHS.isLValueOnePastTheEnd(), RHS.isNullPointer());
257     else
258       setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), NoLValuePath(),
259                 RHS.isNullPointer());
260     break;
261   case Array:
262     MakeArray(RHS.getArrayInitializedElts(), RHS.getArraySize());
263     for (unsigned I = 0, N = RHS.getArrayInitializedElts(); I != N; ++I)
264       getArrayInitializedElt(I) = RHS.getArrayInitializedElt(I);
265     if (RHS.hasArrayFiller())
266       getArrayFiller() = RHS.getArrayFiller();
267     break;
268   case Struct:
269     MakeStruct(RHS.getStructNumBases(), RHS.getStructNumFields());
270     for (unsigned I = 0, N = RHS.getStructNumBases(); I != N; ++I)
271       getStructBase(I) = RHS.getStructBase(I);
272     for (unsigned I = 0, N = RHS.getStructNumFields(); I != N; ++I)
273       getStructField(I) = RHS.getStructField(I);
274     break;
275   case Union:
276     MakeUnion();
277     setUnion(RHS.getUnionField(), RHS.getUnionValue());
278     break;
279   case MemberPointer:
280     MakeMemberPointer(RHS.getMemberPointerDecl(),
281                       RHS.isMemberPointerToDerivedMember(),
282                       RHS.getMemberPointerPath());
283     break;
284   case AddrLabelDiff:
285     MakeAddrLabelDiff();
286     setAddrLabelDiff(RHS.getAddrLabelDiffLHS(), RHS.getAddrLabelDiffRHS());
287     break;
288   }
289 }
290 
291 void APValue::DestroyDataAndMakeUninit() {
292   if (Kind == Int)
293     ((APSInt*)(char*)Data.buffer)->~APSInt();
294   else if (Kind == Float)
295     ((APFloat*)(char*)Data.buffer)->~APFloat();
296   else if (Kind == FixedPoint)
297     ((APFixedPoint *)(char *)Data.buffer)->~APFixedPoint();
298   else if (Kind == Vector)
299     ((Vec*)(char*)Data.buffer)->~Vec();
300   else if (Kind == ComplexInt)
301     ((ComplexAPSInt*)(char*)Data.buffer)->~ComplexAPSInt();
302   else if (Kind == ComplexFloat)
303     ((ComplexAPFloat*)(char*)Data.buffer)->~ComplexAPFloat();
304   else if (Kind == LValue)
305     ((LV*)(char*)Data.buffer)->~LV();
306   else if (Kind == Array)
307     ((Arr*)(char*)Data.buffer)->~Arr();
308   else if (Kind == Struct)
309     ((StructData*)(char*)Data.buffer)->~StructData();
310   else if (Kind == Union)
311     ((UnionData*)(char*)Data.buffer)->~UnionData();
312   else if (Kind == MemberPointer)
313     ((MemberPointerData*)(char*)Data.buffer)->~MemberPointerData();
314   else if (Kind == AddrLabelDiff)
315     ((AddrLabelDiffData*)(char*)Data.buffer)->~AddrLabelDiffData();
316   Kind = Uninitialized;
317 }
318 
319 bool APValue::needsCleanup() const {
320   switch (getKind()) {
321   case Uninitialized:
322   case AddrLabelDiff:
323     return false;
324   case Struct:
325   case Union:
326   case Array:
327   case Vector:
328     return true;
329   case Int:
330     return getInt().needsCleanup();
331   case Float:
332     return getFloat().needsCleanup();
333   case FixedPoint:
334     return getFixedPoint().getValue().needsCleanup();
335   case ComplexFloat:
336     assert(getComplexFloatImag().needsCleanup() ==
337                getComplexFloatReal().needsCleanup() &&
338            "In _Complex float types, real and imaginary values always have the "
339            "same size.");
340     return getComplexFloatReal().needsCleanup();
341   case ComplexInt:
342     assert(getComplexIntImag().needsCleanup() ==
343                getComplexIntReal().needsCleanup() &&
344            "In _Complex int types, real and imaginary values must have the "
345            "same size.");
346     return getComplexIntReal().needsCleanup();
347   case LValue:
348     return reinterpret_cast<const LV *>(Data.buffer)->hasPathPtr();
349   case MemberPointer:
350     return reinterpret_cast<const MemberPointerData *>(Data.buffer)
351         ->hasPathPtr();
352   }
353   llvm_unreachable("Unknown APValue kind!");
354 }
355 
356 void APValue::swap(APValue &RHS) {
357   std::swap(Kind, RHS.Kind);
358   char TmpData[DataSize];
359   memcpy(TmpData, Data.buffer, DataSize);
360   memcpy(Data.buffer, RHS.Data.buffer, DataSize);
361   memcpy(RHS.Data.buffer, TmpData, DataSize);
362 }
363 
364 LLVM_DUMP_METHOD void APValue::dump() const {
365   dump(llvm::errs());
366   llvm::errs() << '\n';
367 }
368 
369 static double GetApproxValue(const llvm::APFloat &F) {
370   llvm::APFloat V = F;
371   bool ignored;
372   V.convert(llvm::APFloat::IEEEdouble(), llvm::APFloat::rmNearestTiesToEven,
373             &ignored);
374   return V.convertToDouble();
375 }
376 
377 void APValue::dump(raw_ostream &OS) const {
378   switch (getKind()) {
379   case Uninitialized:
380     OS << "Uninitialized";
381     return;
382   case Int:
383     OS << "Int: " << getInt();
384     return;
385   case Float:
386     OS << "Float: " << GetApproxValue(getFloat());
387     return;
388   case FixedPoint:
389     OS << "FixedPoint : " << getFixedPoint();
390     return;
391   case Vector:
392     OS << "Vector: ";
393     getVectorElt(0).dump(OS);
394     for (unsigned i = 1; i != getVectorLength(); ++i) {
395       OS << ", ";
396       getVectorElt(i).dump(OS);
397     }
398     return;
399   case ComplexInt:
400     OS << "ComplexInt: " << getComplexIntReal() << ", " << getComplexIntImag();
401     return;
402   case ComplexFloat:
403     OS << "ComplexFloat: " << GetApproxValue(getComplexFloatReal())
404        << ", " << GetApproxValue(getComplexFloatImag());
405     return;
406   case LValue:
407     OS << "LValue: <todo>";
408     return;
409   case Array:
410     OS << "Array: ";
411     for (unsigned I = 0, N = getArrayInitializedElts(); I != N; ++I) {
412       getArrayInitializedElt(I).dump(OS);
413       if (I != getArraySize() - 1) OS << ", ";
414     }
415     if (hasArrayFiller()) {
416       OS << getArraySize() - getArrayInitializedElts() << " x ";
417       getArrayFiller().dump(OS);
418     }
419     return;
420   case Struct:
421     OS << "Struct ";
422     if (unsigned N = getStructNumBases()) {
423       OS << " bases: ";
424       getStructBase(0).dump(OS);
425       for (unsigned I = 1; I != N; ++I) {
426         OS << ", ";
427         getStructBase(I).dump(OS);
428       }
429     }
430     if (unsigned N = getStructNumFields()) {
431       OS << " fields: ";
432       getStructField(0).dump(OS);
433       for (unsigned I = 1; I != N; ++I) {
434         OS << ", ";
435         getStructField(I).dump(OS);
436       }
437     }
438     return;
439   case Union:
440     OS << "Union: ";
441     getUnionValue().dump(OS);
442     return;
443   case MemberPointer:
444     OS << "MemberPointer: <todo>";
445     return;
446   case AddrLabelDiff:
447     OS << "AddrLabelDiff: <todo>";
448     return;
449   }
450   llvm_unreachable("Unknown APValue kind!");
451 }
452 
453 void APValue::printPretty(raw_ostream &Out, ASTContext &Ctx, QualType Ty) const{
454   switch (getKind()) {
455   case APValue::Uninitialized:
456     Out << "<uninitialized>";
457     return;
458   case APValue::Int:
459     if (Ty->isBooleanType())
460       Out << (getInt().getBoolValue() ? "true" : "false");
461     else
462       Out << getInt();
463     return;
464   case APValue::Float:
465     Out << GetApproxValue(getFloat());
466     return;
467   case APValue::FixedPoint:
468     Out << getFixedPoint();
469     return;
470   case APValue::Vector: {
471     Out << '{';
472     QualType ElemTy = Ty->getAs<VectorType>()->getElementType();
473     getVectorElt(0).printPretty(Out, Ctx, ElemTy);
474     for (unsigned i = 1; i != getVectorLength(); ++i) {
475       Out << ", ";
476       getVectorElt(i).printPretty(Out, Ctx, ElemTy);
477     }
478     Out << '}';
479     return;
480   }
481   case APValue::ComplexInt:
482     Out << getComplexIntReal() << "+" << getComplexIntImag() << "i";
483     return;
484   case APValue::ComplexFloat:
485     Out << GetApproxValue(getComplexFloatReal()) << "+"
486         << GetApproxValue(getComplexFloatImag()) << "i";
487     return;
488   case APValue::LValue: {
489     bool IsReference = Ty->isReferenceType();
490     QualType InnerTy
491       = IsReference ? Ty.getNonReferenceType() : Ty->getPointeeType();
492     if (InnerTy.isNull())
493       InnerTy = Ty;
494 
495     LValueBase Base = getLValueBase();
496     if (!Base) {
497       if (isNullPointer()) {
498         Out << (Ctx.getLangOpts().CPlusPlus11 ? "nullptr" : "0");
499       } else if (IsReference) {
500         Out << "*(" << InnerTy.stream(Ctx.getPrintingPolicy()) << "*)"
501             << getLValueOffset().getQuantity();
502       } else {
503         Out << "(" << Ty.stream(Ctx.getPrintingPolicy()) << ")"
504             << getLValueOffset().getQuantity();
505       }
506       return;
507     }
508 
509     if (!hasLValuePath()) {
510       // No lvalue path: just print the offset.
511       CharUnits O = getLValueOffset();
512       CharUnits S = Ctx.getTypeSizeInChars(InnerTy);
513       if (!O.isZero()) {
514         if (IsReference)
515           Out << "*(";
516         if (O % S) {
517           Out << "(char*)";
518           S = CharUnits::One();
519         }
520         Out << '&';
521       } else if (!IsReference)
522         Out << '&';
523 
524       if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>())
525         Out << *VD;
526       else if (TypeInfoLValue TI = Base.dyn_cast<TypeInfoLValue>()) {
527         TI.print(Out, Ctx.getPrintingPolicy());
528       } else {
529         assert(Base.get<const Expr *>() != nullptr &&
530                "Expecting non-null Expr");
531         Base.get<const Expr*>()->printPretty(Out, nullptr,
532                                              Ctx.getPrintingPolicy());
533       }
534 
535       if (!O.isZero()) {
536         Out << " + " << (O / S);
537         if (IsReference)
538           Out << ')';
539       }
540       return;
541     }
542 
543     // We have an lvalue path. Print it out nicely.
544     if (!IsReference)
545       Out << '&';
546     else if (isLValueOnePastTheEnd())
547       Out << "*(&";
548 
549     QualType ElemTy;
550     if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) {
551       Out << *VD;
552       ElemTy = VD->getType();
553     } else if (TypeInfoLValue TI = Base.dyn_cast<TypeInfoLValue>()) {
554       TI.print(Out, Ctx.getPrintingPolicy());
555       ElemTy = Base.getTypeInfoType();
556     } else {
557       const Expr *E = Base.get<const Expr*>();
558       assert(E != nullptr && "Expecting non-null Expr");
559       E->printPretty(Out, nullptr, Ctx.getPrintingPolicy());
560       ElemTy = E->getType();
561     }
562 
563     ArrayRef<LValuePathEntry> Path = getLValuePath();
564     const CXXRecordDecl *CastToBase = nullptr;
565     for (unsigned I = 0, N = Path.size(); I != N; ++I) {
566       if (ElemTy->getAs<RecordType>()) {
567         // The lvalue refers to a class type, so the next path entry is a base
568         // or member.
569         const Decl *BaseOrMember = Path[I].getAsBaseOrMember().getPointer();
570         if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(BaseOrMember)) {
571           CastToBase = RD;
572           ElemTy = Ctx.getRecordType(RD);
573         } else {
574           const ValueDecl *VD = cast<ValueDecl>(BaseOrMember);
575           Out << ".";
576           if (CastToBase)
577             Out << *CastToBase << "::";
578           Out << *VD;
579           ElemTy = VD->getType();
580         }
581       } else {
582         // The lvalue must refer to an array.
583         Out << '[' << Path[I].getAsArrayIndex() << ']';
584         ElemTy = Ctx.getAsArrayType(ElemTy)->getElementType();
585       }
586     }
587 
588     // Handle formatting of one-past-the-end lvalues.
589     if (isLValueOnePastTheEnd()) {
590       // FIXME: If CastToBase is non-0, we should prefix the output with
591       // "(CastToBase*)".
592       Out << " + 1";
593       if (IsReference)
594         Out << ')';
595     }
596     return;
597   }
598   case APValue::Array: {
599     const ArrayType *AT = Ctx.getAsArrayType(Ty);
600     QualType ElemTy = AT->getElementType();
601     Out << '{';
602     if (unsigned N = getArrayInitializedElts()) {
603       getArrayInitializedElt(0).printPretty(Out, Ctx, ElemTy);
604       for (unsigned I = 1; I != N; ++I) {
605         Out << ", ";
606         if (I == 10) {
607           // Avoid printing out the entire contents of large arrays.
608           Out << "...";
609           break;
610         }
611         getArrayInitializedElt(I).printPretty(Out, Ctx, ElemTy);
612       }
613     }
614     Out << '}';
615     return;
616   }
617   case APValue::Struct: {
618     Out << '{';
619     const RecordDecl *RD = Ty->getAs<RecordType>()->getDecl();
620     bool First = true;
621     if (unsigned N = getStructNumBases()) {
622       const CXXRecordDecl *CD = cast<CXXRecordDecl>(RD);
623       CXXRecordDecl::base_class_const_iterator BI = CD->bases_begin();
624       for (unsigned I = 0; I != N; ++I, ++BI) {
625         assert(BI != CD->bases_end());
626         if (!First)
627           Out << ", ";
628         getStructBase(I).printPretty(Out, Ctx, BI->getType());
629         First = false;
630       }
631     }
632     for (const auto *FI : RD->fields()) {
633       if (!First)
634         Out << ", ";
635       if (FI->isUnnamedBitfield()) continue;
636       getStructField(FI->getFieldIndex()).
637         printPretty(Out, Ctx, FI->getType());
638       First = false;
639     }
640     Out << '}';
641     return;
642   }
643   case APValue::Union:
644     Out << '{';
645     if (const FieldDecl *FD = getUnionField()) {
646       Out << "." << *FD << " = ";
647       getUnionValue().printPretty(Out, Ctx, FD->getType());
648     }
649     Out << '}';
650     return;
651   case APValue::MemberPointer:
652     // FIXME: This is not enough to unambiguously identify the member in a
653     // multiple-inheritance scenario.
654     if (const ValueDecl *VD = getMemberPointerDecl()) {
655       Out << '&' << *cast<CXXRecordDecl>(VD->getDeclContext()) << "::" << *VD;
656       return;
657     }
658     Out << "0";
659     return;
660   case APValue::AddrLabelDiff:
661     Out << "&&" << getAddrLabelDiffLHS()->getLabel()->getName();
662     Out << " - ";
663     Out << "&&" << getAddrLabelDiffRHS()->getLabel()->getName();
664     return;
665   }
666   llvm_unreachable("Unknown APValue kind!");
667 }
668 
669 std::string APValue::getAsString(ASTContext &Ctx, QualType Ty) const {
670   std::string Result;
671   llvm::raw_string_ostream Out(Result);
672   printPretty(Out, Ctx, Ty);
673   Out.flush();
674   return Result;
675 }
676 
677 bool APValue::toIntegralConstant(APSInt &Result, QualType SrcTy,
678                                  const ASTContext &Ctx) const {
679   if (isInt()) {
680     Result = getInt();
681     return true;
682   }
683 
684   if (isLValue() && isNullPointer()) {
685     Result = Ctx.MakeIntValue(Ctx.getTargetNullPointerValue(SrcTy), SrcTy);
686     return true;
687   }
688 
689   if (isLValue() && !getLValueBase()) {
690     Result = Ctx.MakeIntValue(getLValueOffset().getQuantity(), SrcTy);
691     return true;
692   }
693 
694   return false;
695 }
696 
697 const APValue::LValueBase APValue::getLValueBase() const {
698   assert(isLValue() && "Invalid accessor");
699   return ((const LV*)(const void*)Data.buffer)->Base;
700 }
701 
702 bool APValue::isLValueOnePastTheEnd() const {
703   assert(isLValue() && "Invalid accessor");
704   return ((const LV*)(const void*)Data.buffer)->IsOnePastTheEnd;
705 }
706 
707 CharUnits &APValue::getLValueOffset() {
708   assert(isLValue() && "Invalid accessor");
709   return ((LV*)(void*)Data.buffer)->Offset;
710 }
711 
712 bool APValue::hasLValuePath() const {
713   assert(isLValue() && "Invalid accessor");
714   return ((const LV*)(const char*)Data.buffer)->hasPath();
715 }
716 
717 ArrayRef<APValue::LValuePathEntry> APValue::getLValuePath() const {
718   assert(isLValue() && hasLValuePath() && "Invalid accessor");
719   const LV &LVal = *((const LV*)(const char*)Data.buffer);
720   return llvm::makeArrayRef(LVal.getPath(), LVal.PathLength);
721 }
722 
723 unsigned APValue::getLValueCallIndex() const {
724   assert(isLValue() && "Invalid accessor");
725   return ((const LV*)(const char*)Data.buffer)->Base.getCallIndex();
726 }
727 
728 unsigned APValue::getLValueVersion() const {
729   assert(isLValue() && "Invalid accessor");
730   return ((const LV*)(const char*)Data.buffer)->Base.getVersion();
731 }
732 
733 bool APValue::isNullPointer() const {
734   assert(isLValue() && "Invalid usage");
735   return ((const LV*)(const char*)Data.buffer)->IsNullPtr;
736 }
737 
738 void APValue::setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
739                         bool IsNullPtr) {
740   assert(isLValue() && "Invalid accessor");
741   LV &LVal = *((LV*)(char*)Data.buffer);
742   LVal.Base = B;
743   LVal.IsOnePastTheEnd = false;
744   LVal.Offset = O;
745   LVal.resizePath((unsigned)-1);
746   LVal.IsNullPtr = IsNullPtr;
747 }
748 
749 void APValue::setLValue(LValueBase B, const CharUnits &O,
750                         ArrayRef<LValuePathEntry> Path, bool IsOnePastTheEnd,
751                         bool IsNullPtr) {
752   assert(isLValue() && "Invalid accessor");
753   LV &LVal = *((LV*)(char*)Data.buffer);
754   LVal.Base = B;
755   LVal.IsOnePastTheEnd = IsOnePastTheEnd;
756   LVal.Offset = O;
757   LVal.resizePath(Path.size());
758   memcpy(LVal.getPath(), Path.data(), Path.size() * sizeof(LValuePathEntry));
759   LVal.IsNullPtr = IsNullPtr;
760 }
761 
762 const ValueDecl *APValue::getMemberPointerDecl() const {
763   assert(isMemberPointer() && "Invalid accessor");
764   const MemberPointerData &MPD =
765       *((const MemberPointerData *)(const char *)Data.buffer);
766   return MPD.MemberAndIsDerivedMember.getPointer();
767 }
768 
769 bool APValue::isMemberPointerToDerivedMember() const {
770   assert(isMemberPointer() && "Invalid accessor");
771   const MemberPointerData &MPD =
772       *((const MemberPointerData *)(const char *)Data.buffer);
773   return MPD.MemberAndIsDerivedMember.getInt();
774 }
775 
776 ArrayRef<const CXXRecordDecl*> APValue::getMemberPointerPath() const {
777   assert(isMemberPointer() && "Invalid accessor");
778   const MemberPointerData &MPD =
779       *((const MemberPointerData *)(const char *)Data.buffer);
780   return llvm::makeArrayRef(MPD.getPath(), MPD.PathLength);
781 }
782 
783 void APValue::MakeLValue() {
784   assert(isUninit() && "Bad state change");
785   static_assert(sizeof(LV) <= DataSize, "LV too big");
786   new ((void*)(char*)Data.buffer) LV();
787   Kind = LValue;
788 }
789 
790 void APValue::MakeArray(unsigned InitElts, unsigned Size) {
791   assert(isUninit() && "Bad state change");
792   new ((void*)(char*)Data.buffer) Arr(InitElts, Size);
793   Kind = Array;
794 }
795 
796 void APValue::MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
797                                 ArrayRef<const CXXRecordDecl*> Path) {
798   assert(isUninit() && "Bad state change");
799   MemberPointerData *MPD = new ((void*)(char*)Data.buffer) MemberPointerData;
800   Kind = MemberPointer;
801   MPD->MemberAndIsDerivedMember.setPointer(Member);
802   MPD->MemberAndIsDerivedMember.setInt(IsDerivedMember);
803   MPD->resizePath(Path.size());
804   memcpy(MPD->getPath(), Path.data(), Path.size()*sizeof(const CXXRecordDecl*));
805 }
806