diff options
Diffstat (limited to 'lib/AST/APValue.cpp')
| -rw-r--r-- | lib/AST/APValue.cpp | 841 | 
1 files changed, 0 insertions, 841 deletions
diff --git a/lib/AST/APValue.cpp b/lib/AST/APValue.cpp deleted file mode 100644 index 50f8d05dacb4f..0000000000000 --- a/lib/AST/APValue.cpp +++ /dev/null @@ -1,841 +0,0 @@ -//===--- APValue.cpp - Union class for APFloat/APSInt/Complex -------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -//  This file implements the APValue class. -// -//===----------------------------------------------------------------------===// - -#include "clang/AST/APValue.h" -#include "clang/AST/ASTContext.h" -#include "clang/AST/CharUnits.h" -#include "clang/AST/DeclCXX.h" -#include "clang/AST/Expr.h" -#include "clang/AST/Type.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/raw_ostream.h" -using namespace clang; - -/// The identity of a type_info object depends on the canonical unqualified -/// type only. -TypeInfoLValue::TypeInfoLValue(const Type *T) -    : T(T->getCanonicalTypeUnqualified().getTypePtr()) {} - -void TypeInfoLValue::print(llvm::raw_ostream &Out, -                           const PrintingPolicy &Policy) const { -  Out << "typeid("; -  QualType(getType(), 0).print(Out, Policy); -  Out << ")"; -} - -static_assert( -    1 << llvm::PointerLikeTypeTraits<TypeInfoLValue>::NumLowBitsAvailable <= -        alignof(Type), -    "Type is insufficiently aligned"); - -APValue::LValueBase::LValueBase(const ValueDecl *P, unsigned I, unsigned V) -    : Ptr(P), Local{I, V} {} -APValue::LValueBase::LValueBase(const Expr *P, unsigned I, unsigned V) -    : Ptr(P), Local{I, V} {} - -APValue::LValueBase APValue::LValueBase::getDynamicAlloc(DynamicAllocLValue LV, -                                                         QualType Type) { -  LValueBase Base; -  Base.Ptr = LV; -  Base.DynamicAllocType = Type.getAsOpaquePtr(); -  return Base; -} - -APValue::LValueBase APValue::LValueBase::getTypeInfo(TypeInfoLValue LV, -                                                     QualType TypeInfo) { -  LValueBase Base; -  Base.Ptr = LV; -  Base.TypeInfoType = TypeInfo.getAsOpaquePtr(); -  return Base; -} - -unsigned APValue::LValueBase::getCallIndex() const { -  return (is<TypeInfoLValue>() || is<DynamicAllocLValue>()) ? 0 -                                                            : Local.CallIndex; -} - -unsigned APValue::LValueBase::getVersion() const { -  return (is<TypeInfoLValue>() || is<DynamicAllocLValue>()) ? 0 : Local.Version; -} - -QualType APValue::LValueBase::getTypeInfoType() const { -  assert(is<TypeInfoLValue>() && "not a type_info lvalue"); -  return QualType::getFromOpaquePtr(TypeInfoType); -} - -QualType APValue::LValueBase::getDynamicAllocType() const { -  assert(is<DynamicAllocLValue>() && "not a dynamic allocation lvalue"); -  return QualType::getFromOpaquePtr(DynamicAllocType); -} - -namespace clang { -bool operator==(const APValue::LValueBase &LHS, -                const APValue::LValueBase &RHS) { -  if (LHS.Ptr != RHS.Ptr) -    return false; -  if (LHS.is<TypeInfoLValue>()) -    return true; -  return LHS.Local.CallIndex == RHS.Local.CallIndex && -         LHS.Local.Version == RHS.Local.Version; -} -} - -namespace { -  struct LVBase { -    APValue::LValueBase Base; -    CharUnits Offset; -    unsigned PathLength; -    bool IsNullPtr : 1; -    bool IsOnePastTheEnd : 1; -  }; -} - -void *APValue::LValueBase::getOpaqueValue() const { -  return Ptr.getOpaqueValue(); -} - -bool APValue::LValueBase::isNull() const { -  return Ptr.isNull(); -} - -APValue::LValueBase::operator bool () const { -  return static_cast<bool>(Ptr); -} - -clang::APValue::LValueBase -llvm::DenseMapInfo<clang::APValue::LValueBase>::getEmptyKey() { -  return clang::APValue::LValueBase( -      DenseMapInfo<const ValueDecl*>::getEmptyKey()); -} - -clang::APValue::LValueBase -llvm::DenseMapInfo<clang::APValue::LValueBase>::getTombstoneKey() { -  return clang::APValue::LValueBase( -      DenseMapInfo<const ValueDecl*>::getTombstoneKey()); -} - -namespace clang { -llvm::hash_code hash_value(const APValue::LValueBase &Base) { -  if (Base.is<TypeInfoLValue>() || Base.is<DynamicAllocLValue>()) -    return llvm::hash_value(Base.getOpaqueValue()); -  return llvm::hash_combine(Base.getOpaqueValue(), Base.getCallIndex(), -                            Base.getVersion()); -} -} - -unsigned llvm::DenseMapInfo<clang::APValue::LValueBase>::getHashValue( -    const clang::APValue::LValueBase &Base) { -  return hash_value(Base); -} - -bool llvm::DenseMapInfo<clang::APValue::LValueBase>::isEqual( -    const clang::APValue::LValueBase &LHS, -    const clang::APValue::LValueBase &RHS) { -  return LHS == RHS; -} - -struct APValue::LV : LVBase { -  static const unsigned InlinePathSpace = -      (DataSize - sizeof(LVBase)) / sizeof(LValuePathEntry); - -  /// Path - The sequence of base classes, fields and array indices to follow to -  /// walk from Base to the subobject. When performing GCC-style folding, there -  /// may not be such a path. -  union { -    LValuePathEntry Path[InlinePathSpace]; -    LValuePathEntry *PathPtr; -  }; - -  LV() { PathLength = (unsigned)-1; } -  ~LV() { resizePath(0); } - -  void resizePath(unsigned Length) { -    if (Length == PathLength) -      return; -    if (hasPathPtr()) -      delete [] PathPtr; -    PathLength = Length; -    if (hasPathPtr()) -      PathPtr = new LValuePathEntry[Length]; -  } - -  bool hasPath() const { return PathLength != (unsigned)-1; } -  bool hasPathPtr() const { return hasPath() && PathLength > InlinePathSpace; } - -  LValuePathEntry *getPath() { return hasPathPtr() ? PathPtr : Path; } -  const LValuePathEntry *getPath() const { -    return hasPathPtr() ? PathPtr : Path; -  } -}; - -namespace { -  struct MemberPointerBase { -    llvm::PointerIntPair<const ValueDecl*, 1, bool> MemberAndIsDerivedMember; -    unsigned PathLength; -  }; -} - -struct APValue::MemberPointerData : MemberPointerBase { -  static const unsigned InlinePathSpace = -      (DataSize - sizeof(MemberPointerBase)) / sizeof(const CXXRecordDecl*); -  typedef const CXXRecordDecl *PathElem; -  union { -    PathElem Path[InlinePathSpace]; -    PathElem *PathPtr; -  }; - -  MemberPointerData() { PathLength = 0; } -  ~MemberPointerData() { resizePath(0); } - -  void resizePath(unsigned Length) { -    if (Length == PathLength) -      return; -    if (hasPathPtr()) -      delete [] PathPtr; -    PathLength = Length; -    if (hasPathPtr()) -      PathPtr = new PathElem[Length]; -  } - -  bool hasPathPtr() const { return PathLength > InlinePathSpace; } - -  PathElem *getPath() { return hasPathPtr() ? PathPtr : Path; } -  const PathElem *getPath() const { -    return hasPathPtr() ? PathPtr : Path; -  } -}; - -// FIXME: Reduce the malloc traffic here. - -APValue::Arr::Arr(unsigned NumElts, unsigned Size) : -  Elts(new APValue[NumElts + (NumElts != Size ? 1 : 0)]), -  NumElts(NumElts), ArrSize(Size) {} -APValue::Arr::~Arr() { delete [] Elts; } - -APValue::StructData::StructData(unsigned NumBases, unsigned NumFields) : -  Elts(new APValue[NumBases+NumFields]), -  NumBases(NumBases), NumFields(NumFields) {} -APValue::StructData::~StructData() { -  delete [] Elts; -} - -APValue::UnionData::UnionData() : Field(nullptr), Value(new APValue) {} -APValue::UnionData::~UnionData () { -  delete Value; -} - -APValue::APValue(const APValue &RHS) : Kind(None) { -  switch (RHS.getKind()) { -  case None: -  case Indeterminate: -    Kind = RHS.getKind(); -    break; -  case Int: -    MakeInt(); -    setInt(RHS.getInt()); -    break; -  case Float: -    MakeFloat(); -    setFloat(RHS.getFloat()); -    break; -  case FixedPoint: { -    APFixedPoint FXCopy = RHS.getFixedPoint(); -    MakeFixedPoint(std::move(FXCopy)); -    break; -  } -  case Vector: -    MakeVector(); -    setVector(((const Vec *)(const char *)RHS.Data.buffer)->Elts, -              RHS.getVectorLength()); -    break; -  case ComplexInt: -    MakeComplexInt(); -    setComplexInt(RHS.getComplexIntReal(), RHS.getComplexIntImag()); -    break; -  case ComplexFloat: -    MakeComplexFloat(); -    setComplexFloat(RHS.getComplexFloatReal(), RHS.getComplexFloatImag()); -    break; -  case LValue: -    MakeLValue(); -    if (RHS.hasLValuePath()) -      setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), RHS.getLValuePath(), -                RHS.isLValueOnePastTheEnd(), RHS.isNullPointer()); -    else -      setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), NoLValuePath(), -                RHS.isNullPointer()); -    break; -  case Array: -    MakeArray(RHS.getArrayInitializedElts(), RHS.getArraySize()); -    for (unsigned I = 0, N = RHS.getArrayInitializedElts(); I != N; ++I) -      getArrayInitializedElt(I) = RHS.getArrayInitializedElt(I); -    if (RHS.hasArrayFiller()) -      getArrayFiller() = RHS.getArrayFiller(); -    break; -  case Struct: -    MakeStruct(RHS.getStructNumBases(), RHS.getStructNumFields()); -    for (unsigned I = 0, N = RHS.getStructNumBases(); I != N; ++I) -      getStructBase(I) = RHS.getStructBase(I); -    for (unsigned I = 0, N = RHS.getStructNumFields(); I != N; ++I) -      getStructField(I) = RHS.getStructField(I); -    break; -  case Union: -    MakeUnion(); -    setUnion(RHS.getUnionField(), RHS.getUnionValue()); -    break; -  case MemberPointer: -    MakeMemberPointer(RHS.getMemberPointerDecl(), -                      RHS.isMemberPointerToDerivedMember(), -                      RHS.getMemberPointerPath()); -    break; -  case AddrLabelDiff: -    MakeAddrLabelDiff(); -    setAddrLabelDiff(RHS.getAddrLabelDiffLHS(), RHS.getAddrLabelDiffRHS()); -    break; -  } -} - -void APValue::DestroyDataAndMakeUninit() { -  if (Kind == Int) -    ((APSInt*)(char*)Data.buffer)->~APSInt(); -  else if (Kind == Float) -    ((APFloat*)(char*)Data.buffer)->~APFloat(); -  else if (Kind == FixedPoint) -    ((APFixedPoint *)(char *)Data.buffer)->~APFixedPoint(); -  else if (Kind == Vector) -    ((Vec*)(char*)Data.buffer)->~Vec(); -  else if (Kind == ComplexInt) -    ((ComplexAPSInt*)(char*)Data.buffer)->~ComplexAPSInt(); -  else if (Kind == ComplexFloat) -    ((ComplexAPFloat*)(char*)Data.buffer)->~ComplexAPFloat(); -  else if (Kind == LValue) -    ((LV*)(char*)Data.buffer)->~LV(); -  else if (Kind == Array) -    ((Arr*)(char*)Data.buffer)->~Arr(); -  else if (Kind == Struct) -    ((StructData*)(char*)Data.buffer)->~StructData(); -  else if (Kind == Union) -    ((UnionData*)(char*)Data.buffer)->~UnionData(); -  else if (Kind == MemberPointer) -    ((MemberPointerData*)(char*)Data.buffer)->~MemberPointerData(); -  else if (Kind == AddrLabelDiff) -    ((AddrLabelDiffData*)(char*)Data.buffer)->~AddrLabelDiffData(); -  Kind = None; -} - -bool APValue::needsCleanup() const { -  switch (getKind()) { -  case None: -  case Indeterminate: -  case AddrLabelDiff: -    return false; -  case Struct: -  case Union: -  case Array: -  case Vector: -    return true; -  case Int: -    return getInt().needsCleanup(); -  case Float: -    return getFloat().needsCleanup(); -  case FixedPoint: -    return getFixedPoint().getValue().needsCleanup(); -  case ComplexFloat: -    assert(getComplexFloatImag().needsCleanup() == -               getComplexFloatReal().needsCleanup() && -           "In _Complex float types, real and imaginary values always have the " -           "same size."); -    return getComplexFloatReal().needsCleanup(); -  case ComplexInt: -    assert(getComplexIntImag().needsCleanup() == -               getComplexIntReal().needsCleanup() && -           "In _Complex int types, real and imaginary values must have the " -           "same size."); -    return getComplexIntReal().needsCleanup(); -  case LValue: -    return reinterpret_cast<const LV *>(Data.buffer)->hasPathPtr(); -  case MemberPointer: -    return reinterpret_cast<const MemberPointerData *>(Data.buffer) -        ->hasPathPtr(); -  } -  llvm_unreachable("Unknown APValue kind!"); -} - -void APValue::swap(APValue &RHS) { -  std::swap(Kind, RHS.Kind); -  char TmpData[DataSize]; -  memcpy(TmpData, Data.buffer, DataSize); -  memcpy(Data.buffer, RHS.Data.buffer, DataSize); -  memcpy(RHS.Data.buffer, TmpData, DataSize); -} - -LLVM_DUMP_METHOD void APValue::dump() const { -  dump(llvm::errs()); -  llvm::errs() << '\n'; -} - -static double GetApproxValue(const llvm::APFloat &F) { -  llvm::APFloat V = F; -  bool ignored; -  V.convert(llvm::APFloat::IEEEdouble(), llvm::APFloat::rmNearestTiesToEven, -            &ignored); -  return V.convertToDouble(); -} - -void APValue::dump(raw_ostream &OS) const { -  switch (getKind()) { -  case None: -    OS << "None"; -    return; -  case Indeterminate: -    OS << "Indeterminate"; -    return; -  case Int: -    OS << "Int: " << getInt(); -    return; -  case Float: -    OS << "Float: " << GetApproxValue(getFloat()); -    return; -  case FixedPoint: -    OS << "FixedPoint : " << getFixedPoint(); -    return; -  case Vector: -    OS << "Vector: "; -    getVectorElt(0).dump(OS); -    for (unsigned i = 1; i != getVectorLength(); ++i) { -      OS << ", "; -      getVectorElt(i).dump(OS); -    } -    return; -  case ComplexInt: -    OS << "ComplexInt: " << getComplexIntReal() << ", " << getComplexIntImag(); -    return; -  case ComplexFloat: -    OS << "ComplexFloat: " << GetApproxValue(getComplexFloatReal()) -       << ", " << GetApproxValue(getComplexFloatImag()); -    return; -  case LValue: -    OS << "LValue: <todo>"; -    return; -  case Array: -    OS << "Array: "; -    for (unsigned I = 0, N = getArrayInitializedElts(); I != N; ++I) { -      getArrayInitializedElt(I).dump(OS); -      if (I != getArraySize() - 1) OS << ", "; -    } -    if (hasArrayFiller()) { -      OS << getArraySize() - getArrayInitializedElts() << " x "; -      getArrayFiller().dump(OS); -    } -    return; -  case Struct: -    OS << "Struct "; -    if (unsigned N = getStructNumBases()) { -      OS << " bases: "; -      getStructBase(0).dump(OS); -      for (unsigned I = 1; I != N; ++I) { -        OS << ", "; -        getStructBase(I).dump(OS); -      } -    } -    if (unsigned N = getStructNumFields()) { -      OS << " fields: "; -      getStructField(0).dump(OS); -      for (unsigned I = 1; I != N; ++I) { -        OS << ", "; -        getStructField(I).dump(OS); -      } -    } -    return; -  case Union: -    OS << "Union: "; -    getUnionValue().dump(OS); -    return; -  case MemberPointer: -    OS << "MemberPointer: <todo>"; -    return; -  case AddrLabelDiff: -    OS << "AddrLabelDiff: <todo>"; -    return; -  } -  llvm_unreachable("Unknown APValue kind!"); -} - -void APValue::printPretty(raw_ostream &Out, const ASTContext &Ctx, -                          QualType Ty) const { -  switch (getKind()) { -  case APValue::None: -    Out << "<out of lifetime>"; -    return; -  case APValue::Indeterminate: -    Out << "<uninitialized>"; -    return; -  case APValue::Int: -    if (Ty->isBooleanType()) -      Out << (getInt().getBoolValue() ? "true" : "false"); -    else -      Out << getInt(); -    return; -  case APValue::Float: -    Out << GetApproxValue(getFloat()); -    return; -  case APValue::FixedPoint: -    Out << getFixedPoint(); -    return; -  case APValue::Vector: { -    Out << '{'; -    QualType ElemTy = Ty->castAs<VectorType>()->getElementType(); -    getVectorElt(0).printPretty(Out, Ctx, ElemTy); -    for (unsigned i = 1; i != getVectorLength(); ++i) { -      Out << ", "; -      getVectorElt(i).printPretty(Out, Ctx, ElemTy); -    } -    Out << '}'; -    return; -  } -  case APValue::ComplexInt: -    Out << getComplexIntReal() << "+" << getComplexIntImag() << "i"; -    return; -  case APValue::ComplexFloat: -    Out << GetApproxValue(getComplexFloatReal()) << "+" -        << GetApproxValue(getComplexFloatImag()) << "i"; -    return; -  case APValue::LValue: { -    bool IsReference = Ty->isReferenceType(); -    QualType InnerTy -      = IsReference ? Ty.getNonReferenceType() : Ty->getPointeeType(); -    if (InnerTy.isNull()) -      InnerTy = Ty; - -    LValueBase Base = getLValueBase(); -    if (!Base) { -      if (isNullPointer()) { -        Out << (Ctx.getLangOpts().CPlusPlus11 ? "nullptr" : "0"); -      } else if (IsReference) { -        Out << "*(" << InnerTy.stream(Ctx.getPrintingPolicy()) << "*)" -            << getLValueOffset().getQuantity(); -      } else { -        Out << "(" << Ty.stream(Ctx.getPrintingPolicy()) << ")" -            << getLValueOffset().getQuantity(); -      } -      return; -    } - -    if (!hasLValuePath()) { -      // No lvalue path: just print the offset. -      CharUnits O = getLValueOffset(); -      CharUnits S = Ctx.getTypeSizeInChars(InnerTy); -      if (!O.isZero()) { -        if (IsReference) -          Out << "*("; -        if (O % S) { -          Out << "(char*)"; -          S = CharUnits::One(); -        } -        Out << '&'; -      } else if (!IsReference) { -        Out << '&'; -      } - -      if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) -        Out << *VD; -      else if (TypeInfoLValue TI = Base.dyn_cast<TypeInfoLValue>()) { -        TI.print(Out, Ctx.getPrintingPolicy()); -      } else if (DynamicAllocLValue DA = Base.dyn_cast<DynamicAllocLValue>()) { -        Out << "{*new " -            << Base.getDynamicAllocType().stream(Ctx.getPrintingPolicy()) << "#" -            << DA.getIndex() << "}"; -      } else { -        assert(Base.get<const Expr *>() != nullptr && -               "Expecting non-null Expr"); -        Base.get<const Expr*>()->printPretty(Out, nullptr, -                                             Ctx.getPrintingPolicy()); -      } - -      if (!O.isZero()) { -        Out << " + " << (O / S); -        if (IsReference) -          Out << ')'; -      } -      return; -    } - -    // We have an lvalue path. Print it out nicely. -    if (!IsReference) -      Out << '&'; -    else if (isLValueOnePastTheEnd()) -      Out << "*(&"; - -    QualType ElemTy; -    if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) { -      Out << *VD; -      ElemTy = VD->getType(); -    } else if (TypeInfoLValue TI = Base.dyn_cast<TypeInfoLValue>()) { -      TI.print(Out, Ctx.getPrintingPolicy()); -      ElemTy = Base.getTypeInfoType(); -    } else if (DynamicAllocLValue DA = Base.dyn_cast<DynamicAllocLValue>()) { -      Out << "{*new " -          << Base.getDynamicAllocType().stream(Ctx.getPrintingPolicy()) << "#" -          << DA.getIndex() << "}"; -      ElemTy = Base.getDynamicAllocType(); -    } else { -      const Expr *E = Base.get<const Expr*>(); -      assert(E != nullptr && "Expecting non-null Expr"); -      E->printPretty(Out, nullptr, Ctx.getPrintingPolicy()); -      // FIXME: This is wrong if E is a MaterializeTemporaryExpr with an lvalue -      // adjustment. -      ElemTy = E->getType(); -    } - -    ArrayRef<LValuePathEntry> Path = getLValuePath(); -    const CXXRecordDecl *CastToBase = nullptr; -    for (unsigned I = 0, N = Path.size(); I != N; ++I) { -      if (ElemTy->getAs<RecordType>()) { -        // The lvalue refers to a class type, so the next path entry is a base -        // or member. -        const Decl *BaseOrMember = Path[I].getAsBaseOrMember().getPointer(); -        if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(BaseOrMember)) { -          CastToBase = RD; -          ElemTy = Ctx.getRecordType(RD); -        } else { -          const ValueDecl *VD = cast<ValueDecl>(BaseOrMember); -          Out << "."; -          if (CastToBase) -            Out << *CastToBase << "::"; -          Out << *VD; -          ElemTy = VD->getType(); -        } -      } else { -        // The lvalue must refer to an array. -        Out << '[' << Path[I].getAsArrayIndex() << ']'; -        ElemTy = Ctx.getAsArrayType(ElemTy)->getElementType(); -      } -    } - -    // Handle formatting of one-past-the-end lvalues. -    if (isLValueOnePastTheEnd()) { -      // FIXME: If CastToBase is non-0, we should prefix the output with -      // "(CastToBase*)". -      Out << " + 1"; -      if (IsReference) -        Out << ')'; -    } -    return; -  } -  case APValue::Array: { -    const ArrayType *AT = Ctx.getAsArrayType(Ty); -    QualType ElemTy = AT->getElementType(); -    Out << '{'; -    if (unsigned N = getArrayInitializedElts()) { -      getArrayInitializedElt(0).printPretty(Out, Ctx, ElemTy); -      for (unsigned I = 1; I != N; ++I) { -        Out << ", "; -        if (I == 10) { -          // Avoid printing out the entire contents of large arrays. -          Out << "..."; -          break; -        } -        getArrayInitializedElt(I).printPretty(Out, Ctx, ElemTy); -      } -    } -    Out << '}'; -    return; -  } -  case APValue::Struct: { -    Out << '{'; -    const RecordDecl *RD = Ty->castAs<RecordType>()->getDecl(); -    bool First = true; -    if (unsigned N = getStructNumBases()) { -      const CXXRecordDecl *CD = cast<CXXRecordDecl>(RD); -      CXXRecordDecl::base_class_const_iterator BI = CD->bases_begin(); -      for (unsigned I = 0; I != N; ++I, ++BI) { -        assert(BI != CD->bases_end()); -        if (!First) -          Out << ", "; -        getStructBase(I).printPretty(Out, Ctx, BI->getType()); -        First = false; -      } -    } -    for (const auto *FI : RD->fields()) { -      if (!First) -        Out << ", "; -      if (FI->isUnnamedBitfield()) continue; -      getStructField(FI->getFieldIndex()). -        printPretty(Out, Ctx, FI->getType()); -      First = false; -    } -    Out << '}'; -    return; -  } -  case APValue::Union: -    Out << '{'; -    if (const FieldDecl *FD = getUnionField()) { -      Out << "." << *FD << " = "; -      getUnionValue().printPretty(Out, Ctx, FD->getType()); -    } -    Out << '}'; -    return; -  case APValue::MemberPointer: -    // FIXME: This is not enough to unambiguously identify the member in a -    // multiple-inheritance scenario. -    if (const ValueDecl *VD = getMemberPointerDecl()) { -      Out << '&' << *cast<CXXRecordDecl>(VD->getDeclContext()) << "::" << *VD; -      return; -    } -    Out << "0"; -    return; -  case APValue::AddrLabelDiff: -    Out << "&&" << getAddrLabelDiffLHS()->getLabel()->getName(); -    Out << " - "; -    Out << "&&" << getAddrLabelDiffRHS()->getLabel()->getName(); -    return; -  } -  llvm_unreachable("Unknown APValue kind!"); -} - -std::string APValue::getAsString(const ASTContext &Ctx, QualType Ty) const { -  std::string Result; -  llvm::raw_string_ostream Out(Result); -  printPretty(Out, Ctx, Ty); -  Out.flush(); -  return Result; -} - -bool APValue::toIntegralConstant(APSInt &Result, QualType SrcTy, -                                 const ASTContext &Ctx) const { -  if (isInt()) { -    Result = getInt(); -    return true; -  } - -  if (isLValue() && isNullPointer()) { -    Result = Ctx.MakeIntValue(Ctx.getTargetNullPointerValue(SrcTy), SrcTy); -    return true; -  } - -  if (isLValue() && !getLValueBase()) { -    Result = Ctx.MakeIntValue(getLValueOffset().getQuantity(), SrcTy); -    return true; -  } - -  return false; -} - -const APValue::LValueBase APValue::getLValueBase() const { -  assert(isLValue() && "Invalid accessor"); -  return ((const LV*)(const void*)Data.buffer)->Base; -} - -bool APValue::isLValueOnePastTheEnd() const { -  assert(isLValue() && "Invalid accessor"); -  return ((const LV*)(const void*)Data.buffer)->IsOnePastTheEnd; -} - -CharUnits &APValue::getLValueOffset() { -  assert(isLValue() && "Invalid accessor"); -  return ((LV*)(void*)Data.buffer)->Offset; -} - -bool APValue::hasLValuePath() const { -  assert(isLValue() && "Invalid accessor"); -  return ((const LV*)(const char*)Data.buffer)->hasPath(); -} - -ArrayRef<APValue::LValuePathEntry> APValue::getLValuePath() const { -  assert(isLValue() && hasLValuePath() && "Invalid accessor"); -  const LV &LVal = *((const LV*)(const char*)Data.buffer); -  return llvm::makeArrayRef(LVal.getPath(), LVal.PathLength); -} - -unsigned APValue::getLValueCallIndex() const { -  assert(isLValue() && "Invalid accessor"); -  return ((const LV*)(const char*)Data.buffer)->Base.getCallIndex(); -} - -unsigned APValue::getLValueVersion() const { -  assert(isLValue() && "Invalid accessor"); -  return ((const LV*)(const char*)Data.buffer)->Base.getVersion(); -} - -bool APValue::isNullPointer() const { -  assert(isLValue() && "Invalid usage"); -  return ((const LV*)(const char*)Data.buffer)->IsNullPtr; -} - -void APValue::setLValue(LValueBase B, const CharUnits &O, NoLValuePath, -                        bool IsNullPtr) { -  assert(isLValue() && "Invalid accessor"); -  LV &LVal = *((LV*)(char*)Data.buffer); -  LVal.Base = B; -  LVal.IsOnePastTheEnd = false; -  LVal.Offset = O; -  LVal.resizePath((unsigned)-1); -  LVal.IsNullPtr = IsNullPtr; -} - -void APValue::setLValue(LValueBase B, const CharUnits &O, -                        ArrayRef<LValuePathEntry> Path, bool IsOnePastTheEnd, -                        bool IsNullPtr) { -  assert(isLValue() && "Invalid accessor"); -  LV &LVal = *((LV*)(char*)Data.buffer); -  LVal.Base = B; -  LVal.IsOnePastTheEnd = IsOnePastTheEnd; -  LVal.Offset = O; -  LVal.resizePath(Path.size()); -  memcpy(LVal.getPath(), Path.data(), Path.size() * sizeof(LValuePathEntry)); -  LVal.IsNullPtr = IsNullPtr; -} - -const ValueDecl *APValue::getMemberPointerDecl() const { -  assert(isMemberPointer() && "Invalid accessor"); -  const MemberPointerData &MPD = -      *((const MemberPointerData *)(const char *)Data.buffer); -  return MPD.MemberAndIsDerivedMember.getPointer(); -} - -bool APValue::isMemberPointerToDerivedMember() const { -  assert(isMemberPointer() && "Invalid accessor"); -  const MemberPointerData &MPD = -      *((const MemberPointerData *)(const char *)Data.buffer); -  return MPD.MemberAndIsDerivedMember.getInt(); -} - -ArrayRef<const CXXRecordDecl*> APValue::getMemberPointerPath() const { -  assert(isMemberPointer() && "Invalid accessor"); -  const MemberPointerData &MPD = -      *((const MemberPointerData *)(const char *)Data.buffer); -  return llvm::makeArrayRef(MPD.getPath(), MPD.PathLength); -} - -void APValue::MakeLValue() { -  assert(isAbsent() && "Bad state change"); -  static_assert(sizeof(LV) <= DataSize, "LV too big"); -  new ((void*)(char*)Data.buffer) LV(); -  Kind = LValue; -} - -void APValue::MakeArray(unsigned InitElts, unsigned Size) { -  assert(isAbsent() && "Bad state change"); -  new ((void*)(char*)Data.buffer) Arr(InitElts, Size); -  Kind = Array; -} - -void APValue::MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember, -                                ArrayRef<const CXXRecordDecl*> Path) { -  assert(isAbsent() && "Bad state change"); -  MemberPointerData *MPD = new ((void*)(char*)Data.buffer) MemberPointerData; -  Kind = MemberPointer; -  MPD->MemberAndIsDerivedMember.setPointer(Member); -  MPD->MemberAndIsDerivedMember.setInt(IsDerivedMember); -  MPD->resizePath(Path.size()); -  memcpy(MPD->getPath(), Path.data(), Path.size()*sizeof(const CXXRecordDecl*)); -}  | 
