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