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