@@ -2439,6 +2439,48 @@ void SymbolFileDWARF::FindGlobalVariables(
24392439 return variables.GetSize () - original_size < max_matches;
24402440 });
24412441
2442+ // If we don't have enough matches and the variable context is not empty, try
2443+ // to resolve the context as a type and look for static const members.
2444+ if (variables.GetSize () - original_size < max_matches && !context.empty ()) {
2445+ llvm::StringRef type_name;
2446+ if (std::optional<Type::ParsedName> parsed_name =
2447+ Type::GetTypeScopeAndBasename (context))
2448+ type_name = parsed_name->basename ;
2449+ else
2450+ type_name = context;
2451+
2452+ m_index->GetTypes (ConstString (type_name), [&](DWARFDIE parent) {
2453+ llvm::StringRef parent_type_name = parent.GetDWARFDeclContext ()
2454+ .GetQualifiedNameAsConstString ()
2455+ .GetStringRef ();
2456+
2457+ // This type is from another scope, skip it.
2458+ if (!parent_type_name.ends_with (context))
2459+ return true ;
2460+
2461+ auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(parent.GetCU ());
2462+ if (!dwarf_cu)
2463+ return true ;
2464+
2465+ sc.comp_unit = GetCompUnitForDWARFCompUnit (*dwarf_cu);
2466+
2467+ for (DWARFDIE die = parent.GetFirstChild (); die.IsValid ();
2468+ die = die.GetSibling ()) {
2469+ // Try parsing the entry as a static const member.
2470+ if (auto var_sp = ParseStaticConstMemberDIE (sc, die)) {
2471+ if (var_sp->GetUnqualifiedName ().GetStringRef () != basename)
2472+ continue ;
2473+
2474+ // There can be only one member with a given name.
2475+ variables.AddVariableIfUnique (var_sp);
2476+ break ;
2477+ }
2478+ }
2479+
2480+ return variables.GetSize () - original_size < max_matches;
2481+ });
2482+ }
2483+
24422484 // Return the number of variable that were appended to the list
24432485 const uint32_t num_matches = variables.GetSize () - original_size;
24442486 if (log && num_matches > 0 ) {
@@ -3371,6 +3413,94 @@ size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) {
33713413 return 0 ;
33723414}
33733415
3416+ VariableSP SymbolFileDWARF::ParseStaticConstMemberDIE (
3417+ const lldb_private::SymbolContext &sc, const DWARFDIE &die) {
3418+ if (die.GetDWARF () != this )
3419+ return die.GetDWARF ()->ParseStaticConstMemberDIE (sc, die);
3420+
3421+ // Look only for members, ignore all other types of entries.
3422+ if (die.Tag () != DW_TAG_member)
3423+ return nullptr ;
3424+
3425+ if (VariableSP var_sp = GetDIEToVariable ()[die.GetDIE ()])
3426+ return var_sp; // Already been parsed!
3427+
3428+ const char *name = nullptr ;
3429+ const char *mangled = nullptr ;
3430+ Declaration decl;
3431+ DWARFExpression location;
3432+ DWARFFormValue type_die_form;
3433+ DWARFFormValue const_value_form;
3434+
3435+ DWARFAttributes attributes = die.GetAttributes ();
3436+ const size_t num_attributes = attributes.Size ();
3437+
3438+ for (size_t i = 0 ; i < num_attributes; ++i) {
3439+ dw_attr_t attr = attributes.AttributeAtIndex (i);
3440+ DWARFFormValue form_value;
3441+
3442+ if (!attributes.ExtractFormValueAtIndex (i, form_value))
3443+ continue ;
3444+
3445+ switch (attr) {
3446+ case DW_AT_decl_file:
3447+ decl.SetFile (sc.comp_unit ->GetSupportFiles ().GetFileSpecAtIndex (
3448+ form_value.Unsigned ()));
3449+ break ;
3450+ case DW_AT_decl_line:
3451+ decl.SetLine (form_value.Unsigned ());
3452+ break ;
3453+ case DW_AT_decl_column:
3454+ decl.SetColumn (form_value.Unsigned ());
3455+ break ;
3456+ case DW_AT_name:
3457+ name = form_value.AsCString ();
3458+ break ;
3459+ case DW_AT_type:
3460+ type_die_form = form_value;
3461+ break ;
3462+ case DW_AT_const_value:
3463+ const_value_form = form_value;
3464+ break ;
3465+ default :
3466+ break ;
3467+ }
3468+ }
3469+
3470+ // Look only for static const members with const values.
3471+ if (!DWARFFormValue::IsDataForm (const_value_form.Form ()))
3472+ return nullptr ;
3473+
3474+ SymbolFileTypeSP type_sp = std::make_shared<SymbolFileType>(
3475+ *this , type_die_form.Reference ().GetID ());
3476+
3477+ if (type_sp->GetType ()) {
3478+ location.UpdateValue (const_value_form.Unsigned (),
3479+ type_sp->GetType ()->GetByteSize (nullptr ).value_or (0 ),
3480+ die.GetCU ()->GetAddressByteSize ());
3481+ }
3482+
3483+ if (Language::LanguageIsCPlusPlus (GetLanguage (*die.GetCU ())))
3484+ mangled =
3485+ die.GetDWARFDeclContext ().GetQualifiedNameAsConstString ().GetCString ();
3486+
3487+ ValueType scope = eValueTypeVariableGlobal;
3488+ Variable::RangeList scope_ranges;
3489+
3490+ DWARFExpressionList location_list (GetObjectFile ()->GetModule (), location,
3491+ die.GetCU ());
3492+ VariableSP var_sp = std::make_shared<Variable>(
3493+ die.GetID (), name, mangled, type_sp, scope, sc.comp_unit , scope_ranges,
3494+ &decl, location_list, /* is_external*/ true , /* is_artificial*/ false ,
3495+ /* is_static_member*/ true );
3496+ var_sp->SetLocationIsConstantValueData (true );
3497+
3498+ // Cache this variable, so we don't parse it over and over again.
3499+ GetDIEToVariable ()[die.GetDIE ()] = var_sp;
3500+
3501+ return var_sp;
3502+ }
3503+
33743504VariableSP SymbolFileDWARF::ParseVariableDIECached (const SymbolContext &sc,
33753505 const DWARFDIE &die) {
33763506 if (!die)
0 commit comments