brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.9 KiB · 6f66540 Raw
281 lines · cpp
1//===-- MsvcStlSmartPointer.cpp -------------------------------------------===//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#include "Generic.h"10#include "MsvcStl.h"11 12#include "lldb/DataFormatters/FormattersHelpers.h"13#include "lldb/DataFormatters/TypeSynthetic.h"14 15using namespace lldb;16 17bool lldb_private::formatters::IsMsvcStlSmartPointer(ValueObject &valobj) {18  if (auto valobj_sp = valobj.GetNonSyntheticValue())19    return valobj_sp->GetChildMemberWithName("_Ptr") != nullptr;20 21  return false;22}23 24bool lldb_private::formatters::MsvcStlSmartPointerSummaryProvider(25    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {26  ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());27  if (!valobj_sp)28    return false;29 30  ValueObjectSP ptr_sp(valobj_sp->GetChildMemberWithName("_Ptr"));31  ValueObjectSP ctrl_sp(valobj_sp->GetChildMemberWithName("_Rep"));32  if (!ctrl_sp || !ptr_sp)33    return false;34 35  DumpCxxSmartPtrPointerSummary(stream, *ptr_sp, options);36 37  bool success;38  uint64_t ctrl_addr = ctrl_sp->GetValueAsUnsigned(0, &success);39  // Empty control field (expired)40  if (!success || ctrl_addr == 0)41    return true;42 43  uint64_t uses = 0;44  if (auto uses_sp = ctrl_sp->GetChildMemberWithName("_Uses")) {45    bool success;46    uses = uses_sp->GetValueAsUnsigned(0, &success);47    if (!success)48      return false;49 50    stream.Printf(" strong=%" PRIu64, uses);51  }52 53  // _Weaks is the number of weak references - (_Uses != 0).54  if (auto weak_count_sp = ctrl_sp->GetChildMemberWithName("_Weaks")) {55    bool success;56    uint64_t count = weak_count_sp->GetValueAsUnsigned(0, &success);57    if (!success)58      return false;59 60    stream.Printf(" weak=%" PRIu64, count - (uses != 0));61  }62 63  return true;64}65 66namespace lldb_private {67namespace formatters {68 69class MsvcStlSmartPointerSyntheticFrontEnd : public SyntheticChildrenFrontEnd {70public:71  MsvcStlSmartPointerSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);72 73  llvm::Expected<uint32_t> CalculateNumChildren() override;74 75  lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;76 77  lldb::ChildCacheState Update() override;78 79  llvm::Expected<size_t> GetIndexOfChildWithName(ConstString name) override;80 81  ~MsvcStlSmartPointerSyntheticFrontEnd() override;82 83private:84  ValueObject *m_ptr_obj = nullptr;85};86 87class MsvcStlUniquePtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd {88public:89  MsvcStlUniquePtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);90 91  llvm::Expected<uint32_t> CalculateNumChildren() override;92 93  lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;94 95  lldb::ChildCacheState Update() override;96 97  llvm::Expected<size_t> GetIndexOfChildWithName(ConstString name) override;98 99private:100  lldb::ValueObjectSP m_value_ptr_sp;101  lldb::ValueObjectSP m_deleter_sp;102};103 104} // namespace formatters105} // namespace lldb_private106 107lldb_private::formatters::MsvcStlSmartPointerSyntheticFrontEnd::108    MsvcStlSmartPointerSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)109    : SyntheticChildrenFrontEnd(*valobj_sp) {110  if (valobj_sp)111    Update();112}113 114llvm::Expected<uint32_t> lldb_private::formatters::115    MsvcStlSmartPointerSyntheticFrontEnd::CalculateNumChildren() {116  return (m_ptr_obj ? 1 : 0);117}118 119lldb::ValueObjectSP120lldb_private::formatters::MsvcStlSmartPointerSyntheticFrontEnd::GetChildAtIndex(121    uint32_t idx) {122  if (!m_ptr_obj)123    return lldb::ValueObjectSP();124 125  ValueObjectSP valobj_sp = m_backend.GetSP();126  if (!valobj_sp)127    return lldb::ValueObjectSP();128 129  if (idx == 0)130    return m_ptr_obj->GetSP();131 132  if (idx == 1) {133    Status status;134    ValueObjectSP value_sp = m_ptr_obj->Dereference(status);135    if (status.Success())136      return value_sp;137  }138 139  return lldb::ValueObjectSP();140}141 142lldb::ChildCacheState143lldb_private::formatters::MsvcStlSmartPointerSyntheticFrontEnd::Update() {144  m_ptr_obj = nullptr;145 146  ValueObjectSP valobj_sp = m_backend.GetSP();147  if (!valobj_sp)148    return lldb::ChildCacheState::eRefetch;149 150  auto ptr_obj_sp = valobj_sp->GetChildMemberWithName("_Ptr");151  if (!ptr_obj_sp)152    return lldb::ChildCacheState::eRefetch;153 154  auto cast_ptr_sp = GetDesugaredSmartPointerValue(*ptr_obj_sp, *valobj_sp);155  if (!cast_ptr_sp)156    return lldb::ChildCacheState::eRefetch;157 158  m_ptr_obj = cast_ptr_sp->Clone(ConstString("pointer")).get();159  return lldb::ChildCacheState::eRefetch;160}161 162llvm::Expected<size_t>163lldb_private::formatters::MsvcStlSmartPointerSyntheticFrontEnd::164    GetIndexOfChildWithName(ConstString name) {165  if (name == "pointer")166    return 0;167 168  if (name == "object" || name == "$$dereference$$")169    return 1;170 171  return llvm::createStringError("Type has no child named '%s'",172                                 name.AsCString());173}174 175lldb_private::formatters::MsvcStlSmartPointerSyntheticFrontEnd::176    ~MsvcStlSmartPointerSyntheticFrontEnd() = default;177 178lldb_private::SyntheticChildrenFrontEnd *179lldb_private::formatters::MsvcStlSmartPointerSyntheticFrontEndCreator(180    lldb::ValueObjectSP valobj_sp) {181  return new MsvcStlSmartPointerSyntheticFrontEnd(valobj_sp);182}183 184bool lldb_private::formatters::IsMsvcStlUniquePtr(ValueObject &valobj) {185  if (auto valobj_sp = valobj.GetNonSyntheticValue())186    return valobj_sp->GetChildMemberWithName("_Mypair") != nullptr;187 188  return false;189}190 191bool lldb_private::formatters::MsvcStlUniquePtrSummaryProvider(192    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {193  ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());194  if (!valobj_sp)195    return false;196 197  ValueObjectSP ptr_sp(valobj_sp->GetChildAtNamePath({"_Mypair", "_Myval2"}));198  if (!ptr_sp)199    return false;200 201  DumpCxxSmartPtrPointerSummary(stream, *ptr_sp, options);202 203  return true;204}205 206lldb_private::formatters::MsvcStlUniquePtrSyntheticFrontEnd::207    MsvcStlUniquePtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)208    : SyntheticChildrenFrontEnd(*valobj_sp) {209  if (valobj_sp)210    Update();211}212 213llvm::Expected<uint32_t> lldb_private::formatters::214    MsvcStlUniquePtrSyntheticFrontEnd::CalculateNumChildren() {215  if (m_value_ptr_sp)216    return m_deleter_sp ? 2 : 1;217  return 0;218}219 220lldb::ValueObjectSP221lldb_private::formatters::MsvcStlUniquePtrSyntheticFrontEnd::GetChildAtIndex(222    uint32_t idx) {223  if (!m_value_ptr_sp)224    return lldb::ValueObjectSP();225 226  if (idx == 0)227    return m_value_ptr_sp;228 229  if (idx == 1)230    return m_deleter_sp;231 232  if (idx == 2) {233    Status status;234    auto value_sp = m_value_ptr_sp->Dereference(status);235    if (status.Success()) {236      return value_sp;237    }238  }239 240  return lldb::ValueObjectSP();241}242 243lldb::ChildCacheState244lldb_private::formatters::MsvcStlUniquePtrSyntheticFrontEnd::Update() {245  ValueObjectSP valobj_sp = m_backend.GetSP();246  if (!valobj_sp)247    return lldb::ChildCacheState::eRefetch;248 249  ValueObjectSP pair_sp = valobj_sp->GetChildMemberWithName("_Mypair");250  if (!pair_sp)251    return lldb::ChildCacheState::eRefetch;252 253  if (auto value_ptr_sp = pair_sp->GetChildMemberWithName("_Myval2"))254    m_value_ptr_sp = value_ptr_sp->Clone(ConstString("pointer"));255 256  // Only present if the deleter is non-empty257  if (auto deleter_sp = pair_sp->GetChildMemberWithName("_Myval1"))258    m_deleter_sp = deleter_sp->Clone(ConstString("deleter"));259 260  return lldb::ChildCacheState::eRefetch;261}262 263llvm::Expected<size_t>264lldb_private::formatters::MsvcStlUniquePtrSyntheticFrontEnd::265    GetIndexOfChildWithName(ConstString name) {266  if (name == "pointer")267    return 0;268  if (name == "deleter")269    return 1;270  if (name == "obj" || name == "object" || name == "$$dereference$$")271    return 2;272  return llvm::createStringError("Type has no child named '%s'",273                                 name.AsCString());274}275 276lldb_private::SyntheticChildrenFrontEnd *277lldb_private::formatters::MsvcStlUniquePtrSyntheticFrontEndCreator(278    lldb::ValueObjectSP valobj_sp) {279  return new MsvcStlUniquePtrSyntheticFrontEnd(valobj_sp);280}281