APValue.h revision 8f826f0e0c90b05ab04e84c29157d2e965713288
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
20namespace clang {
21  class Expr;
22
23/// APValue - This class implements a discriminated union of [uninitialized]
24/// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset].
25class APValue {
26  typedef llvm::APSInt APSInt;
27  typedef llvm::APFloat APFloat;
28public:
29  enum ValueKind {
30    Uninitialized,
31    Int,
32    Float,
33    ComplexInt,
34    ComplexFloat,
35    LValue,
36    Vector
37  };
38private:
39  ValueKind Kind;
40
41  struct ComplexAPSInt {
42    APSInt Real, Imag;
43    ComplexAPSInt() : Real(1), Imag(1) {}
44  };
45  struct ComplexAPFloat {
46    APFloat Real, Imag;
47    ComplexAPFloat() : Real(0.0), Imag(0.0) {}
48  };
49
50  struct LV {
51    Expr* Base;
52    uint64_t Offset;
53  };
54  struct Vec {
55    APValue *Elts;
56    unsigned NumElts;
57    Vec() : Elts(0), NumElts(0) {}
58    ~Vec() { delete[] Elts; }
59  };
60
61  enum {
62    MaxSize = (sizeof(ComplexAPSInt) > sizeof(ComplexAPFloat) ?
63               sizeof(ComplexAPSInt) : sizeof(ComplexAPFloat))
64  };
65
66  /// Data - space for the largest member in units of void*.  This is an effort
67  /// to ensure that the APSInt/APFloat values have proper alignment.
68  void *Data[(MaxSize+sizeof(void*)-1)/sizeof(void*)];
69
70public:
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(Expr* B, uint64_t O) : Kind(Uninitialized) {
91    MakeLValue(); setLValue(B, O);
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*)(void*)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*)(void*)Data;
120  }
121  const APFloat &getFloat() const {
122    return const_cast<APValue*>(this)->getFloat();
123  }
124
125  APValue &getVectorElt(unsigned i) const {
126    assert(isVector() && "Invalid accessor");
127    return ((Vec*)(void*)Data)->Elts[i];
128  }
129  unsigned getVectorLength() const {
130    assert(isVector() && "Invalid accessor");
131    return ((Vec*)(void *)Data)->NumElts;
132  }
133
134  APSInt &getComplexIntReal() {
135    assert(isComplexInt() && "Invalid accessor");
136    return ((ComplexAPSInt*)(void*)Data)->Real;
137  }
138  const APSInt &getComplexIntReal() const {
139    return const_cast<APValue*>(this)->getComplexIntReal();
140  }
141
142  APSInt &getComplexIntImag() {
143    assert(isComplexInt() && "Invalid accessor");
144    return ((ComplexAPSInt*)(void*)Data)->Imag;
145  }
146  const APSInt &getComplexIntImag() const {
147    return const_cast<APValue*>(this)->getComplexIntImag();
148  }
149
150  APFloat &getComplexFloatReal() {
151    assert(isComplexFloat() && "Invalid accessor");
152    return ((ComplexAPFloat*)(void*)Data)->Real;
153  }
154  const APFloat &getComplexFloatReal() const {
155    return const_cast<APValue*>(this)->getComplexFloatReal();
156  }
157
158  APFloat &getComplexFloatImag() {
159    assert(isComplexFloat() && "Invalid accessor");
160    return ((ComplexAPFloat*)(void*)Data)->Imag;
161  }
162  const APFloat &getComplexFloatImag() const {
163    return const_cast<APValue*>(this)->getComplexFloatImag();
164  }
165
166  Expr* getLValueBase() const {
167    assert(isLValue() && "Invalid accessor");
168    return ((const LV*)(const void*)Data)->Base;
169  }
170  uint64_t getLValueOffset() const {
171    assert(isLValue() && "Invalid accessor");
172    return ((const LV*)(const void*)Data)->Offset;
173  }
174
175  void setInt(const APSInt &I) {
176    assert(isInt() && "Invalid accessor");
177    *(APSInt*)(void*)Data = I;
178  }
179  void setFloat(const APFloat &F) {
180    assert(isFloat() && "Invalid accessor");
181    *(APFloat*)(void*)Data = F;
182  }
183  void setVector(const APValue *E, unsigned N) {
184    assert(isVector() && "Invalid accessor");
185    ((Vec*)(void*)Data)->Elts = new APValue[N];
186    ((Vec*)(void*)Data)->NumElts = N;
187    for (unsigned i = 0; i != N; ++i)
188      ((Vec*)(void*)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*)(void*)Data)->Real = R;
195    ((ComplexAPSInt*)(void*)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*)(void*)Data)->Real = R;
202    ((ComplexAPFloat*)(void*)Data)->Imag = I;
203  }
204  void setLValue(Expr *B, uint64_t O) {
205    assert(isLValue() && "Invalid accessor");
206    ((LV*)(void*)Data)->Base = B;
207    ((LV*)(void*)Data)->Offset = O;
208  }
209
210  const APValue &operator=(const APValue &RHS);
211
212private:
213  void MakeUninit();
214  void MakeInt() {
215    assert(isUninit() && "Bad state change");
216    new ((void*)Data) APSInt(1);
217    Kind = Int;
218  }
219  void MakeFloat() {
220    assert(isUninit() && "Bad state change");
221    new ((APFloat*)(void*)Data) APFloat(0.0);
222    Kind = Float;
223  }
224  void MakeVector() {
225    assert(isUninit() && "Bad state change");
226    new ((Vec*)(void*)Data) Vec();
227    Kind = Vector;
228  }
229  void MakeComplexInt() {
230    assert(isUninit() && "Bad state change");
231    new ((ComplexAPSInt*)(void*)Data) ComplexAPSInt();
232    Kind = ComplexInt;
233  }
234  void MakeComplexFloat() {
235    assert(isUninit() && "Bad state change");
236    new ((ComplexAPFloat*)(void*)Data) ComplexAPFloat();
237    Kind = ComplexFloat;
238  }
239  void MakeLValue() {
240    assert(isUninit() && "Bad state change");
241    new ((LV*)(void*)Data) LV();
242    Kind = LValue;
243  }
244};
245
246inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const APValue &V) {
247  V.print(OS);
248  return OS;
249}
250
251} // end namespace clang.
252
253#endif
254