APValue.h revision 08d6e032a2a0a8656d12b3b7b93942987bb12eb7
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 "clang/Basic/LLVM.h" 18#include "llvm/ADT/APSInt.h" 19#include "llvm/ADT/APFloat.h" 20#include "llvm/ADT/PointerIntPair.h" 21#include "llvm/ADT/PointerUnion.h" 22 23namespace clang { 24 class ASTContext; 25 class CharUnits; 26 class DiagnosticBuilder; 27 class Expr; 28 class FieldDecl; 29 class Decl; 30 class ValueDecl; 31 class CXXRecordDecl; 32 class QualType; 33 34/// APValue - This class implements a discriminated union of [uninitialized] 35/// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset], 36/// [Vector: N * APValue], [Array: N * APValue] 37class APValue { 38 typedef llvm::APSInt APSInt; 39 typedef llvm::APFloat APFloat; 40public: 41 enum ValueKind { 42 Uninitialized, 43 Int, 44 Float, 45 ComplexInt, 46 ComplexFloat, 47 LValue, 48 Vector, 49 Array, 50 Struct, 51 Union, 52 MemberPointer 53 }; 54 typedef llvm::PointerUnion<const ValueDecl *, const Expr *> LValueBase; 55 typedef llvm::PointerIntPair<const Decl *, 1, bool> BaseOrMemberType; 56 union LValuePathEntry { 57 /// BaseOrMember - The FieldDecl or CXXRecordDecl indicating the next item 58 /// in the path. An opaque value of type BaseOrMemberType. 59 void *BaseOrMember; 60 /// ArrayIndex - The array index of the next item in the path. 61 uint64_t ArrayIndex; 62 }; 63 struct NoLValuePath {}; 64 struct UninitArray {}; 65 struct UninitStruct {}; 66private: 67 ValueKind Kind; 68 69 struct ComplexAPSInt { 70 APSInt Real, Imag; 71 ComplexAPSInt() : Real(1), Imag(1) {} 72 }; 73 struct ComplexAPFloat { 74 APFloat Real, Imag; 75 ComplexAPFloat() : Real(0.0), Imag(0.0) {} 76 }; 77 struct LV; 78 struct Vec { 79 APValue *Elts; 80 unsigned NumElts; 81 Vec() : Elts(0), NumElts(0) {} 82 ~Vec() { delete[] Elts; } 83 }; 84 struct Arr { 85 APValue *Elts; 86 unsigned NumElts, ArrSize; 87 Arr(unsigned NumElts, unsigned ArrSize); 88 ~Arr(); 89 }; 90 struct StructData { 91 APValue *Elts; 92 unsigned NumBases; 93 unsigned NumFields; 94 StructData(unsigned NumBases, unsigned NumFields); 95 ~StructData(); 96 }; 97 struct UnionData { 98 const FieldDecl *Field; 99 APValue *Value; 100 UnionData(); 101 ~UnionData(); 102 }; 103 struct MemberPointerData; 104 105 enum { 106 MaxSize = (sizeof(ComplexAPSInt) > sizeof(ComplexAPFloat) ? 107 sizeof(ComplexAPSInt) : sizeof(ComplexAPFloat)) 108 }; 109 110 union { 111 void *Aligner; 112 char Data[MaxSize]; 113 }; 114 115public: 116 APValue() : Kind(Uninitialized) {} 117 explicit APValue(const APSInt &I) : Kind(Uninitialized) { 118 MakeInt(); setInt(I); 119 } 120 explicit APValue(const APFloat &F) : Kind(Uninitialized) { 121 MakeFloat(); setFloat(F); 122 } 123 explicit APValue(const APValue *E, unsigned N) : Kind(Uninitialized) { 124 MakeVector(); setVector(E, N); 125 } 126 APValue(const APSInt &R, const APSInt &I) : Kind(Uninitialized) { 127 MakeComplexInt(); setComplexInt(R, I); 128 } 129 APValue(const APFloat &R, const APFloat &I) : Kind(Uninitialized) { 130 MakeComplexFloat(); setComplexFloat(R, I); 131 } 132 APValue(const APValue &RHS) : Kind(Uninitialized) { 133 *this = RHS; 134 } 135 APValue(LValueBase B, const CharUnits &O, NoLValuePath N) 136 : Kind(Uninitialized) { 137 MakeLValue(); setLValue(B, O, N); 138 } 139 APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path, 140 bool OnePastTheEnd) 141 : Kind(Uninitialized) { 142 MakeLValue(); setLValue(B, O, Path, OnePastTheEnd); 143 } 144 APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(Uninitialized) { 145 MakeArray(InitElts, Size); 146 } 147 APValue(UninitStruct, unsigned B, unsigned M) : Kind(Uninitialized) { 148 MakeStruct(B, M); 149 } 150 explicit APValue(const FieldDecl *D, const APValue &V = APValue()) 151 : Kind(Uninitialized) { 152 MakeUnion(); setUnion(D, V); 153 } 154 APValue(const ValueDecl *Member, bool IsDerivedMember, 155 ArrayRef<const CXXRecordDecl*> Path) : Kind(Uninitialized) { 156 MakeMemberPointer(Member, IsDerivedMember, Path); 157 } 158 159 ~APValue() { 160 MakeUninit(); 161 } 162 163 ValueKind getKind() const { return Kind; } 164 bool isUninit() const { return Kind == Uninitialized; } 165 bool isInt() const { return Kind == Int; } 166 bool isFloat() const { return Kind == Float; } 167 bool isComplexInt() const { return Kind == ComplexInt; } 168 bool isComplexFloat() const { return Kind == ComplexFloat; } 169 bool isLValue() const { return Kind == LValue; } 170 bool isVector() const { return Kind == Vector; } 171 bool isArray() const { return Kind == Array; } 172 bool isStruct() const { return Kind == Struct; } 173 bool isUnion() const { return Kind == Union; } 174 bool isMemberPointer() const { return Kind == MemberPointer; } 175 176 void dump() const; 177 void dump(raw_ostream &OS) const; 178 179 void printPretty(raw_ostream &OS, ASTContext &Ctx, QualType Ty) const; 180 std::string getAsString(ASTContext &Ctx, QualType Ty) const; 181 182 APSInt &getInt() { 183 assert(isInt() && "Invalid accessor"); 184 return *(APSInt*)(char*)Data; 185 } 186 const APSInt &getInt() const { 187 return const_cast<APValue*>(this)->getInt(); 188 } 189 190 APFloat &getFloat() { 191 assert(isFloat() && "Invalid accessor"); 192 return *(APFloat*)(char*)Data; 193 } 194 const APFloat &getFloat() const { 195 return const_cast<APValue*>(this)->getFloat(); 196 } 197 198 APSInt &getComplexIntReal() { 199 assert(isComplexInt() && "Invalid accessor"); 200 return ((ComplexAPSInt*)(char*)Data)->Real; 201 } 202 const APSInt &getComplexIntReal() const { 203 return const_cast<APValue*>(this)->getComplexIntReal(); 204 } 205 206 APSInt &getComplexIntImag() { 207 assert(isComplexInt() && "Invalid accessor"); 208 return ((ComplexAPSInt*)(char*)Data)->Imag; 209 } 210 const APSInt &getComplexIntImag() const { 211 return const_cast<APValue*>(this)->getComplexIntImag(); 212 } 213 214 APFloat &getComplexFloatReal() { 215 assert(isComplexFloat() && "Invalid accessor"); 216 return ((ComplexAPFloat*)(char*)Data)->Real; 217 } 218 const APFloat &getComplexFloatReal() const { 219 return const_cast<APValue*>(this)->getComplexFloatReal(); 220 } 221 222 APFloat &getComplexFloatImag() { 223 assert(isComplexFloat() && "Invalid accessor"); 224 return ((ComplexAPFloat*)(char*)Data)->Imag; 225 } 226 const APFloat &getComplexFloatImag() const { 227 return const_cast<APValue*>(this)->getComplexFloatImag(); 228 } 229 230 const LValueBase getLValueBase() const; 231 CharUnits &getLValueOffset(); 232 const CharUnits &getLValueOffset() const { 233 return const_cast<APValue*>(this)->getLValueOffset(); 234 } 235 bool isLValueOnePastTheEnd() const; 236 bool hasLValuePath() const; 237 ArrayRef<LValuePathEntry> getLValuePath() const; 238 239 APValue &getVectorElt(unsigned I) { 240 assert(isVector() && "Invalid accessor"); 241 assert(I < getVectorLength() && "Index out of range"); 242 return ((Vec*)(char*)Data)->Elts[I]; 243 } 244 const APValue &getVectorElt(unsigned I) const { 245 return const_cast<APValue*>(this)->getVectorElt(I); 246 } 247 unsigned getVectorLength() const { 248 assert(isVector() && "Invalid accessor"); 249 return ((const Vec*)(const void *)Data)->NumElts; 250 } 251 252 APValue &getArrayInitializedElt(unsigned I) { 253 assert(isArray() && "Invalid accessor"); 254 assert(I < getArrayInitializedElts() && "Index out of range"); 255 return ((Arr*)(char*)Data)->Elts[I]; 256 } 257 const APValue &getArrayInitializedElt(unsigned I) const { 258 return const_cast<APValue*>(this)->getArrayInitializedElt(I); 259 } 260 bool hasArrayFiller() const { 261 return getArrayInitializedElts() != getArraySize(); 262 } 263 APValue &getArrayFiller() { 264 assert(isArray() && "Invalid accessor"); 265 assert(hasArrayFiller() && "No array filler"); 266 return ((Arr*)(char*)Data)->Elts[getArrayInitializedElts()]; 267 } 268 const APValue &getArrayFiller() const { 269 return const_cast<APValue*>(this)->getArrayFiller(); 270 } 271 unsigned getArrayInitializedElts() const { 272 assert(isArray() && "Invalid accessor"); 273 return ((const Arr*)(const void *)Data)->NumElts; 274 } 275 unsigned getArraySize() const { 276 assert(isArray() && "Invalid accessor"); 277 return ((const Arr*)(const void *)Data)->ArrSize; 278 } 279 280 unsigned getStructNumBases() const { 281 assert(isStruct() && "Invalid accessor"); 282 return ((const StructData*)(const char*)Data)->NumBases; 283 } 284 unsigned getStructNumFields() const { 285 assert(isStruct() && "Invalid accessor"); 286 return ((const StructData*)(const char*)Data)->NumFields; 287 } 288 APValue &getStructBase(unsigned i) { 289 assert(isStruct() && "Invalid accessor"); 290 return ((StructData*)(char*)Data)->Elts[i]; 291 } 292 APValue &getStructField(unsigned i) { 293 assert(isStruct() && "Invalid accessor"); 294 return ((StructData*)(char*)Data)->Elts[getStructNumBases() + i]; 295 } 296 const APValue &getStructBase(unsigned i) const { 297 return const_cast<APValue*>(this)->getStructBase(i); 298 } 299 const APValue &getStructField(unsigned i) const { 300 return const_cast<APValue*>(this)->getStructField(i); 301 } 302 303 const FieldDecl *getUnionField() const { 304 assert(isUnion() && "Invalid accessor"); 305 return ((const UnionData*)(const char*)Data)->Field; 306 } 307 APValue &getUnionValue() { 308 assert(isUnion() && "Invalid accessor"); 309 return *((UnionData*)(char*)Data)->Value; 310 } 311 const APValue &getUnionValue() const { 312 return const_cast<APValue*>(this)->getUnionValue(); 313 } 314 315 const ValueDecl *getMemberPointerDecl() const; 316 bool isMemberPointerToDerivedMember() const; 317 ArrayRef<const CXXRecordDecl*> getMemberPointerPath() const; 318 319 void setInt(const APSInt &I) { 320 assert(isInt() && "Invalid accessor"); 321 *(APSInt*)(char*)Data = I; 322 } 323 void setFloat(const APFloat &F) { 324 assert(isFloat() && "Invalid accessor"); 325 *(APFloat*)(char*)Data = F; 326 } 327 void setVector(const APValue *E, unsigned N) { 328 assert(isVector() && "Invalid accessor"); 329 ((Vec*)(char*)Data)->Elts = new APValue[N]; 330 ((Vec*)(char*)Data)->NumElts = N; 331 for (unsigned i = 0; i != N; ++i) 332 ((Vec*)(char*)Data)->Elts[i] = E[i]; 333 } 334 void setComplexInt(const APSInt &R, const APSInt &I) { 335 assert(R.getBitWidth() == I.getBitWidth() && 336 "Invalid complex int (type mismatch)."); 337 assert(isComplexInt() && "Invalid accessor"); 338 ((ComplexAPSInt*)(char*)Data)->Real = R; 339 ((ComplexAPSInt*)(char*)Data)->Imag = I; 340 } 341 void setComplexFloat(const APFloat &R, const APFloat &I) { 342 assert(&R.getSemantics() == &I.getSemantics() && 343 "Invalid complex float (type mismatch)."); 344 assert(isComplexFloat() && "Invalid accessor"); 345 ((ComplexAPFloat*)(char*)Data)->Real = R; 346 ((ComplexAPFloat*)(char*)Data)->Imag = I; 347 } 348 void setLValue(LValueBase B, const CharUnits &O, NoLValuePath); 349 void setLValue(LValueBase B, const CharUnits &O, 350 ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd); 351 void setUnion(const FieldDecl *Field, const APValue &Value) { 352 assert(isUnion() && "Invalid accessor"); 353 ((UnionData*)(char*)Data)->Field = Field; 354 *((UnionData*)(char*)Data)->Value = Value; 355 } 356 357 const APValue &operator=(const APValue &RHS); 358 359private: 360 void MakeUninit(); 361 void MakeInt() { 362 assert(isUninit() && "Bad state change"); 363 new ((void*)Data) APSInt(1); 364 Kind = Int; 365 } 366 void MakeFloat() { 367 assert(isUninit() && "Bad state change"); 368 new ((void*)(char*)Data) APFloat(0.0); 369 Kind = Float; 370 } 371 void MakeVector() { 372 assert(isUninit() && "Bad state change"); 373 new ((void*)(char*)Data) Vec(); 374 Kind = Vector; 375 } 376 void MakeComplexInt() { 377 assert(isUninit() && "Bad state change"); 378 new ((void*)(char*)Data) ComplexAPSInt(); 379 Kind = ComplexInt; 380 } 381 void MakeComplexFloat() { 382 assert(isUninit() && "Bad state change"); 383 new ((void*)(char*)Data) ComplexAPFloat(); 384 Kind = ComplexFloat; 385 } 386 void MakeLValue(); 387 void MakeArray(unsigned InitElts, unsigned Size); 388 void MakeStruct(unsigned B, unsigned M) { 389 assert(isUninit() && "Bad state change"); 390 new ((void*)(char*)Data) StructData(B, M); 391 Kind = Struct; 392 } 393 void MakeUnion() { 394 assert(isUninit() && "Bad state change"); 395 new ((void*)(char*)Data) UnionData(); 396 Kind = Union; 397 } 398 void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember, 399 ArrayRef<const CXXRecordDecl*> Path); 400}; 401 402} // end namespace clang. 403 404#endif 405