diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 3e08f2550081f..771d33bf8ff7a 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -142,6 +142,18 @@ static bool ShouldIgnoreArtificialField(llvm::StringRef FieldName) { || FieldName.starts_with("_vptr."); } +/// Returns true for C++ constructs represented by clang::CXXRecordDecl +static bool TagIsRecordType(dw_tag_t tag) { + switch (tag) { + case DW_TAG_class_type: + case DW_TAG_structure_type: + case DW_TAG_union_type: + return true; + default: + return false; + } +} + TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc, const DWARFDIE &die, Log *log) { @@ -3293,12 +3305,19 @@ clang::Decl *DWARFASTParserClang::GetClangDeclForDIE(const DWARFDIE &die) { return nullptr; switch (die.Tag()) { - case DW_TAG_variable: case DW_TAG_constant: case DW_TAG_formal_parameter: case DW_TAG_imported_declaration: case DW_TAG_imported_module: break; + case DW_TAG_variable: + // This means 'die' is a C++ static data member. + // We don't want to create decls for such members + // here. + if (auto parent = die.GetParent(); + parent.IsValid() && TagIsRecordType(parent.Tag())) + return nullptr; + break; default: return nullptr; } diff --git a/lldb/test/Shell/SymbolFile/DWARF/Inputs/dwo-static-data-member.cpp b/lldb/test/Shell/SymbolFile/DWARF/Inputs/dwo-static-data-member.cpp new file mode 100644 index 0000000000000..fa7c3500df0f9 --- /dev/null +++ b/lldb/test/Shell/SymbolFile/DWARF/Inputs/dwo-static-data-member.cpp @@ -0,0 +1,8 @@ +struct NoCtor { + NoCtor(); + static int i; +}; + +int NoCtor::i = 15; + +int main() { return NoCtor::i; } diff --git a/lldb/test/Shell/SymbolFile/DWARF/dwo-static-data-member-access.test b/lldb/test/Shell/SymbolFile/DWARF/dwo-static-data-member-access.test new file mode 100644 index 0000000000000..6e4deae7b9a0d --- /dev/null +++ b/lldb/test/Shell/SymbolFile/DWARF/dwo-static-data-member-access.test @@ -0,0 +1,24 @@ +# In DWARFv5, C++ static data members are represented +# as DW_TAG_variable. We make sure LLDB's expression +# evaluator doesn't crash when trying to parse such +# a DW_TAG_variable DIE, whose parent DIE is only +# a forward declaration. + +# RUN: %clangxx_host %S/Inputs/dwo-static-data-member.cpp \ +# RUN: -g -gdwarf-5 -gsplit-dwarf -flimit-debug-info -o %t +# RUN: %lldb %t -s %s -o exit 2>&1 | FileCheck %s + +breakpoint set -n main +process launch + +# CHECK: Process {{.*}} stopped + +# FIXME: The expression evaluator tries to attach +# the static member's VarDecl to the NoCtor RecordDecl +# before passing the AST to clang; this requires the +# RecordDecl to be a full definition. But the debug-info +# only contains forward declaration for NoCtor. So +# LLDB fails to evaluate the expression. +expression NoCtor::i +# CHECK-LABEL: expression NoCtor::i +# CHECK: use of undeclared identifier 'NoCtor'