summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules/TestWithModuleDebugging.py23
-rw-r--r--lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules/main.cpp3
-rw-r--r--lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules/pch.h5
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp37
4 files changed, 68 insertions, 0 deletions
diff --git a/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules/TestWithModuleDebugging.py b/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules/TestWithModuleDebugging.py
index b9f25537258..20207c54db9 100644
--- a/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules/TestWithModuleDebugging.py
+++ b/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules/TestWithModuleDebugging.py
@@ -69,3 +69,26 @@ class TestWithGmodulesDebugInfo(TestBase):
42,
memberValue.GetValueAsSigned(),
"Member value incorrect")
+
+ testValue = frame.EvaluateExpression("bar")
+ self.assertTrue(
+ testValue.GetError().Success(),
+ "Test expression value invalid: %s" %
+ (testValue.GetError().GetCString()))
+ self.assertTrue(
+ testValue.GetTypeName() == "Foo::Bar",
+ "Test expression type incorrect")
+
+ memberValue = testValue.GetChildMemberWithName("i")
+ self.assertTrue(
+ memberValue.GetError().Success(),
+ "Member value missing or invalid: %s" %
+ (testValue.GetError().GetCString()))
+ self.assertTrue(
+ memberValue.GetTypeName() == "int",
+ "Member type incorrect")
+ self.assertEqual(
+ 123,
+ memberValue.GetValueAsSigned(),
+ "Member value incorrect")
+
diff --git a/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules/main.cpp b/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules/main.cpp
index aa401368517..588a3a8e01f 100644
--- a/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules/main.cpp
+++ b/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules/main.cpp
@@ -1,5 +1,8 @@
+class Foo::Bar { int i = 123; };
+
int main(int argc, const char * argv[])
{
IntContainer test(42);
+ Foo::Bar bar;
return 0; // break here
}
diff --git a/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules/pch.h b/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules/pch.h
index a6c59b94c89..dba4fee9a8c 100644
--- a/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules/pch.h
+++ b/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules/pch.h
@@ -10,3 +10,8 @@ class GenericContainer {
};
typedef GenericContainer<int> IntContainer;
+
+struct Foo {
+ class Bar;
+ Bar *bar;
+};
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 3d13d40a687..fbf35b8be09 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -205,6 +205,33 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWO(const DWARFDIE &die, Log *log) {
return type_sp;
}
+static void CompleteExternalTagDeclType(ClangASTImporter &ast_importer,
+ clang::DeclContext *decl_ctx,
+ DWARFDIE die,
+ const char *type_name_cstr) {
+ auto *tag_decl_ctx = clang::dyn_cast<clang::TagDecl>(decl_ctx);
+ if (!tag_decl_ctx)
+ return;
+
+ // If this type was not imported from an external AST, there's
+ // nothing to do.
+ CompilerType type = ClangASTContext::GetTypeForDecl(tag_decl_ctx);
+ if (!type || !ast_importer.CanImport(type))
+ return;
+
+ auto qual_type = ClangUtil::GetQualType(type);
+ if (!ast_importer.RequireCompleteType(qual_type)) {
+ die.GetDWARF()->GetObjectFile()->GetModule()->ReportError(
+ "Unable to complete the Decl context for DIE '%s' at offset "
+ "0x%8.8x.\nPlease file a bug report.",
+ type_name_cstr ?: "", die.GetOffset());
+ // We need to make the type look complete otherwise, we
+ // might crash in Clang when adding children.
+ if (ClangASTContext::StartTagDeclarationDefinition(type))
+ ClangASTContext::CompleteTagDeclarationDefinition(type);
+ }
+}
+
TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
const DWARFDIE &die, Log *log,
bool *type_is_new_ptr) {
@@ -795,6 +822,16 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
if (!clang_type) {
clang::DeclContext *decl_ctx =
GetClangDeclContextContainingDIE(die, nullptr);
+
+ // If your decl context is a record that was imported from
+ // another AST context (in the gmodules case), we need to
+ // make sure the type backing the Decl is complete before
+ // adding children to it. This is not an issue in the
+ // non-gmodules case because the debug info will always contain
+ // a full definition of parent types in that case.
+ CompleteExternalTagDeclType(GetClangASTImporter(), decl_ctx, die,
+ type_name_cstr);
+
if (accessibility == eAccessNone && decl_ctx) {
// Check the decl context that contains this class/struct/union.
// If it is a class we must give it an accessibility.
OpenPOWER on IntegriCloud