]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/AST/APValue.h
Merge clang trunk r351319, resolve conflicts, and update FREEBSD-Xlist.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / include / clang / AST / APValue.h
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
61     LValueBase() : CallIndex(0), Version(0) {}
62
63     template <class T>
64     LValueBase(T P, unsigned I = 0, unsigned V = 0)
65         : Ptr(P), CallIndex(I), Version(V) {}
66
67     template <class T>
68     bool is() const { return Ptr.is<T>(); }
69
70     template <class T>
71     T get() const { return Ptr.get<T>(); }
72
73     template <class T>
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
82     PtrTy getPointer() const {
83       return Ptr;
84     }
85
86     unsigned getCallIndex() const {
87       return CallIndex;
88     }
89
90     void setCallIndex(unsigned Index) {
91       CallIndex = Index;
92     }
93
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;
124     ComplexAPSInt() : Real(1), Imag(1) {}
125   };
126   struct ComplexAPFloat {
127     APFloat Real, Imag;
128     ComplexAPFloat() : Real(0.0), Imag(0.0) {}
129   };
130   struct LV;
131   struct Vec {
132     APValue *Elts;
133     unsigned NumElts;
134     Vec() : Elts(nullptr), NumElts(0) {}
135     ~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:
171   APValue() : Kind(Uninitialized) {}
172   explicit APValue(APSInt I) : Kind(Uninitialized) {
173     MakeInt(); setInt(std::move(I));
174   }
175   explicit APValue(APFloat F) : Kind(Uninitialized) {
176     MakeFloat(); setFloat(std::move(F));
177   }
178   explicit APValue(const APValue *E, unsigned N) : Kind(Uninitialized) {
179     MakeVector(); setVector(E, N);
180   }
181   APValue(APSInt R, APSInt I) : Kind(Uninitialized) {
182     MakeComplexInt(); setComplexInt(std::move(R), std::move(I));
183   }
184   APValue(APFloat R, APFloat I) : Kind(Uninitialized) {
185     MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I));
186   }
187   APValue(const APValue &RHS);
188   APValue(APValue &&RHS) : Kind(Uninitialized) { swap(RHS); }
189   APValue(LValueBase B, const CharUnits &O, NoLValuePath N,
190           bool IsNullPtr = false)
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)
196       : Kind(Uninitialized) {
197     MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, IsNullPtr);
198   }
199   APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(Uninitialized) {
200     MakeArray(InitElts, Size);
201   }
202   APValue(UninitStruct, unsigned B, unsigned M) : Kind(Uninitialized) {
203     MakeStruct(B, M);
204   }
205   explicit APValue(const FieldDecl *D, const APValue &V = APValue())
206       : Kind(Uninitialized) {
207     MakeUnion(); setUnion(D, V);
208   }
209   APValue(const ValueDecl *Member, bool IsDerivedMember,
210           ArrayRef<const CXXRecordDecl*> Path) : Kind(Uninitialized) {
211     MakeMemberPointer(Member, IsDerivedMember, Path);
212   }
213   APValue(const AddrLabelExpr* LHSExpr, const AddrLabelExpr* RHSExpr)
214       : Kind(Uninitialized) {
215     MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr);
216   }
217
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
232   ValueKind getKind() const { return Kind; }
233   bool isUninit() const { return Kind == Uninitialized; }
234   bool isInt() const { return Kind == Int; }
235   bool isFloat() const { return Kind == Float; }
236   bool isComplexInt() const { return Kind == ComplexInt; }
237   bool isComplexFloat() const { return Kind == ComplexFloat; }
238   bool isLValue() const { return Kind == LValue; }
239   bool isVector() const { return Kind == Vector; }
240   bool isArray() const { return Kind == Array; }
241   bool isStruct() const { return Kind == Struct; }
242   bool isUnion() const { return Kind == Union; }
243   bool isMemberPointer() const { return Kind == MemberPointer; }
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
252   APSInt &getInt() {
253     assert(isInt() && "Invalid accessor");
254     return *(APSInt*)(char*)Data.buffer;
255   }
256   const APSInt &getInt() const {
257     return const_cast<APValue*>(this)->getInt();
258   }
259
260   APFloat &getFloat() {
261     assert(isFloat() && "Invalid accessor");
262     return *(APFloat*)(char*)Data.buffer;
263   }
264   const APFloat &getFloat() const {
265     return const_cast<APValue*>(this)->getFloat();
266   }
267
268   APSInt &getComplexIntReal() {
269     assert(isComplexInt() && "Invalid accessor");
270     return ((ComplexAPSInt*)(char*)Data.buffer)->Real;
271   }
272   const APSInt &getComplexIntReal() const {
273     return const_cast<APValue*>(this)->getComplexIntReal();
274   }
275
276   APSInt &getComplexIntImag() {
277     assert(isComplexInt() && "Invalid accessor");
278     return ((ComplexAPSInt*)(char*)Data.buffer)->Imag;
279   }
280   const APSInt &getComplexIntImag() const {
281     return const_cast<APValue*>(this)->getComplexIntImag();
282   }
283
284   APFloat &getComplexFloatReal() {
285     assert(isComplexFloat() && "Invalid accessor");
286     return ((ComplexAPFloat*)(char*)Data.buffer)->Real;
287   }
288   const APFloat &getComplexFloatReal() const {
289     return const_cast<APValue*>(this)->getComplexFloatReal();
290   }
291
292   APFloat &getComplexFloatImag() {
293     assert(isComplexFloat() && "Invalid accessor");
294     return ((ComplexAPFloat*)(char*)Data.buffer)->Imag;
295   }
296   const APFloat &getComplexFloatImag() const {
297     return const_cast<APValue*>(this)->getComplexFloatImag();
298   }
299
300   const LValueBase getLValueBase() const;
301   CharUnits &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
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   }
317   const APValue &getVectorElt(unsigned I) const {
318     return const_cast<APValue*>(this)->getVectorElt(I);
319   }
320   unsigned getVectorLength() const {
321     assert(isVector() && "Invalid accessor");
322     return ((const Vec*)(const void *)Data.buffer)->NumElts;
323   }
324
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   }
330   const APValue &getArrayInitializedElt(unsigned I) const {
331     return const_cast<APValue*>(this)->getArrayInitializedElt(I);
332   }
333   bool hasArrayFiller() const {
334     return getArrayInitializedElts() != getArraySize();
335   }
336   APValue &getArrayFiller() {
337     assert(isArray() && "Invalid accessor");
338     assert(hasArrayFiller() && "No array filler");
339     return ((Arr*)(char*)Data.buffer)->Elts[getArrayInitializedElts()];
340   }
341   const APValue &getArrayFiller() const {
342     return const_cast<APValue*>(this)->getArrayFiller();
343   }
344   unsigned getArrayInitializedElts() const {
345     assert(isArray() && "Invalid accessor");
346     return ((const Arr*)(const void *)Data.buffer)->NumElts;
347   }
348   unsigned getArraySize() const {
349     assert(isArray() && "Invalid accessor");
350     return ((const Arr*)(const void *)Data.buffer)->ArrSize;
351   }
352
353   unsigned getStructNumBases() const {
354     assert(isStruct() && "Invalid accessor");
355     return ((const StructData*)(const char*)Data.buffer)->NumBases;
356   }
357   unsigned getStructNumFields() const {
358     assert(isStruct() && "Invalid accessor");
359     return ((const StructData*)(const char*)Data.buffer)->NumFields;
360   }
361   APValue &getStructBase(unsigned i) {
362     assert(isStruct() && "Invalid accessor");
363     return ((StructData*)(char*)Data.buffer)->Elts[i];
364   }
365   APValue &getStructField(unsigned i) {
366     assert(isStruct() && "Invalid accessor");
367     return ((StructData*)(char*)Data.buffer)->Elts[getStructNumBases() + i];
368   }
369   const APValue &getStructBase(unsigned i) const {
370     return const_cast<APValue*>(this)->getStructBase(i);
371   }
372   const APValue &getStructField(unsigned i) const {
373     return const_cast<APValue*>(this)->getStructField(i);
374   }
375
376   const FieldDecl *getUnionField() const {
377     assert(isUnion() && "Invalid accessor");
378     return ((const UnionData*)(const char*)Data.buffer)->Field;
379   }
380   APValue &getUnionValue() {
381     assert(isUnion() && "Invalid accessor");
382     return *((UnionData*)(char*)Data.buffer)->Value;
383   }
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
392   const AddrLabelExpr* getAddrLabelDiffLHS() const {
393     assert(isAddrLabelDiff() && "Invalid accessor");
394     return ((const AddrLabelDiffData*)(const char*)Data.buffer)->LHSExpr;
395   }
396   const AddrLabelExpr* getAddrLabelDiffRHS() const {
397     assert(isAddrLabelDiff() && "Invalid accessor");
398     return ((const AddrLabelDiffData*)(const char*)Data.buffer)->RHSExpr;
399   }
400
401   void setInt(APSInt I) {
402     assert(isInt() && "Invalid accessor");
403     *(APSInt *)(char *)Data.buffer = std::move(I);
404   }
405   void setFloat(APFloat F) {
406     assert(isFloat() && "Invalid accessor");
407     *(APFloat *)(char *)Data.buffer = std::move(F);
408   }
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   }
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   }
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);
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   }
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();
454   void MakeUninit() {
455     if (Kind != Uninitialized)
456       DestroyDataAndMakeUninit();
457   }
458   void MakeInt() {
459     assert(isUninit() && "Bad state change");
460     new ((void*)Data.buffer) APSInt(1);
461     Kind = Int;
462   }
463   void MakeFloat() {
464     assert(isUninit() && "Bad state change");
465     new ((void*)(char*)Data.buffer) APFloat(0.0);
466     Kind = Float;
467   }
468   void MakeVector() {
469     assert(isUninit() && "Bad state change");
470     new ((void*)(char*)Data.buffer) Vec();
471     Kind = Vector;
472   }
473   void MakeComplexInt() {
474     assert(isUninit() && "Bad state change");
475     new ((void*)(char*)Data.buffer) ComplexAPSInt();
476     Kind = ComplexInt;
477   }
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);
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   }
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);
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