1 //===--- APValue.h - Union class for APFloat/APSInt/Complex -----*- C++ -*-===//
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 defines the APValue class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CLANG_AST_APVALUE_H
15 #define LLVM_CLANG_AST_APVALUE_H
16 
17 #include "clang/Basic/LLVM.h"
18 #include "llvm/ADT/APFloat.h"
19 #include "llvm/ADT/APSInt.h"
20 #include "llvm/ADT/PointerIntPair.h"
21 #include "llvm/ADT/PointerUnion.h"
22 
23 namespace clang {
24   class AddrLabelExpr;
25   class ASTContext;
26   class CharUnits;
27   class DiagnosticBuilder;
28   class Expr;
29   class FieldDecl;
30   class Decl;
31   class ValueDecl;
32   class CXXRecordDecl;
33   class QualType;
34 
35 /// APValue - This class implements a discriminated union of [uninitialized]
36 /// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset],
37 /// [Vector: N * APValue], [Array: N * APValue]
38 class APValue {
39   typedef llvm::APSInt APSInt;
40   typedef llvm::APFloat APFloat;
41 public:
42   enum ValueKind {
43     Uninitialized,
44     Int,
45     Float,
46     ComplexInt,
47     ComplexFloat,
48     LValue,
49     Vector,
50     Array,
51     Struct,
52     Union,
53     MemberPointer,
54     AddrLabelDiff
55   };
56 
57   class LValueBase {
58   public:
59     typedef llvm::PointerUnion<const ValueDecl *, const Expr *> PtrTy;
60 
LValueBase()61     LValueBase() : CallIndex(0), Version(0) {}
62 
63     template <class T>
64     LValueBase(T P, unsigned I = 0, unsigned V = 0)
Ptr(P)65         : Ptr(P), CallIndex(I), Version(V) {}
66 
67     template <class T>
is()68     bool is() const { return Ptr.is<T>(); }
69 
70     template <class T>
get()71     T get() const { return Ptr.get<T>(); }
72 
73     template <class T>
dyn_cast()74     T dyn_cast() const { return Ptr.dyn_cast<T>(); }
75 
76     void *getOpaqueValue() const;
77 
78     bool isNull() const;
79 
80     explicit operator bool () const;
81 
getPointer()82     PtrTy getPointer() const {
83       return Ptr;
84     }
85 
getCallIndex()86     unsigned getCallIndex() const {
87       return CallIndex;
88     }
89 
setCallIndex(unsigned Index)90     void setCallIndex(unsigned Index) {
91       CallIndex = Index;
92     }
93 
getVersion()94     unsigned getVersion() const {
95       return Version;
96     }
97 
98     bool operator==(const LValueBase &Other) const {
99       return Ptr == Other.Ptr && CallIndex == Other.CallIndex &&
100              Version == Other.Version;
101     }
102 
103   private:
104     PtrTy Ptr;
105     unsigned CallIndex, Version;
106   };
107 
108   typedef llvm::PointerIntPair<const Decl *, 1, bool> BaseOrMemberType;
109   union LValuePathEntry {
110     /// BaseOrMember - The FieldDecl or CXXRecordDecl indicating the next item
111     /// in the path. An opaque value of type BaseOrMemberType.
112     void *BaseOrMember;
113     /// ArrayIndex - The array index of the next item in the path.
114     uint64_t ArrayIndex;
115   };
116   struct NoLValuePath {};
117   struct UninitArray {};
118   struct UninitStruct {};
119 private:
120   ValueKind Kind;
121 
122   struct ComplexAPSInt {
123     APSInt Real, Imag;
ComplexAPSIntComplexAPSInt124     ComplexAPSInt() : Real(1), Imag(1) {}
125   };
126   struct ComplexAPFloat {
127     APFloat Real, Imag;
ComplexAPFloatComplexAPFloat128     ComplexAPFloat() : Real(0.0), Imag(0.0) {}
129   };
130   struct LV;
131   struct Vec {
132     APValue *Elts;
133     unsigned NumElts;
VecVec134     Vec() : Elts(nullptr), NumElts(0) {}
~VecVec135     ~Vec() { delete[] Elts; }
136   };
137   struct Arr {
138     APValue *Elts;
139     unsigned NumElts, ArrSize;
140     Arr(unsigned NumElts, unsigned ArrSize);
141     ~Arr();
142   };
143   struct StructData {
144     APValue *Elts;
145     unsigned NumBases;
146     unsigned NumFields;
147     StructData(unsigned NumBases, unsigned NumFields);
148     ~StructData();
149   };
150   struct UnionData {
151     const FieldDecl *Field;
152     APValue *Value;
153     UnionData();
154     ~UnionData();
155   };
156   struct AddrLabelDiffData {
157     const AddrLabelExpr* LHSExpr;
158     const AddrLabelExpr* RHSExpr;
159   };
160   struct MemberPointerData;
161 
162   // We ensure elsewhere that Data is big enough for LV and MemberPointerData.
163   typedef llvm::AlignedCharArrayUnion<void *, APSInt, APFloat, ComplexAPSInt,
164                                       ComplexAPFloat, Vec, Arr, StructData,
165                                       UnionData, AddrLabelDiffData> DataType;
166   static const size_t DataSize = sizeof(DataType);
167 
168   DataType Data;
169 
170 public:
APValue()171   APValue() : Kind(Uninitialized) {}
APValue(APSInt I)172   explicit APValue(APSInt I) : Kind(Uninitialized) {
173     MakeInt(); setInt(std::move(I));
174   }
APValue(APFloat F)175   explicit APValue(APFloat F) : Kind(Uninitialized) {
176     MakeFloat(); setFloat(std::move(F));
177   }
APValue(const APValue * E,unsigned N)178   explicit APValue(const APValue *E, unsigned N) : Kind(Uninitialized) {
179     MakeVector(); setVector(E, N);
180   }
APValue(APSInt R,APSInt I)181   APValue(APSInt R, APSInt I) : Kind(Uninitialized) {
182     MakeComplexInt(); setComplexInt(std::move(R), std::move(I));
183   }
APValue(APFloat R,APFloat I)184   APValue(APFloat R, APFloat I) : Kind(Uninitialized) {
185     MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I));
186   }
187   APValue(const APValue &RHS);
APValue(APValue && RHS)188   APValue(APValue &&RHS) : Kind(Uninitialized) { swap(RHS); }
189   APValue(LValueBase B, const CharUnits &O, NoLValuePath N,
190           bool IsNullPtr = false)
Kind(Uninitialized)191       : Kind(Uninitialized) {
192     MakeLValue(); setLValue(B, O, N, IsNullPtr);
193   }
194   APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path,
195           bool OnePastTheEnd, bool IsNullPtr = false)
Kind(Uninitialized)196       : Kind(Uninitialized) {
197     MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, IsNullPtr);
198   }
APValue(UninitArray,unsigned InitElts,unsigned Size)199   APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(Uninitialized) {
200     MakeArray(InitElts, Size);
201   }
APValue(UninitStruct,unsigned B,unsigned M)202   APValue(UninitStruct, unsigned B, unsigned M) : Kind(Uninitialized) {
203     MakeStruct(B, M);
204   }
205   explicit APValue(const FieldDecl *D, const APValue &V = APValue())
Kind(Uninitialized)206       : Kind(Uninitialized) {
207     MakeUnion(); setUnion(D, V);
208   }
APValue(const ValueDecl * Member,bool IsDerivedMember,ArrayRef<const CXXRecordDecl * > Path)209   APValue(const ValueDecl *Member, bool IsDerivedMember,
210           ArrayRef<const CXXRecordDecl*> Path) : Kind(Uninitialized) {
211     MakeMemberPointer(Member, IsDerivedMember, Path);
212   }
APValue(const AddrLabelExpr * LHSExpr,const AddrLabelExpr * RHSExpr)213   APValue(const AddrLabelExpr* LHSExpr, const AddrLabelExpr* RHSExpr)
214       : Kind(Uninitialized) {
215     MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr);
216   }
217 
~APValue()218   ~APValue() {
219     MakeUninit();
220   }
221 
222   /// Returns whether the object performed allocations.
223   ///
224   /// If APValues are constructed via placement new, \c needsCleanup()
225   /// indicates whether the destructor must be called in order to correctly
226   /// free all allocated memory.
227   bool needsCleanup() const;
228 
229   /// Swaps the contents of this and the given APValue.
230   void swap(APValue &RHS);
231 
getKind()232   ValueKind getKind() const { return Kind; }
isUninit()233   bool isUninit() const { return Kind == Uninitialized; }
isInt()234   bool isInt() const { return Kind == Int; }
isFloat()235   bool isFloat() const { return Kind == Float; }
isComplexInt()236   bool isComplexInt() const { return Kind == ComplexInt; }
isComplexFloat()237   bool isComplexFloat() const { return Kind == ComplexFloat; }
isLValue()238   bool isLValue() const { return Kind == LValue; }
isVector()239   bool isVector() const { return Kind == Vector; }
isArray()240   bool isArray() const { return Kind == Array; }
isStruct()241   bool isStruct() const { return Kind == Struct; }
isUnion()242   bool isUnion() const { return Kind == Union; }
isMemberPointer()243   bool isMemberPointer() const { return Kind == MemberPointer; }
isAddrLabelDiff()244   bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; }
245 
246   void dump() const;
247   void dump(raw_ostream &OS) const;
248 
249   void printPretty(raw_ostream &OS, ASTContext &Ctx, QualType Ty) const;
250   std::string getAsString(ASTContext &Ctx, QualType Ty) const;
251 
getInt()252   APSInt &getInt() {
253     assert(isInt() && "Invalid accessor");
254     return *(APSInt*)(char*)Data.buffer;
255   }
getInt()256   const APSInt &getInt() const {
257     return const_cast<APValue*>(this)->getInt();
258   }
259 
260   /// Try to convert this value to an integral constant. This works if it's an
261   /// integer, null pointer, or offset from a null pointer. Returns true on
262   /// success.
263   bool toIntegralConstant(APSInt &Result, QualType SrcTy,
264                           const ASTContext &Ctx) const;
265 
getFloat()266   APFloat &getFloat() {
267     assert(isFloat() && "Invalid accessor");
268     return *(APFloat*)(char*)Data.buffer;
269   }
getFloat()270   const APFloat &getFloat() const {
271     return const_cast<APValue*>(this)->getFloat();
272   }
273 
getComplexIntReal()274   APSInt &getComplexIntReal() {
275     assert(isComplexInt() && "Invalid accessor");
276     return ((ComplexAPSInt*)(char*)Data.buffer)->Real;
277   }
getComplexIntReal()278   const APSInt &getComplexIntReal() const {
279     return const_cast<APValue*>(this)->getComplexIntReal();
280   }
281 
getComplexIntImag()282   APSInt &getComplexIntImag() {
283     assert(isComplexInt() && "Invalid accessor");
284     return ((ComplexAPSInt*)(char*)Data.buffer)->Imag;
285   }
getComplexIntImag()286   const APSInt &getComplexIntImag() const {
287     return const_cast<APValue*>(this)->getComplexIntImag();
288   }
289 
getComplexFloatReal()290   APFloat &getComplexFloatReal() {
291     assert(isComplexFloat() && "Invalid accessor");
292     return ((ComplexAPFloat*)(char*)Data.buffer)->Real;
293   }
getComplexFloatReal()294   const APFloat &getComplexFloatReal() const {
295     return const_cast<APValue*>(this)->getComplexFloatReal();
296   }
297 
getComplexFloatImag()298   APFloat &getComplexFloatImag() {
299     assert(isComplexFloat() && "Invalid accessor");
300     return ((ComplexAPFloat*)(char*)Data.buffer)->Imag;
301   }
getComplexFloatImag()302   const APFloat &getComplexFloatImag() const {
303     return const_cast<APValue*>(this)->getComplexFloatImag();
304   }
305 
306   const LValueBase getLValueBase() const;
307   CharUnits &getLValueOffset();
getLValueOffset()308   const CharUnits &getLValueOffset() const {
309     return const_cast<APValue*>(this)->getLValueOffset();
310   }
311   bool isLValueOnePastTheEnd() const;
312   bool hasLValuePath() const;
313   ArrayRef<LValuePathEntry> getLValuePath() const;
314   unsigned getLValueCallIndex() const;
315   unsigned getLValueVersion() const;
316   bool isNullPointer() const;
317 
getVectorElt(unsigned I)318   APValue &getVectorElt(unsigned I) {
319     assert(isVector() && "Invalid accessor");
320     assert(I < getVectorLength() && "Index out of range");
321     return ((Vec*)(char*)Data.buffer)->Elts[I];
322   }
getVectorElt(unsigned I)323   const APValue &getVectorElt(unsigned I) const {
324     return const_cast<APValue*>(this)->getVectorElt(I);
325   }
getVectorLength()326   unsigned getVectorLength() const {
327     assert(isVector() && "Invalid accessor");
328     return ((const Vec*)(const void *)Data.buffer)->NumElts;
329   }
330 
getArrayInitializedElt(unsigned I)331   APValue &getArrayInitializedElt(unsigned I) {
332     assert(isArray() && "Invalid accessor");
333     assert(I < getArrayInitializedElts() && "Index out of range");
334     return ((Arr*)(char*)Data.buffer)->Elts[I];
335   }
getArrayInitializedElt(unsigned I)336   const APValue &getArrayInitializedElt(unsigned I) const {
337     return const_cast<APValue*>(this)->getArrayInitializedElt(I);
338   }
hasArrayFiller()339   bool hasArrayFiller() const {
340     return getArrayInitializedElts() != getArraySize();
341   }
getArrayFiller()342   APValue &getArrayFiller() {
343     assert(isArray() && "Invalid accessor");
344     assert(hasArrayFiller() && "No array filler");
345     return ((Arr*)(char*)Data.buffer)->Elts[getArrayInitializedElts()];
346   }
getArrayFiller()347   const APValue &getArrayFiller() const {
348     return const_cast<APValue*>(this)->getArrayFiller();
349   }
getArrayInitializedElts()350   unsigned getArrayInitializedElts() const {
351     assert(isArray() && "Invalid accessor");
352     return ((const Arr*)(const void *)Data.buffer)->NumElts;
353   }
getArraySize()354   unsigned getArraySize() const {
355     assert(isArray() && "Invalid accessor");
356     return ((const Arr*)(const void *)Data.buffer)->ArrSize;
357   }
358 
getStructNumBases()359   unsigned getStructNumBases() const {
360     assert(isStruct() && "Invalid accessor");
361     return ((const StructData*)(const char*)Data.buffer)->NumBases;
362   }
getStructNumFields()363   unsigned getStructNumFields() const {
364     assert(isStruct() && "Invalid accessor");
365     return ((const StructData*)(const char*)Data.buffer)->NumFields;
366   }
getStructBase(unsigned i)367   APValue &getStructBase(unsigned i) {
368     assert(isStruct() && "Invalid accessor");
369     return ((StructData*)(char*)Data.buffer)->Elts[i];
370   }
getStructField(unsigned i)371   APValue &getStructField(unsigned i) {
372     assert(isStruct() && "Invalid accessor");
373     return ((StructData*)(char*)Data.buffer)->Elts[getStructNumBases() + i];
374   }
getStructBase(unsigned i)375   const APValue &getStructBase(unsigned i) const {
376     return const_cast<APValue*>(this)->getStructBase(i);
377   }
getStructField(unsigned i)378   const APValue &getStructField(unsigned i) const {
379     return const_cast<APValue*>(this)->getStructField(i);
380   }
381 
getUnionField()382   const FieldDecl *getUnionField() const {
383     assert(isUnion() && "Invalid accessor");
384     return ((const UnionData*)(const char*)Data.buffer)->Field;
385   }
getUnionValue()386   APValue &getUnionValue() {
387     assert(isUnion() && "Invalid accessor");
388     return *((UnionData*)(char*)Data.buffer)->Value;
389   }
getUnionValue()390   const APValue &getUnionValue() const {
391     return const_cast<APValue*>(this)->getUnionValue();
392   }
393 
394   const ValueDecl *getMemberPointerDecl() const;
395   bool isMemberPointerToDerivedMember() const;
396   ArrayRef<const CXXRecordDecl*> getMemberPointerPath() const;
397 
getAddrLabelDiffLHS()398   const AddrLabelExpr* getAddrLabelDiffLHS() const {
399     assert(isAddrLabelDiff() && "Invalid accessor");
400     return ((const AddrLabelDiffData*)(const char*)Data.buffer)->LHSExpr;
401   }
getAddrLabelDiffRHS()402   const AddrLabelExpr* getAddrLabelDiffRHS() const {
403     assert(isAddrLabelDiff() && "Invalid accessor");
404     return ((const AddrLabelDiffData*)(const char*)Data.buffer)->RHSExpr;
405   }
406 
setInt(APSInt I)407   void setInt(APSInt I) {
408     assert(isInt() && "Invalid accessor");
409     *(APSInt *)(char *)Data.buffer = std::move(I);
410   }
setFloat(APFloat F)411   void setFloat(APFloat F) {
412     assert(isFloat() && "Invalid accessor");
413     *(APFloat *)(char *)Data.buffer = std::move(F);
414   }
setVector(const APValue * E,unsigned N)415   void setVector(const APValue *E, unsigned N) {
416     assert(isVector() && "Invalid accessor");
417     ((Vec*)(char*)Data.buffer)->Elts = new APValue[N];
418     ((Vec*)(char*)Data.buffer)->NumElts = N;
419     for (unsigned i = 0; i != N; ++i)
420       ((Vec*)(char*)Data.buffer)->Elts[i] = E[i];
421   }
setComplexInt(APSInt R,APSInt I)422   void setComplexInt(APSInt R, APSInt I) {
423     assert(R.getBitWidth() == I.getBitWidth() &&
424            "Invalid complex int (type mismatch).");
425     assert(isComplexInt() && "Invalid accessor");
426     ((ComplexAPSInt *)(char *)Data.buffer)->Real = std::move(R);
427     ((ComplexAPSInt *)(char *)Data.buffer)->Imag = std::move(I);
428   }
setComplexFloat(APFloat R,APFloat I)429   void setComplexFloat(APFloat R, APFloat I) {
430     assert(&R.getSemantics() == &I.getSemantics() &&
431            "Invalid complex float (type mismatch).");
432     assert(isComplexFloat() && "Invalid accessor");
433     ((ComplexAPFloat *)(char *)Data.buffer)->Real = std::move(R);
434     ((ComplexAPFloat *)(char *)Data.buffer)->Imag = std::move(I);
435   }
436   void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
437                  bool IsNullPtr);
438   void setLValue(LValueBase B, const CharUnits &O,
439                  ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
440                  bool IsNullPtr);
setUnion(const FieldDecl * Field,const APValue & Value)441   void setUnion(const FieldDecl *Field, const APValue &Value) {
442     assert(isUnion() && "Invalid accessor");
443     ((UnionData*)(char*)Data.buffer)->Field = Field;
444     *((UnionData*)(char*)Data.buffer)->Value = Value;
445   }
setAddrLabelDiff(const AddrLabelExpr * LHSExpr,const AddrLabelExpr * RHSExpr)446   void setAddrLabelDiff(const AddrLabelExpr* LHSExpr,
447                         const AddrLabelExpr* RHSExpr) {
448     ((AddrLabelDiffData*)(char*)Data.buffer)->LHSExpr = LHSExpr;
449     ((AddrLabelDiffData*)(char*)Data.buffer)->RHSExpr = RHSExpr;
450   }
451 
452   /// Assign by swapping from a copy of the RHS.
453   APValue &operator=(APValue RHS) {
454     swap(RHS);
455     return *this;
456   }
457 
458 private:
459   void DestroyDataAndMakeUninit();
MakeUninit()460   void MakeUninit() {
461     if (Kind != Uninitialized)
462       DestroyDataAndMakeUninit();
463   }
MakeInt()464   void MakeInt() {
465     assert(isUninit() && "Bad state change");
466     new ((void*)Data.buffer) APSInt(1);
467     Kind = Int;
468   }
MakeFloat()469   void MakeFloat() {
470     assert(isUninit() && "Bad state change");
471     new ((void*)(char*)Data.buffer) APFloat(0.0);
472     Kind = Float;
473   }
MakeVector()474   void MakeVector() {
475     assert(isUninit() && "Bad state change");
476     new ((void*)(char*)Data.buffer) Vec();
477     Kind = Vector;
478   }
MakeComplexInt()479   void MakeComplexInt() {
480     assert(isUninit() && "Bad state change");
481     new ((void*)(char*)Data.buffer) ComplexAPSInt();
482     Kind = ComplexInt;
483   }
MakeComplexFloat()484   void MakeComplexFloat() {
485     assert(isUninit() && "Bad state change");
486     new ((void*)(char*)Data.buffer) ComplexAPFloat();
487     Kind = ComplexFloat;
488   }
489   void MakeLValue();
490   void MakeArray(unsigned InitElts, unsigned Size);
MakeStruct(unsigned B,unsigned M)491   void MakeStruct(unsigned B, unsigned M) {
492     assert(isUninit() && "Bad state change");
493     new ((void*)(char*)Data.buffer) StructData(B, M);
494     Kind = Struct;
495   }
MakeUnion()496   void MakeUnion() {
497     assert(isUninit() && "Bad state change");
498     new ((void*)(char*)Data.buffer) UnionData();
499     Kind = Union;
500   }
501   void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
502                          ArrayRef<const CXXRecordDecl*> Path);
MakeAddrLabelDiff()503   void MakeAddrLabelDiff() {
504     assert(isUninit() && "Bad state change");
505     new ((void*)(char*)Data.buffer) AddrLabelDiffData();
506     Kind = AddrLabelDiff;
507   }
508 };
509 
510 } // end namespace clang.
511 
512 namespace llvm {
513 template<> struct DenseMapInfo<clang::APValue::LValueBase> {
514   static clang::APValue::LValueBase getEmptyKey();
515   static clang::APValue::LValueBase getTombstoneKey();
516   static unsigned getHashValue(const clang::APValue::LValueBase &Base);
517   static bool isEqual(const clang::APValue::LValueBase &LHS,
518                       const clang::APValue::LValueBase &RHS);
519 };
520 }
521 
522 #endif
523