[Lldb-commits] [lldb] [lldb] Format `atomic<shared_ptr>` on MSVC STL (PR #237631)

via lldb-commits lldb-commits at lists.llvm.org
Mon Nov 2 01:39:22 PST 2026


================
@@ -51,60 +72,131 @@ llvm::Expected<uint32_t> lldb_private::formatters::
 lldb::ValueObjectSP
 lldb_private::formatters::MsvcStlAtomicSyntheticFrontEnd::GetChildAtIndex(
     uint32_t idx) {
-  if (idx == 0 && m_storage && m_element_type.IsValid())
-    return m_storage->Cast(m_element_type)->Clone("Value");
+  if (idx == 0 && m_storage)
+    return m_storage;
   return nullptr;
 }
 
 lldb::ChildCacheState
 lldb_private::formatters::MsvcStlAtomicSyntheticFrontEnd::Update() {
-  m_storage = nullptr;
-  m_element_type.Clear();
-
-  ValueObjectSP storage_sp = m_backend.GetChildMemberWithName("_Storage");
-  if (!storage_sp)
-    return lldb::ChildCacheState::eRefetch;
-
-  CompilerType backend_type = m_backend.GetCompilerType();
-  if (!backend_type)
-    return lldb::ChildCacheState::eRefetch;
-
-  m_element_type = backend_type.GetTypeTemplateArgument(0);
-  if (!m_element_type) {
-    // PDB doesn't have info about templates, so use value_type which equals T.
-    m_element_type = backend_type.GetDirectNestedTypeWithName("value_type");
-
-    if (!m_element_type)
-      return lldb::ChildCacheState::eRefetch;
+  m_storage.reset();
+
+  if (m_is_smart_ptr) {
+    ValueObjectSP ptr = m_backend.GetChildMemberWithName("_Ptr");
+    if (!ptr)
+      return lldb::eRefetch;
+    m_storage = ValueOfAtomic(*ptr);
+  } else {
+    m_storage = ValueOfAtomic(m_backend);
   }
 
-  m_storage = storage_sp.get();
-  return lldb::ChildCacheState::eRefetch;
+  if (m_storage)
+    m_storage = m_storage->Clone("Value");
+
+  return lldb::eRefetch;
 }
 
 llvm::Expected<size_t>
 lldb_private::formatters::MsvcStlAtomicSyntheticFrontEnd::
     GetIndexOfChildWithName(llvm::StringRef name) {
-  if (name == "Value")
+  if (name == "Value" || (m_is_smart_ptr && name == "$$dereference$$"))
     return 0;
   return llvm::createStringErrorV("type has no child named '{0}'", name);
 }
 
 lldb_private::SyntheticChildrenFrontEnd *
 lldb_private::formatters::MsvcStlAtomicSyntheticFrontEndCreator(
     CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
-  if (valobj_sp && IsMsvcStlAtomic(*valobj_sp))
-    return new MsvcStlAtomicSyntheticFrontEnd(valobj_sp);
+  bool is_smart_ptr = false;
+  if (valobj_sp && IsMsvcStlAtomic(*valobj_sp, &is_smart_ptr))
+    return new MsvcStlAtomicSyntheticFrontEnd(valobj_sp, is_smart_ptr);
   return nullptr;
 }
 
+static CompilerType FindLockedPointeeType(Target &target,
+                                          const CompilerType &locked_ptr_type) {
+  ConstString locked_name = locked_ptr_type.GetTypeName();
+  llvm::StringRef pointee_name = locked_name;
+  if (!pointee_name.consume_front("std::_Locked_pointer<"))
+    return {};
+  if (!pointee_name.consume_back(">"))
+    return {};
+
+  TypeQuery query(pointee_name, TypeQueryOptions::e_find_one);
+  TypeResults results;
+  target.GetImages().FindTypes(/*search_first=*/nullptr, query, results);
+  if (TypeSP type_sp = results.GetFirstType())
+    return type_sp->GetFullCompilerType();
+  return {};
+}
+
+static bool AtomicSharedPtrSummaryProvider(ValueObject &ptr,
+                                           ValueObject &rep_wrap,
+                                           Stream &stream,
+                                           const TypeSummaryOptions &options) {
+  // rep_wrap: _Locked_pointer<_Ref_count_base> {
+  //   static constexpr uintptr_t _Lock_mask = 3;
+  //   static constexpr uintptr_t _Ptr_value_mask = ~_Lock_mask;
+  //
+  //   atomic<uintptr_t> Storage_;
+  // }
+  ValueObjectSP rep_storage_sp = rep_wrap.GetChildAtIndex(0);
+  if (!rep_storage_sp)
+    return false;
+  ValueObjectSP rep_ptr_sp = ValueOfAtomic(*rep_storage_sp);
+  if (!rep_ptr_sp)
+    return false;
+
+  bool ok = false;
+  uint64_t rep_ptr_val = rep_ptr_sp->GetValueAsUnsigned(0, &ok);
+  if (!ok)
+    return false;
+
+  CompilerType rep_type = rep_wrap.GetCompilerType();
+  if (!rep_type)
+    return false;
+  CompilerDecl ptr_value_decl =
+      rep_type.GetStaticFieldWithName("_Ptr_value_mask");
+  if (!ptr_value_decl)
+    return false;
+  uint64_t rep_ptr_mask = ptr_value_decl.GetConstantValue().ULongLong(~(3ULL));
+  rep_ptr_val &= rep_ptr_mask;
+
+  CompilerType ref_count_base = rep_type.GetTypeTemplateArgument(0);
+  if (!ref_count_base) {
+    // PDB: Search for the type by name, as it doesn't know about templates.
+    // Unfortunately, there's no typedef inside the type.
----------------
Nerixyz wrote:

An alternative to searching the type by name is to look at its methods. Some return a pointer to the type. I'm not sure which is faster - possibly the method search since it doesn't query the symbol file.

https://github.com/llvm/llvm-project/pull/237631


More information about the lldb-commits mailing list