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