diff --git a/lldb/source/Symbol/ClangASTType.cpp b/lldb/source/Symbol/ClangASTType.cpp index 9e7d52abd0fc..da445d83e79f 100644 --- a/lldb/source/Symbol/ClangASTType.cpp +++ b/lldb/source/Symbol/ClangASTType.cpp @@ -3522,7 +3522,17 @@ ClangASTType::GetIndexOfChildMemberWithName (const char *name, field != field_end; ++field, ++child_idx) { - if (field->getName().equals (name_sref)) + llvm::StringRef field_name = field->getName(); + if (field_name.empty()) + { + ClangASTType field_type(m_ast,field->getType()); + child_indexes.push_back(child_idx); + if (field_type.GetIndexOfChildMemberWithName(name, omit_empty_base_classes, child_indexes)) + return child_indexes.size(); + child_indexes.pop_back(); + + } + else if (field_name.equals (name_sref)) { // We have to add on the number of base classes to this index! child_indexes.push_back (child_idx + ClangASTContext::GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes)); diff --git a/lldb/test/lang/c/anonymous/TestAnonymous.py b/lldb/test/lang/c/anonymous/TestAnonymous.py index d86c31e1e59d..0e8911944ce0 100644 --- a/lldb/test/lang/c/anonymous/TestAnonymous.py +++ b/lldb/test/lang/c/anonymous/TestAnonymous.py @@ -36,6 +36,11 @@ class AnonymousTestCase(TestBase): self.buildDsym() self.expr_null() + @dsym_test + def test_child_by_name(self): + self.buildDsym() + self.child_by_name() + @skipIfGcc # llvm.org/pr15036: LLDB generates an incorrect AST layout for an anonymous struct when DWARF is generated by GCC @skipIfIcc # llvm.org/pr15036: LLDB generates an incorrect AST layout for an anonymous struct when DWARF is generated by ICC @dwarf_test @@ -67,6 +72,11 @@ class AnonymousTestCase(TestBase): self.buildDwarf() self.expr_null() + @dwarf_test + def test_child_by_name_with_dwarf(self): + self.buildDsym() + self.child_by_name() + def setUp(self): # Call super's setUp(). TestBase.setUp(self) @@ -144,6 +154,39 @@ class AnonymousTestCase(TestBase): self.expect("expression *(type_z *)pz", substrs = ["Cannot access memory at address 0x0"], error = True) + def child_by_name(self): + exe = os.path.join (os.getcwd(), "a.out") + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + break_in_main = target.BreakpointCreateBySourceRegex ('// Set breakpoint 2 here.', lldb.SBFileSpec("main.c")) + self.assertTrue(break_in_main, VALID_BREAKPOINT) + + process = target.LaunchSimple (None, None, os.getcwd()) + self.assertTrue (process, PROCESS_IS_VALID) + + threads = lldbutil.get_threads_stopped_at_breakpoint (process, break_in_main) + if len(threads) != 1: + self.fail ("Failed to stop at breakpoint in main.") + + thread = threads[0] + frame = thread.frames[0] + + if not frame.IsValid(): + self.fail ("Failed to get frame 0.") + + var_n = frame.FindVariable("n") + if not var_n.IsValid(): + self.fail ("Failed to get the variable 'n'") + + elem_a = var_n.GetChildMemberWithName("a") + if not elem_a.IsValid(): + self.fail ("Failed to get the element a in n") + + error = lldb.SBError() + value = elem_a.GetValueAsSigned(error, 1000) + if not error.Success() or value != 0: + self.fail ("failed to get the correct value for element a in n") if __name__ == '__main__': import atexit