Breakpoints in symbols with ABI tags (PR c++/19436)
[deliverable/binutils-gdb.git] / gdb / cp-support.c
index 172d8219f475bc01687e2fa546b59dc9b99acf30..34a84395f40f5c8ae5fab6c9c6a33a1f98d4902e 100644 (file)
@@ -1629,7 +1629,23 @@ cp_search_name_hash (const char *search_name)
   if (prefix_len != 0)
     search_name += prefix_len + 2;
 
-  return default_search_name_hash (search_name);
+  unsigned int hash = 0;
+  for (const char *string = search_name; *string != '\0'; ++string)
+    {
+      string = skip_spaces (string);
+
+      if (*string == '(')
+       break;
+
+      /* Ignore ABI tags such as "[abi:cxx11].  */
+      if (*string == '['
+         && startswith (string + 1, "abi:")
+         && string[5] != ':')
+       break;
+
+      hash = SYMBOL_HASH_NEXT (hash, *string);
+    }
+  return hash;
 }
 
 /* Helper for cp_symbol_name_matches (i.e., symbol_name_matcher_ftype
@@ -1674,11 +1690,13 @@ cp_symbol_name_matches_1 (const char *symbol_search_name,
                          completion_match_result *comp_match_res)
 {
   const char *sname = symbol_search_name;
+  completion_match_for_lcd *match_for_lcd
+    = (comp_match_res != NULL ? &comp_match_res->match_for_lcd : NULL);
 
   while (true)
     {
       if (strncmp_iw_with_mode (sname, lookup_name, lookup_name_len,
-                               mode, language_cplus) == 0)
+                               mode, language_cplus, match_for_lcd) == 0)
        {
          if (comp_match_res != NULL)
            {
@@ -1728,14 +1746,15 @@ cp_fq_symbol_name_matches (const char *symbol_search_name,
 {
   /* Get the demangled name.  */
   const std::string &name = lookup_name.cplus ().lookup_name ();
-
+  completion_match_for_lcd *match_for_lcd
+    = (comp_match_res != NULL ? &comp_match_res->match_for_lcd : NULL);
   strncmp_iw_mode mode = (lookup_name.completion_mode ()
                          ? strncmp_iw_mode::NORMAL
                          : strncmp_iw_mode::MATCH_PARAMS);
 
   if (strncmp_iw_with_mode (symbol_search_name,
                            name.c_str (), name.size (),
-                           mode, language_cplus) == 0)
+                           mode, language_cplus, match_for_lcd) == 0)
     {
       if (comp_match_res != NULL)
        comp_match_res->set_match (symbol_search_name);
@@ -1950,6 +1969,32 @@ test_cp_symbol_name_matches ()
   CHECK_NOT_MATCH_C ("foo::function()", "::function()");
   CHECK_NOT_MATCH_C ("foo::function(int)", "::function()");
   CHECK_NOT_MATCH_C ("foo::function(int)", "::function(int)");
+
+  /* Test ABI tag matching/ignoring.  */
+
+  /* If the symbol name has an ABI tag, but the lookup name doesn't,
+     then the ABI tag in the symbol name is ignored.  */
+  CHECK_MATCH_C ("function[abi:foo]()", "function");
+  CHECK_MATCH_C ("function[abi:foo](int)", "function");
+  CHECK_MATCH_C ("function[abi:foo]()", "function ()");
+  CHECK_NOT_MATCH_C ("function[abi:foo]()", "function (int)");
+
+  CHECK_MATCH_C ("function[abi:foo]()", "function[abi:foo]");
+  CHECK_MATCH_C ("function[abi:foo](int)", "function[abi:foo]");
+  CHECK_MATCH_C ("function[abi:foo]()", "function[abi:foo] ()");
+  CHECK_MATCH_C ("function[abi:foo][abi:bar]()", "function");
+  CHECK_MATCH_C ("function[abi:foo][abi:bar](int)", "function");
+  CHECK_MATCH_C ("function[abi:foo][abi:bar]()", "function[abi:foo]");
+  CHECK_MATCH_C ("function[abi:foo][abi:bar](int)", "function[abi:foo]");
+  CHECK_MATCH_C ("function[abi:foo][abi:bar]()", "function[abi:foo] ()");
+  CHECK_NOT_MATCH_C ("function[abi:foo][abi:bar]()", "function[abi:foo] (int)");
+
+  CHECK_MATCH_C ("function  [abi:foo][abi:bar] ( )", "function [abi:foo]");
+
+  /* If the symbol name does not have an ABI tag, while the lookup
+     name has one, then there's no match.  */
+  CHECK_NOT_MATCH_C ("function()", "function[abi:foo]()");
+  CHECK_NOT_MATCH_C ("function()", "function[abi:foo]");
 }
 
 /* If non-NULL, return STR wrapped in quotes.  Otherwise, return a
This page took 0.024869 seconds and 4 git commands to generate.