• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/APSInt.h"
19 #include "llvm/ADT/APFloat.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   typedef llvm::PointerUnion<const ValueDecl *, const Expr *> LValueBase;
57   typedef llvm::PointerIntPair<const Decl *, 1, bool> BaseOrMemberType;
58   union LValuePathEntry {
59     /// BaseOrMember - The FieldDecl or CXXRecordDecl indicating the next item
60     /// in the path. An opaque value of type BaseOrMemberType.
61     void *BaseOrMember;
62     /// ArrayIndex - The array index of the next item in the path.
63     uint64_t ArrayIndex;
64   };
65   struct NoLValuePath {};
66   struct UninitArray {};
67   struct UninitStruct {};
68 private:
69   ValueKind Kind;
70 
71   struct ComplexAPSInt {
72     APSInt Real, Imag;
ComplexAPSIntComplexAPSInt73     ComplexAPSInt() : Real(1), Imag(1) {}
74   };
75   struct ComplexAPFloat {
76     APFloat Real, Imag;
ComplexAPFloatComplexAPFloat77     ComplexAPFloat() : Real(0.0), Imag(0.0) {}
78   };
79   struct LV;
80   struct Vec {
81     APValue *Elts;
82     unsigned NumElts;
VecVec83     Vec() : Elts(0), NumElts(0) {}
~VecVec84     ~Vec() { delete[] Elts; }
85   };
86   struct Arr {
87     APValue *Elts;
88     unsigned NumElts, ArrSize;
89     Arr(unsigned NumElts, unsigned ArrSize);
90     ~Arr();
91   };
92   struct StructData {
93     APValue *Elts;
94     unsigned NumBases;
95     unsigned NumFields;
96     StructData(unsigned NumBases, unsigned NumFields);
97     ~StructData();
98   };
99   struct UnionData {
100     const FieldDecl *Field;
101     APValue *Value;
102     UnionData();
103     ~UnionData();
104   };
105   struct AddrLabelDiffData {
106     const AddrLabelExpr* LHSExpr;
107     const AddrLabelExpr* RHSExpr;
108   };
109   struct MemberPointerData;
110 
111   enum {
112     MaxSize = (sizeof(ComplexAPSInt) > sizeof(ComplexAPFloat) ?
113                sizeof(ComplexAPSInt) : sizeof(ComplexAPFloat))
114   };
115 
116   union {
117     void *Aligner;
118     char Data[MaxSize];
119   };
120 
121 public:
APValue()122   APValue() : Kind(Uninitialized) {}
APValue(const APSInt & I)123   explicit APValue(const APSInt &I) : Kind(Uninitialized) {
124     MakeInt(); setInt(I);
125   }
APValue(const APFloat & F)126   explicit APValue(const APFloat &F) : Kind(Uninitialized) {
127     MakeFloat(); setFloat(F);
128   }
APValue(const APValue * E,unsigned N)129   explicit APValue(const APValue *E, unsigned N) : Kind(Uninitialized) {
130     MakeVector(); setVector(E, N);
131   }
APValue(const APSInt & R,const APSInt & I)132   APValue(const APSInt &R, const APSInt &I) : Kind(Uninitialized) {
133     MakeComplexInt(); setComplexInt(R, I);
134   }
APValue(const APFloat & R,const APFloat & I)135   APValue(const APFloat &R, const APFloat &I) : Kind(Uninitialized) {
136     MakeComplexFloat(); setComplexFloat(R, I);
137   }
138   APValue(const APValue &RHS);
APValue(LValueBase B,const CharUnits & O,NoLValuePath N,unsigned CallIndex)139   APValue(LValueBase B, const CharUnits &O, NoLValuePath N, unsigned CallIndex)
140       : Kind(Uninitialized) {
141     MakeLValue(); setLValue(B, O, N, CallIndex);
142   }
APValue(LValueBase B,const CharUnits & O,ArrayRef<LValuePathEntry> Path,bool OnePastTheEnd,unsigned CallIndex)143   APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path,
144           bool OnePastTheEnd, unsigned CallIndex)
145       : Kind(Uninitialized) {
146     MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, CallIndex);
147   }
APValue(UninitArray,unsigned InitElts,unsigned Size)148   APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(Uninitialized) {
149     MakeArray(InitElts, Size);
150   }
APValue(UninitStruct,unsigned B,unsigned M)151   APValue(UninitStruct, unsigned B, unsigned M) : Kind(Uninitialized) {
152     MakeStruct(B, M);
153   }
154   explicit APValue(const FieldDecl *D, const APValue &V = APValue())
Kind(Uninitialized)155       : Kind(Uninitialized) {
156     MakeUnion(); setUnion(D, V);
157   }
APValue(const ValueDecl * Member,bool IsDerivedMember,ArrayRef<const CXXRecordDecl * > Path)158   APValue(const ValueDecl *Member, bool IsDerivedMember,
159           ArrayRef<const CXXRecordDecl*> Path) : Kind(Uninitialized) {
160     MakeMemberPointer(Member, IsDerivedMember, Path);
161   }
APValue(const AddrLabelExpr * LHSExpr,const AddrLabelExpr * RHSExpr)162   APValue(const AddrLabelExpr* LHSExpr, const AddrLabelExpr* RHSExpr)
163       : Kind(Uninitialized) {
164     MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr);
165   }
166 
~APValue()167   ~APValue() {
168     MakeUninit();
169   }
170 
171   /// \brief Swaps the contents of this and the given APValue.
172   void swap(APValue &RHS);
173 
getKind()174   ValueKind getKind() const { return Kind; }
isUninit()175   bool isUninit() const { return Kind == Uninitialized; }
isInt()176   bool isInt() const { return Kind == Int; }
isFloat()177   bool isFloat() const { return Kind == Float; }
isComplexInt()178   bool isComplexInt() const { return Kind == ComplexInt; }
isComplexFloat()179   bool isComplexFloat() const { return Kind == ComplexFloat; }
isLValue()180   bool isLValue() const { return Kind == LValue; }
isVector()181   bool isVector() const { return Kind == Vector; }
isArray()182   bool isArray() const { return Kind == Array; }
isStruct()183   bool isStruct() const { return Kind == Struct; }
isUnion()184   bool isUnion() const { return Kind == Union; }
isMemberPointer()185   bool isMemberPointer() const { return Kind == MemberPointer; }
isAddrLabelDiff()186   bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; }
187 
188   void dump() const;
189   void dump(raw_ostream &OS) const;
190 
191   void printPretty(raw_ostream &OS, ASTContext &Ctx, QualType Ty) const;
192   std::string getAsString(ASTContext &Ctx, QualType Ty) const;
193 
getInt()194   APSInt &getInt() {
195     assert(isInt() && "Invalid accessor");
196     return *(APSInt*)(char*)Data;
197   }
getInt()198   const APSInt &getInt() const {
199     return const_cast<APValue*>(this)->getInt();
200   }
201 
getFloat()202   APFloat &getFloat() {
203     assert(isFloat() && "Invalid accessor");
204     return *(APFloat*)(char*)Data;
205   }
getFloat()206   const APFloat &getFloat() const {
207     return const_cast<APValue*>(this)->getFloat();
208   }
209 
getComplexIntReal()210   APSInt &getComplexIntReal() {
211     assert(isComplexInt() && "Invalid accessor");
212     return ((ComplexAPSInt*)(char*)Data)->Real;
213   }
getComplexIntReal()214   const APSInt &getComplexIntReal() const {
215     return const_cast<APValue*>(this)->getComplexIntReal();
216   }
217 
getComplexIntImag()218   APSInt &getComplexIntImag() {
219     assert(isComplexInt() && "Invalid accessor");
220     return ((ComplexAPSInt*)(char*)Data)->Imag;
221   }
getComplexIntImag()222   const APSInt &getComplexIntImag() const {
223     return const_cast<APValue*>(this)->getComplexIntImag();
224   }
225 
getComplexFloatReal()226   APFloat &getComplexFloatReal() {
227     assert(isComplexFloat() && "Invalid accessor");
228     return ((ComplexAPFloat*)(char*)Data)->Real;
229   }
getComplexFloatReal()230   const APFloat &getComplexFloatReal() const {
231     return const_cast<APValue*>(this)->getComplexFloatReal();
232   }
233 
getComplexFloatImag()234   APFloat &getComplexFloatImag() {
235     assert(isComplexFloat() && "Invalid accessor");
236     return ((ComplexAPFloat*)(char*)Data)->Imag;
237   }
getComplexFloatImag()238   const APFloat &getComplexFloatImag() const {
239     return const_cast<APValue*>(this)->getComplexFloatImag();
240   }
241 
242   const LValueBase getLValueBase() const;
243   CharUnits &getLValueOffset();
getLValueOffset()244   const CharUnits &getLValueOffset() const {
245     return const_cast<APValue*>(this)->getLValueOffset();
246   }
247   bool isLValueOnePastTheEnd() const;
248   bool hasLValuePath() const;
249   ArrayRef<LValuePathEntry> getLValuePath() const;
250   unsigned getLValueCallIndex() const;
251 
getVectorElt(unsigned I)252   APValue &getVectorElt(unsigned I) {
253     assert(isVector() && "Invalid accessor");
254     assert(I < getVectorLength() && "Index out of range");
255     return ((Vec*)(char*)Data)->Elts[I];
256   }
getVectorElt(unsigned I)257   const APValue &getVectorElt(unsigned I) const {
258     return const_cast<APValue*>(this)->getVectorElt(I);
259   }
getVectorLength()260   unsigned getVectorLength() const {
261     assert(isVector() && "Invalid accessor");
262     return ((const Vec*)(const void *)Data)->NumElts;
263   }
264 
getArrayInitializedElt(unsigned I)265   APValue &getArrayInitializedElt(unsigned I) {
266     assert(isArray() && "Invalid accessor");
267     assert(I < getArrayInitializedElts() && "Index out of range");
268     return ((Arr*)(char*)Data)->Elts[I];
269   }
getArrayInitializedElt(unsigned I)270   const APValue &getArrayInitializedElt(unsigned I) const {
271     return const_cast<APValue*>(this)->getArrayInitializedElt(I);
272   }
hasArrayFiller()273   bool hasArrayFiller() const {
274     return getArrayInitializedElts() != getArraySize();
275   }
getArrayFiller()276   APValue &getArrayFiller() {
277     assert(isArray() && "Invalid accessor");
278     assert(hasArrayFiller() && "No array filler");
279     return ((Arr*)(char*)Data)->Elts[getArrayInitializedElts()];
280   }
getArrayFiller()281   const APValue &getArrayFiller() const {
282     return const_cast<APValue*>(this)->getArrayFiller();
283   }
getArrayInitializedElts()284   unsigned getArrayInitializedElts() const {
285     assert(isArray() && "Invalid accessor");
286     return ((const Arr*)(const void *)Data)->NumElts;
287   }
getArraySize()288   unsigned getArraySize() const {
289     assert(isArray() && "Invalid accessor");
290     return ((const Arr*)(const void *)Data)->ArrSize;
291   }
292 
getStructNumBases()293   unsigned getStructNumBases() const {
294     assert(isStruct() && "Invalid accessor");
295     return ((const StructData*)(const char*)Data)->NumBases;
296   }
getStructNumFields()297   unsigned getStructNumFields() const {
298     assert(isStruct() && "Invalid accessor");
299     return ((const StructData*)(const char*)Data)->NumFields;
300   }
getStructBase(unsigned i)301   APValue &getStructBase(unsigned i) {
302     assert(isStruct() && "Invalid accessor");
303     return ((StructData*)(char*)Data)->Elts[i];
304   }
getStructField(unsigned i)305   APValue &getStructField(unsigned i) {
306     assert(isStruct() && "Invalid accessor");
307     return ((StructData*)(char*)Data)->Elts[getStructNumBases() + i];
308   }
getStructBase(unsigned i)309   const APValue &getStructBase(unsigned i) const {
310     return const_cast<APValue*>(this)->getStructBase(i);
311   }
getStructField(unsigned i)312   const APValue &getStructField(unsigned i) const {
313     return const_cast<APValue*>(this)->getStructField(i);
314   }
315 
getUnionField()316   const FieldDecl *getUnionField() const {
317     assert(isUnion() && "Invalid accessor");
318     return ((const UnionData*)(const char*)Data)->Field;
319   }
getUnionValue()320   APValue &getUnionValue() {
321     assert(isUnion() && "Invalid accessor");
322     return *((UnionData*)(char*)Data)->Value;
323   }
getUnionValue()324   const APValue &getUnionValue() const {
325     return const_cast<APValue*>(this)->getUnionValue();
326   }
327 
328   const ValueDecl *getMemberPointerDecl() const;
329   bool isMemberPointerToDerivedMember() const;
330   ArrayRef<const CXXRecordDecl*> getMemberPointerPath() const;
331 
getAddrLabelDiffLHS()332   const AddrLabelExpr* getAddrLabelDiffLHS() const {
333     assert(isAddrLabelDiff() && "Invalid accessor");
334     return ((const AddrLabelDiffData*)(const char*)Data)->LHSExpr;
335   }
getAddrLabelDiffRHS()336   const AddrLabelExpr* getAddrLabelDiffRHS() const {
337     assert(isAddrLabelDiff() && "Invalid accessor");
338     return ((const AddrLabelDiffData*)(const char*)Data)->RHSExpr;
339   }
340 
setInt(const APSInt & I)341   void setInt(const APSInt &I) {
342     assert(isInt() && "Invalid accessor");
343     *(APSInt*)(char*)Data = I;
344   }
setFloat(const APFloat & F)345   void setFloat(const APFloat &F) {
346     assert(isFloat() && "Invalid accessor");
347     *(APFloat*)(char*)Data = F;
348   }
setVector(const APValue * E,unsigned N)349   void setVector(const APValue *E, unsigned N) {
350     assert(isVector() && "Invalid accessor");
351     ((Vec*)(char*)Data)->Elts = new APValue[N];
352     ((Vec*)(char*)Data)->NumElts = N;
353     for (unsigned i = 0; i != N; ++i)
354       ((Vec*)(char*)Data)->Elts[i] = E[i];
355   }
setComplexInt(const APSInt & R,const APSInt & I)356   void setComplexInt(const APSInt &R, const APSInt &I) {
357     assert(R.getBitWidth() == I.getBitWidth() &&
358            "Invalid complex int (type mismatch).");
359     assert(isComplexInt() && "Invalid accessor");
360     ((ComplexAPSInt*)(char*)Data)->Real = R;
361     ((ComplexAPSInt*)(char*)Data)->Imag = I;
362   }
setComplexFloat(const APFloat & R,const APFloat & I)363   void setComplexFloat(const APFloat &R, const APFloat &I) {
364     assert(&R.getSemantics() == &I.getSemantics() &&
365            "Invalid complex float (type mismatch).");
366     assert(isComplexFloat() && "Invalid accessor");
367     ((ComplexAPFloat*)(char*)Data)->Real = R;
368     ((ComplexAPFloat*)(char*)Data)->Imag = I;
369   }
370   void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
371                  unsigned CallIndex);
372   void setLValue(LValueBase B, const CharUnits &O,
373                  ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
374                  unsigned CallIndex);
setUnion(const FieldDecl * Field,const APValue & Value)375   void setUnion(const FieldDecl *Field, const APValue &Value) {
376     assert(isUnion() && "Invalid accessor");
377     ((UnionData*)(char*)Data)->Field = Field;
378     *((UnionData*)(char*)Data)->Value = Value;
379   }
setAddrLabelDiff(const AddrLabelExpr * LHSExpr,const AddrLabelExpr * RHSExpr)380   void setAddrLabelDiff(const AddrLabelExpr* LHSExpr,
381                         const AddrLabelExpr* RHSExpr) {
382     ((AddrLabelDiffData*)(char*)Data)->LHSExpr = LHSExpr;
383     ((AddrLabelDiffData*)(char*)Data)->RHSExpr = RHSExpr;
384   }
385 
386   /// Assign by swapping from a copy of the RHS.
387   APValue &operator=(APValue RHS) {
388     swap(RHS);
389     return *this;
390   }
391 
392 private:
393   void DestroyDataAndMakeUninit();
MakeUninit()394   void MakeUninit() {
395     if (Kind != Uninitialized)
396       DestroyDataAndMakeUninit();
397   }
MakeInt()398   void MakeInt() {
399     assert(isUninit() && "Bad state change");
400     new ((void*)Data) APSInt(1);
401     Kind = Int;
402   }
MakeFloat()403   void MakeFloat() {
404     assert(isUninit() && "Bad state change");
405     new ((void*)(char*)Data) APFloat(0.0);
406     Kind = Float;
407   }
MakeVector()408   void MakeVector() {
409     assert(isUninit() && "Bad state change");
410     new ((void*)(char*)Data) Vec();
411     Kind = Vector;
412   }
MakeComplexInt()413   void MakeComplexInt() {
414     assert(isUninit() && "Bad state change");
415     new ((void*)(char*)Data) ComplexAPSInt();
416     Kind = ComplexInt;
417   }
MakeComplexFloat()418   void MakeComplexFloat() {
419     assert(isUninit() && "Bad state change");
420     new ((void*)(char*)Data) ComplexAPFloat();
421     Kind = ComplexFloat;
422   }
423   void MakeLValue();
424   void MakeArray(unsigned InitElts, unsigned Size);
MakeStruct(unsigned B,unsigned M)425   void MakeStruct(unsigned B, unsigned M) {
426     assert(isUninit() && "Bad state change");
427     new ((void*)(char*)Data) StructData(B, M);
428     Kind = Struct;
429   }
MakeUnion()430   void MakeUnion() {
431     assert(isUninit() && "Bad state change");
432     new ((void*)(char*)Data) UnionData();
433     Kind = Union;
434   }
435   void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
436                          ArrayRef<const CXXRecordDecl*> Path);
MakeAddrLabelDiff()437   void MakeAddrLabelDiff() {
438     assert(isUninit() && "Bad state change");
439     new ((void*)(char*)Data) AddrLabelDiffData();
440     Kind = AddrLabelDiff;
441   }
442 };
443 
444 } // end namespace clang.
445 
446 #endif
447