Author: Michael Buch Date: 2024-01-08T14:10:02Z New Revision: 2bf01d73f6ebca11f36c17a65b7a86109d44681e
URL: https://github.com/llvm/llvm-project/commit/2bf01d73f6ebca11f36c17a65b7a86109d44681e DIFF: https://github.com/llvm/llvm-project/commit/2bf01d73f6ebca11f36c17a65b7a86109d44681e.diff LOG: [lldb][DWARFASTParserClang] GetClangDeclForDIE: don't create VarDecl for static data members (#77155) With DWARFv5, C++ static data members are represented as `DW_TAG_variable`s (see `faa3a5ea9ae481da757dab1c95c589e2d5645982`). In GetClangDeclForDIE, when trying to parse the `DW_AT_specification` that a static data member's CU-level `DW_TAG_variable` points to, we would try to `CreateVariableDeclaration`. Whereas previously it was a no-op (for `DW_TAG_member`s). However, adding `VarDecls` to RecordDecls for static data members should always be done in `CreateStaticMemberVariable`. The test-case is an exapmle where we would crash if we tried to create a `VarDecl` from within `GetClangDeclForDIE` for a static data member. This patch simply checks whether the `DW_TAG_variable` being parsed is a static data member, and if so, trivially returns from `GetClangDeclForDIE` (as we previously did for `DW_TAG_member`s). Added: lldb/test/Shell/SymbolFile/DWARF/Inputs/dwo-static-data-member.cpp lldb/test/Shell/SymbolFile/DWARF/dwo-static-data-member-access.test Modified: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp Removed: ################################################################################ diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 009722b85aa186..54d06b1115a229 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) { @@ -3304,12 +3316,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 00000000000000..fa7c3500df0f9d --- /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 00000000000000..6e4deae7b9a0d7 --- /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' _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits