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