Index: packages/Python/lldbsuite/test/lang/cpp/nested-class-other-compilation-unit/Makefile =================================================================== --- /dev/null +++ packages/Python/lldbsuite/test/lang/cpp/nested-class-other-compilation-unit/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp other.cpp + +include Makefile.rules Index: packages/Python/lldbsuite/test/lang/cpp/nested-class-other-compilation-unit/TestNestedClassWithParentInAnotherCU.py =================================================================== --- /dev/null +++ packages/Python/lldbsuite/test/lang/cpp/nested-class-other-compilation-unit/TestNestedClassWithParentInAnotherCU.py @@ -0,0 +1,29 @@ +""" +Test that the expression evaluator can access members of nested classes even if +the parents of the nested classes were imported from another compilation unit. +""" +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestNestedClassWithParentInAnotherCU(TestBase): + mydir = TestBase.compute_mydir(__file__) + + def test_nested_class_with_parent_in_another_cu(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() + # Parse the DIEs of the parent classes and the nested classes from + # other.cpp's CU. + warmup_result = frame.EvaluateExpression("b") + self.assertTrue(warmup_result.IsValid()) + # Inspect fields of the nested classes. This will reuse the types that + # were parsed during the evaluation above. By accessing a chain of + # fields, we try to verify that all the DIEs, reused types and + # declaration contexts were wired properly into lldb's parser's state. + expr_result = frame.EvaluateExpression("a.y.oY_inner.oX_inner") + self.assertTrue(expr_result.IsValid()) + self.assertEqual(expr_result.GetValue(), "42") Index: packages/Python/lldbsuite/test/lang/cpp/nested-class-other-compilation-unit/main.cpp =================================================================== --- /dev/null +++ packages/Python/lldbsuite/test/lang/cpp/nested-class-other-compilation-unit/main.cpp @@ -0,0 +1,22 @@ +#include "shared.h" + +struct WrapperA { + OuterY::Inner y; +}; + +int main() { + // WrapperA refers to the Inner and Outer class DIEs from this CU. + WrapperA a; + // WrapperB refers to the Inner and Outer DIEs from the other.cpp CU. + // It is important that WrapperB is only forward-declared in shared.h. + WrapperB* b = foo(); + + // Evaluating 'b' here will parse other.cpp's DIEs for all + // the Inner and Outer classes from shared.h. + // + // Evaluating 'a' here will find and reuse the already-parsed + // versions of the Inner and Outer classes. In the associated test + // we make sure that we can still resolve all the types properly + // by evaluating 'a.y.oY_inner.oX_inner'. + return 0; // break here +} Index: packages/Python/lldbsuite/test/lang/cpp/nested-class-other-compilation-unit/other.cpp =================================================================== --- /dev/null +++ packages/Python/lldbsuite/test/lang/cpp/nested-class-other-compilation-unit/other.cpp @@ -0,0 +1,10 @@ +#include "shared.h" + +struct WrapperB { + OuterY y; + OuterX x; +}; + +WrapperB* foo() { + return new WrapperB(); +} Index: packages/Python/lldbsuite/test/lang/cpp/nested-class-other-compilation-unit/shared.h =================================================================== --- /dev/null +++ packages/Python/lldbsuite/test/lang/cpp/nested-class-other-compilation-unit/shared.h @@ -0,0 +1,17 @@ +struct OuterX { + template + struct Inner { + int oX_inner = 42; + }; +}; + +struct OuterY { + template + struct Inner { + typename OuterX::Inner oY_inner; + }; +}; + +struct WrapperB; + +WrapperB* foo(); Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -690,6 +690,8 @@ type_sp = unique_ast_entry_up->m_type_sp; if (type_sp) { dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); + LinkDeclContextToDIE( + GetCachedClangDeclContextForDIE(unique_ast_entry_up->m_die), die); return type_sp; } }