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 "clang/Basic/LLVM.h"
18 #include "llvm/ADT/APSInt.h"
19 #include "llvm/ADT/APFloat.h"
23 class DiagnosticBuilder;
26 /// APValue - This class implements a discriminated union of [uninitialized]
27 /// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset].
29 typedef llvm::APSInt APSInt;
30 typedef llvm::APFloat APFloat;
44 struct ComplexAPSInt {
46 ComplexAPSInt() : Real(1), Imag(1) {}
48 struct ComplexAPFloat {
50 ComplexAPFloat() : Real(0.0), Imag(0.0) {}
56 Vec() : Elts(0), NumElts(0) {}
57 ~Vec() { delete[] Elts; }
61 MaxSize = (sizeof(ComplexAPSInt) > sizeof(ComplexAPFloat) ?
62 sizeof(ComplexAPSInt) : sizeof(ComplexAPFloat))
71 APValue() : Kind(Uninitialized) {}
72 explicit APValue(const APSInt &I) : Kind(Uninitialized) {
75 explicit APValue(const APFloat &F) : Kind(Uninitialized) {
76 MakeFloat(); setFloat(F);
78 explicit APValue(const APValue *E, unsigned N) : Kind(Uninitialized) {
79 MakeVector(); setVector(E, N);
81 APValue(const APSInt &R, const APSInt &I) : Kind(Uninitialized) {
82 MakeComplexInt(); setComplexInt(R, I);
84 APValue(const APFloat &R, const APFloat &I) : Kind(Uninitialized) {
85 MakeComplexFloat(); setComplexFloat(R, I);
87 APValue(const APValue &RHS) : Kind(Uninitialized) {
90 APValue(const Expr* B, const CharUnits &O) : Kind(Uninitialized) {
91 MakeLValue(); setLValue(B, O);
93 APValue(const Expr* B);
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; }
108 void print(raw_ostream &OS) const;
112 assert(isInt() && "Invalid accessor");
113 return *(APSInt*)(char*)Data;
115 const APSInt &getInt() const {
116 return const_cast<APValue*>(this)->getInt();
119 APFloat &getFloat() {
120 assert(isFloat() && "Invalid accessor");
121 return *(APFloat*)(char*)Data;
123 const APFloat &getFloat() const {
124 return const_cast<APValue*>(this)->getFloat();
127 APValue &getVectorElt(unsigned i) {
128 assert(isVector() && "Invalid accessor");
129 return ((Vec*)(char*)Data)->Elts[i];
131 const APValue &getVectorElt(unsigned i) const {
132 assert(isVector() && "Invalid accessor");
133 return ((const Vec*)(const char*)Data)->Elts[i];
135 unsigned getVectorLength() const {
136 assert(isVector() && "Invalid accessor");
137 return ((const Vec*)(const void *)Data)->NumElts;
140 APSInt &getComplexIntReal() {
141 assert(isComplexInt() && "Invalid accessor");
142 return ((ComplexAPSInt*)(char*)Data)->Real;
144 const APSInt &getComplexIntReal() const {
145 return const_cast<APValue*>(this)->getComplexIntReal();
148 APSInt &getComplexIntImag() {
149 assert(isComplexInt() && "Invalid accessor");
150 return ((ComplexAPSInt*)(char*)Data)->Imag;
152 const APSInt &getComplexIntImag() const {
153 return const_cast<APValue*>(this)->getComplexIntImag();
156 APFloat &getComplexFloatReal() {
157 assert(isComplexFloat() && "Invalid accessor");
158 return ((ComplexAPFloat*)(char*)Data)->Real;
160 const APFloat &getComplexFloatReal() const {
161 return const_cast<APValue*>(this)->getComplexFloatReal();
164 APFloat &getComplexFloatImag() {
165 assert(isComplexFloat() && "Invalid accessor");
166 return ((ComplexAPFloat*)(char*)Data)->Imag;
168 const APFloat &getComplexFloatImag() const {
169 return const_cast<APValue*>(this)->getComplexFloatImag();
172 const Expr* getLValueBase() const;
173 CharUnits getLValueOffset() const;
175 void setInt(const APSInt &I) {
176 assert(isInt() && "Invalid accessor");
177 *(APSInt*)(char*)Data = I;
179 void setFloat(const APFloat &F) {
180 assert(isFloat() && "Invalid accessor");
181 *(APFloat*)(char*)Data = F;
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];
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;
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;
204 void setLValue(const Expr *B, const CharUnits &O);
206 const APValue &operator=(const APValue &RHS);
211 assert(isUninit() && "Bad state change");
212 new ((void*)Data) APSInt(1);
216 assert(isUninit() && "Bad state change");
217 new ((void*)(char*)Data) APFloat(0.0);
221 assert(isUninit() && "Bad state change");
222 new ((void*)(char*)Data) Vec();
225 void MakeComplexInt() {
226 assert(isUninit() && "Bad state change");
227 new ((void*)(char*)Data) ComplexAPSInt();
230 void MakeComplexFloat() {
231 assert(isUninit() && "Bad state change");
232 new ((void*)(char*)Data) ComplexAPFloat();
238 inline raw_ostream &operator<<(raw_ostream &OS, const APValue &V) {
243 // Writes a concise representation of V to DB, in a single << operation.
244 const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
247 } // end namespace clang.