[Lldb-commits] [lldb] [lldb] Lookup static const members in FindGlobalVariables (PR #111859)
Ilia Kuklin via lldb-commits
lldb-commits at lists.llvm.org
Thu Oct 24 11:08:57 PDT 2024
https://github.com/kuilpd updated https://github.com/llvm/llvm-project/pull/111859
>From 4c394ec162b58b3cde3af924a5e9be1de8250a07 Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Tue, 30 Jul 2024 17:02:10 +0500
Subject: [PATCH 1/2] [lldb] Lookup static const members in FindGlobalVariables
Static const members initialized inside a class definition might not have a corresponding DW_TAG_variable (DWARF 4 and earlier), so they're not indexed by ManualDWARFIndex.
Add an additional lookup in FindGlobalVariables. Try looking up the enclosing type (e.g. foo::bar for foo::bar::A) and then searching for a static const member (A) within this type.
---
.../SymbolFile/DWARF/SymbolFileDWARF.cpp | 130 ++++++++++++++++++
.../SymbolFile/DWARF/SymbolFileDWARF.h | 3 +
.../API/python_api/frame/globals/Makefile | 4 +
.../frame/globals/TestTargetGlobals.py | 43 ++++++
.../API/python_api/frame/globals/main.cpp | 12 ++
5 files changed, 192 insertions(+)
create mode 100644 lldb/test/API/python_api/frame/globals/Makefile
create mode 100644 lldb/test/API/python_api/frame/globals/TestTargetGlobals.py
create mode 100644 lldb/test/API/python_api/frame/globals/main.cpp
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 9287d4baf19e9c..d53da79c1efcee 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -2439,6 +2439,48 @@ void SymbolFileDWARF::FindGlobalVariables(
return variables.GetSize() - original_size < max_matches;
});
+ // If we don't have enough matches and the variable context is not empty, try
+ // to resolve the context as a type and look for static const members.
+ if (variables.GetSize() - original_size < max_matches && !context.empty()) {
+ llvm::StringRef type_name;
+ if (std::optional<Type::ParsedName> parsed_name =
+ Type::GetTypeScopeAndBasename(context))
+ type_name = parsed_name->basename;
+ else
+ type_name = context;
+
+ m_index->GetTypes(ConstString(type_name), [&](DWARFDIE parent) {
+ llvm::StringRef parent_type_name = parent.GetDWARFDeclContext()
+ .GetQualifiedNameAsConstString()
+ .GetStringRef();
+
+ // This type is from another scope, skip it.
+ if (!parent_type_name.ends_with(context))
+ return true;
+
+ auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(parent.GetCU());
+ if (!dwarf_cu)
+ return true;
+
+ sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu);
+
+ for (DWARFDIE die = parent.GetFirstChild(); die.IsValid();
+ die = die.GetSibling()) {
+ // Try parsing the entry as a static const member.
+ if (auto var_sp = ParseStaticConstMemberDIE(sc, die)) {
+ if (var_sp->GetUnqualifiedName().GetStringRef() != basename)
+ continue;
+
+ // There can be only one member with a given name.
+ variables.AddVariableIfUnique(var_sp);
+ break;
+ }
+ }
+
+ return variables.GetSize() - original_size < max_matches;
+ });
+ }
+
// Return the number of variable that were appended to the list
const uint32_t num_matches = variables.GetSize() - original_size;
if (log && num_matches > 0) {
@@ -3371,6 +3413,94 @@ size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) {
return 0;
}
+VariableSP SymbolFileDWARF::ParseStaticConstMemberDIE(
+ const lldb_private::SymbolContext &sc, const DWARFDIE &die) {
+ if (die.GetDWARF() != this)
+ return die.GetDWARF()->ParseStaticConstMemberDIE(sc, die);
+
+ // Look only for members, ignore all other types of entries.
+ if (die.Tag() != DW_TAG_member)
+ return nullptr;
+
+ if (VariableSP var_sp = GetDIEToVariable()[die.GetDIE()])
+ return var_sp; // Already been parsed!
+
+ const char *name = nullptr;
+ const char *mangled = nullptr;
+ Declaration decl;
+ DWARFExpression location;
+ DWARFFormValue type_die_form;
+ DWARFFormValue const_value_form;
+
+ DWARFAttributes attributes = die.GetAttributes();
+ const size_t num_attributes = attributes.Size();
+
+ for (size_t i = 0; i < num_attributes; ++i) {
+ dw_attr_t attr = attributes.AttributeAtIndex(i);
+ DWARFFormValue form_value;
+
+ if (!attributes.ExtractFormValueAtIndex(i, form_value))
+ continue;
+
+ switch (attr) {
+ case DW_AT_decl_file:
+ decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
+ form_value.Unsigned()));
+ break;
+ case DW_AT_decl_line:
+ decl.SetLine(form_value.Unsigned());
+ break;
+ case DW_AT_decl_column:
+ decl.SetColumn(form_value.Unsigned());
+ break;
+ case DW_AT_name:
+ name = form_value.AsCString();
+ break;
+ case DW_AT_type:
+ type_die_form = form_value;
+ break;
+ case DW_AT_const_value:
+ const_value_form = form_value;
+ break;
+ default:
+ break;
+ }
+ }
+
+ // Look only for static const members with const values.
+ if (!DWARFFormValue::IsDataForm(const_value_form.Form()))
+ return nullptr;
+
+ SymbolFileTypeSP type_sp = std::make_shared<SymbolFileType>(
+ *this, type_die_form.Reference().GetID());
+
+ if (type_sp->GetType()) {
+ location.UpdateValue(const_value_form.Unsigned(),
+ type_sp->GetType()->GetByteSize(nullptr).value_or(0),
+ die.GetCU()->GetAddressByteSize());
+ }
+
+ if (Language::LanguageIsCPlusPlus(GetLanguage(*die.GetCU())))
+ mangled =
+ die.GetDWARFDeclContext().GetQualifiedNameAsConstString().GetCString();
+
+ ValueType scope = eValueTypeVariableGlobal;
+ Variable::RangeList scope_ranges;
+
+ DWARFExpressionList location_list(GetObjectFile()->GetModule(), location,
+ die.GetCU());
+ VariableSP var_sp = std::make_shared<Variable>(
+ die.GetID(), name, mangled, type_sp, scope, sc.comp_unit, scope_ranges,
+ &decl, location_list, /*is_external*/ true, /*is_artificial*/ false,
+ /*is_static_member*/ true);
+ var_sp->SetLocationIsConstantValueData(true);
+
+ // Cache this variable, so we don't parse it over and over again.
+ GetDIEToVariable()[die.GetDIE()] = var_sp;
+
+ return var_sp;
+}
+
VariableSP SymbolFileDWARF::ParseVariableDIECached(const SymbolContext &sc,
const DWARFDIE &die) {
if (!die)
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index 4967b37d753a09..380b5d4a289300 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -408,6 +408,9 @@ class SymbolFileDWARF : public SymbolFileCommon {
bool ParseSupportFiles(DWARFUnit &dwarf_cu, const lldb::ModuleSP &module,
SupportFileList &support_files);
+ lldb::VariableSP ParseStaticConstMemberDIE(const SymbolContext &sc,
+ const DWARFDIE &die);
+
lldb::VariableSP ParseVariableDIE(const SymbolContext &sc,
const DWARFDIE &die,
const lldb::addr_t func_low_pc);
diff --git a/lldb/test/API/python_api/frame/globals/Makefile b/lldb/test/API/python_api/frame/globals/Makefile
new file mode 100644
index 00000000000000..c24259ec8c9d93
--- /dev/null
+++ b/lldb/test/API/python_api/frame/globals/Makefile
@@ -0,0 +1,4 @@
+CXX_SOURCES := main.cpp
+CXXFLAGS_EXTRAS := -gdwarf-4
+
+include Makefile.rules
diff --git a/lldb/test/API/python_api/frame/globals/TestTargetGlobals.py b/lldb/test/API/python_api/frame/globals/TestTargetGlobals.py
new file mode 100644
index 00000000000000..54d2cd89560a1a
--- /dev/null
+++ b/lldb/test/API/python_api/frame/globals/TestTargetGlobals.py
@@ -0,0 +1,43 @@
+"""
+Test SBTarget::FindGlobalVariables API.
+"""
+
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+
+
+class TargetAPITestCase(TestBase):
+ mydir = TestBase.compute_mydir(__file__)
+
+ @add_test_categories(["pyapi"])
+ def test_find_global_variables(self):
+ """Exercise SBTarget.FindGlobalVariables() API."""
+ self.build()
+
+ # Don't need to launch a process, since we're only interested in
+ # looking up global variables.
+ target = self.dbg.CreateTarget(self.getBuildArtifact())
+
+ def test_global_var(query, name, type_name, value):
+ value_list = target.FindGlobalVariables(query, 1)
+ self.assertEqual(value_list.GetSize(), 1)
+ var = value_list.GetValueAtIndex(0)
+ self.DebugSBValue(var)
+ self.assertTrue(var)
+ self.assertEqual(var.GetName(), name)
+ self.assertEqual(var.GetTypeName(), type_name)
+ self.assertEqual(var.GetValue(), value)
+
+ test_global_var("Vars::inline_static", "Vars::inline_static", "double", "1.5")
+ test_global_var(
+ "Vars::static_constexpr", "Vars::static_constexpr", "const int", "2"
+ )
+ test_global_var(
+ "Vars::static_const_out_out_class",
+ "Vars::static_const_out_out_class",
+ "const int",
+ "3",
+ )
+ test_global_var(
+ "global_var_of_char_type", "::global_var_of_char_type", "char", "'X'"
+ )
\ No newline at end of file
diff --git a/lldb/test/API/python_api/frame/globals/main.cpp b/lldb/test/API/python_api/frame/globals/main.cpp
new file mode 100644
index 00000000000000..e2095e80082677
--- /dev/null
+++ b/lldb/test/API/python_api/frame/globals/main.cpp
@@ -0,0 +1,12 @@
+class Vars {
+public:
+ inline static double inline_static = 1.5;
+ static constexpr int static_constexpr = 2;
+ static const int static_const_out_out_class;
+};
+
+const int Vars::static_const_out_out_class = 3;
+
+char global_var_of_char_type = 'X';
+
+int main() {}
>From 8f7c944be19963362e7e46019b37f7222744195b Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Thu, 24 Oct 2024 23:06:54 +0500
Subject: [PATCH 2/2] Implemented manual indexing of DW_TAG_member in DWARF 4,
combined the test with TestConstStaticIntegralMember.
---
.../SymbolFile/DWARF/DWARFDebugInfoEntry.cpp | 2 +-
.../SymbolFile/DWARF/ManualDWARFIndex.cpp | 24 ++++
.../SymbolFile/DWARF/SymbolFileDWARF.cpp | 136 +-----------------
.../TestConstStaticIntegralMember.py | 35 +++--
.../cpp/const_static_integral_member/main.cpp | 1 +
5 files changed, 54 insertions(+), 144 deletions(-)
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
index 66d0bc4b90cb52..c0a2066f8239e5 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -614,7 +614,7 @@ DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr(const DWARFUnit *cu) const {
}
bool DWARFDebugInfoEntry::IsGlobalOrStaticScopeVariable() const {
- if (Tag() != DW_TAG_variable)
+ if (Tag() != DW_TAG_variable && Tag() != DW_TAG_member)
return false;
const DWARFDebugInfoEntry *parent_die = GetParent();
while (parent_die != nullptr) {
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
index 887983de2e8516..dabaf34237617d 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
@@ -219,6 +219,7 @@ void ManualDWARFIndex::IndexUnitImpl(DWARFUnit &unit,
case DW_TAG_typedef:
case DW_TAG_union_type:
case DW_TAG_unspecified_type:
+ case DW_TAG_member:
case DW_TAG_variable:
break;
@@ -228,6 +229,7 @@ void ManualDWARFIndex::IndexUnitImpl(DWARFUnit &unit,
const char *name = nullptr;
const char *mangled_cstr = nullptr;
+ bool is_external = false;
bool is_declaration = false;
bool has_address = false;
bool has_location_or_const_value = false;
@@ -246,6 +248,11 @@ void ManualDWARFIndex::IndexUnitImpl(DWARFUnit &unit,
name = form_value.AsCString();
break;
+ case DW_AT_external:
+ if (attributes.ExtractFormValueAtIndex(i, form_value))
+ is_external = form_value.Unsigned() != 0;
+ break;
+
case DW_AT_declaration:
if (attributes.ExtractFormValueAtIndex(i, form_value))
is_declaration = form_value.Unsigned() != 0;
@@ -362,6 +369,23 @@ void ManualDWARFIndex::IndexUnitImpl(DWARFUnit &unit,
set.namespaces.Insert(ConstString(name), ref);
break;
+ case DW_TAG_member: {
+ // In DWARF 4 and earlier `static const` members of a struct, a class or a
+ // union have an entry tag `DW_TAG_member`, and are also tagged as
+ // `DW_AT_external` and `DW_AT_declaration`, but otherwise follow the
+ // same rules as `DW_TAG_variable`.
+ if (unit.GetVersion() >= 5)
+ break;
+ bool parent_is_class_type = false;
+ if (auto parent = die.GetParent()) {
+ parent_is_class_type = parent->Tag() == DW_TAG_structure_type ||
+ parent->Tag() == DW_TAG_class_type ||
+ parent->Tag() == DW_TAG_union_type;
+ }
+ if (!parent_is_class_type || !is_external || !is_declaration)
+ break;
+ [[fallthrough]];
+ }
case DW_TAG_variable:
if (name && has_location_or_const_value && is_global_or_static_variable) {
set.globals.Insert(ConstString(name), ref);
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index d53da79c1efcee..e8f9896a2dc8db 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -2402,7 +2402,7 @@ void SymbolFileDWARF::FindGlobalVariables(
sc.module_sp = m_objfile_sp->GetModule();
assert(sc.module_sp);
- if (die.Tag() != DW_TAG_variable)
+ if (die.Tag() != DW_TAG_variable && die.Tag() != DW_TAG_member)
return true;
auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(die.GetCU());
@@ -2439,48 +2439,6 @@ void SymbolFileDWARF::FindGlobalVariables(
return variables.GetSize() - original_size < max_matches;
});
- // If we don't have enough matches and the variable context is not empty, try
- // to resolve the context as a type and look for static const members.
- if (variables.GetSize() - original_size < max_matches && !context.empty()) {
- llvm::StringRef type_name;
- if (std::optional<Type::ParsedName> parsed_name =
- Type::GetTypeScopeAndBasename(context))
- type_name = parsed_name->basename;
- else
- type_name = context;
-
- m_index->GetTypes(ConstString(type_name), [&](DWARFDIE parent) {
- llvm::StringRef parent_type_name = parent.GetDWARFDeclContext()
- .GetQualifiedNameAsConstString()
- .GetStringRef();
-
- // This type is from another scope, skip it.
- if (!parent_type_name.ends_with(context))
- return true;
-
- auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(parent.GetCU());
- if (!dwarf_cu)
- return true;
-
- sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu);
-
- for (DWARFDIE die = parent.GetFirstChild(); die.IsValid();
- die = die.GetSibling()) {
- // Try parsing the entry as a static const member.
- if (auto var_sp = ParseStaticConstMemberDIE(sc, die)) {
- if (var_sp->GetUnqualifiedName().GetStringRef() != basename)
- continue;
-
- // There can be only one member with a given name.
- variables.AddVariableIfUnique(var_sp);
- break;
- }
- }
-
- return variables.GetSize() - original_size < max_matches;
- });
- }
-
// Return the number of variable that were appended to the list
const uint32_t num_matches = variables.GetSize() - original_size;
if (log && num_matches > 0) {
@@ -3413,94 +3371,6 @@ size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) {
return 0;
}
-VariableSP SymbolFileDWARF::ParseStaticConstMemberDIE(
- const lldb_private::SymbolContext &sc, const DWARFDIE &die) {
- if (die.GetDWARF() != this)
- return die.GetDWARF()->ParseStaticConstMemberDIE(sc, die);
-
- // Look only for members, ignore all other types of entries.
- if (die.Tag() != DW_TAG_member)
- return nullptr;
-
- if (VariableSP var_sp = GetDIEToVariable()[die.GetDIE()])
- return var_sp; // Already been parsed!
-
- const char *name = nullptr;
- const char *mangled = nullptr;
- Declaration decl;
- DWARFExpression location;
- DWARFFormValue type_die_form;
- DWARFFormValue const_value_form;
-
- DWARFAttributes attributes = die.GetAttributes();
- const size_t num_attributes = attributes.Size();
-
- for (size_t i = 0; i < num_attributes; ++i) {
- dw_attr_t attr = attributes.AttributeAtIndex(i);
- DWARFFormValue form_value;
-
- if (!attributes.ExtractFormValueAtIndex(i, form_value))
- continue;
-
- switch (attr) {
- case DW_AT_decl_file:
- decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
- form_value.Unsigned()));
- break;
- case DW_AT_decl_line:
- decl.SetLine(form_value.Unsigned());
- break;
- case DW_AT_decl_column:
- decl.SetColumn(form_value.Unsigned());
- break;
- case DW_AT_name:
- name = form_value.AsCString();
- break;
- case DW_AT_type:
- type_die_form = form_value;
- break;
- case DW_AT_const_value:
- const_value_form = form_value;
- break;
- default:
- break;
- }
- }
-
- // Look only for static const members with const values.
- if (!DWARFFormValue::IsDataForm(const_value_form.Form()))
- return nullptr;
-
- SymbolFileTypeSP type_sp = std::make_shared<SymbolFileType>(
- *this, type_die_form.Reference().GetID());
-
- if (type_sp->GetType()) {
- location.UpdateValue(const_value_form.Unsigned(),
- type_sp->GetType()->GetByteSize(nullptr).value_or(0),
- die.GetCU()->GetAddressByteSize());
- }
-
- if (Language::LanguageIsCPlusPlus(GetLanguage(*die.GetCU())))
- mangled =
- die.GetDWARFDeclContext().GetQualifiedNameAsConstString().GetCString();
-
- ValueType scope = eValueTypeVariableGlobal;
- Variable::RangeList scope_ranges;
-
- DWARFExpressionList location_list(GetObjectFile()->GetModule(), location,
- die.GetCU());
- VariableSP var_sp = std::make_shared<Variable>(
- die.GetID(), name, mangled, type_sp, scope, sc.comp_unit, scope_ranges,
- &decl, location_list, /*is_external*/ true, /*is_artificial*/ false,
- /*is_static_member*/ true);
- var_sp->SetLocationIsConstantValueData(true);
-
- // Cache this variable, so we don't parse it over and over again.
- GetDIEToVariable()[die.GetDIE()] = var_sp;
-
- return var_sp;
-}
-
VariableSP SymbolFileDWARF::ParseVariableDIECached(const SymbolContext &sc,
const DWARFDIE &die) {
if (!die)
@@ -3620,7 +3490,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
ModuleSP module = GetObjectFile()->GetModule();
if (tag != DW_TAG_variable && tag != DW_TAG_constant &&
- (tag != DW_TAG_formal_parameter || !sc.function))
+ tag != DW_TAG_member && (tag != DW_TAG_formal_parameter || !sc.function))
return nullptr;
DWARFAttributes attributes = die.GetAttributes();
@@ -3926,7 +3796,7 @@ void SymbolFileDWARF::ParseAndAppendGlobalVariable(
return;
dw_tag_t tag = die.Tag();
- if (tag != DW_TAG_variable && tag != DW_TAG_constant)
+ if (tag != DW_TAG_variable && tag != DW_TAG_constant && tag != DW_TAG_member)
return;
// Check to see if we have already parsed this variable or constant?
diff --git a/lldb/test/API/lang/cpp/const_static_integral_member/TestConstStaticIntegralMember.py b/lldb/test/API/lang/cpp/const_static_integral_member/TestConstStaticIntegralMember.py
index cdade2d335df0b..e3d004b38a1571 100644
--- a/lldb/test/API/lang/cpp/const_static_integral_member/TestConstStaticIntegralMember.py
+++ b/lldb/test/API/lang/cpp/const_static_integral_member/TestConstStaticIntegralMember.py
@@ -120,17 +120,15 @@ def check_global_var(self, name: str, expect_type, expect_val):
self.assertEqual(varobj.type.name, expect_type)
self.assertEqual(varobj.value, expect_val)
- @expectedFailureAll(dwarf_version=["<", "5"])
- # On linux this passes due to the manual index
- @expectedFailureDarwin(debug_info=no_match(["dsym"]))
- def test_inline_static_members(self):
- self.build()
+ def check_inline_static_members(self, flags):
+ self.build(dictionary={"CXXFLAGS_EXTRAS": flags})
lldbutil.run_to_source_breakpoint(
self, "// break here", lldb.SBFileSpec("main.cpp")
)
self.check_global_var("A::int_val", "const int", "1")
self.check_global_var("A::int_val_with_address", "const int", "2")
+ self.check_global_var("A::inline_int_val", "const int", "3")
self.check_global_var("A::bool_val", "const bool", "true")
self.check_global_var("A::enum_val", "Enum", "enum_case2")
self.check_global_var("A::enum_bool_val", "EnumBool", "enum_bool_case1")
@@ -144,6 +142,16 @@ def test_inline_static_members(self):
"ClassWithConstexprs::scoped_enum_val", "ScopedEnum", "scoped_enum_case2"
)
+ # On linux this passes due to the manual index
+ @expectedFailureDarwin(debug_info=no_match(["dsym"]))
+ def test_inline_static_members_dwarf5(self):
+ self.check_inline_static_members("-gdwarf-5")
+
+ # On linux this passes due to the manual index
+ @expectedFailureDarwin(debug_info=no_match(["dsym"]))
+ def test_inline_static_members_dwarf4(self):
+ self.check_inline_static_members("-gdwarf-4")
+
# With older versions of Clang, LLDB fails to evaluate classes with only
# constexpr members when dsymutil is enabled
@expectedFailureAll(
@@ -170,15 +178,12 @@ def test_class_with_only_constexpr_static(self):
"ClassWithEnumAlias::enum_alias_alias", result_value="scoped_enum_case1"
)
- @expectedFailureAll(dwarf_version=["<", "5"])
- # On linux this passes due to the manual index
- @expectedFailureDarwin(debug_info=no_match(["dsym"]))
- def test_shadowed_static_inline_members(self):
+ def check_shadowed_static_inline_members(self, flags):
"""Tests that the expression evaluator and SBAPI can both
correctly determine the requested inline static variable
in the presence of multiple variables of the same name."""
- self.build()
+ self.build(dictionary={"CXXFLAGS_EXTRAS": flags})
lldbutil.run_to_name_breakpoint(self, "bar")
self.check_global_var("ns::Foo::mem", "const int", "10")
@@ -188,6 +193,16 @@ def test_shadowed_static_inline_members(self):
self.expect_expr("ns::Foo::mem", result_value="10")
self.expect_expr("::Foo::mem", result_value="-29")
+ # On linux this passes due to the manual index
+ @expectedFailureDarwin(debug_info=no_match(["dsym"]))
+ def test_shadowed_static_inline_members_dwarf5(self):
+ self.check_shadowed_static_inline_members("-gdwarf-5")
+
+ # On linux this passes due to the manual index
+ @expectedFailureDarwin(debug_info=no_match(["dsym"]))
+ def test_shadowed_static_inline_members_dwarf4(self):
+ self.check_shadowed_static_inline_members("-gdwarf-4")
+
@expectedFailureAll(bugnumber="target var doesn't honour global namespace")
def test_shadowed_static_inline_members_xfail(self):
self.build()
diff --git a/lldb/test/API/lang/cpp/const_static_integral_member/main.cpp b/lldb/test/API/lang/cpp/const_static_integral_member/main.cpp
index fb0b49e2d7aad7..564a3643dd8fcd 100644
--- a/lldb/test/API/lang/cpp/const_static_integral_member/main.cpp
+++ b/lldb/test/API/lang/cpp/const_static_integral_member/main.cpp
@@ -29,6 +29,7 @@ enum class ScopedLongLongEnum : long long {
struct A {
const static int int_val = 1;
const static int int_val_with_address = 2;
+ inline const static int inline_int_val = 3;
const static bool bool_val = true;
const static auto char_max = std::numeric_limits<char>::max();
More information about the lldb-commits
mailing list