]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/AST/APValue.h
Merge OpenSSL 1.0.2n.
[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   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;
73     ComplexAPSInt() : Real(1), Imag(1) {}
74   };
75   struct ComplexAPFloat {
76     APFloat Real, Imag;
77     ComplexAPFloat() : Real(0.0), Imag(0.0) {}
78   };
79   struct LV;
80   struct Vec {
81     APValue *Elts;
82     unsigned NumElts;
83     Vec() : Elts(nullptr), NumElts(0) {}
84     ~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   // We ensure elsewhere that Data is big enough for LV and MemberPointerData.
112   typedef llvm::AlignedCharArrayUnion<void *, APSInt, APFloat, ComplexAPSInt,
113                                       ComplexAPFloat, Vec, Arr, StructData,
114                                       UnionData, AddrLabelDiffData> DataType;
115   static const size_t DataSize = sizeof(DataType);
116
117   DataType Data;
118
119 public:
120   APValue() : Kind(Uninitialized) {}
121   explicit APValue(APSInt I) : Kind(Uninitialized) {
122     MakeInt(); setInt(std::move(I));
123   }
124   explicit APValue(APFloat F) : Kind(Uninitialized) {
125     MakeFloat(); setFloat(std::move(F));
126   }
127   explicit APValue(const APValue *E, unsigned N) : Kind(Uninitialized) {
128     MakeVector(); setVector(E, N);
129   }
130   APValue(APSInt R, APSInt I) : Kind(Uninitialized) {
131     MakeComplexInt(); setComplexInt(std::move(R), std::move(I));
132   }
133   APValue(APFloat R, APFloat I) : Kind(Uninitialized) {
134     MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I));
135   }
136   APValue(const APValue &RHS);
137   APValue(APValue &&RHS) : Kind(Uninitialized) { swap(RHS); }
138   APValue(LValueBase B, const CharUnits &O, NoLValuePath N, unsigned CallIndex,
139           bool IsNullPtr = false)
140       : Kind(Uninitialized) {
141     MakeLValue(); setLValue(B, O, N, CallIndex, IsNullPtr);
142   }
143   APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path,
144           bool OnePastTheEnd, unsigned CallIndex, bool IsNullPtr = false)
145       : Kind(Uninitialized) {
146     MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, CallIndex, IsNullPtr);
147   }
148   APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(Uninitialized) {
149     MakeArray(InitElts, Size);
150   }
151   APValue(UninitStruct, unsigned B, unsigned M) : Kind(Uninitialized) {
152     MakeStruct(B, M);
153   }
154   explicit APValue(const FieldDecl *D, const APValue &V = APValue())
155       : Kind(Uninitialized) {
156     MakeUnion(); setUnion(D, V);
157   }
158   APValue(const ValueDecl *Member, bool IsDerivedMember,
159           ArrayRef<const CXXRecordDecl*> Path) : Kind(Uninitialized) {
160     MakeMemberPointer(Member, IsDerivedMember, Path);
161   }
162   APValue(const AddrLabelExpr* LHSExpr, const AddrLabelExpr* RHSExpr)
163       : Kind(Uninitialized) {
164     MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr);
165   }
166
167   ~APValue() {
168     MakeUninit();
169   }
170
171   /// \brief Returns whether the object performed allocations.
172   ///
173   /// If APValues are constructed via placement new, \c needsCleanup()
174   /// indicates whether the destructor must be called in order to correctly
175   /// free all allocated memory.
176   bool needsCleanup() const;
177
178   /// \brief Swaps the contents of this and the given APValue.
179   void swap(APValue &RHS);
180
181   ValueKind getKind() const { return Kind; }
182   bool isUninit() const { return Kind == Uninitialized; }
183   bool isInt() const { return Kind == Int; }
184   bool isFloat() const { return Kind == Float; }
185   bool isComplexInt() const { return Kind == ComplexInt; }
186   bool isComplexFloat() const { return Kind == ComplexFloat; }
187   bool isLValue() const { return Kind == LValue; }
188   bool isVector() const { return Kind == Vector; }
189   bool isArray() const { return Kind == Array; }
190   bool isStruct() const { return Kind == Struct; }
191   bool isUnion() const { return Kind == Union; }
192   bool isMemberPointer() const { return Kind == MemberPointer; }
193   bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; }
194
195   void dump() const;
196   void dump(raw_ostream &OS) const;
197
198   void printPretty(raw_ostream &OS, ASTContext &Ctx, QualType Ty) const;
199   std::string getAsString(ASTContext &Ctx, QualType Ty) const;
200
201   APSInt &getInt() {
202     assert(isInt() && "Invalid accessor");
203     return *(APSInt*)(char*)Data.buffer;
204   }
205   const APSInt &getInt() const {
206     return const_cast<APValue*>(this)->getInt();
207   }
208
209   APFloat &getFloat() {
210     assert(isFloat() && "Invalid accessor");
211     return *(APFloat*)(char*)Data.buffer;
212   }
213   const APFloat &getFloat() const {
214     return const_cast<APValue*>(this)->getFloat();
215   }
216
217   APSInt &getComplexIntReal() {
218     assert(isComplexInt() && "Invalid accessor");
219     return ((ComplexAPSInt*)(char*)Data.buffer)->Real;
220   }
221   const APSInt &getComplexIntReal() const {
222     return const_cast<APValue*>(this)->getComplexIntReal();
223   }
224
225   APSInt &getComplexIntImag() {
226     assert(isComplexInt() && "Invalid accessor");
227     return ((ComplexAPSInt*)(char*)Data.buffer)->Imag;
228   }
229   const APSInt &getComplexIntImag() const {
230     return const_cast<APValue*>(this)->getComplexIntImag();
231   }
232
233   APFloat &getComplexFloatReal() {
234     assert(isComplexFloat() && "Invalid accessor");
235     return ((ComplexAPFloat*)(char*)Data.buffer)->Real;
236   }
237   const APFloat &getComplexFloatReal() const {
238     return const_cast<APValue*>(this)->getComplexFloatReal();
239   }
240
241   APFloat &getComplexFloatImag() {
242     assert(isComplexFloat() && "Invalid accessor");
243     return ((ComplexAPFloat*)(char*)Data.buffer)->Imag;
244   }
245   const APFloat &getComplexFloatImag() const {
246     return const_cast<APValue*>(this)->getComplexFloatImag();
247   }
248
249   const LValueBase getLValueBase() const;
250   CharUnits &getLValueOffset();
251   const CharUnits &getLValueOffset() const {
252     return const_cast<APValue*>(this)->getLValueOffset();
253   }
254   bool isLValueOnePastTheEnd() const;
255   bool hasLValuePath() const;
256   ArrayRef<LValuePathEntry> getLValuePath() const;
257   unsigned getLValueCallIndex() const;
258   bool isNullPointer() const;
259
260   APValue &getVectorElt(unsigned I) {
261     assert(isVector() && "Invalid accessor");
262     assert(I < getVectorLength() && "Index out of range");
263     return ((Vec*)(char*)Data.buffer)->Elts[I];
264   }
265   const APValue &getVectorElt(unsigned I) const {
266     return const_cast<APValue*>(this)->getVectorElt(I);
267   }
268   unsigned getVectorLength() const {
269     assert(isVector() && "Invalid accessor");
270     return ((const Vec*)(const void *)Data.buffer)->NumElts;
271   }
272
273   APValue &getArrayInitializedElt(unsigned I) {
274     assert(isArray() && "Invalid accessor");
275     assert(I < getArrayInitializedElts() && "Index out of range");
276     return ((Arr*)(char*)Data.buffer)->Elts[I];
277   }
278   const APValue &getArrayInitializedElt(unsigned I) const {
279     return const_cast<APValue*>(this)->getArrayInitializedElt(I);
280   }
281   bool hasArrayFiller() const {
282     return getArrayInitializedElts() != getArraySize();
283   }
284   APValue &getArrayFiller() {
285     assert(isArray() && "Invalid accessor");
286     assert(hasArrayFiller() && "No array filler");
287     return ((Arr*)(char*)Data.buffer)->Elts[getArrayInitializedElts()];
288   }
289   const APValue &getArrayFiller() const {
290     return const_cast<APValue*>(this)->getArrayFiller();
291   }
292   unsigned getArrayInitializedElts() const {
293     assert(isArray() && "Invalid accessor");
294     return ((const Arr*)(const void *)Data.buffer)->NumElts;
295   }
296   unsigned getArraySize() const {
297     assert(isArray() && "Invalid accessor");
298     return ((const Arr*)(const void *)Data.buffer)->ArrSize;
299   }
300
301   unsigned getStructNumBases() const {
302     assert(isStruct() && "Invalid accessor");
303     return ((const StructData*)(const char*)Data.buffer)->NumBases;
304   }
305   unsigned getStructNumFields() const {
306     assert(isStruct() && "Invalid accessor");
307     return ((const StructData*)(const char*)Data.buffer)->NumFields;
308   }
309   APValue &getStructBase(unsigned i) {
310     assert(isStruct() && "Invalid accessor");
311     return ((StructData*)(char*)Data.buffer)->Elts[i];
312   }
313   APValue &getStructField(unsigned i) {
314     assert(isStruct() && "Invalid accessor");
315     return ((StructData*)(char*)Data.buffer)->Elts[getStructNumBases() + i];
316   }
317   const APValue &getStructBase(unsigned i) const {
318     return const_cast<APValue*>(this)->getStructBase(i);
319   }
320   const APValue &getStructField(unsigned i) const {
321     return const_cast<APValue*>(this)->getStructField(i);
322   }
323
324   const FieldDecl *getUnionField() const {
325     assert(isUnion() && "Invalid accessor");
326     return ((const UnionData*)(const char*)Data.buffer)->Field;
327   }
328   APValue &getUnionValue() {
329     assert(isUnion() && "Invalid accessor");
330     return *((UnionData*)(char*)Data.buffer)->Value;
331   }
332   const APValue &getUnionValue() const {
333     return const_cast<APValue*>(this)->getUnionValue();
334   }
335
336   const ValueDecl *getMemberPointerDecl() const;
337   bool isMemberPointerToDerivedMember() const;
338   ArrayRef<const CXXRecordDecl*> getMemberPointerPath() const;
339
340   const AddrLabelExpr* getAddrLabelDiffLHS() const {
341     assert(isAddrLabelDiff() && "Invalid accessor");
342     return ((const AddrLabelDiffData*)(const char*)Data.buffer)->LHSExpr;
343   }
344   const AddrLabelExpr* getAddrLabelDiffRHS() const {
345     assert(isAddrLabelDiff() && "Invalid accessor");
346     return ((const AddrLabelDiffData*)(const char*)Data.buffer)->RHSExpr;
347   }
348
349   void setInt(APSInt I) {
350     assert(isInt() && "Invalid accessor");
351     *(APSInt *)(char *)Data.buffer = std::move(I);
352   }
353   void setFloat(APFloat F) {
354     assert(isFloat() && "Invalid accessor");
355     *(APFloat *)(char *)Data.buffer = std::move(F);
356   }
357   void setVector(const APValue *E, unsigned N) {
358     assert(isVector() && "Invalid accessor");
359     ((Vec*)(char*)Data.buffer)->Elts = new APValue[N];
360     ((Vec*)(char*)Data.buffer)->NumElts = N;
361     for (unsigned i = 0; i != N; ++i)
362       ((Vec*)(char*)Data.buffer)->Elts[i] = E[i];
363   }
364   void setComplexInt(APSInt R, APSInt I) {
365     assert(R.getBitWidth() == I.getBitWidth() &&
366            "Invalid complex int (type mismatch).");
367     assert(isComplexInt() && "Invalid accessor");
368     ((ComplexAPSInt *)(char *)Data.buffer)->Real = std::move(R);
369     ((ComplexAPSInt *)(char *)Data.buffer)->Imag = std::move(I);
370   }
371   void setComplexFloat(APFloat R, APFloat I) {
372     assert(&R.getSemantics() == &I.getSemantics() &&
373            "Invalid complex float (type mismatch).");
374     assert(isComplexFloat() && "Invalid accessor");
375     ((ComplexAPFloat *)(char *)Data.buffer)->Real = std::move(R);
376     ((ComplexAPFloat *)(char *)Data.buffer)->Imag = std::move(I);
377   }
378   void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
379                  unsigned CallIndex, bool IsNullPtr);
380   void setLValue(LValueBase B, const CharUnits &O,
381                  ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
382                  unsigned CallIndex, bool IsNullPtr);
383   void setUnion(const FieldDecl *Field, const APValue &Value) {
384     assert(isUnion() && "Invalid accessor");
385     ((UnionData*)(char*)Data.buffer)->Field = Field;
386     *((UnionData*)(char*)Data.buffer)->Value = Value;
387   }
388   void setAddrLabelDiff(const AddrLabelExpr* LHSExpr,
389                         const AddrLabelExpr* RHSExpr) {
390     ((AddrLabelDiffData*)(char*)Data.buffer)->LHSExpr = LHSExpr;
391     ((AddrLabelDiffData*)(char*)Data.buffer)->RHSExpr = RHSExpr;
392   }
393
394   /// Assign by swapping from a copy of the RHS.
395   APValue &operator=(APValue RHS) {
396     swap(RHS);
397     return *this;
398   }
399
400 private:
401   void DestroyDataAndMakeUninit();
402   void MakeUninit() {
403     if (Kind != Uninitialized)
404       DestroyDataAndMakeUninit();
405   }
406   void MakeInt() {
407     assert(isUninit() && "Bad state change");
408     new ((void*)Data.buffer) APSInt(1);
409     Kind = Int;
410   }
411   void MakeFloat() {
412     assert(isUninit() && "Bad state change");
413     new ((void*)(char*)Data.buffer) APFloat(0.0);
414     Kind = Float;
415   }
416   void MakeVector() {
417     assert(isUninit() && "Bad state change");
418     new ((void*)(char*)Data.buffer) Vec();
419     Kind = Vector;
420   }
421   void MakeComplexInt() {
422     assert(isUninit() && "Bad state change");
423     new ((void*)(char*)Data.buffer) ComplexAPSInt();
424     Kind = ComplexInt;
425   }
426   void MakeComplexFloat() {
427     assert(isUninit() && "Bad state change");
428     new ((void*)(char*)Data.buffer) ComplexAPFloat();
429     Kind = ComplexFloat;
430   }
431   void MakeLValue();
432   void MakeArray(unsigned InitElts, unsigned Size);
433   void MakeStruct(unsigned B, unsigned M) {
434     assert(isUninit() && "Bad state change");
435     new ((void*)(char*)Data.buffer) StructData(B, M);
436     Kind = Struct;
437   }
438   void MakeUnion() {
439     assert(isUninit() && "Bad state change");
440     new ((void*)(char*)Data.buffer) UnionData();
441     Kind = Union;
442   }
443   void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
444                          ArrayRef<const CXXRecordDecl*> Path);
445   void MakeAddrLabelDiff() {
446     assert(isUninit() && "Bad state change");
447     new ((void*)(char*)Data.buffer) AddrLabelDiffData();
448     Kind = AddrLabelDiff;
449   }
450 };
451
452 } // end namespace clang.
453
454 #endif