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