Fix regression: expression completer and scope operator (PR gdb/22584)
[deliverable/binutils-gdb.git] / gdb / completer.h
index f756412dc48b695ad80c2af09c7bfd3135dafbee..df3c8e86de02ce9fb7bc90e10d0fd3773e13def5 100644 (file)
@@ -122,28 +122,82 @@ private:
    "b push_ba" on a C++ program usually completes to
    std::vector<...>::push_back, std::string::push_back etc.  In such
    case, the symbol comparison routine will set the LCD match to point
-   into the "push_back" substring within the symbol's name string.  */
+   into the "push_back" substring within the symbol's name string.
+   Also, in some cases, the symbol comparison routine will want to
+   ignore parts of the symbol name for LCD purposes, such as for
+   example symbols with abi tags in C++.  In such cases, the symbol
+   comparison routine will set MARK_IGNORED_RANGE to mark the ignored
+   substrings of the matched string.  The resulting LCD string with
+   the ignored parts stripped out is computed at the end of a
+   completion match sequence iff we had a positive match.  */
 
 class completion_match_for_lcd
 {
 public:
+  /* Get the resulting LCD, after a successful match.  */
+  const char *match ()
+  { return m_match; }
+
   /* Set the match for LCD.  See m_match's description.  */
   void set_match (const char *match)
   { m_match = match; }
 
-  /* Get the resulting LCD, after a successful match.  */
+  /* Mark the range between [BEGIN, END) as ignored.  */
+  void mark_ignored_range (const char *begin, const char *end)
+  { m_ignored_ranges.emplace_back (begin, end); }
+
+  /* Get the resulting LCD, after a successful match.  If there are
+     ignored ranges, then this builds a new string with the ignored
+     parts removed (and stores it internally).  As such, the result of
+     this call is only good for the current completion match
+     sequence.  */
   const char *finish ()
-  { return m_match; }
+  {
+    if (m_ignored_ranges.empty ())
+      return m_match;
+    else
+      {
+       m_finished_storage.clear ();
+
+       const char *prev = m_match;
+       for (const auto &range : m_ignored_ranges)
+         {
+           m_finished_storage.append (prev, range.first);
+           prev = range.second;
+         }
+       m_finished_storage.append (prev);
+
+       return m_finished_storage.c_str ();
+      }
+  }
 
   /* Prepare for another completion matching sequence.  */
   void clear ()
-  { m_match = NULL; }
+  {
+    m_match = NULL;
+    m_ignored_ranges.clear ();
+  }
 
 private:
   /* The completion match result for LCD.  This is usually either a
      pointer into to a substring within a symbol's name, or to the
      storage of the pairing completion_match object.  */
   const char *m_match;
+
+  /* The ignored substring ranges within M_MATCH.  E.g., if we were
+     looking for completion matches for C++ functions starting with
+       "functio"
+     and successfully match:
+       "function[abi:cxx11](int)"
+     the ignored ranges vector will contain an entry that delimits the
+     "[abi:cxx11]" substring, such that calling finish() results in:
+       "function(int)"
+   */
+  std::vector<std::pair<const char *, const char *>> m_ignored_ranges;
+
+  /* Storage used by the finish() method, if it has to compute a new
+     string.  */
+  std::string m_finished_storage;
 };
 
 /* Convenience aggregate holding info returned by the symbol name
@@ -265,7 +319,8 @@ public:
      it is not there already.  If too many completions were already
      found, this throws an error.  */
   void add_completion (gdb::unique_xmalloc_ptr<char> name,
-                      completion_match_for_lcd *match_for_lcd = NULL);
+                      completion_match_for_lcd *match_for_lcd = NULL,
+                      const char *text = NULL, const char *word = NULL);
 
   /* Add all completions matches in LIST.  Elements are moved out of
      LIST.  */
@@ -352,7 +407,8 @@ private:
      it is not there already.  If false is returned, too many
      completions were found.  */
   bool maybe_add_completion (gdb::unique_xmalloc_ptr<char> name,
-                            completion_match_for_lcd *match_for_lcd);
+                            completion_match_for_lcd *match_for_lcd,
+                            const char *text, const char *word);
 
   /* Given a new match, recompute the lowest common denominator (LCD)
      to hand over to readline.  Normally readline computes this itself
@@ -364,7 +420,8 @@ private:
      "std::vector<..>::push_back", "std::string::push_back", etc., and
      in this case we want the lowest common denominator to be
      "push_back" instead of "std::".  */
-  void recompute_lowest_common_denominator (const char *new_match);
+  void recompute_lowest_common_denominator
+    (gdb::unique_xmalloc_ptr<char> &&new_match);
 
   /* Completion match outputs returned by the symbol name matching
      routines (see symbol_name_matcher_ftype).  These results are only
@@ -428,6 +485,21 @@ private:
   bool m_lowest_common_denominator_unique = false;
 };
 
+/* Return a string to hand off to readline as a completion match
+   candidate, potentially composed of parts of MATCH_NAME and of
+   TEXT/WORD.  For a description of TEXT/WORD see completer_ftype.  */
+
+extern gdb::unique_xmalloc_ptr<char>
+  make_completion_match_str (const char *match_name,
+                            const char *text, const char *word);
+
+/* Like above, but takes ownership of MATCH_NAME (i.e., can
+   reuse/return it).  */
+
+extern gdb::unique_xmalloc_ptr<char>
+  make_completion_match_str (gdb::unique_xmalloc_ptr<char> &&match_name,
+                            const char *text, const char *word);
+
 extern void gdb_display_match_list (char **matches, int len, int max,
                                    const struct match_list_displayer *);
 
This page took 0.031295 seconds and 4 git commands to generate.