1216 lines · cpp
1//===--- APValue.cpp - Union class for APFloat/APSInt/Complex -------------===//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-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements the APValue class.10//11//===----------------------------------------------------------------------===//12 13#include "clang/AST/APValue.h"14#include "Linkage.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/ExprCXX.h"20#include "clang/AST/Type.h"21#include "llvm/Support/ErrorHandling.h"22#include "llvm/Support/raw_ostream.h"23using namespace clang;24 25/// The identity of a type_info object depends on the canonical unqualified26/// type only.27TypeInfoLValue::TypeInfoLValue(const Type *T)28 : T(T->getCanonicalTypeUnqualified().getTypePtr()) {}29 30void TypeInfoLValue::print(llvm::raw_ostream &Out,31 const PrintingPolicy &Policy) const {32 Out << "typeid(";33 QualType(getType(), 0).print(Out, Policy);34 Out << ")";35}36 37static_assert(38 1 << llvm::PointerLikeTypeTraits<TypeInfoLValue>::NumLowBitsAvailable <=39 alignof(Type),40 "Type is insufficiently aligned");41 42APValue::LValueBase::LValueBase(const ValueDecl *P, unsigned I, unsigned V)43 : Ptr(P ? cast<ValueDecl>(P->getCanonicalDecl()) : nullptr), Local{I, V} {}44APValue::LValueBase::LValueBase(const Expr *P, unsigned I, unsigned V)45 : Ptr(P), Local{I, V} {}46 47APValue::LValueBase APValue::LValueBase::getDynamicAlloc(DynamicAllocLValue LV,48 QualType Type) {49 LValueBase Base;50 Base.Ptr = LV;51 Base.DynamicAllocType = Type.getAsOpaquePtr();52 return Base;53}54 55APValue::LValueBase APValue::LValueBase::getTypeInfo(TypeInfoLValue LV,56 QualType TypeInfo) {57 LValueBase Base;58 Base.Ptr = LV;59 Base.TypeInfoType = TypeInfo.getAsOpaquePtr();60 return Base;61}62 63QualType APValue::LValueBase::getType() const {64 if (!*this) return QualType();65 if (const ValueDecl *D = dyn_cast<const ValueDecl*>()) {66 // FIXME: It's unclear where we're supposed to take the type from, and67 // this actually matters for arrays of unknown bound. Eg:68 //69 // extern int arr[]; void f() { extern int arr[3]; };70 // constexpr int *p = &arr[1]; // valid?71 //72 // For now, we take the most complete type we can find.73 for (auto *Redecl = cast<ValueDecl>(D->getMostRecentDecl()); Redecl;74 Redecl = cast_or_null<ValueDecl>(Redecl->getPreviousDecl())) {75 QualType T = Redecl->getType();76 if (!T->isIncompleteArrayType())77 return T;78 }79 return D->getType();80 }81 82 if (is<TypeInfoLValue>())83 return getTypeInfoType();84 85 if (is<DynamicAllocLValue>())86 return getDynamicAllocType();87 88 const Expr *Base = get<const Expr*>();89 90 // For a materialized temporary, the type of the temporary we materialized91 // may not be the type of the expression.92 if (const MaterializeTemporaryExpr *MTE =93 llvm::dyn_cast<MaterializeTemporaryExpr>(Base)) {94 SmallVector<const Expr *, 2> CommaLHSs;95 SmallVector<SubobjectAdjustment, 2> Adjustments;96 const Expr *Temp = MTE->getSubExpr();97 const Expr *Inner = Temp->skipRValueSubobjectAdjustments(CommaLHSs,98 Adjustments);99 // Keep any cv-qualifiers from the reference if we generated a temporary100 // for it directly. Otherwise use the type after adjustment.101 if (!Adjustments.empty())102 return Inner->getType();103 }104 105 return Base->getType();106}107 108unsigned APValue::LValueBase::getCallIndex() const {109 return (is<TypeInfoLValue>() || is<DynamicAllocLValue>()) ? 0110 : Local.CallIndex;111}112 113unsigned APValue::LValueBase::getVersion() const {114 return (is<TypeInfoLValue>() || is<DynamicAllocLValue>()) ? 0 : Local.Version;115}116 117QualType APValue::LValueBase::getTypeInfoType() const {118 assert(is<TypeInfoLValue>() && "not a type_info lvalue");119 return QualType::getFromOpaquePtr(TypeInfoType);120}121 122QualType APValue::LValueBase::getDynamicAllocType() const {123 assert(is<DynamicAllocLValue>() && "not a dynamic allocation lvalue");124 return QualType::getFromOpaquePtr(DynamicAllocType);125}126 127void APValue::LValueBase::Profile(llvm::FoldingSetNodeID &ID) const {128 ID.AddPointer(Ptr.getOpaqueValue());129 if (is<TypeInfoLValue>() || is<DynamicAllocLValue>())130 return;131 ID.AddInteger(Local.CallIndex);132 ID.AddInteger(Local.Version);133}134 135namespace clang {136bool operator==(const APValue::LValueBase &LHS,137 const APValue::LValueBase &RHS) {138 if (LHS.Ptr != RHS.Ptr)139 return false;140 if (LHS.is<TypeInfoLValue>() || LHS.is<DynamicAllocLValue>())141 return true;142 return LHS.Local.CallIndex == RHS.Local.CallIndex &&143 LHS.Local.Version == RHS.Local.Version;144}145}146 147APValue::LValuePathEntry::LValuePathEntry(BaseOrMemberType BaseOrMember) {148 if (const Decl *D = BaseOrMember.getPointer())149 BaseOrMember.setPointer(D->getCanonicalDecl());150 Value = reinterpret_cast<uintptr_t>(BaseOrMember.getOpaqueValue());151}152 153void APValue::LValuePathEntry::Profile(llvm::FoldingSetNodeID &ID) const {154 ID.AddInteger(Value);155}156 157APValue::LValuePathSerializationHelper::LValuePathSerializationHelper(158 ArrayRef<LValuePathEntry> Path, QualType ElemTy)159 : Ty((const void *)ElemTy.getTypePtrOrNull()), Path(Path) {}160 161QualType APValue::LValuePathSerializationHelper::getType() {162 return QualType::getFromOpaquePtr(Ty);163}164 165namespace {166 struct LVBase {167 APValue::LValueBase Base;168 CharUnits Offset;169 unsigned PathLength;170 bool IsNullPtr : 1;171 bool IsOnePastTheEnd : 1;172 };173}174 175void *APValue::LValueBase::getOpaqueValue() const {176 return Ptr.getOpaqueValue();177}178 179bool APValue::LValueBase::isNull() const {180 return Ptr.isNull();181}182 183APValue::LValueBase::operator bool () const {184 return static_cast<bool>(Ptr);185}186 187clang::APValue::LValueBase188llvm::DenseMapInfo<clang::APValue::LValueBase>::getEmptyKey() {189 clang::APValue::LValueBase B;190 B.Ptr = DenseMapInfo<const ValueDecl*>::getEmptyKey();191 return B;192}193 194clang::APValue::LValueBase195llvm::DenseMapInfo<clang::APValue::LValueBase>::getTombstoneKey() {196 clang::APValue::LValueBase B;197 B.Ptr = DenseMapInfo<const ValueDecl*>::getTombstoneKey();198 return B;199}200 201namespace clang {202llvm::hash_code hash_value(const APValue::LValueBase &Base) {203 if (Base.is<TypeInfoLValue>() || Base.is<DynamicAllocLValue>())204 return llvm::hash_value(Base.getOpaqueValue());205 return llvm::hash_combine(Base.getOpaqueValue(), Base.getCallIndex(),206 Base.getVersion());207}208}209 210unsigned llvm::DenseMapInfo<clang::APValue::LValueBase>::getHashValue(211 const clang::APValue::LValueBase &Base) {212 return hash_value(Base);213}214 215bool llvm::DenseMapInfo<clang::APValue::LValueBase>::isEqual(216 const clang::APValue::LValueBase &LHS,217 const clang::APValue::LValueBase &RHS) {218 return LHS == RHS;219}220 221struct APValue::LV : LVBase {222 static const unsigned InlinePathSpace =223 (DataSize - sizeof(LVBase)) / sizeof(LValuePathEntry);224 225 /// Path - The sequence of base classes, fields and array indices to follow to226 /// walk from Base to the subobject. When performing GCC-style folding, there227 /// may not be such a path.228 union {229 LValuePathEntry Path[InlinePathSpace];230 LValuePathEntry *PathPtr;231 };232 233 LV() { PathLength = (unsigned)-1; }234 ~LV() { resizePath(0); }235 236 void resizePath(unsigned Length) {237 if (Length == PathLength)238 return;239 if (hasPathPtr())240 delete [] PathPtr;241 PathLength = Length;242 if (hasPathPtr())243 PathPtr = new LValuePathEntry[Length];244 }245 246 bool hasPath() const { return PathLength != (unsigned)-1; }247 bool hasPathPtr() const { return hasPath() && PathLength > InlinePathSpace; }248 249 LValuePathEntry *getPath() { return hasPathPtr() ? PathPtr : Path; }250 const LValuePathEntry *getPath() const {251 return hasPathPtr() ? PathPtr : Path;252 }253};254 255namespace {256 struct MemberPointerBase {257 llvm::PointerIntPair<const ValueDecl*, 1, bool> MemberAndIsDerivedMember;258 unsigned PathLength;259 };260}261 262struct APValue::MemberPointerData : MemberPointerBase {263 static const unsigned InlinePathSpace =264 (DataSize - sizeof(MemberPointerBase)) / sizeof(const CXXRecordDecl*);265 typedef const CXXRecordDecl *PathElem;266 union {267 PathElem Path[InlinePathSpace];268 PathElem *PathPtr;269 };270 271 MemberPointerData() { PathLength = 0; }272 ~MemberPointerData() { resizePath(0); }273 274 void resizePath(unsigned Length) {275 if (Length == PathLength)276 return;277 if (hasPathPtr())278 delete [] PathPtr;279 PathLength = Length;280 if (hasPathPtr())281 PathPtr = new PathElem[Length];282 }283 284 bool hasPathPtr() const { return PathLength > InlinePathSpace; }285 286 PathElem *getPath() { return hasPathPtr() ? PathPtr : Path; }287 const PathElem *getPath() const {288 return hasPathPtr() ? PathPtr : Path;289 }290};291 292// FIXME: Reduce the malloc traffic here.293 294APValue::Arr::Arr(unsigned NumElts, unsigned Size) :295 Elts(new APValue[NumElts + (NumElts != Size ? 1 : 0)]),296 NumElts(NumElts), ArrSize(Size) {}297APValue::Arr::~Arr() { delete [] Elts; }298 299APValue::StructData::StructData(unsigned NumBases, unsigned NumFields) :300 Elts(new APValue[NumBases+NumFields]),301 NumBases(NumBases), NumFields(NumFields) {}302APValue::StructData::~StructData() {303 delete [] Elts;304}305 306APValue::UnionData::UnionData() : Field(nullptr), Value(new APValue) {}307APValue::UnionData::~UnionData () {308 delete Value;309}310 311APValue::APValue(const APValue &RHS)312 : Kind(None), AllowConstexprUnknown(RHS.AllowConstexprUnknown) {313 switch (RHS.getKind()) {314 case None:315 case Indeterminate:316 Kind = RHS.getKind();317 break;318 case Int:319 MakeInt();320 setInt(RHS.getInt());321 break;322 case Float:323 MakeFloat();324 setFloat(RHS.getFloat());325 break;326 case FixedPoint: {327 APFixedPoint FXCopy = RHS.getFixedPoint();328 MakeFixedPoint(std::move(FXCopy));329 break;330 }331 case Vector:332 MakeVector();333 setVector(((const Vec *)(const char *)&RHS.Data)->Elts,334 RHS.getVectorLength());335 break;336 case ComplexInt:337 MakeComplexInt();338 setComplexInt(RHS.getComplexIntReal(), RHS.getComplexIntImag());339 break;340 case ComplexFloat:341 MakeComplexFloat();342 setComplexFloat(RHS.getComplexFloatReal(), RHS.getComplexFloatImag());343 break;344 case LValue:345 MakeLValue();346 if (RHS.hasLValuePath())347 setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), RHS.getLValuePath(),348 RHS.isLValueOnePastTheEnd(), RHS.isNullPointer());349 else350 setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), NoLValuePath(),351 RHS.isNullPointer());352 break;353 case Array:354 MakeArray(RHS.getArrayInitializedElts(), RHS.getArraySize());355 for (unsigned I = 0, N = RHS.getArrayInitializedElts(); I != N; ++I)356 getArrayInitializedElt(I) = RHS.getArrayInitializedElt(I);357 if (RHS.hasArrayFiller())358 getArrayFiller() = RHS.getArrayFiller();359 break;360 case Struct:361 MakeStruct(RHS.getStructNumBases(), RHS.getStructNumFields());362 for (unsigned I = 0, N = RHS.getStructNumBases(); I != N; ++I)363 getStructBase(I) = RHS.getStructBase(I);364 for (unsigned I = 0, N = RHS.getStructNumFields(); I != N; ++I)365 getStructField(I) = RHS.getStructField(I);366 break;367 case Union:368 MakeUnion();369 setUnion(RHS.getUnionField(), RHS.getUnionValue());370 break;371 case MemberPointer:372 MakeMemberPointer(RHS.getMemberPointerDecl(),373 RHS.isMemberPointerToDerivedMember(),374 RHS.getMemberPointerPath());375 break;376 case AddrLabelDiff:377 MakeAddrLabelDiff();378 setAddrLabelDiff(RHS.getAddrLabelDiffLHS(), RHS.getAddrLabelDiffRHS());379 break;380 }381}382 383APValue::APValue(APValue &&RHS)384 : Kind(RHS.Kind), AllowConstexprUnknown(RHS.AllowConstexprUnknown),385 Data(RHS.Data) {386 RHS.Kind = None;387}388 389APValue &APValue::operator=(const APValue &RHS) {390 if (this != &RHS)391 *this = APValue(RHS);392 393 return *this;394}395 396APValue &APValue::operator=(APValue &&RHS) {397 if (this != &RHS) {398 if (Kind != None && Kind != Indeterminate)399 DestroyDataAndMakeUninit();400 Kind = RHS.Kind;401 Data = RHS.Data;402 AllowConstexprUnknown = RHS.AllowConstexprUnknown;403 RHS.Kind = None;404 }405 return *this;406}407 408void APValue::DestroyDataAndMakeUninit() {409 if (Kind == Int)410 ((APSInt *)(char *)&Data)->~APSInt();411 else if (Kind == Float)412 ((APFloat *)(char *)&Data)->~APFloat();413 else if (Kind == FixedPoint)414 ((APFixedPoint *)(char *)&Data)->~APFixedPoint();415 else if (Kind == Vector)416 ((Vec *)(char *)&Data)->~Vec();417 else if (Kind == ComplexInt)418 ((ComplexAPSInt *)(char *)&Data)->~ComplexAPSInt();419 else if (Kind == ComplexFloat)420 ((ComplexAPFloat *)(char *)&Data)->~ComplexAPFloat();421 else if (Kind == LValue)422 ((LV *)(char *)&Data)->~LV();423 else if (Kind == Array)424 ((Arr *)(char *)&Data)->~Arr();425 else if (Kind == Struct)426 ((StructData *)(char *)&Data)->~StructData();427 else if (Kind == Union)428 ((UnionData *)(char *)&Data)->~UnionData();429 else if (Kind == MemberPointer)430 ((MemberPointerData *)(char *)&Data)->~MemberPointerData();431 else if (Kind == AddrLabelDiff)432 ((AddrLabelDiffData *)(char *)&Data)->~AddrLabelDiffData();433 Kind = None;434 AllowConstexprUnknown = false;435}436 437bool APValue::needsCleanup() const {438 switch (getKind()) {439 case None:440 case Indeterminate:441 case AddrLabelDiff:442 return false;443 case Struct:444 case Union:445 case Array:446 case Vector:447 return true;448 case Int:449 return getInt().needsCleanup();450 case Float:451 return getFloat().needsCleanup();452 case FixedPoint:453 return getFixedPoint().getValue().needsCleanup();454 case ComplexFloat:455 assert(getComplexFloatImag().needsCleanup() ==456 getComplexFloatReal().needsCleanup() &&457 "In _Complex float types, real and imaginary values always have the "458 "same size.");459 return getComplexFloatReal().needsCleanup();460 case ComplexInt:461 assert(getComplexIntImag().needsCleanup() ==462 getComplexIntReal().needsCleanup() &&463 "In _Complex int types, real and imaginary values must have the "464 "same size.");465 return getComplexIntReal().needsCleanup();466 case LValue:467 return reinterpret_cast<const LV *>(&Data)->hasPathPtr();468 case MemberPointer:469 return reinterpret_cast<const MemberPointerData *>(&Data)->hasPathPtr();470 }471 llvm_unreachable("Unknown APValue kind!");472}473 474void APValue::swap(APValue &RHS) {475 std::swap(Kind, RHS.Kind);476 std::swap(Data, RHS.Data);477 // We can't use std::swap w/ bit-fields478 bool tmp = AllowConstexprUnknown;479 AllowConstexprUnknown = RHS.AllowConstexprUnknown;480 RHS.AllowConstexprUnknown = tmp;481}482 483/// Profile the value of an APInt, excluding its bit-width.484static void profileIntValue(llvm::FoldingSetNodeID &ID, const llvm::APInt &V) {485 for (unsigned I = 0, N = V.getBitWidth(); I < N; I += 32)486 ID.AddInteger((uint32_t)V.extractBitsAsZExtValue(std::min(32u, N - I), I));487}488 489void APValue::Profile(llvm::FoldingSetNodeID &ID) const {490 // Note that our profiling assumes that only APValues of the same type are491 // ever compared. As a result, we don't consider collisions that could only492 // happen if the types are different. (For example, structs with different493 // numbers of members could profile the same.)494 495 ID.AddInteger(Kind);496 497 switch (Kind) {498 case None:499 case Indeterminate:500 return;501 502 case AddrLabelDiff:503 ID.AddPointer(getAddrLabelDiffLHS()->getLabel()->getCanonicalDecl());504 ID.AddPointer(getAddrLabelDiffRHS()->getLabel()->getCanonicalDecl());505 return;506 507 case Struct:508 for (unsigned I = 0, N = getStructNumBases(); I != N; ++I)509 getStructBase(I).Profile(ID);510 for (unsigned I = 0, N = getStructNumFields(); I != N; ++I)511 getStructField(I).Profile(ID);512 return;513 514 case Union:515 if (!getUnionField()) {516 ID.AddInteger(0);517 return;518 }519 ID.AddInteger(getUnionField()->getFieldIndex() + 1);520 getUnionValue().Profile(ID);521 return;522 523 case Array: {524 if (getArraySize() == 0)525 return;526 527 // The profile should not depend on whether the array is expanded or528 // not, but we don't want to profile the array filler many times for529 // a large array. So treat all equal trailing elements as the filler.530 // Elements are profiled in reverse order to support this, and the531 // first profiled element is followed by a count. For example:532 //533 // ['a', 'c', 'x', 'x', 'x'] is profiled as534 // [5, 'x', 3, 'c', 'a']535 llvm::FoldingSetNodeID FillerID;536 (hasArrayFiller() ? getArrayFiller()537 : getArrayInitializedElt(getArrayInitializedElts() - 1))538 .Profile(FillerID);539 ID.AddNodeID(FillerID);540 unsigned NumFillers = getArraySize() - getArrayInitializedElts();541 unsigned N = getArrayInitializedElts();542 543 // Count the number of elements equal to the last one. This loop ends544 // by adding an integer indicating the number of such elements, with545 // N set to the number of elements left to profile.546 while (true) {547 if (N == 0) {548 // All elements are fillers.549 assert(NumFillers == getArraySize());550 ID.AddInteger(NumFillers);551 break;552 }553 554 // No need to check if the last element is equal to the last555 // element.556 if (N != getArraySize()) {557 llvm::FoldingSetNodeID ElemID;558 getArrayInitializedElt(N - 1).Profile(ElemID);559 if (ElemID != FillerID) {560 ID.AddInteger(NumFillers);561 ID.AddNodeID(ElemID);562 --N;563 break;564 }565 }566 567 // This is a filler.568 ++NumFillers;569 --N;570 }571 572 // Emit the remaining elements.573 for (; N != 0; --N)574 getArrayInitializedElt(N - 1).Profile(ID);575 return;576 }577 578 case Vector:579 for (unsigned I = 0, N = getVectorLength(); I != N; ++I)580 getVectorElt(I).Profile(ID);581 return;582 583 case Int:584 profileIntValue(ID, getInt());585 return;586 587 case Float:588 profileIntValue(ID, getFloat().bitcastToAPInt());589 return;590 591 case FixedPoint:592 profileIntValue(ID, getFixedPoint().getValue());593 return;594 595 case ComplexFloat:596 profileIntValue(ID, getComplexFloatReal().bitcastToAPInt());597 profileIntValue(ID, getComplexFloatImag().bitcastToAPInt());598 return;599 600 case ComplexInt:601 profileIntValue(ID, getComplexIntReal());602 profileIntValue(ID, getComplexIntImag());603 return;604 605 case LValue:606 getLValueBase().Profile(ID);607 ID.AddInteger(getLValueOffset().getQuantity());608 ID.AddInteger((isNullPointer() ? 1 : 0) |609 (isLValueOnePastTheEnd() ? 2 : 0) |610 (hasLValuePath() ? 4 : 0));611 if (hasLValuePath()) {612 ID.AddInteger(getLValuePath().size());613 // For uniqueness, we only need to profile the entries corresponding614 // to union members, but we don't have the type here so we don't know615 // how to interpret the entries.616 for (LValuePathEntry E : getLValuePath())617 E.Profile(ID);618 }619 return;620 621 case MemberPointer:622 ID.AddPointer(getMemberPointerDecl());623 ID.AddInteger(isMemberPointerToDerivedMember());624 for (const CXXRecordDecl *D : getMemberPointerPath())625 ID.AddPointer(D);626 return;627 }628 629 llvm_unreachable("Unknown APValue kind!");630}631 632static double GetApproxValue(const llvm::APFloat &F) {633 llvm::APFloat V = F;634 bool ignored;635 V.convert(llvm::APFloat::IEEEdouble(), llvm::APFloat::rmNearestTiesToEven,636 &ignored);637 return V.convertToDouble();638}639 640static bool TryPrintAsStringLiteral(raw_ostream &Out,641 const PrintingPolicy &Policy,642 const ArrayType *ATy,643 ArrayRef<APValue> Inits) {644 if (Inits.empty())645 return false;646 647 QualType Ty = ATy->getElementType();648 if (!Ty->isAnyCharacterType())649 return false;650 651 // Nothing we can do about a sequence that is not null-terminated652 if (!Inits.back().isInt() || !Inits.back().getInt().isZero())653 return false;654 655 Inits = Inits.drop_back();656 657 llvm::SmallString<40> Buf;658 Buf.push_back('"');659 660 // Better than printing a two-digit sequence of 10 integers.661 constexpr size_t MaxN = 36;662 StringRef Ellipsis;663 if (Inits.size() > MaxN && !Policy.EntireContentsOfLargeArray) {664 Ellipsis = "[...]";665 Inits =666 Inits.take_front(std::min(MaxN - Ellipsis.size() / 2, Inits.size()));667 }668 669 for (auto &Val : Inits) {670 if (!Val.isInt())671 return false;672 int64_t Char64 = Val.getInt().getExtValue();673 if (!isASCII(Char64))674 return false; // Bye bye, see you in integers.675 auto Ch = static_cast<unsigned char>(Char64);676 // The diagnostic message is 'quoted'677 StringRef Escaped = escapeCStyle<EscapeChar::SingleAndDouble>(Ch);678 if (Escaped.empty()) {679 if (!isPrintable(Ch))680 return false;681 Buf.emplace_back(Ch);682 } else {683 Buf.append(Escaped);684 }685 }686 687 Buf.append(Ellipsis);688 Buf.push_back('"');689 690 if (Ty->isWideCharType())691 Out << 'L';692 else if (Ty->isChar8Type())693 Out << "u8";694 else if (Ty->isChar16Type())695 Out << 'u';696 else if (Ty->isChar32Type())697 Out << 'U';698 699 Out << Buf;700 return true;701}702 703void APValue::printPretty(raw_ostream &Out, const ASTContext &Ctx,704 QualType Ty) const {705 printPretty(Out, Ctx.getPrintingPolicy(), Ty, &Ctx);706}707 708void APValue::printPretty(raw_ostream &Out, const PrintingPolicy &Policy,709 QualType Ty, const ASTContext *Ctx) const {710 // There are no objects of type 'void', but values of this type can be711 // returned from functions.712 if (Ty->isVoidType()) {713 Out << "void()";714 return;715 }716 717 if (const auto *AT = Ty->getAs<AtomicType>())718 Ty = AT->getValueType();719 720 switch (getKind()) {721 case APValue::None:722 Out << "<out of lifetime>";723 return;724 case APValue::Indeterminate:725 Out << "<uninitialized>";726 return;727 case APValue::Int:728 if (Ty->isBooleanType())729 Out << (getInt().getBoolValue() ? "true" : "false");730 else731 Out << getInt();732 return;733 case APValue::Float:734 Out << GetApproxValue(getFloat());735 return;736 case APValue::FixedPoint:737 Out << getFixedPoint();738 return;739 case APValue::Vector: {740 Out << '{';741 QualType ElemTy = Ty->castAs<VectorType>()->getElementType();742 getVectorElt(0).printPretty(Out, Policy, ElemTy, Ctx);743 for (unsigned i = 1; i != getVectorLength(); ++i) {744 Out << ", ";745 getVectorElt(i).printPretty(Out, Policy, ElemTy, Ctx);746 }747 Out << '}';748 return;749 }750 case APValue::ComplexInt:751 Out << getComplexIntReal() << "+" << getComplexIntImag() << "i";752 return;753 case APValue::ComplexFloat:754 Out << GetApproxValue(getComplexFloatReal()) << "+"755 << GetApproxValue(getComplexFloatImag()) << "i";756 return;757 case APValue::LValue: {758 bool IsReference = Ty->isReferenceType();759 QualType InnerTy760 = IsReference ? Ty.getNonReferenceType() : Ty->getPointeeType();761 if (InnerTy.isNull())762 InnerTy = Ty;763 764 LValueBase Base = getLValueBase();765 if (!Base) {766 if (isNullPointer()) {767 Out << (Policy.Nullptr ? "nullptr" : "0");768 } else if (IsReference) {769 Out << "*(" << InnerTy.stream(Policy) << "*)"770 << getLValueOffset().getQuantity();771 } else {772 Out << "(" << Ty.stream(Policy) << ")"773 << getLValueOffset().getQuantity();774 }775 return;776 }777 778 if (!hasLValuePath()) {779 // No lvalue path: just print the offset.780 CharUnits O = getLValueOffset();781 CharUnits S = Ctx ? Ctx->getTypeSizeInCharsIfKnown(InnerTy).value_or(782 CharUnits::Zero())783 : CharUnits::Zero();784 if (!O.isZero()) {785 if (IsReference)786 Out << "*(";787 if (S.isZero() || !O.isMultipleOf(S)) {788 Out << "(char*)";789 S = CharUnits::One();790 }791 Out << '&';792 } else if (!IsReference) {793 Out << '&';794 }795 796 if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>())797 Out << *VD;798 else if (TypeInfoLValue TI = Base.dyn_cast<TypeInfoLValue>()) {799 TI.print(Out, Policy);800 } else if (DynamicAllocLValue DA = Base.dyn_cast<DynamicAllocLValue>()) {801 Out << "{*new "802 << Base.getDynamicAllocType().stream(Policy) << "#"803 << DA.getIndex() << "}";804 } else {805 assert(Base.get<const Expr *>() != nullptr &&806 "Expecting non-null Expr");807 Base.get<const Expr*>()->printPretty(Out, nullptr, Policy);808 }809 810 if (!O.isZero()) {811 Out << " + " << (O / S);812 if (IsReference)813 Out << ')';814 }815 return;816 }817 818 // We have an lvalue path. Print it out nicely.819 if (!IsReference)820 Out << '&';821 else if (isLValueOnePastTheEnd())822 Out << "*(&";823 824 QualType ElemTy = Base.getType().getNonReferenceType();825 if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) {826 Out << *VD;827 } else if (TypeInfoLValue TI = Base.dyn_cast<TypeInfoLValue>()) {828 TI.print(Out, Policy);829 } else if (DynamicAllocLValue DA = Base.dyn_cast<DynamicAllocLValue>()) {830 Out << "{*new " << Base.getDynamicAllocType().stream(Policy) << "#"831 << DA.getIndex() << "}";832 } else {833 const Expr *E = Base.get<const Expr*>();834 assert(E != nullptr && "Expecting non-null Expr");835 E->printPretty(Out, nullptr, Policy);836 }837 838 ArrayRef<LValuePathEntry> Path = getLValuePath();839 const CXXRecordDecl *CastToBase = nullptr;840 for (unsigned I = 0, N = Path.size(); I != N; ++I) {841 if (ElemTy->isRecordType()) {842 // The lvalue refers to a class type, so the next path entry is a base843 // or member.844 const Decl *BaseOrMember = Path[I].getAsBaseOrMember().getPointer();845 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(BaseOrMember)) {846 CastToBase = RD;847 // Leave ElemTy referring to the most-derived class. The actual type848 // doesn't matter except for array types.849 } else {850 const ValueDecl *VD = cast<ValueDecl>(BaseOrMember);851 Out << ".";852 if (CastToBase)853 Out << *CastToBase << "::";854 Out << *VD;855 ElemTy = VD->getType();856 }857 } else if (ElemTy->isAnyComplexType()) {858 // The lvalue refers to a complex type859 Out << (Path[I].getAsArrayIndex() == 0 ? ".real" : ".imag");860 ElemTy = ElemTy->castAs<ComplexType>()->getElementType();861 } else {862 // The lvalue must refer to an array.863 Out << '[' << Path[I].getAsArrayIndex() << ']';864 ElemTy = ElemTy->castAsArrayTypeUnsafe()->getElementType();865 }866 }867 868 // Handle formatting of one-past-the-end lvalues.869 if (isLValueOnePastTheEnd()) {870 // FIXME: If CastToBase is non-0, we should prefix the output with871 // "(CastToBase*)".872 Out << " + 1";873 if (IsReference)874 Out << ')';875 }876 return;877 }878 case APValue::Array: {879 const ArrayType *AT = Ty->castAsArrayTypeUnsafe();880 unsigned N = getArrayInitializedElts();881 if (N != 0 && TryPrintAsStringLiteral(Out, Policy, AT,882 {&getArrayInitializedElt(0), N}))883 return;884 QualType ElemTy = AT->getElementType();885 Out << '{';886 unsigned I = 0;887 switch (N) {888 case 0:889 for (; I != N; ++I) {890 Out << ", ";891 if (I == 10 && !Policy.EntireContentsOfLargeArray) {892 Out << "...}";893 return;894 }895 [[fallthrough]];896 default:897 getArrayInitializedElt(I).printPretty(Out, Policy, ElemTy, Ctx);898 }899 }900 Out << '}';901 return;902 }903 case APValue::Struct: {904 Out << '{';905 bool First = true;906 const auto *RD = Ty->castAsRecordDecl();907 if (unsigned N = getStructNumBases()) {908 const CXXRecordDecl *CD = cast<CXXRecordDecl>(RD);909 CXXRecordDecl::base_class_const_iterator BI = CD->bases_begin();910 for (unsigned I = 0; I != N; ++I, ++BI) {911 assert(BI != CD->bases_end());912 if (!First)913 Out << ", ";914 getStructBase(I).printPretty(Out, Policy, BI->getType(), Ctx);915 First = false;916 }917 }918 for (const auto *FI : RD->fields()) {919 if (!First)920 Out << ", ";921 if (FI->isUnnamedBitField())922 continue;923 getStructField(FI->getFieldIndex()).924 printPretty(Out, Policy, FI->getType(), Ctx);925 First = false;926 }927 Out << '}';928 return;929 }930 case APValue::Union:931 Out << '{';932 if (const FieldDecl *FD = getUnionField()) {933 Out << "." << *FD << " = ";934 getUnionValue().printPretty(Out, Policy, FD->getType(), Ctx);935 }936 Out << '}';937 return;938 case APValue::MemberPointer:939 // FIXME: This is not enough to unambiguously identify the member in a940 // multiple-inheritance scenario.941 if (const ValueDecl *VD = getMemberPointerDecl()) {942 Out << '&' << *cast<CXXRecordDecl>(VD->getDeclContext()) << "::" << *VD;943 return;944 }945 Out << "0";946 return;947 case APValue::AddrLabelDiff:948 Out << "&&" << getAddrLabelDiffLHS()->getLabel()->getName();949 Out << " - ";950 Out << "&&" << getAddrLabelDiffRHS()->getLabel()->getName();951 return;952 }953 llvm_unreachable("Unknown APValue kind!");954}955 956std::string APValue::getAsString(const ASTContext &Ctx, QualType Ty) const {957 std::string Result;958 llvm::raw_string_ostream Out(Result);959 printPretty(Out, Ctx, Ty);960 return Result;961}962 963bool APValue::toIntegralConstant(APSInt &Result, QualType SrcTy,964 const ASTContext &Ctx) const {965 if (isInt()) {966 Result = getInt();967 return true;968 }969 970 if (isLValue() && isNullPointer()) {971 Result = Ctx.MakeIntValue(Ctx.getTargetNullPointerValue(SrcTy), SrcTy);972 return true;973 }974 975 if (isLValue() && !getLValueBase()) {976 Result = Ctx.MakeIntValue(getLValueOffset().getQuantity(), SrcTy);977 return true;978 }979 980 return false;981}982 983const APValue::LValueBase APValue::getLValueBase() const {984 assert(isLValue() && "Invalid accessor");985 return ((const LV *)(const void *)&Data)->Base;986}987 988bool APValue::isLValueOnePastTheEnd() const {989 assert(isLValue() && "Invalid accessor");990 return ((const LV *)(const void *)&Data)->IsOnePastTheEnd;991}992 993CharUnits &APValue::getLValueOffset() {994 assert(isLValue() && "Invalid accessor");995 return ((LV *)(void *)&Data)->Offset;996}997 998bool APValue::hasLValuePath() const {999 assert(isLValue() && "Invalid accessor");1000 return ((const LV *)(const char *)&Data)->hasPath();1001}1002 1003ArrayRef<APValue::LValuePathEntry> APValue::getLValuePath() const {1004 assert(isLValue() && hasLValuePath() && "Invalid accessor");1005 const LV &LVal = *((const LV *)(const char *)&Data);1006 return {LVal.getPath(), LVal.PathLength};1007}1008 1009unsigned APValue::getLValueCallIndex() const {1010 assert(isLValue() && "Invalid accessor");1011 return ((const LV *)(const char *)&Data)->Base.getCallIndex();1012}1013 1014unsigned APValue::getLValueVersion() const {1015 assert(isLValue() && "Invalid accessor");1016 return ((const LV *)(const char *)&Data)->Base.getVersion();1017}1018 1019bool APValue::isNullPointer() const {1020 assert(isLValue() && "Invalid usage");1021 return ((const LV *)(const char *)&Data)->IsNullPtr;1022}1023 1024void APValue::setLValue(LValueBase B, const CharUnits &O, NoLValuePath,1025 bool IsNullPtr) {1026 assert(isLValue() && "Invalid accessor");1027 LV &LVal = *((LV *)(char *)&Data);1028 LVal.Base = B;1029 LVal.IsOnePastTheEnd = false;1030 LVal.Offset = O;1031 LVal.resizePath((unsigned)-1);1032 LVal.IsNullPtr = IsNullPtr;1033}1034 1035MutableArrayRef<APValue::LValuePathEntry>1036APValue::setLValueUninit(LValueBase B, const CharUnits &O, unsigned Size,1037 bool IsOnePastTheEnd, bool IsNullPtr) {1038 assert(isLValue() && "Invalid accessor");1039 LV &LVal = *((LV *)(char *)&Data);1040 LVal.Base = B;1041 LVal.IsOnePastTheEnd = IsOnePastTheEnd;1042 LVal.Offset = O;1043 LVal.IsNullPtr = IsNullPtr;1044 LVal.resizePath(Size);1045 return {LVal.getPath(), Size};1046}1047 1048void APValue::setLValue(LValueBase B, const CharUnits &O,1049 ArrayRef<LValuePathEntry> Path, bool IsOnePastTheEnd,1050 bool IsNullPtr) {1051 MutableArrayRef<APValue::LValuePathEntry> InternalPath =1052 setLValueUninit(B, O, Path.size(), IsOnePastTheEnd, IsNullPtr);1053 if (Path.size()) {1054 memcpy(InternalPath.data(), Path.data(),1055 Path.size() * sizeof(LValuePathEntry));1056 }1057}1058 1059void APValue::setUnion(const FieldDecl *Field, const APValue &Value) {1060 assert(isUnion() && "Invalid accessor");1061 ((UnionData *)(char *)&Data)->Field =1062 Field ? Field->getCanonicalDecl() : nullptr;1063 *((UnionData *)(char *)&Data)->Value = Value;1064}1065 1066const ValueDecl *APValue::getMemberPointerDecl() const {1067 assert(isMemberPointer() && "Invalid accessor");1068 const MemberPointerData &MPD =1069 *((const MemberPointerData *)(const char *)&Data);1070 return MPD.MemberAndIsDerivedMember.getPointer();1071}1072 1073bool APValue::isMemberPointerToDerivedMember() const {1074 assert(isMemberPointer() && "Invalid accessor");1075 const MemberPointerData &MPD =1076 *((const MemberPointerData *)(const char *)&Data);1077 return MPD.MemberAndIsDerivedMember.getInt();1078}1079 1080ArrayRef<const CXXRecordDecl*> APValue::getMemberPointerPath() const {1081 assert(isMemberPointer() && "Invalid accessor");1082 const MemberPointerData &MPD =1083 *((const MemberPointerData *)(const char *)&Data);1084 return {MPD.getPath(), MPD.PathLength};1085}1086 1087void APValue::MakeLValue() {1088 assert(isAbsent() && "Bad state change");1089 static_assert(sizeof(LV) <= DataSize, "LV too big");1090 new ((void *)(char *)&Data) LV();1091 Kind = LValue;1092}1093 1094void APValue::MakeArray(unsigned InitElts, unsigned Size) {1095 assert(isAbsent() && "Bad state change");1096 new ((void *)(char *)&Data) Arr(InitElts, Size);1097 Kind = Array;1098}1099 1100MutableArrayRef<const CXXRecordDecl *>1101APValue::setMemberPointerUninit(const ValueDecl *Member, bool IsDerivedMember,1102 unsigned Size) {1103 assert(isAbsent() && "Bad state change");1104 MemberPointerData *MPD = new ((void *)(char *)&Data) MemberPointerData;1105 Kind = MemberPointer;1106 MPD->MemberAndIsDerivedMember.setPointer(1107 Member ? cast<ValueDecl>(Member->getCanonicalDecl()) : nullptr);1108 MPD->MemberAndIsDerivedMember.setInt(IsDerivedMember);1109 MPD->resizePath(Size);1110 return {MPD->getPath(), MPD->PathLength};1111}1112 1113void APValue::MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,1114 ArrayRef<const CXXRecordDecl *> Path) {1115 MutableArrayRef<const CXXRecordDecl *> InternalPath =1116 setMemberPointerUninit(Member, IsDerivedMember, Path.size());1117 for (unsigned I = 0; I != Path.size(); ++I)1118 InternalPath[I] = Path[I]->getCanonicalDecl();1119}1120 1121LinkageInfo LinkageComputer::getLVForValue(const APValue &V,1122 LVComputationKind computation) {1123 LinkageInfo LV = LinkageInfo::external();1124 1125 auto MergeLV = [&](LinkageInfo MergeLV) {1126 LV.merge(MergeLV);1127 return LV.getLinkage() == Linkage::Internal;1128 };1129 auto Merge = [&](const APValue &V) {1130 return MergeLV(getLVForValue(V, computation));1131 };1132 1133 switch (V.getKind()) {1134 case APValue::None:1135 case APValue::Indeterminate:1136 case APValue::Int:1137 case APValue::Float:1138 case APValue::FixedPoint:1139 case APValue::ComplexInt:1140 case APValue::ComplexFloat:1141 case APValue::Vector:1142 break;1143 1144 case APValue::AddrLabelDiff:1145 // Even for an inline function, it's not reasonable to treat a difference1146 // between the addresses of labels as an external value.1147 return LinkageInfo::internal();1148 1149 case APValue::Struct: {1150 for (unsigned I = 0, N = V.getStructNumBases(); I != N; ++I)1151 if (Merge(V.getStructBase(I)))1152 break;1153 for (unsigned I = 0, N = V.getStructNumFields(); I != N; ++I)1154 if (Merge(V.getStructField(I)))1155 break;1156 break;1157 }1158 1159 case APValue::Union:1160 if (V.getUnionField())1161 Merge(V.getUnionValue());1162 break;1163 1164 case APValue::Array: {1165 for (unsigned I = 0, N = V.getArrayInitializedElts(); I != N; ++I)1166 if (Merge(V.getArrayInitializedElt(I)))1167 break;1168 if (V.hasArrayFiller())1169 Merge(V.getArrayFiller());1170 break;1171 }1172 1173 case APValue::LValue: {1174 if (!V.getLValueBase()) {1175 // Null or absolute address: this is external.1176 } else if (const auto *VD =1177 V.getLValueBase().dyn_cast<const ValueDecl *>()) {1178 if (VD && MergeLV(getLVForDecl(VD, computation)))1179 break;1180 } else if (const auto TI = V.getLValueBase().dyn_cast<TypeInfoLValue>()) {1181 if (MergeLV(getLVForType(*TI.getType(), computation)))1182 break;1183 } else if (const Expr *E = V.getLValueBase().dyn_cast<const Expr *>()) {1184 // Almost all expression bases are internal. The exception is1185 // lifetime-extended temporaries.1186 // FIXME: These should be modeled as having the1187 // LifetimeExtendedTemporaryDecl itself as the base.1188 // FIXME: If we permit Objective-C object literals in template arguments,1189 // they should not imply internal linkage.1190 auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E);1191 if (!MTE || MTE->getStorageDuration() == SD_FullExpression)1192 return LinkageInfo::internal();1193 if (MergeLV(getLVForDecl(MTE->getExtendingDecl(), computation)))1194 break;1195 } else {1196 assert(V.getLValueBase().is<DynamicAllocLValue>() &&1197 "unexpected LValueBase kind");1198 return LinkageInfo::internal();1199 }1200 // The lvalue path doesn't matter: pointers to all subobjects always have1201 // the same visibility as pointers to the complete object.1202 break;1203 }1204 1205 case APValue::MemberPointer:1206 if (const NamedDecl *D = V.getMemberPointerDecl())1207 MergeLV(getLVForDecl(D, computation));1208 // Note that we could have a base-to-derived conversion here to a member of1209 // a derived class with less linkage/visibility. That's covered by the1210 // linkage and visibility of the value's type.1211 break;1212 }1213 1214 return LV;1215}1216