llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-lldb Author: Michael Buch (Michael137) <details> <summary>Changes</summary> This is a **draft** patch that shows how LLDB could continue to support static initialisers even if the declaration didn't have a `DW_AT_const_value` anymore. https://github.com/llvm/llvm-project/pull/70639 proposes moving the `DW_AT_const_value` on inline static members from the declaration DIE to the definition DIE. Previously the expression evaluator would find the constant for a VarDecl from its declaration `DW_TAG_member` DIE. In cases where the initialiser was specified out-of-class, LLDB could find it during symbol resolution. However, neither of those will work for constants, since we don't have a constant attribute on the declaration anymore and we don't have constants in the symbol table. --- Full diff: https://github.com/llvm/llvm-project/pull/71004.diff 2 Files Affected: - (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp (+50-1) - (modified) lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h (+5-5) ``````````diff diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 182cc6764651747..39571dbcd30a57b 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -31,6 +31,7 @@ #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/TypeList.h" #include "lldb/Symbol/TypeMap.h" +#include "lldb/Symbol/VariableList.h" #include "lldb/Target/Language.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" @@ -133,6 +134,42 @@ static lldb::ModuleSP GetContainingClangModule(const DWARFDIE &die) { return lldb::ModuleSP(); } +static std::optional<DWARFFormValue> +FindConstantOnVariableDefinition(DWARFDIE die) { + auto *dwarf = die.GetDWARF(); + if (!dwarf) + return {}; + + ConstString name{die.GetName()}; + if (!name) + return {}; + + // Make sure we populate the GetDieToVariable cache. + VariableList variables; + dwarf->FindGlobalVariables(name, {}, UINT_MAX, variables); + + auto const &die_to_var = dwarf->GetDIEToVariable(); + auto it = die_to_var.find(die.GetDIE()); + if (it == die_to_var.end()) + return {}; + + auto var_sp = it->getSecond(); + assert(var_sp != nullptr); + + if (!var_sp->GetLocationIsConstantValueData()) + return {}; + + auto def = dwarf->GetDIE(var_sp->GetID()); + auto def_attrs = def.GetAttributes(); + DWARFFormValue form_value; + if (!def_attrs.ExtractFormValueAtIndex( + def_attrs.FindAttributeIndex(llvm::dwarf::DW_AT_const_value), + form_value)) + return {}; + + return form_value; +} + TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc, const DWARFDIE &die, Log *log) { @@ -2906,9 +2943,21 @@ void DWARFASTParserClang::ParseSingleMember( bool unused; // TODO: Support float/double static members as well. - if (!attrs.const_value_form || !ct.IsIntegerOrEnumerationType(unused)) + if (!ct.IsIntegerOrEnumerationType(unused)) return; + // Newer versions of Clang don't emit the DW_AT_const_value + // on the declaration of a inline static data member. Instead + // it's attached to the definition DIE. If that's the case, + // try and fetch it. + if (!attrs.const_value_form) { + auto maybe_form_value = FindConstantOnVariableDefinition(die); + if (!maybe_form_value) + return; + + attrs.const_value_form = *maybe_form_value; + } + llvm::Expected<llvm::APInt> const_value_or_err = ExtractIntFromFormValue(ct, *attrs.const_value_form); if (!const_value_or_err) { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index 069a2050f0eaadc..ba4532c48338b76 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -342,6 +342,11 @@ class SymbolFileDWARF : public SymbolFileCommon { return m_forward_decl_compiler_type_to_die; } + typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb::VariableSP> + DIEToVariableSP; + + virtual DIEToVariableSP &GetDIEToVariable() { return m_die_to_variable_sp; } + virtual UniqueDWARFASTTypeMap &GetUniqueDWARFASTTypeMap(); bool ClassOrStructIsVirtual(const DWARFDIE &die); @@ -361,9 +366,6 @@ class SymbolFileDWARF : public SymbolFileCommon { Type *ResolveTypeUID(const DIERef &die_ref); protected: - typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb::VariableSP> - DIEToVariableSP; - SymbolFileDWARF(const SymbolFileDWARF &) = delete; const SymbolFileDWARF &operator=(const SymbolFileDWARF &) = delete; @@ -487,8 +489,6 @@ class SymbolFileDWARF : public SymbolFileCommon { void UpdateExternalModuleListIfNeeded(); - virtual DIEToVariableSP &GetDIEToVariable() { return m_die_to_variable_sp; } - void BuildCuTranslationTable(); std::optional<uint32_t> GetDWARFUnitIndex(uint32_t cu_idx); `````````` </details> https://github.com/llvm/llvm-project/pull/71004 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits