APValue.h revision 64c34f1c6f613eef02a7b488f8edadbe7a8650a8
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 }; 37private: 38 ValueKind Kind; 39 40 struct ComplexAPSInt { 41 APSInt Real, Imag; 42 ComplexAPSInt() : Real(1), Imag(1) {} 43 }; 44 struct ComplexAPFloat { 45 APFloat Real, Imag; 46 ComplexAPFloat() : Real(0.0), Imag(0.0) {} 47 }; 48 49 struct LV { 50 Expr* Base; 51 uint64_t Offset; 52 }; 53 54 enum { 55 MaxSize = (sizeof(ComplexAPSInt) > sizeof(ComplexAPFloat) ? 56 sizeof(ComplexAPSInt) : sizeof(ComplexAPFloat)) 57 }; 58 59 /// Data - space for the largest member in units of void*. This is an effort 60 /// to ensure that the APSInt/APFloat values have proper alignment. 61 void *Data[(MaxSize+sizeof(void*)-1)/sizeof(void*)]; 62 63public: 64 APValue() : Kind(Uninitialized) {} 65 explicit APValue(const APSInt &I) : Kind(Uninitialized) { 66 MakeInt(); setInt(I); 67 } 68 explicit APValue(const APFloat &F) : Kind(Uninitialized) { 69 MakeFloat(); setFloat(F); 70 } 71 APValue(const APSInt &R, const APSInt &I) : Kind(Uninitialized) { 72 MakeComplexInt(); setComplexInt(R, I); 73 } 74 APValue(const APFloat &R, const APFloat &I) : Kind(Uninitialized) { 75 MakeComplexFloat(); setComplexFloat(R, I); 76 } 77 APValue(const APValue &RHS) : Kind(Uninitialized) { 78 *this = RHS; 79 } 80 APValue(Expr* B, uint64_t O) : Kind(Uninitialized) { 81 MakeLValue(); setLValue(B, O); 82 } 83 ~APValue() { 84 MakeUninit(); 85 } 86 87 ValueKind getKind() const { return Kind; } 88 bool isUninit() const { return Kind == Uninitialized; } 89 bool isInt() const { return Kind == Int; } 90 bool isFloat() const { return Kind == Float; } 91 bool isComplexInt() const { return Kind == ComplexInt; } 92 bool isComplexFloat() const { return Kind == ComplexFloat; } 93 bool isLValue() const { return Kind == LValue; } 94 95 void print(llvm::raw_ostream &OS) const; 96 void dump() const; 97 98 APSInt &getInt() { 99 assert(isInt() && "Invalid accessor"); 100 return *(APSInt*)(void*)Data; 101 } 102 const APSInt &getInt() const { 103 return const_cast<APValue*>(this)->getInt(); 104 } 105 106 APFloat &getFloat() { 107 assert(isFloat() && "Invalid accessor"); 108 return *(APFloat*)(void*)Data; 109 } 110 const APFloat &getFloat() const { 111 return const_cast<APValue*>(this)->getFloat(); 112 } 113 114 APSInt &getComplexIntReal() { 115 assert(isComplexInt() && "Invalid accessor"); 116 return ((ComplexAPSInt*)(void*)Data)->Real; 117 } 118 const APSInt &getComplexIntReal() const { 119 return const_cast<APValue*>(this)->getComplexIntReal(); 120 } 121 122 APSInt &getComplexIntImag() { 123 assert(isComplexInt() && "Invalid accessor"); 124 return ((ComplexAPSInt*)(void*)Data)->Imag; 125 } 126 const APSInt &getComplexIntImag() const { 127 return const_cast<APValue*>(this)->getComplexIntImag(); 128 } 129 130 APFloat &getComplexFloatReal() { 131 assert(isComplexFloat() && "Invalid accessor"); 132 return ((ComplexAPFloat*)(void*)Data)->Real; 133 } 134 const APFloat &getComplexFloatReal() const { 135 return const_cast<APValue*>(this)->getComplexFloatReal(); 136 } 137 138 APFloat &getComplexFloatImag() { 139 assert(isComplexFloat() && "Invalid accessor"); 140 return ((ComplexAPFloat*)(void*)Data)->Imag; 141 } 142 const APFloat &getComplexFloatImag() const { 143 return const_cast<APValue*>(this)->getComplexFloatImag(); 144 } 145 146 Expr* getLValueBase() const { 147 assert(isLValue() && "Invalid accessor"); 148 return ((const LV*)(const void*)Data)->Base; 149 } 150 uint64_t getLValueOffset() const { 151 assert(isLValue() && "Invalid accessor"); 152 return ((const LV*)(const void*)Data)->Offset; 153 } 154 155 void setInt(const APSInt &I) { 156 assert(isInt() && "Invalid accessor"); 157 *(APSInt*)(void*)Data = I; 158 } 159 void setFloat(const APFloat &F) { 160 assert(isFloat() && "Invalid accessor"); 161 *(APFloat*)(void*)Data = F; 162 } 163 void setComplexInt(const APSInt &R, const APSInt &I) { 164 assert(isComplexInt() && "Invalid accessor"); 165 ((ComplexAPSInt*)(void*)Data)->Real = R; 166 ((ComplexAPSInt*)(void*)Data)->Imag = I; 167 } 168 void setComplexFloat(const APFloat &R, const APFloat &I) { 169 assert(isComplexFloat() && "Invalid accessor"); 170 ((ComplexAPFloat*)(void*)Data)->Real = R; 171 ((ComplexAPFloat*)(void*)Data)->Imag = I; 172 } 173 void setLValue(Expr *B, uint64_t O) { 174 assert(isLValue() && "Invalid accessor"); 175 ((LV*)(void*)Data)->Base = B; 176 ((LV*)(void*)Data)->Offset = O; 177 } 178 179 const APValue &operator=(const APValue &RHS); 180 181private: 182 void MakeUninit(); 183 void MakeInt() { 184 assert(isUninit() && "Bad state change"); 185 new ((void*)Data) APSInt(1); 186 Kind = Int; 187 } 188 void MakeFloat() { 189 assert(isUninit() && "Bad state change"); 190 new ((APFloat*)(void*)Data) APFloat(0.0); 191 Kind = Float; 192 } 193 void MakeComplexInt() { 194 assert(isUninit() && "Bad state change"); 195 new ((ComplexAPSInt*)(void*)Data) ComplexAPSInt(); 196 Kind = ComplexInt; 197 } 198 void MakeComplexFloat() { 199 assert(isUninit() && "Bad state change"); 200 new ((ComplexAPFloat*)(void*)Data) ComplexAPFloat(); 201 Kind = ComplexFloat; 202 } 203 void MakeLValue() { 204 assert(isUninit() && "Bad state change"); 205 new ((LV*)(void*)Data) LV(); 206 Kind = LValue; 207 } 208}; 209 210inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const APValue &V) { 211 V.print(OS); 212 return OS; 213} 214 215} // end namespace clang. 216 217#endif 218