]> CyberLeo.Net >> Repos - FreeBSD/releng/9.0.git/blob - contrib/llvm/tools/clang/include/clang/AST/APValue.h
Copy stable/9 to releng/9.0 as part of the FreeBSD 9.0-RELEASE release
[FreeBSD/releng/9.0.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/APSInt.h"
19 #include "llvm/ADT/APFloat.h"
20
21 namespace clang {
22   class CharUnits;
23   class DiagnosticBuilder;
24   class Expr;
25
26 /// APValue - This class implements a discriminated union of [uninitialized]
27 /// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset].
28 class APValue {
29   typedef llvm::APSInt APSInt;
30   typedef llvm::APFloat APFloat;
31 public:
32   enum ValueKind {
33     Uninitialized,
34     Int,
35     Float,
36     ComplexInt,
37     ComplexFloat,
38     LValue,
39     Vector
40   };
41 private:
42   ValueKind Kind;
43
44   struct ComplexAPSInt {
45     APSInt Real, Imag;
46     ComplexAPSInt() : Real(1), Imag(1) {}
47   };
48   struct ComplexAPFloat {
49     APFloat Real, Imag;
50     ComplexAPFloat() : Real(0.0), Imag(0.0) {}
51   };
52
53   struct Vec {
54     APValue *Elts;
55     unsigned NumElts;
56     Vec() : Elts(0), NumElts(0) {}
57     ~Vec() { delete[] Elts; }
58   };
59
60   enum {
61     MaxSize = (sizeof(ComplexAPSInt) > sizeof(ComplexAPFloat) ?
62                sizeof(ComplexAPSInt) : sizeof(ComplexAPFloat))
63   };
64
65   union {
66     void *Aligner;
67     char Data[MaxSize];
68   };
69
70 public:
71   APValue() : Kind(Uninitialized) {}
72   explicit APValue(const APSInt &I) : Kind(Uninitialized) {
73     MakeInt(); setInt(I);
74   }
75   explicit APValue(const APFloat &F) : Kind(Uninitialized) {
76     MakeFloat(); setFloat(F);
77   }
78   explicit APValue(const APValue *E, unsigned N) : Kind(Uninitialized) {
79     MakeVector(); setVector(E, N);
80   }
81   APValue(const APSInt &R, const APSInt &I) : Kind(Uninitialized) {
82     MakeComplexInt(); setComplexInt(R, I);
83   }
84   APValue(const APFloat &R, const APFloat &I) : Kind(Uninitialized) {
85     MakeComplexFloat(); setComplexFloat(R, I);
86   }
87   APValue(const APValue &RHS) : Kind(Uninitialized) {
88     *this = RHS;
89   }
90   APValue(const Expr* B, const CharUnits &O) : Kind(Uninitialized) {
91     MakeLValue(); setLValue(B, O);
92   }
93   APValue(const Expr* B);
94
95   ~APValue() {
96     MakeUninit();
97   }
98
99   ValueKind getKind() const { return Kind; }
100   bool isUninit() const { return Kind == Uninitialized; }
101   bool isInt() const { return Kind == Int; }
102   bool isFloat() const { return Kind == Float; }
103   bool isComplexInt() const { return Kind == ComplexInt; }
104   bool isComplexFloat() const { return Kind == ComplexFloat; }
105   bool isLValue() const { return Kind == LValue; }
106   bool isVector() const { return Kind == Vector; }
107
108   void print(raw_ostream &OS) const;
109   void dump() const;
110
111   APSInt &getInt() {
112     assert(isInt() && "Invalid accessor");
113     return *(APSInt*)(char*)Data;
114   }
115   const APSInt &getInt() const {
116     return const_cast<APValue*>(this)->getInt();
117   }
118
119   APFloat &getFloat() {
120     assert(isFloat() && "Invalid accessor");
121     return *(APFloat*)(char*)Data;
122   }
123   const APFloat &getFloat() const {
124     return const_cast<APValue*>(this)->getFloat();
125   }
126
127   APValue &getVectorElt(unsigned i) {
128     assert(isVector() && "Invalid accessor");
129     return ((Vec*)(char*)Data)->Elts[i];
130   }
131   const APValue &getVectorElt(unsigned i) const {
132     assert(isVector() && "Invalid accessor");
133     return ((const Vec*)(const char*)Data)->Elts[i];
134   }
135   unsigned getVectorLength() const {
136     assert(isVector() && "Invalid accessor");
137     return ((const Vec*)(const void *)Data)->NumElts;
138   }
139
140   APSInt &getComplexIntReal() {
141     assert(isComplexInt() && "Invalid accessor");
142     return ((ComplexAPSInt*)(char*)Data)->Real;
143   }
144   const APSInt &getComplexIntReal() const {
145     return const_cast<APValue*>(this)->getComplexIntReal();
146   }
147
148   APSInt &getComplexIntImag() {
149     assert(isComplexInt() && "Invalid accessor");
150     return ((ComplexAPSInt*)(char*)Data)->Imag;
151   }
152   const APSInt &getComplexIntImag() const {
153     return const_cast<APValue*>(this)->getComplexIntImag();
154   }
155
156   APFloat &getComplexFloatReal() {
157     assert(isComplexFloat() && "Invalid accessor");
158     return ((ComplexAPFloat*)(char*)Data)->Real;
159   }
160   const APFloat &getComplexFloatReal() const {
161     return const_cast<APValue*>(this)->getComplexFloatReal();
162   }
163
164   APFloat &getComplexFloatImag() {
165     assert(isComplexFloat() && "Invalid accessor");
166     return ((ComplexAPFloat*)(char*)Data)->Imag;
167   }
168   const APFloat &getComplexFloatImag() const {
169     return const_cast<APValue*>(this)->getComplexFloatImag();
170   }
171
172   const Expr* getLValueBase() const;
173   CharUnits getLValueOffset() const;
174
175   void setInt(const APSInt &I) {
176     assert(isInt() && "Invalid accessor");
177     *(APSInt*)(char*)Data = I;
178   }
179   void setFloat(const APFloat &F) {
180     assert(isFloat() && "Invalid accessor");
181     *(APFloat*)(char*)Data = F;
182   }
183   void setVector(const APValue *E, unsigned N) {
184     assert(isVector() && "Invalid accessor");
185     ((Vec*)(char*)Data)->Elts = new APValue[N];
186     ((Vec*)(char*)Data)->NumElts = N;
187     for (unsigned i = 0; i != N; ++i)
188       ((Vec*)(char*)Data)->Elts[i] = E[i];
189   }
190   void setComplexInt(const APSInt &R, const APSInt &I) {
191     assert(R.getBitWidth() == I.getBitWidth() &&
192            "Invalid complex int (type mismatch).");
193     assert(isComplexInt() && "Invalid accessor");
194     ((ComplexAPSInt*)(char*)Data)->Real = R;
195     ((ComplexAPSInt*)(char*)Data)->Imag = I;
196   }
197   void setComplexFloat(const APFloat &R, const APFloat &I) {
198     assert(&R.getSemantics() == &I.getSemantics() &&
199            "Invalid complex float (type mismatch).");
200     assert(isComplexFloat() && "Invalid accessor");
201     ((ComplexAPFloat*)(char*)Data)->Real = R;
202     ((ComplexAPFloat*)(char*)Data)->Imag = I;
203   }
204   void setLValue(const Expr *B, const CharUnits &O);
205
206   const APValue &operator=(const APValue &RHS);
207
208 private:
209   void MakeUninit();
210   void MakeInt() {
211     assert(isUninit() && "Bad state change");
212     new ((void*)Data) APSInt(1);
213     Kind = Int;
214   }
215   void MakeFloat() {
216     assert(isUninit() && "Bad state change");
217     new ((void*)(char*)Data) APFloat(0.0);
218     Kind = Float;
219   }
220   void MakeVector() {
221     assert(isUninit() && "Bad state change");
222     new ((void*)(char*)Data) Vec();
223     Kind = Vector;
224   }
225   void MakeComplexInt() {
226     assert(isUninit() && "Bad state change");
227     new ((void*)(char*)Data) ComplexAPSInt();
228     Kind = ComplexInt;
229   }
230   void MakeComplexFloat() {
231     assert(isUninit() && "Bad state change");
232     new ((void*)(char*)Data) ComplexAPFloat();
233     Kind = ComplexFloat;
234   }
235   void MakeLValue();
236 };
237
238 inline raw_ostream &operator<<(raw_ostream &OS, const APValue &V) {
239   V.print(OS);
240   return OS;
241 }
242
243 // Writes a concise representation of V to DB, in a single << operation.
244 const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
245                                     const APValue &V);
246
247 } // end namespace clang.
248
249 #endif