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