jarin created this revision.
jarin added reviewers: teemperor, jingham.
jarin added a project: LLDB.
Herald added a subscriber: lldb-commits.

This is an attempt to fix https://bugs.llvm.org/show_bug.cgi?id=45988, where 
SBValue::GetNumChildren returns 2, but SBValue::GetChildAtIndex(1) returns an 
invalid value sentinel.

The root cause of this seems to be that GetNumChildren can return the number of 
children of a wrong value. In particular, for pointers GetNumChildren just 
recursively calls itself on the pointee type, so it effectively walks chains of 
pointers. This is different from the logic of GetChildAtIndex, which only 
recurses if pointee.IsAggregateType() returns true (IsAggregateType is false 
for pointers and references), so it never follows chain of pointers.

This patch aims to make GetNumChildren (more) consistent with GetChildAtIndex 
by only recursively calling GetNumChildren for aggregate types.

Ideally, GetNumChildren and GetChildAtIndex would share the code that decides 
which pointers/references are followed, but that is a bit more invasive change.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D80254

Files:
  lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
  lldb/test/API/functionalities/pointer_num_children/Makefile
  lldb/test/API/functionalities/pointer_num_children/TestPointerNumChildren.py
  lldb/test/API/functionalities/pointer_num_children/main.cpp

Index: lldb/test/API/functionalities/pointer_num_children/main.cpp
===================================================================
--- /dev/null
+++ lldb/test/API/functionalities/pointer_num_children/main.cpp
@@ -0,0 +1,19 @@
+struct Inner
+{
+  int a;
+  int b;
+};
+
+struct Outer
+{
+  Inner *inner;
+};
+
+int main()
+{
+  Inner inner{42, 56};
+  Outer outer{&inner};
+  auto Ptr = &(outer.inner);
+  auto& Ref = outer.inner;
+  return 0;  // break here
+}
Index: lldb/test/API/functionalities/pointer_num_children/TestPointerNumChildren.py
===================================================================
--- /dev/null
+++ lldb/test/API/functionalities/pointer_num_children/TestPointerNumChildren.py
@@ -0,0 +1,24 @@
+"""
+"""
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class TestPointerNumChilden(TestBase):
+    mydir = TestBase.compute_mydir(__file__)
+
+    def test_pointer_num_children(self):
+        self.main_source_file = lldb.SBFileSpec("main.cpp")
+        self.build()
+        (_, _, thread, _) = lldbutil.run_to_source_breakpoint(self, "// break here", self.main_source_file)
+        frame = thread.GetSelectedFrame()
+
+        result = frame.FindVariable("Ref")
+        self.assertEqual("42", result.GetChildAtIndex(0).GetChildAtIndex(0).GetValue())
+        self.assertEqual(1, result.GetNumChildren())
+
+        result = frame.FindVariable("Ptr")
+        self.assertEqual("42", result.GetChildAtIndex(0).GetChildAtIndex(0).GetValue())
+        self.assertEqual(1, result.GetNumChildren())
Index: lldb/test/API/functionalities/pointer_num_children/Makefile
===================================================================
--- /dev/null
+++ lldb/test/API/functionalities/pointer_num_children/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
Index: lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
===================================================================
--- lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -5173,11 +5173,12 @@
     break;
 
   case clang::Type::ObjCObjectPointer: {
-    const clang::ObjCObjectPointerType *pointer_type =
-        llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr());
-    clang::QualType pointee_type = pointer_type->getPointeeType();
-    uint32_t num_pointee_children =
-        GetType(pointee_type).GetNumChildren(omit_empty_base_classes, exe_ctx);
+    CompilerType pointee_clang_type(GetPointeeType(type));
+
+    uint32_t num_pointee_children = 0;
+    if (pointee_clang_type.IsAggregateType())
+      num_pointee_children =
+          pointee_clang_type.GetNumChildren(omit_empty_base_classes, exe_ctx);
     // If this type points to a simple type, then it has 1 child
     if (num_pointee_children == 0)
       num_children = 1;
@@ -5209,8 +5210,11 @@
     const clang::PointerType *pointer_type =
         llvm::cast<clang::PointerType>(qual_type.getTypePtr());
     clang::QualType pointee_type(pointer_type->getPointeeType());
-    uint32_t num_pointee_children =
-        GetType(pointee_type).GetNumChildren(omit_empty_base_classes, exe_ctx);
+    CompilerType pointee_clang_type(GetType(pointee_type));
+    uint32_t num_pointee_children = 0;
+    if (pointee_clang_type.IsAggregateType())
+      num_pointee_children =
+          pointee_clang_type.GetNumChildren(omit_empty_base_classes, exe_ctx);
     if (num_pointee_children == 0) {
       // We have a pointer to a pointee type that claims it has no children. We
       // will want to look at
@@ -5223,9 +5227,11 @@
   case clang::Type::RValueReference: {
     const clang::ReferenceType *reference_type =
         llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
-    clang::QualType pointee_type = reference_type->getPointeeType();
-    uint32_t num_pointee_children =
-        GetType(pointee_type).GetNumChildren(omit_empty_base_classes, exe_ctx);
+    CompilerType pointee_clang_type = GetType(reference_type->getPointeeType());
+    uint32_t num_pointee_children = 0;
+    if (pointee_clang_type.IsAggregateType())
+      num_pointee_children =
+          pointee_clang_type.GetNumChildren(omit_empty_base_classes, exe_ctx);
     // If this type points to a simple type, then it has 1 child
     if (num_pointee_children == 0)
       num_children = 1;
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to