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      (MaxSize - 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      (MaxSize - 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(0), 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)->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)->~APSInt();
192  else if (Kind == Float)
193    ((APFloat*)(char*)Data)->~APFloat();
194  else if (Kind == Vector)
195    ((Vec*)(char*)Data)->~Vec();
196  else if (Kind == ComplexInt)
197    ((ComplexAPSInt*)(char*)Data)->~ComplexAPSInt();
198  else if (Kind == ComplexFloat)
199    ((ComplexAPFloat*)(char*)Data)->~ComplexAPFloat();
200  else if (Kind == LValue)
201    ((LV*)(char*)Data)->~LV();
202  else if (Kind == Array)
203    ((Arr*)(char*)Data)->~Arr();
204  else if (Kind == Struct)
205    ((StructData*)(char*)Data)->~StructData();
206  else if (Kind == Union)
207    ((UnionData*)(char*)Data)->~UnionData();
208  else if (Kind == MemberPointer)
209    ((MemberPointerData*)(char*)Data)->~MemberPointerData();
210  else if (Kind == AddrLabelDiff)
211    ((AddrLabelDiffData*)(char*)Data)->~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)->hasPathPtr();
243  case MemberPointer:
244    return reinterpret_cast<const MemberPointerData *>(Data)->hasPathPtr();
245  }
246  llvm_unreachable("Unknown APValue kind!");
247}
248
249void APValue::swap(APValue &RHS) {
250  std::swap(Kind, RHS.Kind);
251  char TmpData[MaxSize];
252  memcpy(TmpData, Data, MaxSize);
253  memcpy(Data, RHS.Data, MaxSize);
254  memcpy(RHS.Data, TmpData, MaxSize);
255}
256
257void APValue::dump() const {
258  dump(llvm::errs());
259  llvm::errs() << '\n';
260}
261
262static double GetApproxValue(const llvm::APFloat &F) {
263  llvm::APFloat V = F;
264  bool ignored;
265  V.convert(llvm::APFloat::IEEEdouble, llvm::APFloat::rmNearestTiesToEven,
266            &ignored);
267  return V.convertToDouble();
268}
269
270void APValue::dump(raw_ostream &OS) const {
271  switch (getKind()) {
272  case Uninitialized:
273    OS << "Uninitialized";
274    return;
275  case Int:
276    OS << "Int: " << getInt();
277    return;
278  case Float:
279    OS << "Float: " << GetApproxValue(getFloat());
280    return;
281  case Vector:
282    OS << "Vector: ";
283    getVectorElt(0).dump(OS);
284    for (unsigned i = 1; i != getVectorLength(); ++i) {
285      OS << ", ";
286      getVectorElt(i).dump(OS);
287    }
288    return;
289  case ComplexInt:
290    OS << "ComplexInt: " << getComplexIntReal() << ", " << getComplexIntImag();
291    return;
292  case ComplexFloat:
293    OS << "ComplexFloat: " << GetApproxValue(getComplexFloatReal())
294       << ", " << GetApproxValue(getComplexFloatImag());
295    return;
296  case LValue:
297    OS << "LValue: <todo>";
298    return;
299  case Array:
300    OS << "Array: ";
301    for (unsigned I = 0, N = getArrayInitializedElts(); I != N; ++I) {
302      getArrayInitializedElt(I).dump(OS);
303      if (I != getArraySize() - 1) OS << ", ";
304    }
305    if (hasArrayFiller()) {
306      OS << getArraySize() - getArrayInitializedElts() << " x ";
307      getArrayFiller().dump(OS);
308    }
309    return;
310  case Struct:
311    OS << "Struct ";
312    if (unsigned N = getStructNumBases()) {
313      OS << " bases: ";
314      getStructBase(0).dump(OS);
315      for (unsigned I = 1; I != N; ++I) {
316        OS << ", ";
317        getStructBase(I).dump(OS);
318      }
319    }
320    if (unsigned N = getStructNumFields()) {
321      OS << " fields: ";
322      getStructField(0).dump(OS);
323      for (unsigned I = 1; I != N; ++I) {
324        OS << ", ";
325        getStructField(I).dump(OS);
326      }
327    }
328    return;
329  case Union:
330    OS << "Union: ";
331    getUnionValue().dump(OS);
332    return;
333  case MemberPointer:
334    OS << "MemberPointer: <todo>";
335    return;
336  case AddrLabelDiff:
337    OS << "AddrLabelDiff: <todo>";
338    return;
339  }
340  llvm_unreachable("Unknown APValue kind!");
341}
342
343void APValue::printPretty(raw_ostream &Out, ASTContext &Ctx, QualType Ty) const{
344  switch (getKind()) {
345  case APValue::Uninitialized:
346    Out << "<uninitialized>";
347    return;
348  case APValue::Int:
349    if (Ty->isBooleanType())
350      Out << (getInt().getBoolValue() ? "true" : "false");
351    else
352      Out << getInt();
353    return;
354  case APValue::Float:
355    Out << GetApproxValue(getFloat());
356    return;
357  case APValue::Vector: {
358    Out << '{';
359    QualType ElemTy = Ty->getAs<VectorType>()->getElementType();
360    getVectorElt(0).printPretty(Out, Ctx, ElemTy);
361    for (unsigned i = 1; i != getVectorLength(); ++i) {
362      Out << ", ";
363      getVectorElt(i).printPretty(Out, Ctx, ElemTy);
364    }
365    Out << '}';
366    return;
367  }
368  case APValue::ComplexInt:
369    Out << getComplexIntReal() << "+" << getComplexIntImag() << "i";
370    return;
371  case APValue::ComplexFloat:
372    Out << GetApproxValue(getComplexFloatReal()) << "+"
373        << GetApproxValue(getComplexFloatImag()) << "i";
374    return;
375  case APValue::LValue: {
376    LValueBase Base = getLValueBase();
377    if (!Base) {
378      Out << "0";
379      return;
380    }
381
382    bool IsReference = Ty->isReferenceType();
383    QualType InnerTy
384      = IsReference ? Ty.getNonReferenceType() : Ty->getPointeeType();
385    if (InnerTy.isNull())
386      InnerTy = Ty;
387
388    if (!hasLValuePath()) {
389      // No lvalue path: just print the offset.
390      CharUnits O = getLValueOffset();
391      CharUnits S = Ctx.getTypeSizeInChars(InnerTy);
392      if (!O.isZero()) {
393        if (IsReference)
394          Out << "*(";
395        if (O % S) {
396          Out << "(char*)";
397          S = CharUnits::One();
398        }
399        Out << '&';
400      } else if (!IsReference)
401        Out << '&';
402
403      if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>())
404        Out << *VD;
405      else
406        Base.get<const Expr*>()->printPretty(Out, 0, Ctx.getPrintingPolicy());
407      if (!O.isZero()) {
408        Out << " + " << (O / S);
409        if (IsReference)
410          Out << ')';
411      }
412      return;
413    }
414
415    // We have an lvalue path. Print it out nicely.
416    if (!IsReference)
417      Out << '&';
418    else if (isLValueOnePastTheEnd())
419      Out << "*(&";
420
421    QualType ElemTy;
422    if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) {
423      Out << *VD;
424      ElemTy = VD->getType();
425    } else {
426      const Expr *E = Base.get<const Expr*>();
427      E->printPretty(Out, 0, Ctx.getPrintingPolicy());
428      ElemTy = E->getType();
429    }
430
431    ArrayRef<LValuePathEntry> Path = getLValuePath();
432    const CXXRecordDecl *CastToBase = 0;
433    for (unsigned I = 0, N = Path.size(); I != N; ++I) {
434      if (ElemTy->getAs<RecordType>()) {
435        // The lvalue refers to a class type, so the next path entry is a base
436        // or member.
437        const Decl *BaseOrMember =
438        BaseOrMemberType::getFromOpaqueValue(Path[I].BaseOrMember).getPointer();
439        if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(BaseOrMember)) {
440          CastToBase = RD;
441          ElemTy = Ctx.getRecordType(RD);
442        } else {
443          const ValueDecl *VD = cast<ValueDecl>(BaseOrMember);
444          Out << ".";
445          if (CastToBase)
446            Out << *CastToBase << "::";
447          Out << *VD;
448          ElemTy = VD->getType();
449        }
450      } else {
451        // The lvalue must refer to an array.
452        Out << '[' << Path[I].ArrayIndex << ']';
453        ElemTy = Ctx.getAsArrayType(ElemTy)->getElementType();
454      }
455    }
456
457    // Handle formatting of one-past-the-end lvalues.
458    if (isLValueOnePastTheEnd()) {
459      // FIXME: If CastToBase is non-0, we should prefix the output with
460      // "(CastToBase*)".
461      Out << " + 1";
462      if (IsReference)
463        Out << ')';
464    }
465    return;
466  }
467  case APValue::Array: {
468    const ArrayType *AT = Ctx.getAsArrayType(Ty);
469    QualType ElemTy = AT->getElementType();
470    Out << '{';
471    if (unsigned N = getArrayInitializedElts()) {
472      getArrayInitializedElt(0).printPretty(Out, Ctx, ElemTy);
473      for (unsigned I = 1; I != N; ++I) {
474        Out << ", ";
475        if (I == 10) {
476          // Avoid printing out the entire contents of large arrays.
477          Out << "...";
478          break;
479        }
480        getArrayInitializedElt(I).printPretty(Out, Ctx, ElemTy);
481      }
482    }
483    Out << '}';
484    return;
485  }
486  case APValue::Struct: {
487    Out << '{';
488    const RecordDecl *RD = Ty->getAs<RecordType>()->getDecl();
489    bool First = true;
490    if (unsigned N = getStructNumBases()) {
491      const CXXRecordDecl *CD = cast<CXXRecordDecl>(RD);
492      CXXRecordDecl::base_class_const_iterator BI = CD->bases_begin();
493      for (unsigned I = 0; I != N; ++I, ++BI) {
494        assert(BI != CD->bases_end());
495        if (!First)
496          Out << ", ";
497        getStructBase(I).printPretty(Out, Ctx, BI->getType());
498        First = false;
499      }
500    }
501    for (RecordDecl::field_iterator FI = RD->field_begin();
502         FI != RD->field_end(); ++FI) {
503      if (!First)
504        Out << ", ";
505      if (FI->isUnnamedBitfield()) continue;
506      getStructField(FI->getFieldIndex()).
507        printPretty(Out, Ctx, FI->getType());
508      First = false;
509    }
510    Out << '}';
511    return;
512  }
513  case APValue::Union:
514    Out << '{';
515    if (const FieldDecl *FD = getUnionField()) {
516      Out << "." << *FD << " = ";
517      getUnionValue().printPretty(Out, Ctx, FD->getType());
518    }
519    Out << '}';
520    return;
521  case APValue::MemberPointer:
522    // FIXME: This is not enough to unambiguously identify the member in a
523    // multiple-inheritance scenario.
524    if (const ValueDecl *VD = getMemberPointerDecl()) {
525      Out << '&' << *cast<CXXRecordDecl>(VD->getDeclContext()) << "::" << *VD;
526      return;
527    }
528    Out << "0";
529    return;
530  case APValue::AddrLabelDiff:
531    Out << "&&" << getAddrLabelDiffLHS()->getLabel()->getName();
532    Out << " - ";
533    Out << "&&" << getAddrLabelDiffRHS()->getLabel()->getName();
534    return;
535  }
536  llvm_unreachable("Unknown APValue kind!");
537}
538
539std::string APValue::getAsString(ASTContext &Ctx, QualType Ty) const {
540  std::string Result;
541  llvm::raw_string_ostream Out(Result);
542  printPretty(Out, Ctx, Ty);
543  Out.flush();
544  return Result;
545}
546
547const APValue::LValueBase APValue::getLValueBase() const {
548  assert(isLValue() && "Invalid accessor");
549  return ((const LV*)(const void*)Data)->BaseAndIsOnePastTheEnd.getPointer();
550}
551
552bool APValue::isLValueOnePastTheEnd() const {
553  assert(isLValue() && "Invalid accessor");
554  return ((const LV*)(const void*)Data)->BaseAndIsOnePastTheEnd.getInt();
555}
556
557CharUnits &APValue::getLValueOffset() {
558  assert(isLValue() && "Invalid accessor");
559  return ((LV*)(void*)Data)->Offset;
560}
561
562bool APValue::hasLValuePath() const {
563  assert(isLValue() && "Invalid accessor");
564  return ((const LV*)(const char*)Data)->hasPath();
565}
566
567ArrayRef<APValue::LValuePathEntry> APValue::getLValuePath() const {
568  assert(isLValue() && hasLValuePath() && "Invalid accessor");
569  const LV &LVal = *((const LV*)(const char*)Data);
570  return ArrayRef<LValuePathEntry>(LVal.getPath(), LVal.PathLength);
571}
572
573unsigned APValue::getLValueCallIndex() const {
574  assert(isLValue() && "Invalid accessor");
575  return ((const LV*)(const char*)Data)->CallIndex;
576}
577
578void APValue::setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
579                        unsigned CallIndex) {
580  assert(isLValue() && "Invalid accessor");
581  LV &LVal = *((LV*)(char*)Data);
582  LVal.BaseAndIsOnePastTheEnd.setPointer(B);
583  LVal.BaseAndIsOnePastTheEnd.setInt(false);
584  LVal.Offset = O;
585  LVal.CallIndex = CallIndex;
586  LVal.resizePath((unsigned)-1);
587}
588
589void APValue::setLValue(LValueBase B, const CharUnits &O,
590                        ArrayRef<LValuePathEntry> Path, bool IsOnePastTheEnd,
591                        unsigned CallIndex) {
592  assert(isLValue() && "Invalid accessor");
593  LV &LVal = *((LV*)(char*)Data);
594  LVal.BaseAndIsOnePastTheEnd.setPointer(B);
595  LVal.BaseAndIsOnePastTheEnd.setInt(IsOnePastTheEnd);
596  LVal.Offset = O;
597  LVal.CallIndex = CallIndex;
598  LVal.resizePath(Path.size());
599  memcpy(LVal.getPath(), Path.data(), Path.size() * sizeof(LValuePathEntry));
600}
601
602const ValueDecl *APValue::getMemberPointerDecl() const {
603  assert(isMemberPointer() && "Invalid accessor");
604  const MemberPointerData &MPD = *((const MemberPointerData*)(const char*)Data);
605  return MPD.MemberAndIsDerivedMember.getPointer();
606}
607
608bool APValue::isMemberPointerToDerivedMember() const {
609  assert(isMemberPointer() && "Invalid accessor");
610  const MemberPointerData &MPD = *((const MemberPointerData*)(const char*)Data);
611  return MPD.MemberAndIsDerivedMember.getInt();
612}
613
614ArrayRef<const CXXRecordDecl*> APValue::getMemberPointerPath() const {
615  assert(isMemberPointer() && "Invalid accessor");
616  const MemberPointerData &MPD = *((const MemberPointerData*)(const char*)Data);
617  return ArrayRef<const CXXRecordDecl*>(MPD.getPath(), MPD.PathLength);
618}
619
620void APValue::MakeLValue() {
621  assert(isUninit() && "Bad state change");
622  assert(sizeof(LV) <= MaxSize && "LV too big");
623  new ((void*)(char*)Data) LV();
624  Kind = LValue;
625}
626
627void APValue::MakeArray(unsigned InitElts, unsigned Size) {
628  assert(isUninit() && "Bad state change");
629  new ((void*)(char*)Data) Arr(InitElts, Size);
630  Kind = Array;
631}
632
633void APValue::MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
634                                ArrayRef<const CXXRecordDecl*> Path) {
635  assert(isUninit() && "Bad state change");
636  MemberPointerData *MPD = new ((void*)(char*)Data) MemberPointerData;
637  Kind = MemberPointer;
638  MPD->MemberAndIsDerivedMember.setPointer(Member);
639  MPD->MemberAndIsDerivedMember.setInt(IsDerivedMember);
640  MPD->resizePath(Path.size());
641  memcpy(MPD->getPath(), Path.data(), Path.size()*sizeof(const CXXRecordDecl*));
642}
643