[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