1 //===--- APValue.cpp - Union class for APFloat/APSInt/Complex -------------===// 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 implements the APValue class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "clang/AST/APValue.h" 15 #include "clang/AST/ASTContext.h" 16 #include "clang/AST/CharUnits.h" 17 #include "clang/AST/DeclCXX.h" 18 #include "clang/AST/Expr.h" 19 #include "clang/AST/Type.h" 20 #include "llvm/Support/ErrorHandling.h" 21 #include "llvm/Support/raw_ostream.h" 22 using namespace clang; 23 24 namespace { 25 struct LVBase { 26 APValue::LValueBase Base; 27 CharUnits Offset; 28 unsigned PathLength; 29 bool IsNullPtr : 1; 30 bool IsOnePastTheEnd : 1; 31 }; 32 } 33 34 void *APValue::LValueBase::getOpaqueValue() const { 35 return Ptr.getOpaqueValue(); 36 } 37 38 bool APValue::LValueBase::isNull() const { 39 return Ptr.isNull(); 40 } 41 42 APValue::LValueBase::operator bool () const { 43 return static_cast<bool>(Ptr); 44 } 45 46 clang::APValue::LValueBase 47 llvm::DenseMapInfo<clang::APValue::LValueBase>::getEmptyKey() { 48 return clang::APValue::LValueBase( 49 DenseMapInfo<clang::APValue::LValueBase::PtrTy>::getEmptyKey(), 50 DenseMapInfo<unsigned>::getEmptyKey(), 51 DenseMapInfo<unsigned>::getEmptyKey()); 52 } 53 54 clang::APValue::LValueBase 55 llvm::DenseMapInfo<clang::APValue::LValueBase>::getTombstoneKey() { 56 return clang::APValue::LValueBase( 57 DenseMapInfo<clang::APValue::LValueBase::PtrTy>::getTombstoneKey(), 58 DenseMapInfo<unsigned>::getTombstoneKey(), 59 DenseMapInfo<unsigned>::getTombstoneKey()); 60 } 61 62 unsigned llvm::DenseMapInfo<clang::APValue::LValueBase>::getHashValue( 63 const clang::APValue::LValueBase &Base) { 64 llvm::FoldingSetNodeID ID; 65 ID.AddPointer(Base.getOpaqueValue()); 66 ID.AddInteger(Base.getCallIndex()); 67 ID.AddInteger(Base.getVersion()); 68 return ID.ComputeHash(); 69 } 70 71 bool llvm::DenseMapInfo<clang::APValue::LValueBase>::isEqual( 72 const clang::APValue::LValueBase &LHS, 73 const clang::APValue::LValueBase &RHS) { 74 return LHS == RHS; 75 } 76 77 struct APValue::LV : LVBase { 78 static const unsigned InlinePathSpace = 79 (DataSize - sizeof(LVBase)) / sizeof(LValuePathEntry); 80 81 /// Path - The sequence of base classes, fields and array indices to follow to 82 /// walk from Base to the subobject. When performing GCC-style folding, there 83 /// may not be such a path. 84 union { 85 LValuePathEntry Path[InlinePathSpace]; 86 LValuePathEntry *PathPtr; 87 }; 88 89 LV() { PathLength = (unsigned)-1; } 90 ~LV() { resizePath(0); } 91 92 void resizePath(unsigned Length) { 93 if (Length == PathLength) 94 return; 95 if (hasPathPtr()) 96 delete [] PathPtr; 97 PathLength = Length; 98 if (hasPathPtr()) 99 PathPtr = new LValuePathEntry[Length]; 100 } 101 102 bool hasPath() const { return PathLength != (unsigned)-1; } 103 bool hasPathPtr() const { return hasPath() && PathLength > InlinePathSpace; } 104 105 LValuePathEntry *getPath() { return hasPathPtr() ? PathPtr : Path; } 106 const LValuePathEntry *getPath() const { 107 return hasPathPtr() ? PathPtr : Path; 108 } 109 }; 110 111 namespace { 112 struct MemberPointerBase { 113 llvm::PointerIntPair<const ValueDecl*, 1, bool> MemberAndIsDerivedMember; 114 unsigned PathLength; 115 }; 116 } 117 118 struct APValue::MemberPointerData : MemberPointerBase { 119 static const unsigned InlinePathSpace = 120 (DataSize - sizeof(MemberPointerBase)) / sizeof(const CXXRecordDecl*); 121 typedef const CXXRecordDecl *PathElem; 122 union { 123 PathElem Path[InlinePathSpace]; 124 PathElem *PathPtr; 125 }; 126 127 MemberPointerData() { PathLength = 0; } 128 ~MemberPointerData() { resizePath(0); } 129 130 void resizePath(unsigned Length) { 131 if (Length == PathLength) 132 return; 133 if (hasPathPtr()) 134 delete [] PathPtr; 135 PathLength = Length; 136 if (hasPathPtr()) 137 PathPtr = new PathElem[Length]; 138 } 139 140 bool hasPathPtr() const { return PathLength > InlinePathSpace; } 141 142 PathElem *getPath() { return hasPathPtr() ? PathPtr : Path; } 143 const PathElem *getPath() const { 144 return hasPathPtr() ? PathPtr : Path; 145 } 146 }; 147 148 // FIXME: Reduce the malloc traffic here. 149 150 APValue::Arr::Arr(unsigned NumElts, unsigned Size) : 151 Elts(new APValue[NumElts + (NumElts != Size ? 1 : 0)]), 152 NumElts(NumElts), ArrSize(Size) {} 153 APValue::Arr::~Arr() { delete [] Elts; } 154 155 APValue::StructData::StructData(unsigned NumBases, unsigned NumFields) : 156 Elts(new APValue[NumBases+NumFields]), 157 NumBases(NumBases), NumFields(NumFields) {} 158 APValue::StructData::~StructData() { 159 delete [] Elts; 160 } 161 162 APValue::UnionData::UnionData() : Field(nullptr), Value(new APValue) {} 163 APValue::UnionData::~UnionData () { 164 delete Value; 165 } 166 167 APValue::APValue(const APValue &RHS) : Kind(Uninitialized) { 168 switch (RHS.getKind()) { 169 case Uninitialized: 170 break; 171 case Int: 172 MakeInt(); 173 setInt(RHS.getInt()); 174 break; 175 case Float: 176 MakeFloat(); 177 setFloat(RHS.getFloat()); 178 break; 179 case Vector: 180 MakeVector(); 181 setVector(((const Vec *)(const char *)RHS.Data.buffer)->Elts, 182 RHS.getVectorLength()); 183 break; 184 case ComplexInt: 185 MakeComplexInt(); 186 setComplexInt(RHS.getComplexIntReal(), RHS.getComplexIntImag()); 187 break; 188 case ComplexFloat: 189 MakeComplexFloat(); 190 setComplexFloat(RHS.getComplexFloatReal(), RHS.getComplexFloatImag()); 191 break; 192 case LValue: 193 MakeLValue(); 194 if (RHS.hasLValuePath()) 195 setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), RHS.getLValuePath(), 196 RHS.isLValueOnePastTheEnd(), RHS.isNullPointer()); 197 else 198 setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), NoLValuePath(), 199 RHS.isNullPointer()); 200 break; 201 case Array: 202 MakeArray(RHS.getArrayInitializedElts(), RHS.getArraySize()); 203 for (unsigned I = 0, N = RHS.getArrayInitializedElts(); I != N; ++I) 204 getArrayInitializedElt(I) = RHS.getArrayInitializedElt(I); 205 if (RHS.hasArrayFiller()) 206 getArrayFiller() = RHS.getArrayFiller(); 207 break; 208 case Struct: 209 MakeStruct(RHS.getStructNumBases(), RHS.getStructNumFields()); 210 for (unsigned I = 0, N = RHS.getStructNumBases(); I != N; ++I) 211 getStructBase(I) = RHS.getStructBase(I); 212 for (unsigned I = 0, N = RHS.getStructNumFields(); I != N; ++I) 213 getStructField(I) = RHS.getStructField(I); 214 break; 215 case Union: 216 MakeUnion(); 217 setUnion(RHS.getUnionField(), RHS.getUnionValue()); 218 break; 219 case MemberPointer: 220 MakeMemberPointer(RHS.getMemberPointerDecl(), 221 RHS.isMemberPointerToDerivedMember(), 222 RHS.getMemberPointerPath()); 223 break; 224 case AddrLabelDiff: 225 MakeAddrLabelDiff(); 226 setAddrLabelDiff(RHS.getAddrLabelDiffLHS(), RHS.getAddrLabelDiffRHS()); 227 break; 228 } 229 } 230 231 void APValue::DestroyDataAndMakeUninit() { 232 if (Kind == Int) 233 ((APSInt*)(char*)Data.buffer)->~APSInt(); 234 else if (Kind == Float) 235 ((APFloat*)(char*)Data.buffer)->~APFloat(); 236 else if (Kind == Vector) 237 ((Vec*)(char*)Data.buffer)->~Vec(); 238 else if (Kind == ComplexInt) 239 ((ComplexAPSInt*)(char*)Data.buffer)->~ComplexAPSInt(); 240 else if (Kind == ComplexFloat) 241 ((ComplexAPFloat*)(char*)Data.buffer)->~ComplexAPFloat(); 242 else if (Kind == LValue) 243 ((LV*)(char*)Data.buffer)->~LV(); 244 else if (Kind == Array) 245 ((Arr*)(char*)Data.buffer)->~Arr(); 246 else if (Kind == Struct) 247 ((StructData*)(char*)Data.buffer)->~StructData(); 248 else if (Kind == Union) 249 ((UnionData*)(char*)Data.buffer)->~UnionData(); 250 else if (Kind == MemberPointer) 251 ((MemberPointerData*)(char*)Data.buffer)->~MemberPointerData(); 252 else if (Kind == AddrLabelDiff) 253 ((AddrLabelDiffData*)(char*)Data.buffer)->~AddrLabelDiffData(); 254 Kind = Uninitialized; 255 } 256 257 bool APValue::needsCleanup() const { 258 switch (getKind()) { 259 case Uninitialized: 260 case AddrLabelDiff: 261 return false; 262 case Struct: 263 case Union: 264 case Array: 265 case Vector: 266 return true; 267 case Int: 268 return getInt().needsCleanup(); 269 case Float: 270 return getFloat().needsCleanup(); 271 case ComplexFloat: 272 assert(getComplexFloatImag().needsCleanup() == 273 getComplexFloatReal().needsCleanup() && 274 "In _Complex float types, real and imaginary values always have the " 275 "same size."); 276 return getComplexFloatReal().needsCleanup(); 277 case ComplexInt: 278 assert(getComplexIntImag().needsCleanup() == 279 getComplexIntReal().needsCleanup() && 280 "In _Complex int types, real and imaginary values must have the " 281 "same size."); 282 return getComplexIntReal().needsCleanup(); 283 case LValue: 284 return reinterpret_cast<const LV *>(Data.buffer)->hasPathPtr(); 285 case MemberPointer: 286 return reinterpret_cast<const MemberPointerData *>(Data.buffer) 287 ->hasPathPtr(); 288 } 289 llvm_unreachable("Unknown APValue kind!"); 290 } 291 292 void APValue::swap(APValue &RHS) { 293 std::swap(Kind, RHS.Kind); 294 char TmpData[DataSize]; 295 memcpy(TmpData, Data.buffer, DataSize); 296 memcpy(Data.buffer, RHS.Data.buffer, DataSize); 297 memcpy(RHS.Data.buffer, TmpData, DataSize); 298 } 299 300 LLVM_DUMP_METHOD void APValue::dump() const { 301 dump(llvm::errs()); 302 llvm::errs() << '\n'; 303 } 304 305 static double GetApproxValue(const llvm::APFloat &F) { 306 llvm::APFloat V = F; 307 bool ignored; 308 V.convert(llvm::APFloat::IEEEdouble(), llvm::APFloat::rmNearestTiesToEven, 309 &ignored); 310 return V.convertToDouble(); 311 } 312 313 void APValue::dump(raw_ostream &OS) const { 314 switch (getKind()) { 315 case Uninitialized: 316 OS << "Uninitialized"; 317 return; 318 case Int: 319 OS << "Int: " << getInt(); 320 return; 321 case Float: 322 OS << "Float: " << GetApproxValue(getFloat()); 323 return; 324 case Vector: 325 OS << "Vector: "; 326 getVectorElt(0).dump(OS); 327 for (unsigned i = 1; i != getVectorLength(); ++i) { 328 OS << ", "; 329 getVectorElt(i).dump(OS); 330 } 331 return; 332 case ComplexInt: 333 OS << "ComplexInt: " << getComplexIntReal() << ", " << getComplexIntImag(); 334 return; 335 case ComplexFloat: 336 OS << "ComplexFloat: " << GetApproxValue(getComplexFloatReal()) 337 << ", " << GetApproxValue(getComplexFloatImag()); 338 return; 339 case LValue: 340 OS << "LValue: <todo>"; 341 return; 342 case Array: 343 OS << "Array: "; 344 for (unsigned I = 0, N = getArrayInitializedElts(); I != N; ++I) { 345 getArrayInitializedElt(I).dump(OS); 346 if (I != getArraySize() - 1) OS << ", "; 347 } 348 if (hasArrayFiller()) { 349 OS << getArraySize() - getArrayInitializedElts() << " x "; 350 getArrayFiller().dump(OS); 351 } 352 return; 353 case Struct: 354 OS << "Struct "; 355 if (unsigned N = getStructNumBases()) { 356 OS << " bases: "; 357 getStructBase(0).dump(OS); 358 for (unsigned I = 1; I != N; ++I) { 359 OS << ", "; 360 getStructBase(I).dump(OS); 361 } 362 } 363 if (unsigned N = getStructNumFields()) { 364 OS << " fields: "; 365 getStructField(0).dump(OS); 366 for (unsigned I = 1; I != N; ++I) { 367 OS << ", "; 368 getStructField(I).dump(OS); 369 } 370 } 371 return; 372 case Union: 373 OS << "Union: "; 374 getUnionValue().dump(OS); 375 return; 376 case MemberPointer: 377 OS << "MemberPointer: <todo>"; 378 return; 379 case AddrLabelDiff: 380 OS << "AddrLabelDiff: <todo>"; 381 return; 382 } 383 llvm_unreachable("Unknown APValue kind!"); 384 } 385 386 void APValue::printPretty(raw_ostream &Out, ASTContext &Ctx, QualType Ty) const{ 387 switch (getKind()) { 388 case APValue::Uninitialized: 389 Out << "<uninitialized>"; 390 return; 391 case APValue::Int: 392 if (Ty->isBooleanType()) 393 Out << (getInt().getBoolValue() ? "true" : "false"); 394 else 395 Out << getInt(); 396 return; 397 case APValue::Float: 398 Out << GetApproxValue(getFloat()); 399 return; 400 case APValue::Vector: { 401 Out << '{'; 402 QualType ElemTy = Ty->getAs<VectorType>()->getElementType(); 403 getVectorElt(0).printPretty(Out, Ctx, ElemTy); 404 for (unsigned i = 1; i != getVectorLength(); ++i) { 405 Out << ", "; 406 getVectorElt(i).printPretty(Out, Ctx, ElemTy); 407 } 408 Out << '}'; 409 return; 410 } 411 case APValue::ComplexInt: 412 Out << getComplexIntReal() << "+" << getComplexIntImag() << "i"; 413 return; 414 case APValue::ComplexFloat: 415 Out << GetApproxValue(getComplexFloatReal()) << "+" 416 << GetApproxValue(getComplexFloatImag()) << "i"; 417 return; 418 case APValue::LValue: { 419 bool IsReference = Ty->isReferenceType(); 420 QualType InnerTy 421 = IsReference ? Ty.getNonReferenceType() : Ty->getPointeeType(); 422 if (InnerTy.isNull()) 423 InnerTy = Ty; 424 425 LValueBase Base = getLValueBase(); 426 if (!Base) { 427 if (isNullPointer()) { 428 Out << (Ctx.getLangOpts().CPlusPlus11 ? "nullptr" : "0"); 429 } else if (IsReference) { 430 Out << "*(" << InnerTy.stream(Ctx.getPrintingPolicy()) << "*)" 431 << getLValueOffset().getQuantity(); 432 } else { 433 Out << "(" << Ty.stream(Ctx.getPrintingPolicy()) << ")" 434 << getLValueOffset().getQuantity(); 435 } 436 return; 437 } 438 439 if (!hasLValuePath()) { 440 // No lvalue path: just print the offset. 441 CharUnits O = getLValueOffset(); 442 CharUnits S = Ctx.getTypeSizeInChars(InnerTy); 443 if (!O.isZero()) { 444 if (IsReference) 445 Out << "*("; 446 if (O % S) { 447 Out << "(char*)"; 448 S = CharUnits::One(); 449 } 450 Out << '&'; 451 } else if (!IsReference) 452 Out << '&'; 453 454 if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) 455 Out << *VD; 456 else { 457 assert(Base.get<const Expr *>() != nullptr && 458 "Expecting non-null Expr"); 459 Base.get<const Expr*>()->printPretty(Out, nullptr, 460 Ctx.getPrintingPolicy()); 461 } 462 463 if (!O.isZero()) { 464 Out << " + " << (O / S); 465 if (IsReference) 466 Out << ')'; 467 } 468 return; 469 } 470 471 // We have an lvalue path. Print it out nicely. 472 if (!IsReference) 473 Out << '&'; 474 else if (isLValueOnePastTheEnd()) 475 Out << "*(&"; 476 477 QualType ElemTy; 478 if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) { 479 Out << *VD; 480 ElemTy = VD->getType(); 481 } else { 482 const Expr *E = Base.get<const Expr*>(); 483 assert(E != nullptr && "Expecting non-null Expr"); 484 E->printPretty(Out, nullptr, Ctx.getPrintingPolicy()); 485 ElemTy = E->getType(); 486 } 487 488 ArrayRef<LValuePathEntry> Path = getLValuePath(); 489 const CXXRecordDecl *CastToBase = nullptr; 490 for (unsigned I = 0, N = Path.size(); I != N; ++I) { 491 if (ElemTy->getAs<RecordType>()) { 492 // The lvalue refers to a class type, so the next path entry is a base 493 // or member. 494 const Decl *BaseOrMember = 495 BaseOrMemberType::getFromOpaqueValue(Path[I].BaseOrMember).getPointer(); 496 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(BaseOrMember)) { 497 CastToBase = RD; 498 ElemTy = Ctx.getRecordType(RD); 499 } else { 500 const ValueDecl *VD = cast<ValueDecl>(BaseOrMember); 501 Out << "."; 502 if (CastToBase) 503 Out << *CastToBase << "::"; 504 Out << *VD; 505 ElemTy = VD->getType(); 506 } 507 } else { 508 // The lvalue must refer to an array. 509 Out << '[' << Path[I].ArrayIndex << ']'; 510 ElemTy = Ctx.getAsArrayType(ElemTy)->getElementType(); 511 } 512 } 513 514 // Handle formatting of one-past-the-end lvalues. 515 if (isLValueOnePastTheEnd()) { 516 // FIXME: If CastToBase is non-0, we should prefix the output with 517 // "(CastToBase*)". 518 Out << " + 1"; 519 if (IsReference) 520 Out << ')'; 521 } 522 return; 523 } 524 case APValue::Array: { 525 const ArrayType *AT = Ctx.getAsArrayType(Ty); 526 QualType ElemTy = AT->getElementType(); 527 Out << '{'; 528 if (unsigned N = getArrayInitializedElts()) { 529 getArrayInitializedElt(0).printPretty(Out, Ctx, ElemTy); 530 for (unsigned I = 1; I != N; ++I) { 531 Out << ", "; 532 if (I == 10) { 533 // Avoid printing out the entire contents of large arrays. 534 Out << "..."; 535 break; 536 } 537 getArrayInitializedElt(I).printPretty(Out, Ctx, ElemTy); 538 } 539 } 540 Out << '}'; 541 return; 542 } 543 case APValue::Struct: { 544 Out << '{'; 545 const RecordDecl *RD = Ty->getAs<RecordType>()->getDecl(); 546 bool First = true; 547 if (unsigned N = getStructNumBases()) { 548 const CXXRecordDecl *CD = cast<CXXRecordDecl>(RD); 549 CXXRecordDecl::base_class_const_iterator BI = CD->bases_begin(); 550 for (unsigned I = 0; I != N; ++I, ++BI) { 551 assert(BI != CD->bases_end()); 552 if (!First) 553 Out << ", "; 554 getStructBase(I).printPretty(Out, Ctx, BI->getType()); 555 First = false; 556 } 557 } 558 for (const auto *FI : RD->fields()) { 559 if (!First) 560 Out << ", "; 561 if (FI->isUnnamedBitfield()) continue; 562 getStructField(FI->getFieldIndex()). 563 printPretty(Out, Ctx, FI->getType()); 564 First = false; 565 } 566 Out << '}'; 567 return; 568 } 569 case APValue::Union: 570 Out << '{'; 571 if (const FieldDecl *FD = getUnionField()) { 572 Out << "." << *FD << " = "; 573 getUnionValue().printPretty(Out, Ctx, FD->getType()); 574 } 575 Out << '}'; 576 return; 577 case APValue::MemberPointer: 578 // FIXME: This is not enough to unambiguously identify the member in a 579 // multiple-inheritance scenario. 580 if (const ValueDecl *VD = getMemberPointerDecl()) { 581 Out << '&' << *cast<CXXRecordDecl>(VD->getDeclContext()) << "::" << *VD; 582 return; 583 } 584 Out << "0"; 585 return; 586 case APValue::AddrLabelDiff: 587 Out << "&&" << getAddrLabelDiffLHS()->getLabel()->getName(); 588 Out << " - "; 589 Out << "&&" << getAddrLabelDiffRHS()->getLabel()->getName(); 590 return; 591 } 592 llvm_unreachable("Unknown APValue kind!"); 593 } 594 595 std::string APValue::getAsString(ASTContext &Ctx, QualType Ty) const { 596 std::string Result; 597 llvm::raw_string_ostream Out(Result); 598 printPretty(Out, Ctx, Ty); 599 Out.flush(); 600 return Result; 601 } 602 603 const APValue::LValueBase APValue::getLValueBase() const { 604 assert(isLValue() && "Invalid accessor"); 605 return ((const LV*)(const void*)Data.buffer)->Base; 606 } 607 608 bool APValue::isLValueOnePastTheEnd() const { 609 assert(isLValue() && "Invalid accessor"); 610 return ((const LV*)(const void*)Data.buffer)->IsOnePastTheEnd; 611 } 612 613 CharUnits &APValue::getLValueOffset() { 614 assert(isLValue() && "Invalid accessor"); 615 return ((LV*)(void*)Data.buffer)->Offset; 616 } 617 618 bool APValue::hasLValuePath() const { 619 assert(isLValue() && "Invalid accessor"); 620 return ((const LV*)(const char*)Data.buffer)->hasPath(); 621 } 622 623 ArrayRef<APValue::LValuePathEntry> APValue::getLValuePath() const { 624 assert(isLValue() && hasLValuePath() && "Invalid accessor"); 625 const LV &LVal = *((const LV*)(const char*)Data.buffer); 626 return llvm::makeArrayRef(LVal.getPath(), LVal.PathLength); 627 } 628 629 unsigned APValue::getLValueCallIndex() const { 630 assert(isLValue() && "Invalid accessor"); 631 return ((const LV*)(const char*)Data.buffer)->Base.getCallIndex(); 632 } 633 634 unsigned APValue::getLValueVersion() const { 635 assert(isLValue() && "Invalid accessor"); 636 return ((const LV*)(const char*)Data.buffer)->Base.getVersion(); 637 } 638 639 bool APValue::isNullPointer() const { 640 assert(isLValue() && "Invalid usage"); 641 return ((const LV*)(const char*)Data.buffer)->IsNullPtr; 642 } 643 644 void APValue::setLValue(LValueBase B, const CharUnits &O, NoLValuePath, 645 bool IsNullPtr) { 646 assert(isLValue() && "Invalid accessor"); 647 LV &LVal = *((LV*)(char*)Data.buffer); 648 LVal.Base = B; 649 LVal.IsOnePastTheEnd = false; 650 LVal.Offset = O; 651 LVal.resizePath((unsigned)-1); 652 LVal.IsNullPtr = IsNullPtr; 653 } 654 655 void APValue::setLValue(LValueBase B, const CharUnits &O, 656 ArrayRef<LValuePathEntry> Path, bool IsOnePastTheEnd, 657 bool IsNullPtr) { 658 assert(isLValue() && "Invalid accessor"); 659 LV &LVal = *((LV*)(char*)Data.buffer); 660 LVal.Base = B; 661 LVal.IsOnePastTheEnd = IsOnePastTheEnd; 662 LVal.Offset = O; 663 LVal.resizePath(Path.size()); 664 memcpy(LVal.getPath(), Path.data(), Path.size() * sizeof(LValuePathEntry)); 665 LVal.IsNullPtr = IsNullPtr; 666 } 667 668 const ValueDecl *APValue::getMemberPointerDecl() const { 669 assert(isMemberPointer() && "Invalid accessor"); 670 const MemberPointerData &MPD = 671 *((const MemberPointerData *)(const char *)Data.buffer); 672 return MPD.MemberAndIsDerivedMember.getPointer(); 673 } 674 675 bool APValue::isMemberPointerToDerivedMember() const { 676 assert(isMemberPointer() && "Invalid accessor"); 677 const MemberPointerData &MPD = 678 *((const MemberPointerData *)(const char *)Data.buffer); 679 return MPD.MemberAndIsDerivedMember.getInt(); 680 } 681 682 ArrayRef<const CXXRecordDecl*> APValue::getMemberPointerPath() const { 683 assert(isMemberPointer() && "Invalid accessor"); 684 const MemberPointerData &MPD = 685 *((const MemberPointerData *)(const char *)Data.buffer); 686 return llvm::makeArrayRef(MPD.getPath(), MPD.PathLength); 687 } 688 689 void APValue::MakeLValue() { 690 assert(isUninit() && "Bad state change"); 691 static_assert(sizeof(LV) <= DataSize, "LV too big"); 692 new ((void*)(char*)Data.buffer) LV(); 693 Kind = LValue; 694 } 695 696 void APValue::MakeArray(unsigned InitElts, unsigned Size) { 697 assert(isUninit() && "Bad state change"); 698 new ((void*)(char*)Data.buffer) Arr(InitElts, Size); 699 Kind = Array; 700 } 701 702 void APValue::MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember, 703 ArrayRef<const CXXRecordDecl*> Path) { 704 assert(isUninit() && "Bad state change"); 705 MemberPointerData *MPD = new ((void*)(char*)Data.buffer) MemberPointerData; 706 Kind = MemberPointer; 707 MPD->MemberAndIsDerivedMember.setPointer(Member); 708 MPD->MemberAndIsDerivedMember.setInt(IsDerivedMember); 709 MPD->resizePath(Path.size()); 710 memcpy(MPD->getPath(), Path.data(), Path.size()*sizeof(const CXXRecordDecl*)); 711 } 712