fdeazeve updated this revision to Diff 541987. fdeazeve added a comment. Rebased
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D155334/new/ https://reviews.llvm.org/D155334 Files: lldb/include/lldb/Symbol/VariableList.h lldb/source/Commands/CommandObjectFrame.cpp lldb/test/API/commands/frame/var/TestFrameVar.py
Index: lldb/test/API/commands/frame/var/TestFrameVar.py =================================================================== --- lldb/test/API/commands/frame/var/TestFrameVar.py +++ lldb/test/API/commands/frame/var/TestFrameVar.py @@ -58,6 +58,16 @@ command_result = lldb.SBCommandReturnObject() interp = self.dbg.GetCommandInterpreter() + # Ensure --regex can find globals if it is the very first frame var command. + result = interp.HandleCommand("frame var --regex g_", command_result) + self.assertEqual( + result, + lldb.eReturnStatusSuccessFinishResult, + "frame var --regex g_ didn't succeed", + ) + output = command_result.GetOutput() + self.assertIn("g_var", output, "g_var not found with regex g_") + # Just get args: result = interp.HandleCommand("frame var -l", command_result) self.assertEqual( Index: lldb/source/Commands/CommandObjectFrame.cpp =================================================================== --- lldb/source/Commands/CommandObjectFrame.cpp +++ lldb/source/Commands/CommandObjectFrame.cpp @@ -499,6 +499,31 @@ } } + /// Finds all variables in `all_variables` whose name matches `regex`, + /// inserting them into `matches`. Variables already contained in `matches` + /// are not inserted again. + /// Nullopt is returned in case of no matches. + /// A sub-range of `matches` with all newly added variables is returned. This + /// may be empty if all matches were already contained in `matches`. + std::optional<llvm::ArrayRef<VariableSP>> + findUniqueRegexMatches(RegularExpression ®ex, + VariableList &matches, + const VariableList &all_variables) { + bool any_matches = false; + const size_t previous_num_vars = matches.GetSize(); + + for (const VariableSP &var : all_variables) { + if (!var->NameMatches(regex) || !ScopeRequested(var->GetScope())) + continue; + any_matches = true; + matches.AddVariableIfUnique(var); + } + + if (any_matches) + return matches.toArrayRef().drop_front(previous_num_vars); + return std::nullopt; + } + bool DoExecute(Args &command, CommandReturnObject &result) override { // No need to check "frame" for validity as eCommandRequiresFrame ensures // it is valid @@ -506,6 +531,10 @@ Stream &s = result.GetOutputStream(); + // Using a regex should behave like looking for an exact name match: it + // also finds globals. + m_option_variable.show_globals |= m_option_variable.use_regex; + // Be careful about the stack frame, if any summary formatter runs code, it // might clear the StackFrameList for the thread. So hold onto a shared // pointer to the frame so it stays alive. @@ -518,7 +547,6 @@ result.AppendError(error.AsCString()); } - VariableSP var_sp; ValueObjectSP valobj_sp; TypeSummaryImplSP summary_format_sp; @@ -551,46 +579,38 @@ // objects from them... for (auto &entry : command) { if (m_option_variable.use_regex) { - const size_t regex_start_index = regex_var_list.GetSize(); llvm::StringRef name_str = entry.ref(); RegularExpression regex(name_str); if (regex.IsValid()) { - size_t num_matches = 0; - const size_t num_new_regex_vars = - variable_list->AppendVariablesIfUnique(regex, regex_var_list, - num_matches); - if (num_new_regex_vars > 0) { - for (size_t regex_idx = regex_start_index, - end_index = regex_var_list.GetSize(); - regex_idx < end_index; ++regex_idx) { - var_sp = regex_var_list.GetVariableAtIndex(regex_idx); - if (var_sp) { - valobj_sp = frame->GetValueObjectForFrameVariable( - var_sp, m_varobj_options.use_dynamic); - if (valobj_sp) { - std::string scope_string; - if (m_option_variable.show_scope) - scope_string = GetScopeString(var_sp).str(); - - if (!scope_string.empty()) - s.PutCString(scope_string); - - if (m_option_variable.show_decl && - var_sp->GetDeclaration().GetFile()) { - bool show_fullpaths = false; - bool show_module = true; - if (var_sp->DumpDeclaration(&s, show_fullpaths, - show_module)) - s.PutCString(": "); - } - valobj_sp->Dump(result.GetOutputStream(), options); - } - } - } - } else if (num_matches == 0) { + std::optional<llvm::ArrayRef<VariableSP>> results = + findUniqueRegexMatches(regex, regex_var_list, *variable_list); + if (!results) { result.AppendErrorWithFormat( "no variables matched the regular expression '%s'.", entry.c_str()); + continue; + } + for (const VariableSP &var_sp : *results) { + valobj_sp = frame->GetValueObjectForFrameVariable( + var_sp, m_varobj_options.use_dynamic); + if (valobj_sp) { + std::string scope_string; + if (m_option_variable.show_scope) + scope_string = GetScopeString(var_sp).str(); + + if (!scope_string.empty()) + s.PutCString(scope_string); + + if (m_option_variable.show_decl && + var_sp->GetDeclaration().GetFile()) { + bool show_fullpaths = false; + bool show_module = true; + if (var_sp->DumpDeclaration(&s, show_fullpaths, + show_module)) + s.PutCString(": "); + } + valobj_sp->Dump(result.GetOutputStream(), options); + } } } else { if (llvm::Error err = regex.GetError()) @@ -648,7 +668,7 @@ const size_t num_variables = variable_list->GetSize(); if (num_variables > 0) { for (size_t i = 0; i < num_variables; i++) { - var_sp = variable_list->GetVariableAtIndex(i); + VariableSP var_sp = variable_list->GetVariableAtIndex(i); if (!ScopeRequested(var_sp->GetScope())) continue; std::string scope_string; Index: lldb/include/lldb/Symbol/VariableList.h =================================================================== --- lldb/include/lldb/Symbol/VariableList.h +++ lldb/include/lldb/Symbol/VariableList.h @@ -75,6 +75,10 @@ const_iterator begin() const { return m_variables.begin(); } const_iterator end() const { return m_variables.end(); } + llvm::ArrayRef<lldb::VariableSP> toArrayRef() { + return llvm::makeArrayRef(m_variables); + } + protected: collection m_variables;
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits