1 //===--- APValue.h - Union class for APFloat/APSInt/Complex -----*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the APValue class.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_AST_APVALUE_H
15 #define LLVM_CLANG_AST_APVALUE_H
17 #include "llvm/ADT/APSInt.h"
18 #include "llvm/ADT/APFloat.h"
24 /// APValue - This class implements a discriminated union of [uninitialized]
25 /// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset].
27 typedef llvm::APSInt APSInt;
28 typedef llvm::APFloat APFloat;
42 struct ComplexAPSInt {
44 ComplexAPSInt() : Real(1), Imag(1) {}
46 struct ComplexAPFloat {
48 ComplexAPFloat() : Real(0.0), Imag(0.0) {}
54 Vec() : Elts(0), NumElts(0) {}
55 ~Vec() { delete[] Elts; }
59 MaxSize = (sizeof(ComplexAPSInt) > sizeof(ComplexAPFloat) ?
60 sizeof(ComplexAPSInt) : sizeof(ComplexAPFloat))
69 APValue() : Kind(Uninitialized) {}
70 explicit APValue(const APSInt &I) : Kind(Uninitialized) {
73 explicit APValue(const APFloat &F) : Kind(Uninitialized) {
74 MakeFloat(); setFloat(F);
76 explicit APValue(const APValue *E, unsigned N) : Kind(Uninitialized) {
77 MakeVector(); setVector(E, N);
79 APValue(const APSInt &R, const APSInt &I) : Kind(Uninitialized) {
80 MakeComplexInt(); setComplexInt(R, I);
82 APValue(const APFloat &R, const APFloat &I) : Kind(Uninitialized) {
83 MakeComplexFloat(); setComplexFloat(R, I);
85 APValue(const APValue &RHS) : Kind(Uninitialized) {
88 APValue(const Expr* B, const CharUnits &O) : Kind(Uninitialized) {
89 MakeLValue(); setLValue(B, O);
91 APValue(const Expr* B);
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; }
106 void print(llvm::raw_ostream &OS) const;
110 assert(isInt() && "Invalid accessor");
111 return *(APSInt*)(char*)Data;
113 const APSInt &getInt() const {
114 return const_cast<APValue*>(this)->getInt();
117 APFloat &getFloat() {
118 assert(isFloat() && "Invalid accessor");
119 return *(APFloat*)(char*)Data;
121 const APFloat &getFloat() const {
122 return const_cast<APValue*>(this)->getFloat();
125 APValue &getVectorElt(unsigned i) {
126 assert(isVector() && "Invalid accessor");
127 return ((Vec*)(char*)Data)->Elts[i];
129 const APValue &getVectorElt(unsigned i) const {
130 assert(isVector() && "Invalid accessor");
131 return ((const Vec*)(const char*)Data)->Elts[i];
133 unsigned getVectorLength() const {
134 assert(isVector() && "Invalid accessor");
135 return ((const Vec*)(const void *)Data)->NumElts;
138 APSInt &getComplexIntReal() {
139 assert(isComplexInt() && "Invalid accessor");
140 return ((ComplexAPSInt*)(char*)Data)->Real;
142 const APSInt &getComplexIntReal() const {
143 return const_cast<APValue*>(this)->getComplexIntReal();
146 APSInt &getComplexIntImag() {
147 assert(isComplexInt() && "Invalid accessor");
148 return ((ComplexAPSInt*)(char*)Data)->Imag;
150 const APSInt &getComplexIntImag() const {
151 return const_cast<APValue*>(this)->getComplexIntImag();
154 APFloat &getComplexFloatReal() {
155 assert(isComplexFloat() && "Invalid accessor");
156 return ((ComplexAPFloat*)(char*)Data)->Real;
158 const APFloat &getComplexFloatReal() const {
159 return const_cast<APValue*>(this)->getComplexFloatReal();
162 APFloat &getComplexFloatImag() {
163 assert(isComplexFloat() && "Invalid accessor");
164 return ((ComplexAPFloat*)(char*)Data)->Imag;
166 const APFloat &getComplexFloatImag() const {
167 return const_cast<APValue*>(this)->getComplexFloatImag();
170 const Expr* getLValueBase() const;
171 CharUnits getLValueOffset() const;
173 void setInt(const APSInt &I) {
174 assert(isInt() && "Invalid accessor");
175 *(APSInt*)(char*)Data = I;
177 void setFloat(const APFloat &F) {
178 assert(isFloat() && "Invalid accessor");
179 *(APFloat*)(char*)Data = F;
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];
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;
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;
202 void setLValue(const Expr *B, const CharUnits &O);
204 const APValue &operator=(const APValue &RHS);
209 assert(isUninit() && "Bad state change");
210 new ((void*)Data) APSInt(1);
214 assert(isUninit() && "Bad state change");
215 new ((void*)(char*)Data) APFloat(0.0);
219 assert(isUninit() && "Bad state change");
220 new ((void*)(char*)Data) Vec();
223 void MakeComplexInt() {
224 assert(isUninit() && "Bad state change");
225 new ((void*)(char*)Data) ComplexAPSInt();
228 void MakeComplexFloat() {
229 assert(isUninit() && "Bad state change");
230 new ((void*)(char*)Data) ComplexAPFloat();
236 inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const APValue &V) {
241 } // end namespace clang.