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 &regex,
+                         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
  • [Lldb-commits]... Felipe de Azevedo Piovezan via Phabricator via lldb-commits
    • [Lldb-com... Felipe de Azevedo Piovezan via Phabricator via lldb-commits
    • [Lldb-com... Jim Ingham via Phabricator via lldb-commits
    • [Lldb-com... Felipe de Azevedo Piovezan via Phabricator via lldb-commits
    • [Lldb-com... Jim Ingham via Phabricator via lldb-commits
    • [Lldb-com... Felipe de Azevedo Piovezan via Phabricator via lldb-commits

Reply via email to