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 
getFloat()260   APFloat &getFloat() {
261     assert(isFloat() && "Invalid accessor");
262     return *(APFloat*)(char*)Data.buffer;
263   }
getFloat()264   const APFloat &getFloat() const {
265     return const_cast<APValue*>(this)->getFloat();
266   }
267 
getComplexIntReal()268   APSInt &getComplexIntReal() {
269     assert(isComplexInt() && "Invalid accessor");
270     return ((ComplexAPSInt*)(char*)Data.buffer)->Real;
271   }
getComplexIntReal()272   const APSInt &getComplexIntReal() const {
273     return const_cast<APValue*>(this)->getComplexIntReal();
274   }
275 
getComplexIntImag()276   APSInt &getComplexIntImag() {
277     assert(isComplexInt() && "Invalid accessor");
278     return ((ComplexAPSInt*)(char*)Data.buffer)->Imag;
279   }
getComplexIntImag()280   const APSInt &getComplexIntImag() const {
281     return const_cast<APValue*>(this)->getComplexIntImag();
282   }
283 
getComplexFloatReal()284   APFloat &getComplexFloatReal() {
285     assert(isComplexFloat() && "Invalid accessor");
286     return ((ComplexAPFloat*)(char*)Data.buffer)->Real;
287   }
getComplexFloatReal()288   const APFloat &getComplexFloatReal() const {
289     return const_cast<APValue*>(this)->getComplexFloatReal();
290   }
291 
getComplexFloatImag()292   APFloat &getComplexFloatImag() {
293     assert(isComplexFloat() && "Invalid accessor");
294     return ((ComplexAPFloat*)(char*)Data.buffer)->Imag;
295   }
getComplexFloatImag()296   const APFloat &getComplexFloatImag() const {
297     return const_cast<APValue*>(this)->getComplexFloatImag();
298   }
299 
300   const LValueBase getLValueBase() const;
301   CharUnits &getLValueOffset();
getLValueOffset()302   const CharUnits &getLValueOffset() const {
303     return const_cast<APValue*>(this)->getLValueOffset();
304   }
305   bool isLValueOnePastTheEnd() const;
306   bool hasLValuePath() const;
307   ArrayRef<LValuePathEntry> getLValuePath() const;
308   unsigned getLValueCallIndex() const;
309   unsigned getLValueVersion() const;
310   bool isNullPointer() const;
311 
getVectorElt(unsigned I)312   APValue &getVectorElt(unsigned I) {
313     assert(isVector() && "Invalid accessor");
314     assert(I < getVectorLength() && "Index out of range");
315     return ((Vec*)(char*)Data.buffer)->Elts[I];
316   }
getVectorElt(unsigned I)317   const APValue &getVectorElt(unsigned I) const {
318     return const_cast<APValue*>(this)->getVectorElt(I);
319   }
getVectorLength()320   unsigned getVectorLength() const {
321     assert(isVector() && "Invalid accessor");
322     return ((const Vec*)(const void *)Data.buffer)->NumElts;
323   }
324 
getArrayInitializedElt(unsigned I)325   APValue &getArrayInitializedElt(unsigned I) {
326     assert(isArray() && "Invalid accessor");
327     assert(I < getArrayInitializedElts() && "Index out of range");
328     return ((Arr*)(char*)Data.buffer)->Elts[I];
329   }
getArrayInitializedElt(unsigned I)330   const APValue &getArrayInitializedElt(unsigned I) const {
331     return const_cast<APValue*>(this)->getArrayInitializedElt(I);
332   }
hasArrayFiller()333   bool hasArrayFiller() const {
334     return getArrayInitializedElts() != getArraySize();
335   }
getArrayFiller()336   APValue &getArrayFiller() {
337     assert(isArray() && "Invalid accessor");
338     assert(hasArrayFiller() && "No array filler");
339     return ((Arr*)(char*)Data.buffer)->Elts[getArrayInitializedElts()];
340   }
getArrayFiller()341   const APValue &getArrayFiller() const {
342     return const_cast<APValue*>(this)->getArrayFiller();
343   }
getArrayInitializedElts()344   unsigned getArrayInitializedElts() const {
345     assert(isArray() && "Invalid accessor");
346     return ((const Arr*)(const void *)Data.buffer)->NumElts;
347   }
getArraySize()348   unsigned getArraySize() const {
349     assert(isArray() && "Invalid accessor");
350     return ((const Arr*)(const void *)Data.buffer)->ArrSize;
351   }
352 
getStructNumBases()353   unsigned getStructNumBases() const {
354     assert(isStruct() && "Invalid accessor");
355     return ((const StructData*)(const char*)Data.buffer)->NumBases;
356   }
getStructNumFields()357   unsigned getStructNumFields() const {
358     assert(isStruct() && "Invalid accessor");
359     return ((const StructData*)(const char*)Data.buffer)->NumFields;
360   }
getStructBase(unsigned i)361   APValue &getStructBase(unsigned i) {
362     assert(isStruct() && "Invalid accessor");
363     return ((StructData*)(char*)Data.buffer)->Elts[i];
364   }
getStructField(unsigned i)365   APValue &getStructField(unsigned i) {
366     assert(isStruct() && "Invalid accessor");
367     return ((StructData*)(char*)Data.buffer)->Elts[getStructNumBases() + i];
368   }
getStructBase(unsigned i)369   const APValue &getStructBase(unsigned i) const {
370     return const_cast<APValue*>(this)->getStructBase(i);
371   }
getStructField(unsigned i)372   const APValue &getStructField(unsigned i) const {
373     return const_cast<APValue*>(this)->getStructField(i);
374   }
375 
getUnionField()376   const FieldDecl *getUnionField() const {
377     assert(isUnion() && "Invalid accessor");
378     return ((const UnionData*)(const char*)Data.buffer)->Field;
379   }
getUnionValue()380   APValue &getUnionValue() {
381     assert(isUnion() && "Invalid accessor");
382     return *((UnionData*)(char*)Data.buffer)->Value;
383   }
getUnionValue()384   const APValue &getUnionValue() const {
385     return const_cast<APValue*>(this)->getUnionValue();
386   }
387 
388   const ValueDecl *getMemberPointerDecl() const;
389   bool isMemberPointerToDerivedMember() const;
390   ArrayRef<const CXXRecordDecl*> getMemberPointerPath() const;
391 
getAddrLabelDiffLHS()392   const AddrLabelExpr* getAddrLabelDiffLHS() const {
393     assert(isAddrLabelDiff() && "Invalid accessor");
394     return ((const AddrLabelDiffData*)(const char*)Data.buffer)->LHSExpr;
395   }
getAddrLabelDiffRHS()396   const AddrLabelExpr* getAddrLabelDiffRHS() const {
397     assert(isAddrLabelDiff() && "Invalid accessor");
398     return ((const AddrLabelDiffData*)(const char*)Data.buffer)->RHSExpr;
399   }
400 
setInt(APSInt I)401   void setInt(APSInt I) {
402     assert(isInt() && "Invalid accessor");
403     *(APSInt *)(char *)Data.buffer = std::move(I);
404   }
setFloat(APFloat F)405   void setFloat(APFloat F) {
406     assert(isFloat() && "Invalid accessor");
407     *(APFloat *)(char *)Data.buffer = std::move(F);
408   }
setVector(const APValue * E,unsigned N)409   void setVector(const APValue *E, unsigned N) {
410     assert(isVector() && "Invalid accessor");
411     ((Vec*)(char*)Data.buffer)->Elts = new APValue[N];
412     ((Vec*)(char*)Data.buffer)->NumElts = N;
413     for (unsigned i = 0; i != N; ++i)
414       ((Vec*)(char*)Data.buffer)->Elts[i] = E[i];
415   }
setComplexInt(APSInt R,APSInt I)416   void setComplexInt(APSInt R, APSInt I) {
417     assert(R.getBitWidth() == I.getBitWidth() &&
418            "Invalid complex int (type mismatch).");
419     assert(isComplexInt() && "Invalid accessor");
420     ((ComplexAPSInt *)(char *)Data.buffer)->Real = std::move(R);
421     ((ComplexAPSInt *)(char *)Data.buffer)->Imag = std::move(I);
422   }
setComplexFloat(APFloat R,APFloat I)423   void setComplexFloat(APFloat R, APFloat I) {
424     assert(&R.getSemantics() == &I.getSemantics() &&
425            "Invalid complex float (type mismatch).");
426     assert(isComplexFloat() && "Invalid accessor");
427     ((ComplexAPFloat *)(char *)Data.buffer)->Real = std::move(R);
428     ((ComplexAPFloat *)(char *)Data.buffer)->Imag = std::move(I);
429   }
430   void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
431                  bool IsNullPtr);
432   void setLValue(LValueBase B, const CharUnits &O,
433                  ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
434                  bool IsNullPtr);
setUnion(const FieldDecl * Field,const APValue & Value)435   void setUnion(const FieldDecl *Field, const APValue &Value) {
436     assert(isUnion() && "Invalid accessor");
437     ((UnionData*)(char*)Data.buffer)->Field = Field;
438     *((UnionData*)(char*)Data.buffer)->Value = Value;
439   }
setAddrLabelDiff(const AddrLabelExpr * LHSExpr,const AddrLabelExpr * RHSExpr)440   void setAddrLabelDiff(const AddrLabelExpr* LHSExpr,
441                         const AddrLabelExpr* RHSExpr) {
442     ((AddrLabelDiffData*)(char*)Data.buffer)->LHSExpr = LHSExpr;
443     ((AddrLabelDiffData*)(char*)Data.buffer)->RHSExpr = RHSExpr;
444   }
445 
446   /// Assign by swapping from a copy of the RHS.
447   APValue &operator=(APValue RHS) {
448     swap(RHS);
449     return *this;
450   }
451 
452 private:
453   void DestroyDataAndMakeUninit();
MakeUninit()454   void MakeUninit() {
455     if (Kind != Uninitialized)
456       DestroyDataAndMakeUninit();
457   }
MakeInt()458   void MakeInt() {
459     assert(isUninit() && "Bad state change");
460     new ((void*)Data.buffer) APSInt(1);
461     Kind = Int;
462   }
MakeFloat()463   void MakeFloat() {
464     assert(isUninit() && "Bad state change");
465     new ((void*)(char*)Data.buffer) APFloat(0.0);
466     Kind = Float;
467   }
MakeVector()468   void MakeVector() {
469     assert(isUninit() && "Bad state change");
470     new ((void*)(char*)Data.buffer) Vec();
471     Kind = Vector;
472   }
MakeComplexInt()473   void MakeComplexInt() {
474     assert(isUninit() && "Bad state change");
475     new ((void*)(char*)Data.buffer) ComplexAPSInt();
476     Kind = ComplexInt;
477   }
MakeComplexFloat()478   void MakeComplexFloat() {
479     assert(isUninit() && "Bad state change");
480     new ((void*)(char*)Data.buffer) ComplexAPFloat();
481     Kind = ComplexFloat;
482   }
483   void MakeLValue();
484   void MakeArray(unsigned InitElts, unsigned Size);
MakeStruct(unsigned B,unsigned M)485   void MakeStruct(unsigned B, unsigned M) {
486     assert(isUninit() && "Bad state change");
487     new ((void*)(char*)Data.buffer) StructData(B, M);
488     Kind = Struct;
489   }
MakeUnion()490   void MakeUnion() {
491     assert(isUninit() && "Bad state change");
492     new ((void*)(char*)Data.buffer) UnionData();
493     Kind = Union;
494   }
495   void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
496                          ArrayRef<const CXXRecordDecl*> Path);
MakeAddrLabelDiff()497   void MakeAddrLabelDiff() {
498     assert(isUninit() && "Bad state change");
499     new ((void*)(char*)Data.buffer) AddrLabelDiffData();
500     Kind = AddrLabelDiff;
501   }
502 };
503 
504 } // end namespace clang.
505 
506 namespace llvm {
507 template<> struct DenseMapInfo<clang::APValue::LValueBase> {
508   static clang::APValue::LValueBase getEmptyKey();
509   static clang::APValue::LValueBase getTombstoneKey();
510   static unsigned getHashValue(const clang::APValue::LValueBase &Base);
511   static bool isEqual(const clang::APValue::LValueBase &LHS,
512                       const clang::APValue::LValueBase &RHS);
513 };
514 }
515 
516 #endif
517