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