[libcxx-commits] [libcxx] [llvm] [libcxx][lldb] Add initial LLDB data-formatters (PR #187677)

Dave Lee via libcxx-commits libcxx-commits at lists.llvm.org
Fri Mar 20 09:29:59 PDT 2026


================
@@ -0,0 +1,263 @@
+"""
+Python LLDB data formatter for libc++ std::vector
+
+1-to-1 translation from the LLDB builtin std::vector formatter.
+
+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
+"""
+
+import lldb
+
+
+def get_data_pointer(root):
+    """Get the data pointer from a vector, handling compressed pair layout."""
+    # Try new layout
+    cap_sp = root.GetChildMemberWithName("__cap_")
+    if cap_sp and cap_sp.IsValid():
+        return cap_sp
+
+    # Try old compressed pair layout
+    end_cap_sp = root.GetChildMemberWithName("__end_cap_")
+    if not end_cap_sp or not end_cap_sp.IsValid():
+        return None
+
+    # Get first value of compressed pair
+    value_sp = end_cap_sp.GetChildMemberWithName("__value_")
+    if value_sp and value_sp.IsValid():
+        return value_sp
+
+    first_sp = end_cap_sp.GetChildMemberWithName("__first_")
+    if first_sp and first_sp.IsValid():
+        return first_sp
+
+    return None
+
+
+class LibCxxStdVectorSyntheticFrontEnd:
+    """Synthetic children frontend for libc++ std::vector."""
+
+    def __init__(self, valobj, internal_dict):
+        self.valobj = valobj
+        self.m_start = None
+        self.m_finish = None
+        self.m_element_type = None
+        self.m_element_size = 0
+        self.update()
+
+    def num_children(self):
+        if not self.m_start or not self.m_finish:
+            return 0
+
+        start_val = self.m_start.GetValueAsUnsigned(0)
+        finish_val = self.m_finish.GetValueAsUnsigned(0)
+
+        # A default-initialized empty vector
+        if start_val == 0 and finish_val == 0:
+            return 0
+
+        if start_val == 0:
+            return 0
+
+        if finish_val == 0:
+            return 0
+
+        if start_val > finish_val:
+            return 0
+
+        num_children = finish_val - start_val
+        if num_children % self.m_element_size != 0:
+            return 0
+
+        return num_children // self.m_element_size
+
+    def get_child_index(self, name):
+        if not self.m_start or not self.m_finish:
+            return None
+        try:
+            if name.startswith("[") and name.endswith("]"):
+                return int(name[1:-1])
+        except ValueError:
+            pass
+        return None
+
+    def get_child_at_index(self, index):
+        if not self.m_start or not self.m_finish:
+            return None
+
+        offset = index * self.m_element_size
+        offset = offset + self.m_start.GetValueAsUnsigned(0)
+
+        name = "[%d]" % index
+        target = self.valobj.GetTarget()
+        if not target or not target.IsValid():
+            return None
+
+        addr = lldb.SBAddress(offset, target)
+        return target.CreateValueFromAddress(name, addr, self.m_element_type)
+
+    def update(self):
+        self.m_start = None
+        self.m_finish = None
+
+        data_sp = get_data_pointer(self.valobj)
+        if not data_sp or not data_sp.IsValid():
+            return False
+
+        self.m_element_type = data_sp.GetType().GetPointeeType()
+        if not self.m_element_type.IsValid():
+            return False
+
+        size = self.m_element_type.GetByteSize()
+        if not size or size == 0:
+            return False
+
+        self.m_element_size = size
+
+        begin_sp = self.valobj.GetChildMemberWithName("__begin_")
+        end_sp = self.valobj.GetChildMemberWithName("__end_")
+
+        if not begin_sp or not end_sp:
+            return False
+
+        self.m_start = begin_sp
+        self.m_finish = end_sp
+
+        return True
+
+    def has_children(self):
+        return True
----------------
kastiglione wrote:

I think this is already the default.

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


More information about the libcxx-commits mailing list