brintos

brintos / llvm-project-archived public Read only

0
0
Text · 37.4 KiB · 2e1c8eb Raw
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