@@ -2439,6 +2439,48 @@ void SymbolFileDWARF::FindGlobalVariables(
2439
2439
return variables.GetSize () - original_size < max_matches;
2440
2440
});
2441
2441
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
+
2442
2484
// Return the number of variable that were appended to the list
2443
2485
const uint32_t num_matches = variables.GetSize () - original_size;
2444
2486
if (log && num_matches > 0 ) {
@@ -3371,6 +3413,94 @@ size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) {
3371
3413
return 0 ;
3372
3414
}
3373
3415
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
+
3374
3504
VariableSP SymbolFileDWARF::ParseVariableDIECached (const SymbolContext &sc,
3375
3505
const DWARFDIE &die) {
3376
3506
if (!die)
0 commit comments