================
@@ -0,0 +1,168 @@
+//===-- MsvcStlSmartPointer.cpp 
-------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "Generic.h"
+#include "MsvcStl.h"
+
+#include "lldb/DataFormatters/FormattersHelpers.h"
+#include "lldb/DataFormatters/TypeSynthetic.h"
+
+using namespace lldb;
+
+bool lldb_private::formatters::IsMsvcStlSmartPointer(ValueObject &valobj) {
+  return valobj.GetChildMemberWithName("_Ptr") != nullptr;
+}
+
+bool lldb_private::formatters::MsvcStlSmartPointerSummaryProvider(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+  ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
+  if (!valobj_sp)
+    return false;
+
+  ValueObjectSP ptr_sp(valobj_sp->GetChildMemberWithName("_Ptr"));
+  ValueObjectSP ctrl_sp(valobj_sp->GetChildMemberWithName("_Rep"));
+  if (!ctrl_sp || !ptr_sp)
+    return false;
+
+  DumpCxxSmartPtrPointerSummary(stream, *ptr_sp, options);
+
+  bool success;
+  uint64_t ctrl_addr = ctrl_sp->GetValueAsUnsigned(0, &success);
+  // Empty control field (expired)
+  if (!success || ctrl_addr == 0)
+    return true;
+
+  uint64_t uses = 0;
+  if (auto uses_sp = ctrl_sp->GetChildMemberWithName("_Uses")) {
+    bool success;
+    uses = uses_sp->GetValueAsUnsigned(0, &success);
+    if (!success)
+      return false;
+
+    stream.Printf(" strong=%" PRIu64, uses);
+  }
+
+  // _Weaks is the number of weak references - (_Uses != 0).
+  if (auto weak_count_sp = ctrl_sp->GetChildMemberWithName("_Weaks")) {
+    bool success;
+    uint64_t count = weak_count_sp->GetValueAsUnsigned(0, &success);
+    if (!success)
+      return false;
+
+    stream.Printf(" weak=%" PRIu64, count - (uses != 0));
+  }
+
+  return true;
+}
+
+namespace lldb_private {
+namespace formatters {
+
+class MsvcStlSmartPointerSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+  MsvcStlSmartPointerSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+  llvm::Expected<uint32_t> CalculateNumChildren() override;
+
+  lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;
+
+  lldb::ChildCacheState Update() override;
+
+  llvm::Expected<size_t> GetIndexOfChildWithName(ConstString name) override;
+
+  ~MsvcStlSmartPointerSyntheticFrontEnd() override;
+
+private:
+  ValueObject *m_ptr_obj = nullptr;
+};
+
+} // namespace formatters
+} // namespace lldb_private
+
+lldb_private::formatters::MsvcStlSmartPointerSyntheticFrontEnd::
+    MsvcStlSmartPointerSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+    : SyntheticChildrenFrontEnd(*valobj_sp) {
+  if (valobj_sp)
+    Update();
+}
+
+llvm::Expected<uint32_t> lldb_private::formatters::
+    MsvcStlSmartPointerSyntheticFrontEnd::CalculateNumChildren() {
+  return (m_ptr_obj ? 1 : 0);
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::MsvcStlSmartPointerSyntheticFrontEnd::GetChildAtIndex(
+    uint32_t idx) {
+  if (!m_ptr_obj)
+    return lldb::ValueObjectSP();
+
+  ValueObjectSP valobj_sp = m_backend.GetSP();
+  if (!valobj_sp)
+    return lldb::ValueObjectSP();
+
+  if (idx == 0)
+    return m_ptr_obj->GetSP();
+
+  if (idx == 1) {
+    Status status;
+    ValueObjectSP value_sp = m_ptr_obj->Dereference(status);
+    if (status.Success())
+      return value_sp;
+  }
+
+  return lldb::ValueObjectSP();
+}
+
+lldb::ChildCacheState
+lldb_private::formatters::MsvcStlSmartPointerSyntheticFrontEnd::Update() {
+  m_ptr_obj = nullptr;
+
+  ValueObjectSP valobj_sp = m_backend.GetSP();
+  if (!valobj_sp)
+    return lldb::ChildCacheState::eRefetch;
+
+  auto ptr_obj_sp = valobj_sp->GetChildMemberWithName("_Ptr");
+  if (!ptr_obj_sp)
+    return lldb::ChildCacheState::eRefetch;
+
+  auto cast_ptr_sp = GetDesugaredSmartPointerValue(*ptr_obj_sp, *valobj_sp);
+  if (!cast_ptr_sp)
+    return lldb::ChildCacheState::eRefetch;
+
+  m_ptr_obj = cast_ptr_sp->Clone(ConstString("pointer")).get();
+  return lldb::ChildCacheState::eRefetch;
+}
+
+llvm::Expected<size_t>
+lldb_private::formatters::MsvcStlSmartPointerSyntheticFrontEnd::
+    GetIndexOfChildWithName(ConstString name) {
+  if (name == "_Ptr" || name == "pointer")
----------------
Michael137 wrote:

```suggestion
  if (name == "pointer")
```

https://github.com/llvm/llvm-project/pull/147575
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to