https://github.com/Iasonaskrpr updated https://github.com/llvm/llvm-project/pull/213323
>From 020f20e84a0ebcd77a5c4d1af7800a8cc29ba85e Mon Sep 17 00:00:00 2001 From: Iasonaskrpr <[email protected]> Date: Fri, 26 Jun 2026 20:01:29 +0300 Subject: [PATCH 1/4] [lldb]Added case-insensitive support --- lldb/include/lldb/Symbol/CompileUnit.h | 10 +++++ lldb/include/lldb/lldb-enumerations.h | 15 +++++++ .../Plugins/SymbolFile/DWARF/DWARFUnit.cpp | 32 ++++++++++++++ .../Plugins/SymbolFile/DWARF/DWARFUnit.h | 3 ++ .../SymbolFile/DWARF/ManualDWARFIndex.cpp | 5 +++ .../SymbolFile/DWARF/ManualDWARFIndex.h | 11 +++++ .../Plugins/SymbolFile/DWARF/NameToDIE.cpp | 14 +++++++ .../Plugins/SymbolFile/DWARF/NameToDIE.h | 3 ++ .../SymbolFile/DWARF/SymbolFileDWARF.cpp | 9 ++-- lldb/source/ValueObject/DILEval.cpp | 42 +++++++++++++++---- 10 files changed, 134 insertions(+), 10 deletions(-) diff --git a/lldb/include/lldb/Symbol/CompileUnit.h b/lldb/include/lldb/Symbol/CompileUnit.h index bb9594699df33..7d99bd16ae02d 100644 --- a/lldb/include/lldb/Symbol/CompileUnit.h +++ b/lldb/include/lldb/Symbol/CompileUnit.h @@ -152,6 +152,14 @@ class CompileUnit : public std::enable_shared_from_this<CompileUnit>, m_language = language; } + lldb::IdentifierCaseType GetCasing() { + return m_identifier_case; + } + + void SetCasing(lldb::IdentifierCaseType identifier_case){ + m_identifier_case = identifier_case; + } + void GetDescription(Stream *s, lldb::DescriptionLevel level) const; /// Apply a lambda to each function in this compile unit. @@ -422,6 +430,8 @@ class CompileUnit : public std::enable_shared_from_this<CompileUnit>, void *m_user_data; /// The programming language enumeration value. lldb::LanguageType m_language; + /// Used to determine if lookups should be case-insensitive + lldb::IdentifierCaseType m_identifier_case = lldb::eCaseSensitive; /// Compile unit flags that help with partial parsing. Flags m_flags; /// Maps UIDs to functions. diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index 32a341b354d9f..4c0d2c27a8745 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -631,6 +631,21 @@ enum LanguageType { eNumLanguageTypes }; +//---------------------------------------------------------------------- +/// Identifier Case type +/// +/// this enumeration indetifies the treatment of identifiers within +/// compilation unit. the default is case sensitive in case it is absent +/// in compilation unit. +//---------------------------------------------------------------------- +enum IdentifierCaseType { + eCaseSensitive = 0, + eUpperCase = 1, + eLowerCase = 2, + eCaseInsensitive = 3, + eCaseUnknown = 4, +}; + enum InstrumentationRuntimeType { eInstrumentationRuntimeTypeAddressSanitizer = 0x0000, eInstrumentationRuntimeTypeThreadSanitizer = 0x0001, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp index 4b02124e987e8..7fbef4a831ff1 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -888,6 +888,38 @@ llvm::VersionTuple DWARFUnit::GetProducerVersion() { return m_producer_version; } +lldb::IdentifierCaseType DWARFUnit::GetIdentifierCase() { + if(m_identifier_case != eCaseUnknown) + return m_identifier_case; + + const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly(); + + if(!die) + m_identifier_case = eCaseSensitive; + + else { + uint64_t identifier_case = die->GetAttributeValueAsUnsigned(this, DW_AT_identifier_case, llvm::dwarf::DW_ID_case_sensitive); + + switch (identifier_case) { + case llvm::dwarf::DW_ID_up_case: + m_identifier_case = eUpperCase; + break; + case llvm::dwarf::DW_ID_down_case: + m_identifier_case = eLowerCase; + break; + case llvm::dwarf::DW_ID_case_insensitive: + m_identifier_case = eCaseInsensitive; + break; + case llvm::dwarf::DW_ID_case_sensitive: + default: + m_identifier_case = eCaseSensitive; + break; + } + } + + return m_identifier_case; +} + uint64_t DWARFUnit::GetDWARFLanguageType() { if (m_language_type) return *m_language_type; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h index 6fde9af57fa8b..51bafa75ca1cf 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -204,6 +204,8 @@ class DWARFUnit : public DWARFExpression::Delegate, public UserID { llvm::VersionTuple GetProducerVersion(); + lldb::IdentifierCaseType GetIdentifierCase(); + uint64_t GetDWARFLanguageType(); bool GetIsOptimized(); @@ -352,6 +354,7 @@ class DWARFUnit : public DWARFExpression::Delegate, public UserID { DWARFProducer m_producer = eProducerInvalid; llvm::VersionTuple m_producer_version; std::optional<uint64_t> m_language_type; + lldb::IdentifierCaseType m_identifier_case = lldb::eCaseUnknown; LazyBool m_is_optimized = eLazyBoolCalculate; std::optional<FileSpec> m_comp_dir; std::optional<FileSpec> m_file_spec; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp index 0971e66df86ae..15efee15fd713 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp @@ -158,6 +158,11 @@ void ManualDWARFIndex::IndexUnit(DWARFUnit &unit, SymbolFileDWARFDwo *dwp, const LanguageType cu_language = SymbolFileDWARF::GetLanguage(unit); + lldb::IdentifierCaseType cu_identifier_case = unit.GetIdentifierCase(); + + if(cu_identifier_case != eCaseSensitive) + SetNameCaseInsensitive(); + // First check if the unit has a DWO ID. If it does then we only want to index // the .dwo file or nothing at all. If we have a compile unit where we can't // locate the .dwo/.dwp file we don't want to index anything from the skeleton diff --git a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h index 41e0e620a4896..40da3ea82ab0c 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h @@ -169,6 +169,17 @@ class ManualDWARFIndex : public DWARFIndex { /// True if this index is a partial index, false otherwise. bool IsPartial() const; + void SetNameCaseInsensitive() { + m_set.function_basenames.SetNameCaseInsensitive(); + m_set.function_fullnames.SetNameCaseInsensitive(); + m_set.function_methods.SetNameCaseInsensitive(); + m_set.function_selectors.SetNameCaseInsensitive(); + m_set.objc_class_selectors.SetNameCaseInsensitive(); + m_set.globals.SetNameCaseInsensitive(); + m_set.types.SetNameCaseInsensitive(); + m_set.namespaces.SetNameCaseInsensitive(); + } + /// The DWARF file which we are indexing. SymbolFileDWARF *m_dwarf; /// Which dwarf units should we skip while building the index. diff --git a/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp index b34fda5740924..d6636195e2bbb 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp @@ -38,6 +38,20 @@ bool NameToDIE::Find( for (const auto &entry : m_map.equal_range(name)) if (callback(entry.value) == IterationAction::Stop) return false; + + if(!NameCaseInsensitive){ + for (const auto &entry : m_map.equal_range(name)) + if (callback(entry.value) == IterationAction::Stop) + return false; + return true; + } + + for (const auto &entry : m_map){ + if(ConstString::Equals(ConstString(entry.cstring.GetCString()), name, false)) + if (callback(entry.value) == IterationAction::Stop) + return false; + } + return true; } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h index 9f9b631f178ee..6040de1f09b27 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h @@ -86,8 +86,11 @@ class NameToDIE { void Clear() { m_map.Clear(); } + void SetNameCaseInsensitive() { NameCaseInsensitive = true; } + protected: UniqueCStringMap<DIERef> m_map; + bool NameCaseInsensitive = false; }; } // namespace dwarf } // namespace lldb_private::plugin diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 56fbf3fd771b5..881a009553df2 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -792,6 +792,7 @@ lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) { if (module_sp) { auto initialize_cu = [&](SupportFileNSP support_file_nsp, LanguageType cu_language, + IdentifierCaseType cu_casing, SupportFileList &&support_files = {}) { BuildCuTranslationTable(); cu_sp = std::make_shared<CompileUnit>( @@ -799,8 +800,10 @@ lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) { *GetDWARFUnitIndex(dwarf_cu.GetID()), cu_language, eLazyBoolCalculate, std::move(support_files)); - dwarf_cu.SetLLDBCompUnit(cu_sp.get()); + cu_sp->SetCasing(cu_casing); + dwarf_cu.SetLLDBCompUnit(cu_sp.get()); + SetCompileUnitAtIndex(dwarf_cu.GetID(), cu_sp); }; @@ -829,7 +832,7 @@ lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) { if (support_files.GetSize() == 0) return false; initialize_cu(support_files.GetSupportFileAtIndex(0), - eLanguageTypeUnknown, std::move(support_files)); + eLanguageTypeUnknown, dwarf_cu.GetIdentifierCase(), std::move(support_files)); return true; }; @@ -848,7 +851,7 @@ lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) { MakeAbsoluteAndRemap(cu_file_spec, dwarf_cu, module_sp); initialize_cu(std::make_shared<SupportFile>(cu_file_spec), - cu_language); + cu_language, dwarf_cu.GetIdentifierCase()); } } } diff --git a/lldb/source/ValueObject/DILEval.cpp b/lldb/source/ValueObject/DILEval.cpp index 5fc2376be0e75..b358948bee093 100644 --- a/lldb/source/ValueObject/DILEval.cpp +++ b/lldb/source/ValueObject/DILEval.cpp @@ -289,14 +289,28 @@ lldb::ValueObjectSP LookupGlobalIdentifier(llvm::StringRef name_ref, SymbolContext symbol_context = stack_frame.GetSymbolContext(lldb::eSymbolContextCompUnit); lldb::VariableListSP variable_list; - if (symbol_context.comp_unit) + lldb::IdentifierCaseType identifier_case = lldb::eCaseSensitive; + + if (symbol_context.comp_unit){ variable_list = symbol_context.comp_unit->GetVariableList(true); + identifier_case = symbol_context.comp_unit->GetCasing(); + } + name_ref.consume_front("::"); + + std::string search_string; + if(identifier_case == lldb::eLowerCase) + search_string = name_ref.lower(); + else if(identifier_case == lldb::eUpperCase) + search_string = name_ref.upper(); + else + search_string = name_ref.str(); + lldb::ValueObjectSP value_sp; if (variable_list) { lldb::VariableSP var_sp = - DILFindVariable(ConstString(name_ref), *variable_list); + DILFindVariable(ConstString(search_string), *variable_list); if (var_sp) value_sp = stack_frame.GetValueObjectForFrameVariable(var_sp, use_dynamic); @@ -308,12 +322,12 @@ lldb::ValueObjectSP LookupGlobalIdentifier(llvm::StringRef name_ref, // Check for match in modules global variables. VariableList modules_var_list; target_sp->GetImages().FindGlobalVariables( - ConstString(name_ref), std::numeric_limits<uint32_t>::max(), + ConstString(search_string), std::numeric_limits<uint32_t>::max(), modules_var_list); if (!modules_var_list.Empty()) { lldb::VariableSP var_sp = - DILFindVariable(ConstString(name_ref), modules_var_list); + DILFindVariable(ConstString(search_string), modules_var_list); if (var_sp) value_sp = ValueObjectVariable::Create(&stack_frame, var_sp); @@ -345,10 +359,24 @@ lldb::ValueObjectSP LookupIdentifier(llvm::StringRef name_ref, lldb::VariableListSP variable_list( stack_frame.GetInScopeVariableList(false)); + SymbolContext sc = stack_frame.GetSymbolContext(lldb::eSymbolContextCompUnit); + + lldb::IdentifierCaseType identifier_case = lldb::eCaseSensitive; + if(sc.comp_unit) + identifier_case = sc.comp_unit->GetCasing(); + + std::string search_string; + if(identifier_case == lldb::eLowerCase) + search_string = name_ref.lower(); + else if(identifier_case == lldb::eUpperCase) + search_string = name_ref.upper(); + else + search_string = name_ref.str(); + lldb::ValueObjectSP value_sp; if (variable_list) { lldb::VariableSP var_sp = - variable_list->FindVariable(ConstString(name_ref)); + variable_list->FindVariable(ConstString(search_string)); if (var_sp) value_sp = stack_frame.GetValueObjectForFrameVariable(var_sp, use_dynamic); @@ -358,12 +386,12 @@ lldb::ValueObjectSP LookupIdentifier(llvm::StringRef name_ref, return value_sp; // Try looking for an instance variable (class member). - SymbolContext sc = stack_frame.GetSymbolContext( + sc = stack_frame.GetSymbolContext( lldb::eSymbolContextFunction | lldb::eSymbolContextBlock); llvm::StringRef instance_name = sc.GetInstanceName(); value_sp = stack_frame.FindVariable(ConstString(instance_name)); if (value_sp) - value_sp = value_sp->GetChildMemberWithName(name_ref); + value_sp = value_sp->GetChildMemberWithName(search_string); if (value_sp) return value_sp; >From fac18d88edd30488eff3b36ea2f8d8aabd1fe286 Mon Sep 17 00:00:00 2001 From: Iasonaskrpr <[email protected]> Date: Sun, 28 Jun 2026 19:36:56 +0300 Subject: [PATCH 2/4] [lldb] Case sensitivity now defaults to case sensitive if at least one CU is case sensitive --- .../Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp | 4 ++++ .../Plugins/SymbolFile/DWARF/ManualDWARFIndex.h | 11 +++++++++++ lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h | 8 +++++++- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp index 15efee15fd713..43f53ea34163b 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp @@ -160,8 +160,12 @@ void ManualDWARFIndex::IndexUnit(DWARFUnit &unit, SymbolFileDWARFDwo *dwp, lldb::IdentifierCaseType cu_identifier_case = unit.GetIdentifierCase(); + // If at least one of the Compile Units is case sensitive, then all compile + // units will be case sensitive if(cu_identifier_case != eCaseSensitive) SetNameCaseInsensitive(); + else + SetStrictlyCaseSensitive(); // First check if the unit has a DWO ID. If it does then we only want to index // the .dwo file or nothing at all. If we have a compile unit where we can't diff --git a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h index 40da3ea82ab0c..5e137c0f930d8 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h @@ -180,6 +180,17 @@ class ManualDWARFIndex : public DWARFIndex { m_set.namespaces.SetNameCaseInsensitive(); } + void SetStrictlyCaseSensitive() { + m_set.function_basenames.SetStrictlyCaseSensitive(); + m_set.function_fullnames.SetStrictlyCaseSensitive(); + m_set.function_methods.SetStrictlyCaseSensitive(); + m_set.function_selectors.SetStrictlyCaseSensitive(); + m_set.objc_class_selectors.SetStrictlyCaseSensitive(); + m_set.globals.SetStrictlyCaseSensitive(); + m_set.types.SetStrictlyCaseSensitive(); + m_set.namespaces.SetStrictlyCaseSensitive(); + } + /// The DWARF file which we are indexing. SymbolFileDWARF *m_dwarf; /// Which dwarf units should we skip while building the index. diff --git a/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h index 6040de1f09b27..a85c6a2cda846 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h @@ -86,11 +86,17 @@ class NameToDIE { void Clear() { m_map.Clear(); } - void SetNameCaseInsensitive() { NameCaseInsensitive = true; } + void SetNameCaseInsensitive() { if(!StrictlyCaseSensitive) NameCaseInsensitive = true; } + + void SetStrictlyCaseSensitive() { + NameCaseInsensitive = false; + StrictlyCaseSensitive = true; + } protected: UniqueCStringMap<DIERef> m_map; bool NameCaseInsensitive = false; + bool StrictlyCaseSensitive = false; }; } // namespace dwarf } // namespace lldb_private::plugin >From a1c953f3c01fb56a8f98aa0fc16804ebdfe14e9d Mon Sep 17 00:00:00 2001 From: Iasonaskrpr <[email protected]> Date: Fri, 31 Jul 2026 20:34:41 +0300 Subject: [PATCH 3/4] [lldb] Added tests for case-insensitivity and removed redundant loop in NameToDIE --- .../Plugins/SymbolFile/DWARF/NameToDIE.cpp | 10 +- .../basics/CaseSensitiveLookup/Makefile | 3 + .../TestFrameVarDILCaseSensitiveLookup.py | 59 +++++ .../basics/CaseSensitiveLookup/main.cpp | 6 + .../DWARF/DWARFDebugNamesIndexTest.cpp | 201 +++++++++++++++++- 5 files changed, 269 insertions(+), 10 deletions(-) create mode 100644 lldb/test/API/commands/frame/var-dil/basics/CaseSensitiveLookup/Makefile create mode 100644 lldb/test/API/commands/frame/var-dil/basics/CaseSensitiveLookup/TestFrameVarDILCaseSensitiveLookup.py create mode 100644 lldb/test/API/commands/frame/var-dil/basics/CaseSensitiveLookup/main.cpp diff --git a/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp index d6636195e2bbb..c370eaa2a6471 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp @@ -38,14 +38,10 @@ bool NameToDIE::Find( for (const auto &entry : m_map.equal_range(name)) if (callback(entry.value) == IterationAction::Stop) return false; - - if(!NameCaseInsensitive){ - for (const auto &entry : m_map.equal_range(name)) - if (callback(entry.value) == IterationAction::Stop) - return false; + + if (!NameCaseInsensitive) return true; - } - + for (const auto &entry : m_map){ if(ConstString::Equals(ConstString(entry.cstring.GetCString()), name, false)) if (callback(entry.value) == IterationAction::Stop) diff --git a/lldb/test/API/commands/frame/var-dil/basics/CaseSensitiveLookup/Makefile b/lldb/test/API/commands/frame/var-dil/basics/CaseSensitiveLookup/Makefile new file mode 100644 index 0000000000000..2bb9ce046a907 --- /dev/null +++ b/lldb/test/API/commands/frame/var-dil/basics/CaseSensitiveLookup/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules \ No newline at end of file diff --git a/lldb/test/API/commands/frame/var-dil/basics/CaseSensitiveLookup/TestFrameVarDILCaseSensitiveLookup.py b/lldb/test/API/commands/frame/var-dil/basics/CaseSensitiveLookup/TestFrameVarDILCaseSensitiveLookup.py new file mode 100644 index 0000000000000..876107f1e4017 --- /dev/null +++ b/lldb/test/API/commands/frame/var-dil/basics/CaseSensitiveLookup/TestFrameVarDILCaseSensitiveLookup.py @@ -0,0 +1,59 @@ +""" +Test that DIL matches variables correctly for case-sensitive languages. +""" + +import lldb +from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import * +from lldbsuite.test import lldbutil + + +class TestFrameVarDILCaseSensitiveLookup(TestBase): + # If your test case doesn't stress debug info, then + # set this to true. That way it won't be run once for + # each debug info format. + NO_DEBUG_INFO_TESTCASE = True + + def test_frame_var(self): + self.build() + lldbutil.run_to_source_breakpoint( + self, "Set a breakpoint here", lldb.SBFileSpec("main.cpp") + ) + + self.runCmd("settings set target.experimental.use-DIL true") + + self.expect_var_path("globalVar", type="int", value="-559038737") # 0xDEADBEEF + + self.expect( + "frame var GlobaLVaR", + error=True, + substrs=["use of undeclared identifier 'GlobaLVaR'"], + ) + self.expect( + "frame var GLOBALVAR", + error=True, + substrs=["use of undeclared identifier 'GLOBALVAR'"], + ) + self.expect( + "frame var globalvar", + error=True, + substrs=["use of undeclared identifier 'globalvar'"], + ) + + self.expect_var_path("testVariable", type="int", value="3") + + self.expect( + "frame var TestVaRiable", + error=True, + substrs=["use of undeclared identifier 'TestVaRiable'"], + ) + self.expect( + "frame var testvariable", + error=True, + substrs=["use of undeclared identifier 'testvariable'"], + ) + self.expect( + "frame var TESTVARIABLE", + error=True, + substrs=["use of undeclared identifier 'TESTVARIABLE'"], + ) diff --git a/lldb/test/API/commands/frame/var-dil/basics/CaseSensitiveLookup/main.cpp b/lldb/test/API/commands/frame/var-dil/basics/CaseSensitiveLookup/main.cpp new file mode 100644 index 0000000000000..c604dc67e73bc --- /dev/null +++ b/lldb/test/API/commands/frame/var-dil/basics/CaseSensitiveLookup/main.cpp @@ -0,0 +1,6 @@ +int globalVar = 0xDEADBEEF; +int main(int argc, char **argv) { + int testVariable; + testVariable = 3; + return 0; // Set a breakpoint here +} \ No newline at end of file diff --git a/lldb/unittests/SymbolFile/DWARF/DWARFDebugNamesIndexTest.cpp b/lldb/unittests/SymbolFile/DWARF/DWARFDebugNamesIndexTest.cpp index dd8a0742f6b70..854e6e1f49898 100644 --- a/lldb/unittests/SymbolFile/DWARF/DWARFDebugNamesIndexTest.cpp +++ b/lldb/unittests/SymbolFile/DWARF/DWARFDebugNamesIndexTest.cpp @@ -1,4 +1,5 @@ -//===-- DWARFDIETest.cpp ----------------------------------------------=---===// +//===-- DWARFDebugNamesIndexTest.cpp +//----------------------------------------------=---===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -10,7 +11,9 @@ #include "Plugins/SymbolFile/DWARF/DWARFDebugInfo.h" #include "Plugins/SymbolFile/DWARF/DWARFDeclContext.h" #include "Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h" +#include "TestingSupport/SubsystemRAII.h" #include "TestingSupport/Symbol/YAMLModuleTester.h" +#include "lldb/Core/Debugger.h" #include "lldb/lldb-private-enumerations.h" #include "llvm/ADT/STLExtras.h" #include "gmock/gmock.h" @@ -21,6 +24,15 @@ using namespace lldb_private; using namespace lldb_private::plugin::dwarf; using StringRef = llvm::StringRef; +class DWARFDebugNamesIndexTest : public testing::Test { +public: + void SetUp() override { + Debugger::Initialize(nullptr); + } + + void TearDown() override { Debugger::Terminate(); } +}; + static void check_num_matches(DebugNamesDWARFIndex &index, int expected_num_matches, llvm::ArrayRef<DWARFDeclContext::Entry> ctx_entries) { @@ -38,7 +50,7 @@ static DWARFDeclContext::Entry make_entry(const char *c) { return DWARFDeclContext::Entry(llvm::dwarf::DW_TAG_class_type, c); } -TEST(DWARFDebugNamesIndexTest, FullyQualifiedQueryWithIDXParent) { +TEST_F(DWARFDebugNamesIndexTest, FullyQualifiedQueryWithIDXParent) { const char *yamldata = R"( --- !ELF FileHeader: @@ -130,7 +142,7 @@ TEST(DWARFDebugNamesIndexTest, FullyQualifiedQueryWithIDXParent) { check_num_matches(*index, 1, {make_entry("3")}); } -TEST(DWARFDebugNamesIndexTest, FullyQualifiedQueryWithoutIDXParent) { +TEST_F(DWARFDebugNamesIndexTest, FullyQualifiedQueryWithoutIDXParent) { const char *yamldata = R"( --- !ELF FileHeader: @@ -207,3 +219,186 @@ TEST(DWARFDebugNamesIndexTest, FullyQualifiedQueryWithoutIDXParent) { check_num_matches(*index, 1, {make_entry("2"), make_entry("1")}); check_num_matches(*index, 1, {make_entry("2")}); } + +TEST_F(DWARFDebugNamesIndexTest, CaseInsesitiveQuery) { + const char *yamldata = R"( +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +DWARF: + debug_str: + - 'num_int' + debug_abbrev: + - Table: + - Code: 0x1 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_language + Form: DW_FORM_data2 + - Attribute: DW_AT_identifier_case + Form: DW_FORM_data1 + - Code: 0x2 + Tag: DW_TAG_variable + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_const_value + Form: DW_FORM_udata + debug_info: + - Version: 4 + AddrSize: 8 + Entries: + - AbbrCode: 0x1 + Values: + - Value: 0x0008 # DW_LANG_Fortran90 + - Value: 0x03 # DW_ID_case_insensitive (0x3) + - AbbrCode: 0x2 + Values: + - Value: 0x0 + - Value: 0x2a + - AbbrCode: 0x0 +)"; + + YAMLModuleTester t(yamldata); + auto *symbol_file = + llvm::cast<SymbolFileDWARF>(t.GetModule()->GetSymbolFile()); + auto *index = symbol_file->getIndex(); + int num_matches = 0; + index->GetGlobalVariables(ConstString("NUM_INT"), [&](DWARFDIE die) { + num_matches++; + return IterationAction::Stop; + }); + EXPECT_EQ(num_matches, 1); + + num_matches = 0; + index->GetGlobalVariables(ConstString("num_int"), [&](DWARFDIE die) { + num_matches++; + return IterationAction::Stop; + }); + EXPECT_EQ(num_matches, 1); + + num_matches = 0; + index->GetGlobalVariables(ConstString("NuM_iNT"), [&](DWARFDIE die) { + num_matches++; + return IterationAction::Stop; + }); + EXPECT_EQ(num_matches, 1); + + num_matches = 0; + index->GetGlobalVariables(ConstString("num_in"), [&](DWARFDIE die) { + num_matches++; + return IterationAction::Stop; + }); + EXPECT_EQ(num_matches, 0); +} + +TEST_F(DWARFDebugNamesIndexTest, CasesSesitiveDefaultQuery) { + const char *yamldata = R"( +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +DWARF: + debug_abbrev: + - Table: + - Code: 0x1 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_language + Form: DW_FORM_data2 + - Code: 0x2 + Tag: DW_TAG_variable + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_string + - Attribute: DW_AT_const_value + Form: DW_FORM_udata + + - Table: + - Code: 0x1 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_language + Form: DW_FORM_data2 + - Attribute: DW_AT_identifier_case + Form: DW_FORM_data1 + - Code: 0x2 + Tag: DW_TAG_variable + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_string + - Attribute: DW_AT_const_value + Form: DW_FORM_udata + + debug_info: + - Version: 4 + AddrSize: 8 + Entries: + - AbbrCode: 0x1 + Values: + - Value: 0x0004 # DW_LANG_C_plus_plus + - AbbrCode: 0x2 + Values: + - CStr: 'SensitiveVar' + - Value: 0x2a + - AbbrCode: 0x0 + + - Version: 4 + AddrSize: 8 + Entries: + - AbbrCode: 0x1 + Values: + - Value: 0x0008 # DW_LANG_Fortran90 + - Value: 0x03 # DW_ID_case_insensitive + - AbbrCode: 0x2 + Values: + - CStr: 'InsensitiveVar' + - Value: 0x2a + - AbbrCode: 0x0 +)"; + // If one Compile unit is case-insensitive and the other is case-sensitive we + // should default to all compile units being case-sensitive. + YAMLModuleTester t(yamldata); + auto *symbol_file = + llvm::cast<SymbolFileDWARF>(t.GetModule()->GetSymbolFile()); + auto *index = symbol_file->getIndex(); + + int sens_exact = 0; + index->GetGlobalVariables(ConstString("SensitiveVar"), [&](DWARFDIE die) { + sens_exact++; + return IterationAction::Stop; + }); + EXPECT_EQ(sens_exact, 1); + + int sens_mismatch = 0; + index->GetGlobalVariables(ConstString("sensitivevar"), [&](DWARFDIE die) { + sens_mismatch++; + return IterationAction::Stop; + }); + EXPECT_EQ(sens_mismatch, 0); + + int insens_exact = 0; + index->GetGlobalVariables(ConstString("InsensitiveVar"), [&](DWARFDIE die) { + insens_exact++; + return IterationAction::Stop; + }); + EXPECT_EQ(insens_exact, 1); + + int insens_mismatch = 0; + index->GetGlobalVariables(ConstString("insensitivevar"), [&](DWARFDIE die) { + insens_mismatch++; + return IterationAction::Stop; + }); + EXPECT_EQ(insens_mismatch, 0); +} \ No newline at end of file >From e1073f6b3ba4c063a191eef87ddd7e97491bd879 Mon Sep 17 00:00:00 2001 From: Iasonaskrpr <[email protected]> Date: Fri, 31 Jul 2026 20:55:12 +0300 Subject: [PATCH 4/4] [lldb] Fixed formatting --- lldb/include/lldb/Symbol/CompileUnit.h | 6 +-- .../Plugins/SymbolFile/DWARF/DWARFUnit.cpp | 35 ++++++++-------- .../SymbolFile/DWARF/ManualDWARFIndex.cpp | 4 +- .../SymbolFile/DWARF/ManualDWARFIndex.h | 42 +++++++++---------- .../Plugins/SymbolFile/DWARF/NameToDIE.cpp | 5 ++- .../Plugins/SymbolFile/DWARF/NameToDIE.h | 7 +++- .../SymbolFile/DWARF/SymbolFileDWARF.cpp | 5 ++- lldb/source/ValueObject/DILEval.cpp | 24 +++++------ .../DWARF/DWARFDebugNamesIndexTest.cpp | 4 +- 9 files changed, 67 insertions(+), 65 deletions(-) diff --git a/lldb/include/lldb/Symbol/CompileUnit.h b/lldb/include/lldb/Symbol/CompileUnit.h index 7d99bd16ae02d..e598a0794acb3 100644 --- a/lldb/include/lldb/Symbol/CompileUnit.h +++ b/lldb/include/lldb/Symbol/CompileUnit.h @@ -152,11 +152,9 @@ class CompileUnit : public std::enable_shared_from_this<CompileUnit>, m_language = language; } - lldb::IdentifierCaseType GetCasing() { - return m_identifier_case; - } + lldb::IdentifierCaseType GetCasing() { return m_identifier_case; } - void SetCasing(lldb::IdentifierCaseType identifier_case){ + void SetCasing(lldb::IdentifierCaseType identifier_case) { m_identifier_case = identifier_case; } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp index 7fbef4a831ff1..f1068ea4aec20 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -889,31 +889,32 @@ llvm::VersionTuple DWARFUnit::GetProducerVersion() { } lldb::IdentifierCaseType DWARFUnit::GetIdentifierCase() { - if(m_identifier_case != eCaseUnknown) + if (m_identifier_case != eCaseUnknown) return m_identifier_case; const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly(); - if(!die) + if (!die) m_identifier_case = eCaseSensitive; - + else { - uint64_t identifier_case = die->GetAttributeValueAsUnsigned(this, DW_AT_identifier_case, llvm::dwarf::DW_ID_case_sensitive); + uint64_t identifier_case = die->GetAttributeValueAsUnsigned( + this, DW_AT_identifier_case, llvm::dwarf::DW_ID_case_sensitive); switch (identifier_case) { - case llvm::dwarf::DW_ID_up_case: - m_identifier_case = eUpperCase; - break; - case llvm::dwarf::DW_ID_down_case: - m_identifier_case = eLowerCase; - break; - case llvm::dwarf::DW_ID_case_insensitive: - m_identifier_case = eCaseInsensitive; - break; - case llvm::dwarf::DW_ID_case_sensitive: - default: - m_identifier_case = eCaseSensitive; - break; + case llvm::dwarf::DW_ID_up_case: + m_identifier_case = eUpperCase; + break; + case llvm::dwarf::DW_ID_down_case: + m_identifier_case = eLowerCase; + break; + case llvm::dwarf::DW_ID_case_insensitive: + m_identifier_case = eCaseInsensitive; + break; + case llvm::dwarf::DW_ID_case_sensitive: + default: + m_identifier_case = eCaseSensitive; + break; } } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp index 43f53ea34163b..76506daea4450 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp @@ -160,9 +160,9 @@ void ManualDWARFIndex::IndexUnit(DWARFUnit &unit, SymbolFileDWARFDwo *dwp, lldb::IdentifierCaseType cu_identifier_case = unit.GetIdentifierCase(); - // If at least one of the Compile Units is case sensitive, then all compile + // If at least one of the Compile Units is case sensitive, then all compile // units will be case sensitive - if(cu_identifier_case != eCaseSensitive) + if (cu_identifier_case != eCaseSensitive) SetNameCaseInsensitive(); else SetStrictlyCaseSensitive(); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h index 5e137c0f930d8..4612e7b97f2d8 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h @@ -169,27 +169,27 @@ class ManualDWARFIndex : public DWARFIndex { /// True if this index is a partial index, false otherwise. bool IsPartial() const; - void SetNameCaseInsensitive() { - m_set.function_basenames.SetNameCaseInsensitive(); - m_set.function_fullnames.SetNameCaseInsensitive(); - m_set.function_methods.SetNameCaseInsensitive(); - m_set.function_selectors.SetNameCaseInsensitive(); - m_set.objc_class_selectors.SetNameCaseInsensitive(); - m_set.globals.SetNameCaseInsensitive(); - m_set.types.SetNameCaseInsensitive(); - m_set.namespaces.SetNameCaseInsensitive(); - } - - void SetStrictlyCaseSensitive() { - m_set.function_basenames.SetStrictlyCaseSensitive(); - m_set.function_fullnames.SetStrictlyCaseSensitive(); - m_set.function_methods.SetStrictlyCaseSensitive(); - m_set.function_selectors.SetStrictlyCaseSensitive(); - m_set.objc_class_selectors.SetStrictlyCaseSensitive(); - m_set.globals.SetStrictlyCaseSensitive(); - m_set.types.SetStrictlyCaseSensitive(); - m_set.namespaces.SetStrictlyCaseSensitive(); - } + void SetNameCaseInsensitive() { + m_set.function_basenames.SetNameCaseInsensitive(); + m_set.function_fullnames.SetNameCaseInsensitive(); + m_set.function_methods.SetNameCaseInsensitive(); + m_set.function_selectors.SetNameCaseInsensitive(); + m_set.objc_class_selectors.SetNameCaseInsensitive(); + m_set.globals.SetNameCaseInsensitive(); + m_set.types.SetNameCaseInsensitive(); + m_set.namespaces.SetNameCaseInsensitive(); + } + + void SetStrictlyCaseSensitive() { + m_set.function_basenames.SetStrictlyCaseSensitive(); + m_set.function_fullnames.SetStrictlyCaseSensitive(); + m_set.function_methods.SetStrictlyCaseSensitive(); + m_set.function_selectors.SetStrictlyCaseSensitive(); + m_set.objc_class_selectors.SetStrictlyCaseSensitive(); + m_set.globals.SetStrictlyCaseSensitive(); + m_set.types.SetStrictlyCaseSensitive(); + m_set.namespaces.SetStrictlyCaseSensitive(); + } /// The DWARF file which we are indexing. SymbolFileDWARF *m_dwarf; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp index c370eaa2a6471..c2699517b8950 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp @@ -42,8 +42,9 @@ bool NameToDIE::Find( if (!NameCaseInsensitive) return true; - for (const auto &entry : m_map){ - if(ConstString::Equals(ConstString(entry.cstring.GetCString()), name, false)) + for (const auto &entry : m_map) { + if (ConstString::Equals(ConstString(entry.cstring.GetCString()), name, + false)) if (callback(entry.value) == IterationAction::Stop) return false; } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h index a85c6a2cda846..01cdffb5bb2db 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h @@ -86,8 +86,11 @@ class NameToDIE { void Clear() { m_map.Clear(); } - void SetNameCaseInsensitive() { if(!StrictlyCaseSensitive) NameCaseInsensitive = true; } - + void SetNameCaseInsensitive() { + if (!StrictlyCaseSensitive) + NameCaseInsensitive = true; + } + void SetStrictlyCaseSensitive() { NameCaseInsensitive = false; StrictlyCaseSensitive = true; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 881a009553df2..68294913de962 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -803,7 +803,7 @@ lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) { cu_sp->SetCasing(cu_casing); dwarf_cu.SetLLDBCompUnit(cu_sp.get()); - + SetCompileUnitAtIndex(dwarf_cu.GetID(), cu_sp); }; @@ -832,7 +832,8 @@ lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) { if (support_files.GetSize() == 0) return false; initialize_cu(support_files.GetSupportFileAtIndex(0), - eLanguageTypeUnknown, dwarf_cu.GetIdentifierCase(), std::move(support_files)); + eLanguageTypeUnknown, dwarf_cu.GetIdentifierCase(), + std::move(support_files)); return true; }; diff --git a/lldb/source/ValueObject/DILEval.cpp b/lldb/source/ValueObject/DILEval.cpp index b358948bee093..374faaed043f9 100644 --- a/lldb/source/ValueObject/DILEval.cpp +++ b/lldb/source/ValueObject/DILEval.cpp @@ -291,20 +291,19 @@ lldb::ValueObjectSP LookupGlobalIdentifier(llvm::StringRef name_ref, lldb::VariableListSP variable_list; lldb::IdentifierCaseType identifier_case = lldb::eCaseSensitive; - if (symbol_context.comp_unit){ + if (symbol_context.comp_unit) { variable_list = symbol_context.comp_unit->GetVariableList(true); identifier_case = symbol_context.comp_unit->GetCasing(); } - name_ref.consume_front("::"); std::string search_string; - if(identifier_case == lldb::eLowerCase) + if (identifier_case == lldb::eLowerCase) search_string = name_ref.lower(); - else if(identifier_case == lldb::eUpperCase) + else if (identifier_case == lldb::eUpperCase) search_string = name_ref.upper(); - else + else search_string = name_ref.str(); lldb::ValueObjectSP value_sp; @@ -359,18 +358,19 @@ lldb::ValueObjectSP LookupIdentifier(llvm::StringRef name_ref, lldb::VariableListSP variable_list( stack_frame.GetInScopeVariableList(false)); - SymbolContext sc = stack_frame.GetSymbolContext(lldb::eSymbolContextCompUnit); + SymbolContext sc = + stack_frame.GetSymbolContext(lldb::eSymbolContextCompUnit); lldb::IdentifierCaseType identifier_case = lldb::eCaseSensitive; - if(sc.comp_unit) + if (sc.comp_unit) identifier_case = sc.comp_unit->GetCasing(); std::string search_string; - if(identifier_case == lldb::eLowerCase) + if (identifier_case == lldb::eLowerCase) search_string = name_ref.lower(); - else if(identifier_case == lldb::eUpperCase) + else if (identifier_case == lldb::eUpperCase) search_string = name_ref.upper(); - else + else search_string = name_ref.str(); lldb::ValueObjectSP value_sp; @@ -386,8 +386,8 @@ lldb::ValueObjectSP LookupIdentifier(llvm::StringRef name_ref, return value_sp; // Try looking for an instance variable (class member). - sc = stack_frame.GetSymbolContext( - lldb::eSymbolContextFunction | lldb::eSymbolContextBlock); + sc = stack_frame.GetSymbolContext(lldb::eSymbolContextFunction | + lldb::eSymbolContextBlock); llvm::StringRef instance_name = sc.GetInstanceName(); value_sp = stack_frame.FindVariable(ConstString(instance_name)); if (value_sp) diff --git a/lldb/unittests/SymbolFile/DWARF/DWARFDebugNamesIndexTest.cpp b/lldb/unittests/SymbolFile/DWARF/DWARFDebugNamesIndexTest.cpp index 854e6e1f49898..81fa3aca72da2 100644 --- a/lldb/unittests/SymbolFile/DWARF/DWARFDebugNamesIndexTest.cpp +++ b/lldb/unittests/SymbolFile/DWARF/DWARFDebugNamesIndexTest.cpp @@ -26,9 +26,7 @@ using StringRef = llvm::StringRef; class DWARFDebugNamesIndexTest : public testing::Test { public: - void SetUp() override { - Debugger::Initialize(nullptr); - } + void SetUp() override { Debugger::Initialize(nullptr); } void TearDown() override { Debugger::Terminate(); } }; _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
