1 //===--- APValue.h - Union class for APFloat/APSInt/Complex -----*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines the APValue class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_CLANG_AST_APVALUE_H 14 #define LLVM_CLANG_AST_APVALUE_H 15 16 #include "clang/Basic/LLVM.h" 17 #include "llvm/ADT/APFixedPoint.h" 18 #include "llvm/ADT/APFloat.h" 19 #include "llvm/ADT/APSInt.h" 20 #include "llvm/ADT/FoldingSet.h" 21 #include "llvm/ADT/PointerIntPair.h" 22 #include "llvm/ADT/PointerUnion.h" 23 #include "llvm/Support/AlignOf.h" 24 25 namespace clang { 26 namespace serialization { 27 template <typename T> class BasicReaderBase; 28 } // end namespace serialization 29 30 class AddrLabelExpr; 31 class ASTContext; 32 class CharUnits; 33 class CXXRecordDecl; 34 class Decl; 35 class DiagnosticBuilder; 36 class Expr; 37 class FieldDecl; 38 struct PrintingPolicy; 39 class Type; 40 class ValueDecl; 41 class QualType; 42 43 /// Symbolic representation of typeid(T) for some type T. 44 class TypeInfoLValue { 45 const Type *T; 46 47 public: TypeInfoLValue()48 TypeInfoLValue() : T() {} 49 explicit TypeInfoLValue(const Type *T); 50 getType()51 const Type *getType() const { return T; } 52 explicit operator bool() const { return T; } 53 getOpaqueValue()54 void *getOpaqueValue() { return const_cast<Type*>(T); } getFromOpaqueValue(void * Value)55 static TypeInfoLValue getFromOpaqueValue(void *Value) { 56 TypeInfoLValue V; 57 V.T = reinterpret_cast<const Type*>(Value); 58 return V; 59 } 60 61 void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy) const; 62 }; 63 64 /// Symbolic representation of a dynamic allocation. 65 class DynamicAllocLValue { 66 unsigned Index; 67 68 public: DynamicAllocLValue()69 DynamicAllocLValue() : Index(0) {} DynamicAllocLValue(unsigned Index)70 explicit DynamicAllocLValue(unsigned Index) : Index(Index + 1) {} getIndex()71 unsigned getIndex() { return Index - 1; } 72 73 explicit operator bool() const { return Index != 0; } 74 getOpaqueValue()75 void *getOpaqueValue() { 76 return reinterpret_cast<void *>(static_cast<uintptr_t>(Index) 77 << NumLowBitsAvailable); 78 } getFromOpaqueValue(void * Value)79 static DynamicAllocLValue getFromOpaqueValue(void *Value) { 80 DynamicAllocLValue V; 81 V.Index = reinterpret_cast<uintptr_t>(Value) >> NumLowBitsAvailable; 82 return V; 83 } 84 getMaxIndex()85 static unsigned getMaxIndex() { 86 return (std::numeric_limits<unsigned>::max() >> NumLowBitsAvailable) - 1; 87 } 88 89 static constexpr int NumLowBitsAvailable = 3; 90 }; 91 } 92 93 namespace llvm { 94 template<> struct PointerLikeTypeTraits<clang::TypeInfoLValue> { 95 static void *getAsVoidPointer(clang::TypeInfoLValue V) { 96 return V.getOpaqueValue(); 97 } 98 static clang::TypeInfoLValue getFromVoidPointer(void *P) { 99 return clang::TypeInfoLValue::getFromOpaqueValue(P); 100 } 101 // Validated by static_assert in APValue.cpp; hardcoded to avoid needing 102 // to include Type.h. 103 static constexpr int NumLowBitsAvailable = 3; 104 }; 105 106 template<> struct PointerLikeTypeTraits<clang::DynamicAllocLValue> { 107 static void *getAsVoidPointer(clang::DynamicAllocLValue V) { 108 return V.getOpaqueValue(); 109 } 110 static clang::DynamicAllocLValue getFromVoidPointer(void *P) { 111 return clang::DynamicAllocLValue::getFromOpaqueValue(P); 112 } 113 static constexpr int NumLowBitsAvailable = 114 clang::DynamicAllocLValue::NumLowBitsAvailable; 115 }; 116 } 117 118 namespace clang { 119 /// APValue - This class implements a discriminated union of [uninitialized] 120 /// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset], 121 /// [Vector: N * APValue], [Array: N * APValue] 122 class APValue { 123 typedef llvm::APFixedPoint APFixedPoint; 124 typedef llvm::APSInt APSInt; 125 typedef llvm::APFloat APFloat; 126 public: 127 enum ValueKind { 128 /// There is no such object (it's outside its lifetime). 129 None, 130 /// This object has an indeterminate value (C++ [basic.indet]). 131 Indeterminate, 132 Int, 133 Float, 134 FixedPoint, 135 ComplexInt, 136 ComplexFloat, 137 LValue, 138 Vector, 139 Array, 140 Struct, 141 Union, 142 MemberPointer, 143 AddrLabelDiff 144 }; 145 146 class LValueBase { 147 typedef llvm::PointerUnion<const ValueDecl *, const Expr *, TypeInfoLValue, 148 DynamicAllocLValue> 149 PtrTy; 150 151 public: 152 LValueBase() : Local{} {} 153 LValueBase(const ValueDecl *P, unsigned I = 0, unsigned V = 0); 154 LValueBase(const Expr *P, unsigned I = 0, unsigned V = 0); 155 static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type); 156 static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo); 157 158 void Profile(llvm::FoldingSetNodeID &ID) const; 159 160 template <class T> 161 bool is() const { return Ptr.is<T>(); } 162 163 template <class T> 164 T get() const { return Ptr.get<T>(); } 165 166 template <class T> 167 T dyn_cast() const { return Ptr.dyn_cast<T>(); } 168 169 void *getOpaqueValue() const; 170 171 bool isNull() const; 172 173 explicit operator bool() const; 174 175 unsigned getCallIndex() const; 176 unsigned getVersion() const; 177 QualType getTypeInfoType() const; 178 QualType getDynamicAllocType() const; 179 180 QualType getType() const; 181 182 friend bool operator==(const LValueBase &LHS, const LValueBase &RHS); 183 friend bool operator!=(const LValueBase &LHS, const LValueBase &RHS) { 184 return !(LHS == RHS); 185 } 186 friend llvm::hash_code hash_value(const LValueBase &Base); 187 friend struct llvm::DenseMapInfo<LValueBase>; 188 189 private: 190 PtrTy Ptr; 191 struct LocalState { 192 unsigned CallIndex, Version; 193 }; 194 union { 195 LocalState Local; 196 /// The type std::type_info, if this is a TypeInfoLValue. 197 void *TypeInfoType; 198 /// The QualType, if this is a DynamicAllocLValue. 199 void *DynamicAllocType; 200 }; 201 }; 202 203 /// A FieldDecl or CXXRecordDecl, along with a flag indicating whether we 204 /// mean a virtual or non-virtual base class subobject. 205 typedef llvm::PointerIntPair<const Decl *, 1, bool> BaseOrMemberType; 206 207 /// A non-discriminated union of a base, field, or array index. 208 class LValuePathEntry { 209 static_assert(sizeof(uintptr_t) <= sizeof(uint64_t), 210 "pointer doesn't fit in 64 bits?"); 211 uint64_t Value; 212 213 public: 214 LValuePathEntry() : Value() {} 215 LValuePathEntry(BaseOrMemberType BaseOrMember); 216 static LValuePathEntry ArrayIndex(uint64_t Index) { 217 LValuePathEntry Result; 218 Result.Value = Index; 219 return Result; 220 } 221 222 BaseOrMemberType getAsBaseOrMember() const { 223 return BaseOrMemberType::getFromOpaqueValue( 224 reinterpret_cast<void *>(Value)); 225 } 226 uint64_t getAsArrayIndex() const { return Value; } 227 228 void Profile(llvm::FoldingSetNodeID &ID) const; 229 230 friend bool operator==(LValuePathEntry A, LValuePathEntry B) { 231 return A.Value == B.Value; 232 } 233 friend bool operator!=(LValuePathEntry A, LValuePathEntry B) { 234 return A.Value != B.Value; 235 } 236 friend llvm::hash_code hash_value(LValuePathEntry A) { 237 return llvm::hash_value(A.Value); 238 } 239 }; 240 class LValuePathSerializationHelper { 241 const void *ElemTy; 242 243 public: 244 ArrayRef<LValuePathEntry> Path; 245 246 LValuePathSerializationHelper(ArrayRef<LValuePathEntry>, QualType); 247 QualType getType(); 248 }; 249 struct NoLValuePath {}; 250 struct UninitArray {}; 251 struct UninitStruct {}; 252 253 template <typename Impl> friend class clang::serialization::BasicReaderBase; 254 friend class ASTImporter; 255 friend class ASTNodeImporter; 256 257 private: 258 ValueKind Kind; 259 260 struct ComplexAPSInt { 261 APSInt Real, Imag; 262 ComplexAPSInt() : Real(1), Imag(1) {} 263 }; 264 struct ComplexAPFloat { 265 APFloat Real, Imag; 266 ComplexAPFloat() : Real(0.0), Imag(0.0) {} 267 }; 268 struct LV; 269 struct Vec { 270 APValue *Elts; 271 unsigned NumElts; 272 Vec() : Elts(nullptr), NumElts(0) {} 273 ~Vec() { delete[] Elts; } 274 }; 275 struct Arr { 276 APValue *Elts; 277 unsigned NumElts, ArrSize; 278 Arr(unsigned NumElts, unsigned ArrSize); 279 ~Arr(); 280 }; 281 struct StructData { 282 APValue *Elts; 283 unsigned NumBases; 284 unsigned NumFields; 285 StructData(unsigned NumBases, unsigned NumFields); 286 ~StructData(); 287 }; 288 struct UnionData { 289 const FieldDecl *Field; 290 APValue *Value; 291 UnionData(); 292 ~UnionData(); 293 }; 294 struct AddrLabelDiffData { 295 const AddrLabelExpr* LHSExpr; 296 const AddrLabelExpr* RHSExpr; 297 }; 298 struct MemberPointerData; 299 300 // We ensure elsewhere that Data is big enough for LV and MemberPointerData. 301 typedef llvm::AlignedCharArrayUnion<void *, APSInt, APFloat, ComplexAPSInt, 302 ComplexAPFloat, Vec, Arr, StructData, 303 UnionData, AddrLabelDiffData> DataType; 304 static const size_t DataSize = sizeof(DataType); 305 306 DataType Data; 307 308 public: 309 APValue() : Kind(None) {} 310 explicit APValue(APSInt I) : Kind(None) { 311 MakeInt(); setInt(std::move(I)); 312 } 313 explicit APValue(APFloat F) : Kind(None) { 314 MakeFloat(); setFloat(std::move(F)); 315 } 316 explicit APValue(APFixedPoint FX) : Kind(None) { 317 MakeFixedPoint(std::move(FX)); 318 } 319 explicit APValue(const APValue *E, unsigned N) : Kind(None) { 320 MakeVector(); setVector(E, N); 321 } 322 APValue(APSInt R, APSInt I) : Kind(None) { 323 MakeComplexInt(); setComplexInt(std::move(R), std::move(I)); 324 } 325 APValue(APFloat R, APFloat I) : Kind(None) { 326 MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I)); 327 } 328 APValue(const APValue &RHS); 329 APValue(APValue &&RHS); 330 APValue(LValueBase B, const CharUnits &O, NoLValuePath N, 331 bool IsNullPtr = false) 332 : Kind(None) { 333 MakeLValue(); setLValue(B, O, N, IsNullPtr); 334 } 335 APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path, 336 bool OnePastTheEnd, bool IsNullPtr = false) 337 : Kind(None) { 338 MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, IsNullPtr); 339 } 340 APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(None) { 341 MakeArray(InitElts, Size); 342 } 343 APValue(UninitStruct, unsigned B, unsigned M) : Kind(None) { 344 MakeStruct(B, M); 345 } 346 explicit APValue(const FieldDecl *D, const APValue &V = APValue()) 347 : Kind(None) { 348 MakeUnion(); setUnion(D, V); 349 } 350 APValue(const ValueDecl *Member, bool IsDerivedMember, 351 ArrayRef<const CXXRecordDecl*> Path) : Kind(None) { 352 MakeMemberPointer(Member, IsDerivedMember, Path); 353 } 354 APValue(const AddrLabelExpr* LHSExpr, const AddrLabelExpr* RHSExpr) 355 : Kind(None) { 356 MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr); 357 } 358 static APValue IndeterminateValue() { 359 APValue Result; 360 Result.Kind = Indeterminate; 361 return Result; 362 } 363 364 APValue &operator=(const APValue &RHS); 365 APValue &operator=(APValue &&RHS); 366 367 ~APValue() { 368 if (Kind != None && Kind != Indeterminate) 369 DestroyDataAndMakeUninit(); 370 } 371 372 /// Returns whether the object performed allocations. 373 /// 374 /// If APValues are constructed via placement new, \c needsCleanup() 375 /// indicates whether the destructor must be called in order to correctly 376 /// free all allocated memory. 377 bool needsCleanup() const; 378 379 /// Swaps the contents of this and the given APValue. 380 void swap(APValue &RHS); 381 382 /// profile this value. There is no guarantee that values of different 383 /// types will not produce the same profiled value, so the type should 384 /// typically also be profiled if it's not implied by the context. 385 void Profile(llvm::FoldingSetNodeID &ID) const; 386 387 ValueKind getKind() const { return Kind; } 388 389 bool isAbsent() const { return Kind == None; } 390 bool isIndeterminate() const { return Kind == Indeterminate; } 391 bool hasValue() const { return Kind != None && Kind != Indeterminate; } 392 393 bool isInt() const { return Kind == Int; } 394 bool isFloat() const { return Kind == Float; } 395 bool isFixedPoint() const { return Kind == FixedPoint; } 396 bool isComplexInt() const { return Kind == ComplexInt; } 397 bool isComplexFloat() const { return Kind == ComplexFloat; } 398 bool isLValue() const { return Kind == LValue; } 399 bool isVector() const { return Kind == Vector; } 400 bool isArray() const { return Kind == Array; } 401 bool isStruct() const { return Kind == Struct; } 402 bool isUnion() const { return Kind == Union; } 403 bool isMemberPointer() const { return Kind == MemberPointer; } 404 bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; } 405 406 void dump() const; 407 void dump(raw_ostream &OS, const ASTContext &Context) const; 408 409 void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const; 410 void printPretty(raw_ostream &OS, const PrintingPolicy &Policy, QualType Ty, 411 const ASTContext *Ctx = nullptr) const; 412 413 std::string getAsString(const ASTContext &Ctx, QualType Ty) const; 414 415 APSInt &getInt() { 416 assert(isInt() && "Invalid accessor"); 417 return *(APSInt *)(char *)&Data; 418 } 419 const APSInt &getInt() const { 420 return const_cast<APValue*>(this)->getInt(); 421 } 422 423 /// Try to convert this value to an integral constant. This works if it's an 424 /// integer, null pointer, or offset from a null pointer. Returns true on 425 /// success. 426 bool toIntegralConstant(APSInt &Result, QualType SrcTy, 427 const ASTContext &Ctx) const; 428 429 APFloat &getFloat() { 430 assert(isFloat() && "Invalid accessor"); 431 return *(APFloat *)(char *)&Data; 432 } 433 const APFloat &getFloat() const { 434 return const_cast<APValue*>(this)->getFloat(); 435 } 436 437 APFixedPoint &getFixedPoint() { 438 assert(isFixedPoint() && "Invalid accessor"); 439 return *(APFixedPoint *)(char *)&Data; 440 } 441 const APFixedPoint &getFixedPoint() const { 442 return const_cast<APValue *>(this)->getFixedPoint(); 443 } 444 445 APSInt &getComplexIntReal() { 446 assert(isComplexInt() && "Invalid accessor"); 447 return ((ComplexAPSInt *)(char *)&Data)->Real; 448 } 449 const APSInt &getComplexIntReal() const { 450 return const_cast<APValue*>(this)->getComplexIntReal(); 451 } 452 453 APSInt &getComplexIntImag() { 454 assert(isComplexInt() && "Invalid accessor"); 455 return ((ComplexAPSInt *)(char *)&Data)->Imag; 456 } 457 const APSInt &getComplexIntImag() const { 458 return const_cast<APValue*>(this)->getComplexIntImag(); 459 } 460 461 APFloat &getComplexFloatReal() { 462 assert(isComplexFloat() && "Invalid accessor"); 463 return ((ComplexAPFloat *)(char *)&Data)->Real; 464 } 465 const APFloat &getComplexFloatReal() const { 466 return const_cast<APValue*>(this)->getComplexFloatReal(); 467 } 468 469 APFloat &getComplexFloatImag() { 470 assert(isComplexFloat() && "Invalid accessor"); 471 return ((ComplexAPFloat *)(char *)&Data)->Imag; 472 } 473 const APFloat &getComplexFloatImag() const { 474 return const_cast<APValue*>(this)->getComplexFloatImag(); 475 } 476 477 const LValueBase getLValueBase() const; 478 CharUnits &getLValueOffset(); 479 const CharUnits &getLValueOffset() const { 480 return const_cast<APValue*>(this)->getLValueOffset(); 481 } 482 bool isLValueOnePastTheEnd() const; 483 bool hasLValuePath() const; 484 ArrayRef<LValuePathEntry> getLValuePath() const; 485 unsigned getLValueCallIndex() const; 486 unsigned getLValueVersion() const; 487 bool isNullPointer() const; 488 489 APValue &getVectorElt(unsigned I) { 490 assert(isVector() && "Invalid accessor"); 491 assert(I < getVectorLength() && "Index out of range"); 492 return ((Vec *)(char *)&Data)->Elts[I]; 493 } 494 const APValue &getVectorElt(unsigned I) const { 495 return const_cast<APValue*>(this)->getVectorElt(I); 496 } 497 unsigned getVectorLength() const { 498 assert(isVector() && "Invalid accessor"); 499 return ((const Vec *)(const void *)&Data)->NumElts; 500 } 501 502 APValue &getArrayInitializedElt(unsigned I) { 503 assert(isArray() && "Invalid accessor"); 504 assert(I < getArrayInitializedElts() && "Index out of range"); 505 return ((Arr *)(char *)&Data)->Elts[I]; 506 } 507 const APValue &getArrayInitializedElt(unsigned I) const { 508 return const_cast<APValue*>(this)->getArrayInitializedElt(I); 509 } 510 bool hasArrayFiller() const { 511 return getArrayInitializedElts() != getArraySize(); 512 } 513 APValue &getArrayFiller() { 514 assert(isArray() && "Invalid accessor"); 515 assert(hasArrayFiller() && "No array filler"); 516 return ((Arr *)(char *)&Data)->Elts[getArrayInitializedElts()]; 517 } 518 const APValue &getArrayFiller() const { 519 return const_cast<APValue*>(this)->getArrayFiller(); 520 } 521 unsigned getArrayInitializedElts() const { 522 assert(isArray() && "Invalid accessor"); 523 return ((const Arr *)(const void *)&Data)->NumElts; 524 } 525 unsigned getArraySize() const { 526 assert(isArray() && "Invalid accessor"); 527 return ((const Arr *)(const void *)&Data)->ArrSize; 528 } 529 530 unsigned getStructNumBases() const { 531 assert(isStruct() && "Invalid accessor"); 532 return ((const StructData *)(const char *)&Data)->NumBases; 533 } 534 unsigned getStructNumFields() const { 535 assert(isStruct() && "Invalid accessor"); 536 return ((const StructData *)(const char *)&Data)->NumFields; 537 } 538 APValue &getStructBase(unsigned i) { 539 assert(isStruct() && "Invalid accessor"); 540 assert(i < getStructNumBases() && "base class index OOB"); 541 return ((StructData *)(char *)&Data)->Elts[i]; 542 } 543 APValue &getStructField(unsigned i) { 544 assert(isStruct() && "Invalid accessor"); 545 assert(i < getStructNumFields() && "field index OOB"); 546 return ((StructData *)(char *)&Data)->Elts[getStructNumBases() + i]; 547 } 548 const APValue &getStructBase(unsigned i) const { 549 return const_cast<APValue*>(this)->getStructBase(i); 550 } 551 const APValue &getStructField(unsigned i) const { 552 return const_cast<APValue*>(this)->getStructField(i); 553 } 554 555 const FieldDecl *getUnionField() const { 556 assert(isUnion() && "Invalid accessor"); 557 return ((const UnionData *)(const char *)&Data)->Field; 558 } 559 APValue &getUnionValue() { 560 assert(isUnion() && "Invalid accessor"); 561 return *((UnionData *)(char *)&Data)->Value; 562 } 563 const APValue &getUnionValue() const { 564 return const_cast<APValue*>(this)->getUnionValue(); 565 } 566 567 const ValueDecl *getMemberPointerDecl() const; 568 bool isMemberPointerToDerivedMember() const; 569 ArrayRef<const CXXRecordDecl*> getMemberPointerPath() const; 570 571 const AddrLabelExpr* getAddrLabelDiffLHS() const { 572 assert(isAddrLabelDiff() && "Invalid accessor"); 573 return ((const AddrLabelDiffData *)(const char *)&Data)->LHSExpr; 574 } 575 const AddrLabelExpr* getAddrLabelDiffRHS() const { 576 assert(isAddrLabelDiff() && "Invalid accessor"); 577 return ((const AddrLabelDiffData *)(const char *)&Data)->RHSExpr; 578 } 579 580 void setInt(APSInt I) { 581 assert(isInt() && "Invalid accessor"); 582 *(APSInt *)(char *)&Data = std::move(I); 583 } 584 void setFloat(APFloat F) { 585 assert(isFloat() && "Invalid accessor"); 586 *(APFloat *)(char *)&Data = std::move(F); 587 } 588 void setFixedPoint(APFixedPoint FX) { 589 assert(isFixedPoint() && "Invalid accessor"); 590 *(APFixedPoint *)(char *)&Data = std::move(FX); 591 } 592 void setVector(const APValue *E, unsigned N) { 593 MutableArrayRef<APValue> InternalElts = setVectorUninit(N); 594 for (unsigned i = 0; i != N; ++i) 595 InternalElts[i] = E[i]; 596 } 597 void setComplexInt(APSInt R, APSInt I) { 598 assert(R.getBitWidth() == I.getBitWidth() && 599 "Invalid complex int (type mismatch)."); 600 assert(isComplexInt() && "Invalid accessor"); 601 ((ComplexAPSInt *)(char *)&Data)->Real = std::move(R); 602 ((ComplexAPSInt *)(char *)&Data)->Imag = std::move(I); 603 } 604 void setComplexFloat(APFloat R, APFloat I) { 605 assert(&R.getSemantics() == &I.getSemantics() && 606 "Invalid complex float (type mismatch)."); 607 assert(isComplexFloat() && "Invalid accessor"); 608 ((ComplexAPFloat *)(char *)&Data)->Real = std::move(R); 609 ((ComplexAPFloat *)(char *)&Data)->Imag = std::move(I); 610 } 611 void setLValue(LValueBase B, const CharUnits &O, NoLValuePath, 612 bool IsNullPtr); 613 void setLValue(LValueBase B, const CharUnits &O, 614 ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd, 615 bool IsNullPtr); 616 void setUnion(const FieldDecl *Field, const APValue &Value); 617 void setAddrLabelDiff(const AddrLabelExpr* LHSExpr, 618 const AddrLabelExpr* RHSExpr) { 619 ((AddrLabelDiffData *)(char *)&Data)->LHSExpr = LHSExpr; 620 ((AddrLabelDiffData *)(char *)&Data)->RHSExpr = RHSExpr; 621 } 622 623 private: 624 void DestroyDataAndMakeUninit(); 625 void MakeInt() { 626 assert(isAbsent() && "Bad state change"); 627 new ((void *)&Data) APSInt(1); 628 Kind = Int; 629 } 630 void MakeFloat() { 631 assert(isAbsent() && "Bad state change"); 632 new ((void *)(char *)&Data) APFloat(0.0); 633 Kind = Float; 634 } 635 void MakeFixedPoint(APFixedPoint &&FX) { 636 assert(isAbsent() && "Bad state change"); 637 new ((void *)(char *)&Data) APFixedPoint(std::move(FX)); 638 Kind = FixedPoint; 639 } 640 void MakeVector() { 641 assert(isAbsent() && "Bad state change"); 642 new ((void *)(char *)&Data) Vec(); 643 Kind = Vector; 644 } 645 void MakeComplexInt() { 646 assert(isAbsent() && "Bad state change"); 647 new ((void *)(char *)&Data) ComplexAPSInt(); 648 Kind = ComplexInt; 649 } 650 void MakeComplexFloat() { 651 assert(isAbsent() && "Bad state change"); 652 new ((void *)(char *)&Data) ComplexAPFloat(); 653 Kind = ComplexFloat; 654 } 655 void MakeLValue(); 656 void MakeArray(unsigned InitElts, unsigned Size); 657 void MakeStruct(unsigned B, unsigned M) { 658 assert(isAbsent() && "Bad state change"); 659 new ((void *)(char *)&Data) StructData(B, M); 660 Kind = Struct; 661 } 662 void MakeUnion() { 663 assert(isAbsent() && "Bad state change"); 664 new ((void *)(char *)&Data) UnionData(); 665 Kind = Union; 666 } 667 void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember, 668 ArrayRef<const CXXRecordDecl*> Path); 669 void MakeAddrLabelDiff() { 670 assert(isAbsent() && "Bad state change"); 671 new ((void *)(char *)&Data) AddrLabelDiffData(); 672 Kind = AddrLabelDiff; 673 } 674 675 private: 676 /// The following functions are used as part of initialization, during 677 /// deserialization and importing. Reserve the space so that it can be 678 /// filled in by those steps. 679 MutableArrayRef<APValue> setVectorUninit(unsigned N) { 680 assert(isVector() && "Invalid accessor"); 681 Vec *V = ((Vec *)(char *)&Data); 682 V->Elts = new APValue[N]; 683 V->NumElts = N; 684 return {V->Elts, V->NumElts}; 685 } 686 MutableArrayRef<LValuePathEntry> 687 setLValueUninit(LValueBase B, const CharUnits &O, unsigned Size, 688 bool OnePastTheEnd, bool IsNullPtr); 689 MutableArrayRef<const CXXRecordDecl *> 690 setMemberPointerUninit(const ValueDecl *Member, bool IsDerivedMember, 691 unsigned Size); 692 }; 693 694 } // end namespace clang. 695 696 namespace llvm { 697 template<> struct DenseMapInfo<clang::APValue::LValueBase> { 698 static clang::APValue::LValueBase getEmptyKey(); 699 static clang::APValue::LValueBase getTombstoneKey(); 700 static unsigned getHashValue(const clang::APValue::LValueBase &Base); 701 static bool isEqual(const clang::APValue::LValueBase &LHS, 702 const clang::APValue::LValueBase &RHS); 703 }; 704 } 705 706 #endif 707