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 25namespace clang { 26namespace serialization { 27template <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. 44class TypeInfoLValue { 45 const Type *T; 46 47public: 48 TypeInfoLValue() : T() {} 49 explicit TypeInfoLValue(const Type *T); 50 51 const Type *getType() const { return T; } 52 explicit operator bool() const { return T; } 53 54 void *getOpaqueValue() { return const_cast<Type*>(T); } 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. 65class DynamicAllocLValue { 66 unsigned Index; 67 68public: 69 DynamicAllocLValue() : Index(0) {} 70 explicit DynamicAllocLValue(unsigned Index) : Index(Index + 1) {} 71 unsigned getIndex() { return Index - 1; } 72 73 explicit operator bool() const { return Index != 0; } 74 75 void *getOpaqueValue() { 76 return reinterpret_cast<void *>(static_cast<uintptr_t>(Index) 77 << NumLowBitsAvailable); 78 } 79 static DynamicAllocLValue getFromOpaqueValue(void *Value) { 80 DynamicAllocLValue V; 81 V.Index = reinterpret_cast<uintptr_t>(Value) >> NumLowBitsAvailable; 82 return V; 83 } 84 85 static unsigned getMaxIndex() { 86 return (std::numeric_limits<unsigned>::max() >> NumLowBitsAvailable) - 1; 87 } 88 89 static constexpr int NumLowBitsAvailable = 3; 90}; 91} 92 93namespace llvm { 94template<> 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 106template<> 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 118namespace 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] 122class APValue { 123 typedef llvm::APFixedPoint APFixedPoint; 124 typedef llvm::APSInt APSInt; 125 typedef llvm::APFloat APFloat; 126public: 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 *Ty; 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 257private: 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 = nullptr; 271 unsigned NumElts = 0; 272 Vec() = default; 273 Vec(const Vec &) = delete; 274 Vec &operator=(const Vec &) = delete; 275 ~Vec() { delete[] Elts; } 276 }; 277 struct Arr { 278 APValue *Elts; 279 unsigned NumElts, ArrSize; 280 Arr(unsigned NumElts, unsigned ArrSize); 281 Arr(const Arr &) = delete; 282 Arr &operator=(const Arr &) = delete; 283 ~Arr(); 284 }; 285 struct StructData { 286 APValue *Elts; 287 unsigned NumBases; 288 unsigned NumFields; 289 StructData(unsigned NumBases, unsigned NumFields); 290 StructData(const StructData &) = delete; 291 StructData &operator=(const StructData &) = delete; 292 ~StructData(); 293 }; 294 struct UnionData { 295 const FieldDecl *Field; 296 APValue *Value; 297 UnionData(); 298 UnionData(const UnionData &) = delete; 299 UnionData &operator=(const UnionData &) = delete; 300 ~UnionData(); 301 }; 302 struct AddrLabelDiffData { 303 const AddrLabelExpr* LHSExpr; 304 const AddrLabelExpr* RHSExpr; 305 }; 306 struct MemberPointerData; 307 308 // We ensure elsewhere that Data is big enough for LV and MemberPointerData. 309 typedef llvm::AlignedCharArrayUnion<void *, APSInt, APFloat, ComplexAPSInt, 310 ComplexAPFloat, Vec, Arr, StructData, 311 UnionData, AddrLabelDiffData> DataType; 312 static const size_t DataSize = sizeof(DataType); 313 314 DataType Data; 315 316public: 317 APValue() : Kind(None) {} 318 explicit APValue(APSInt I) : Kind(None) { 319 MakeInt(); setInt(std::move(I)); 320 } 321 explicit APValue(APFloat F) : Kind(None) { 322 MakeFloat(); setFloat(std::move(F)); 323 } 324 explicit APValue(APFixedPoint FX) : Kind(None) { 325 MakeFixedPoint(std::move(FX)); 326 } 327 explicit APValue(const APValue *E, unsigned N) : Kind(None) { 328 MakeVector(); setVector(E, N); 329 } 330 APValue(APSInt R, APSInt I) : Kind(None) { 331 MakeComplexInt(); setComplexInt(std::move(R), std::move(I)); 332 } 333 APValue(APFloat R, APFloat I) : Kind(None) { 334 MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I)); 335 } 336 APValue(const APValue &RHS); 337 APValue(APValue &&RHS); 338 APValue(LValueBase B, const CharUnits &O, NoLValuePath N, 339 bool IsNullPtr = false) 340 : Kind(None) { 341 MakeLValue(); setLValue(B, O, N, IsNullPtr); 342 } 343 APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path, 344 bool OnePastTheEnd, bool IsNullPtr = false) 345 : Kind(None) { 346 MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, IsNullPtr); 347 } 348 APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(None) { 349 MakeArray(InitElts, Size); 350 } 351 APValue(UninitStruct, unsigned B, unsigned M) : Kind(None) { 352 MakeStruct(B, M); 353 } 354 explicit APValue(const FieldDecl *D, const APValue &V = APValue()) 355 : Kind(None) { 356 MakeUnion(); setUnion(D, V); 357 } 358 APValue(const ValueDecl *Member, bool IsDerivedMember, 359 ArrayRef<const CXXRecordDecl*> Path) : Kind(None) { 360 MakeMemberPointer(Member, IsDerivedMember, Path); 361 } 362 APValue(const AddrLabelExpr* LHSExpr, const AddrLabelExpr* RHSExpr) 363 : Kind(None) { 364 MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr); 365 } 366 static APValue IndeterminateValue() { 367 APValue Result; 368 Result.Kind = Indeterminate; 369 return Result; 370 } 371 372 APValue &operator=(const APValue &RHS); 373 APValue &operator=(APValue &&RHS); 374 375 ~APValue() { 376 if (Kind != None && Kind != Indeterminate) 377 DestroyDataAndMakeUninit(); 378 } 379 380 /// Returns whether the object performed allocations. 381 /// 382 /// If APValues are constructed via placement new, \c needsCleanup() 383 /// indicates whether the destructor must be called in order to correctly 384 /// free all allocated memory. 385 bool needsCleanup() const; 386 387 /// Swaps the contents of this and the given APValue. 388 void swap(APValue &RHS); 389 390 /// profile this value. There is no guarantee that values of different 391 /// types will not produce the same profiled value, so the type should 392 /// typically also be profiled if it's not implied by the context. 393 void Profile(llvm::FoldingSetNodeID &ID) const; 394 395 ValueKind getKind() const { return Kind; } 396 397 bool isAbsent() const { return Kind == None; } 398 bool isIndeterminate() const { return Kind == Indeterminate; } 399 bool hasValue() const { return Kind != None && Kind != Indeterminate; } 400 401 bool isInt() const { return Kind == Int; } 402 bool isFloat() const { return Kind == Float; } 403 bool isFixedPoint() const { return Kind == FixedPoint; } 404 bool isComplexInt() const { return Kind == ComplexInt; } 405 bool isComplexFloat() const { return Kind == ComplexFloat; } 406 bool isLValue() const { return Kind == LValue; } 407 bool isVector() const { return Kind == Vector; } 408 bool isArray() const { return Kind == Array; } 409 bool isStruct() const { return Kind == Struct; } 410 bool isUnion() const { return Kind == Union; } 411 bool isMemberPointer() const { return Kind == MemberPointer; } 412 bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; } 413 414 void dump() const; 415 void dump(raw_ostream &OS, const ASTContext &Context) const; 416 417 void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const; 418 void printPretty(raw_ostream &OS, const PrintingPolicy &Policy, QualType Ty, 419 const ASTContext *Ctx = nullptr) const; 420 421 std::string getAsString(const ASTContext &Ctx, QualType Ty) const; 422 423 APSInt &getInt() { 424 assert(isInt() && "Invalid accessor"); 425 return *(APSInt *)(char *)&Data; 426 } 427 const APSInt &getInt() const { 428 return const_cast<APValue*>(this)->getInt(); 429 } 430 431 /// Try to convert this value to an integral constant. This works if it's an 432 /// integer, null pointer, or offset from a null pointer. Returns true on 433 /// success. 434 bool toIntegralConstant(APSInt &Result, QualType SrcTy, 435 const ASTContext &Ctx) const; 436 437 APFloat &getFloat() { 438 assert(isFloat() && "Invalid accessor"); 439 return *(APFloat *)(char *)&Data; 440 } 441 const APFloat &getFloat() const { 442 return const_cast<APValue*>(this)->getFloat(); 443 } 444 445 APFixedPoint &getFixedPoint() { 446 assert(isFixedPoint() && "Invalid accessor"); 447 return *(APFixedPoint *)(char *)&Data; 448 } 449 const APFixedPoint &getFixedPoint() const { 450 return const_cast<APValue *>(this)->getFixedPoint(); 451 } 452 453 APSInt &getComplexIntReal() { 454 assert(isComplexInt() && "Invalid accessor"); 455 return ((ComplexAPSInt *)(char *)&Data)->Real; 456 } 457 const APSInt &getComplexIntReal() const { 458 return const_cast<APValue*>(this)->getComplexIntReal(); 459 } 460 461 APSInt &getComplexIntImag() { 462 assert(isComplexInt() && "Invalid accessor"); 463 return ((ComplexAPSInt *)(char *)&Data)->Imag; 464 } 465 const APSInt &getComplexIntImag() const { 466 return const_cast<APValue*>(this)->getComplexIntImag(); 467 } 468 469 APFloat &getComplexFloatReal() { 470 assert(isComplexFloat() && "Invalid accessor"); 471 return ((ComplexAPFloat *)(char *)&Data)->Real; 472 } 473 const APFloat &getComplexFloatReal() const { 474 return const_cast<APValue*>(this)->getComplexFloatReal(); 475 } 476 477 APFloat &getComplexFloatImag() { 478 assert(isComplexFloat() && "Invalid accessor"); 479 return ((ComplexAPFloat *)(char *)&Data)->Imag; 480 } 481 const APFloat &getComplexFloatImag() const { 482 return const_cast<APValue*>(this)->getComplexFloatImag(); 483 } 484 485 const LValueBase getLValueBase() const; 486 CharUnits &getLValueOffset(); 487 const CharUnits &getLValueOffset() const { 488 return const_cast<APValue*>(this)->getLValueOffset(); 489 } 490 bool isLValueOnePastTheEnd() const; 491 bool hasLValuePath() const; 492 ArrayRef<LValuePathEntry> getLValuePath() const; 493 unsigned getLValueCallIndex() const; 494 unsigned getLValueVersion() const; 495 bool isNullPointer() const; 496 497 APValue &getVectorElt(unsigned I) { 498 assert(isVector() && "Invalid accessor"); 499 assert(I < getVectorLength() && "Index out of range"); 500 return ((Vec *)(char *)&Data)->Elts[I]; 501 } 502 const APValue &getVectorElt(unsigned I) const { 503 return const_cast<APValue*>(this)->getVectorElt(I); 504 } 505 unsigned getVectorLength() const { 506 assert(isVector() && "Invalid accessor"); 507 return ((const Vec *)(const void *)&Data)->NumElts; 508 } 509 510 APValue &getArrayInitializedElt(unsigned I) { 511 assert(isArray() && "Invalid accessor"); 512 assert(I < getArrayInitializedElts() && "Index out of range"); 513 return ((Arr *)(char *)&Data)->Elts[I]; 514 } 515 const APValue &getArrayInitializedElt(unsigned I) const { 516 return const_cast<APValue*>(this)->getArrayInitializedElt(I); 517 } 518 bool hasArrayFiller() const { 519 return getArrayInitializedElts() != getArraySize(); 520 } 521 APValue &getArrayFiller() { 522 assert(isArray() && "Invalid accessor"); 523 assert(hasArrayFiller() && "No array filler"); 524 return ((Arr *)(char *)&Data)->Elts[getArrayInitializedElts()]; 525 } 526 const APValue &getArrayFiller() const { 527 return const_cast<APValue*>(this)->getArrayFiller(); 528 } 529 unsigned getArrayInitializedElts() const { 530 assert(isArray() && "Invalid accessor"); 531 return ((const Arr *)(const void *)&Data)->NumElts; 532 } 533 unsigned getArraySize() const { 534 assert(isArray() && "Invalid accessor"); 535 return ((const Arr *)(const void *)&Data)->ArrSize; 536 } 537 538 unsigned getStructNumBases() const { 539 assert(isStruct() && "Invalid accessor"); 540 return ((const StructData *)(const char *)&Data)->NumBases; 541 } 542 unsigned getStructNumFields() const { 543 assert(isStruct() && "Invalid accessor"); 544 return ((const StructData *)(const char *)&Data)->NumFields; 545 } 546 APValue &getStructBase(unsigned i) { 547 assert(isStruct() && "Invalid accessor"); 548 assert(i < getStructNumBases() && "base class index OOB"); 549 return ((StructData *)(char *)&Data)->Elts[i]; 550 } 551 APValue &getStructField(unsigned i) { 552 assert(isStruct() && "Invalid accessor"); 553 assert(i < getStructNumFields() && "field index OOB"); 554 return ((StructData *)(char *)&Data)->Elts[getStructNumBases() + i]; 555 } 556 const APValue &getStructBase(unsigned i) const { 557 return const_cast<APValue*>(this)->getStructBase(i); 558 } 559 const APValue &getStructField(unsigned i) const { 560 return const_cast<APValue*>(this)->getStructField(i); 561 } 562 563 const FieldDecl *getUnionField() const { 564 assert(isUnion() && "Invalid accessor"); 565 return ((const UnionData *)(const char *)&Data)->Field; 566 } 567 APValue &getUnionValue() { 568 assert(isUnion() && "Invalid accessor"); 569 return *((UnionData *)(char *)&Data)->Value; 570 } 571 const APValue &getUnionValue() const { 572 return const_cast<APValue*>(this)->getUnionValue(); 573 } 574 575 const ValueDecl *getMemberPointerDecl() const; 576 bool isMemberPointerToDerivedMember() const; 577 ArrayRef<const CXXRecordDecl*> getMemberPointerPath() const; 578 579 const AddrLabelExpr* getAddrLabelDiffLHS() const { 580 assert(isAddrLabelDiff() && "Invalid accessor"); 581 return ((const AddrLabelDiffData *)(const char *)&Data)->LHSExpr; 582 } 583 const AddrLabelExpr* getAddrLabelDiffRHS() const { 584 assert(isAddrLabelDiff() && "Invalid accessor"); 585 return ((const AddrLabelDiffData *)(const char *)&Data)->RHSExpr; 586 } 587 588 void setInt(APSInt I) { 589 assert(isInt() && "Invalid accessor"); 590 *(APSInt *)(char *)&Data = std::move(I); 591 } 592 void setFloat(APFloat F) { 593 assert(isFloat() && "Invalid accessor"); 594 *(APFloat *)(char *)&Data = std::move(F); 595 } 596 void setFixedPoint(APFixedPoint FX) { 597 assert(isFixedPoint() && "Invalid accessor"); 598 *(APFixedPoint *)(char *)&Data = std::move(FX); 599 } 600 void setVector(const APValue *E, unsigned N) { 601 MutableArrayRef<APValue> InternalElts = setVectorUninit(N); 602 for (unsigned i = 0; i != N; ++i) 603 InternalElts[i] = E[i]; 604 } 605 void setComplexInt(APSInt R, APSInt I) { 606 assert(R.getBitWidth() == I.getBitWidth() && 607 "Invalid complex int (type mismatch)."); 608 assert(isComplexInt() && "Invalid accessor"); 609 ((ComplexAPSInt *)(char *)&Data)->Real = std::move(R); 610 ((ComplexAPSInt *)(char *)&Data)->Imag = std::move(I); 611 } 612 void setComplexFloat(APFloat R, APFloat I) { 613 assert(&R.getSemantics() == &I.getSemantics() && 614 "Invalid complex float (type mismatch)."); 615 assert(isComplexFloat() && "Invalid accessor"); 616 ((ComplexAPFloat *)(char *)&Data)->Real = std::move(R); 617 ((ComplexAPFloat *)(char *)&Data)->Imag = std::move(I); 618 } 619 void setLValue(LValueBase B, const CharUnits &O, NoLValuePath, 620 bool IsNullPtr); 621 void setLValue(LValueBase B, const CharUnits &O, 622 ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd, 623 bool IsNullPtr); 624 void setUnion(const FieldDecl *Field, const APValue &Value); 625 void setAddrLabelDiff(const AddrLabelExpr* LHSExpr, 626 const AddrLabelExpr* RHSExpr) { 627 ((AddrLabelDiffData *)(char *)&Data)->LHSExpr = LHSExpr; 628 ((AddrLabelDiffData *)(char *)&Data)->RHSExpr = RHSExpr; 629 } 630 631private: 632 void DestroyDataAndMakeUninit(); 633 void MakeInt() { 634 assert(isAbsent() && "Bad state change"); 635 new ((void *)&Data) APSInt(1); 636 Kind = Int; 637 } 638 void MakeFloat() { 639 assert(isAbsent() && "Bad state change"); 640 new ((void *)(char *)&Data) APFloat(0.0); 641 Kind = Float; 642 } 643 void MakeFixedPoint(APFixedPoint &&FX) { 644 assert(isAbsent() && "Bad state change"); 645 new ((void *)(char *)&Data) APFixedPoint(std::move(FX)); 646 Kind = FixedPoint; 647 } 648 void MakeVector() { 649 assert(isAbsent() && "Bad state change"); 650 new ((void *)(char *)&Data) Vec(); 651 Kind = Vector; 652 } 653 void MakeComplexInt() { 654 assert(isAbsent() && "Bad state change"); 655 new ((void *)(char *)&Data) ComplexAPSInt(); 656 Kind = ComplexInt; 657 } 658 void MakeComplexFloat() { 659 assert(isAbsent() && "Bad state change"); 660 new ((void *)(char *)&Data) ComplexAPFloat(); 661 Kind = ComplexFloat; 662 } 663 void MakeLValue(); 664 void MakeArray(unsigned InitElts, unsigned Size); 665 void MakeStruct(unsigned B, unsigned M) { 666 assert(isAbsent() && "Bad state change"); 667 new ((void *)(char *)&Data) StructData(B, M); 668 Kind = Struct; 669 } 670 void MakeUnion() { 671 assert(isAbsent() && "Bad state change"); 672 new ((void *)(char *)&Data) UnionData(); 673 Kind = Union; 674 } 675 void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember, 676 ArrayRef<const CXXRecordDecl*> Path); 677 void MakeAddrLabelDiff() { 678 assert(isAbsent() && "Bad state change"); 679 new ((void *)(char *)&Data) AddrLabelDiffData(); 680 Kind = AddrLabelDiff; 681 } 682 683private: 684 /// The following functions are used as part of initialization, during 685 /// deserialization and importing. Reserve the space so that it can be 686 /// filled in by those steps. 687 MutableArrayRef<APValue> setVectorUninit(unsigned N) { 688 assert(isVector() && "Invalid accessor"); 689 Vec *V = ((Vec *)(char *)&Data); 690 V->Elts = new APValue[N]; 691 V->NumElts = N; 692 return {V->Elts, V->NumElts}; 693 } 694 MutableArrayRef<LValuePathEntry> 695 setLValueUninit(LValueBase B, const CharUnits &O, unsigned Size, 696 bool OnePastTheEnd, bool IsNullPtr); 697 MutableArrayRef<const CXXRecordDecl *> 698 setMemberPointerUninit(const ValueDecl *Member, bool IsDerivedMember, 699 unsigned Size); 700}; 701 702} // end namespace clang. 703 704namespace llvm { 705template<> struct DenseMapInfo<clang::APValue::LValueBase> { 706 static clang::APValue::LValueBase getEmptyKey(); 707 static clang::APValue::LValueBase getTombstoneKey(); 708 static unsigned getHashValue(const clang::APValue::LValueBase &Base); 709 static bool isEqual(const clang::APValue::LValueBase &LHS, 710 const clang::APValue::LValueBase &RHS); 711}; 712} 713 714#endif 715