[gdb/testsuite] Accept new complex print style in mixed-lang-stack.exp
[deliverable/binutils-gdb.git] / gdb / symtab.c
index f456f4d852df46299e715a8166cc09febb9c0f92..680280105f57c5c1ffc19bbb61ebb7e099fd3638 100644 (file)
@@ -869,14 +869,9 @@ general_symbol_info::compute_and_set_names (gdb::string_view linkage_name,
       if (!copy_name)
        m_name = linkage_name.data ();
       else
-       {
-         char *name = (char *) obstack_alloc (&per_bfd->storage_obstack,
-                                              linkage_name.length () + 1);
-
-         memcpy (name, linkage_name.data (), linkage_name.length ());
-         name[linkage_name.length ()] = '\0';
-         m_name = name;
-       }
+       m_name = obstack_strndup (&per_bfd->storage_obstack,
+                                 linkage_name.data (),
+                                 linkage_name.length ());
       symbol_set_demangled_name (this, NULL, &per_bfd->storage_obstack);
 
       return;
@@ -967,11 +962,8 @@ general_symbol_info::compute_and_set_names (gdb::string_view linkage_name,
     m_language = (*slot)->language;
 
   m_name = (*slot)->mangled.data ();
-  if ((*slot)->demangled != nullptr)
-    symbol_set_demangled_name (this, (*slot)->demangled.get (),
-                              &per_bfd->storage_obstack);
-  else
-    symbol_set_demangled_name (this, NULL, &per_bfd->storage_obstack);
+  symbol_set_demangled_name (this, (*slot)->demangled.get (),
+                            &per_bfd->storage_obstack);
 }
 
 /* See symtab.h.  */
@@ -1798,7 +1790,7 @@ demangle_for_lookup_info::demangle_for_lookup_info
   if (lookup_name.ignore_parameters () && lang == language_cplus)
     {
       gdb::unique_xmalloc_ptr<char> without_params
-       = cp_remove_params_if_any (lookup_name.name ().c_str (),
+       = cp_remove_params_if_any (lookup_name.c_str (),
                                   lookup_name.completion_mode ());
 
       if (without_params != NULL)
@@ -1811,9 +1803,9 @@ demangle_for_lookup_info::demangle_for_lookup_info
     }
 
   if (lookup_name.match_type () == symbol_name_match_type::SEARCH_NAME)
-    m_demangled_name = lookup_name.name ();
+    m_demangled_name = lookup_name.c_str ();
   else
-    m_demangled_name = demangle_for_lookup (lookup_name.name ().c_str (),
+    m_demangled_name = demangle_for_lookup (lookup_name.c_str (),
                                            lang, storage);
 }
 
@@ -1824,7 +1816,7 @@ lookup_name_info::match_any ()
 {
   /* Lookup any symbol that "" would complete.  I.e., this matches all
      symbol names.  */
-  static const lookup_name_info lookup_name ({}, symbol_name_match_type::FULL,
+  static const lookup_name_info lookup_name ("", symbol_name_match_type::FULL,
                                             true);
 
   return lookup_name;
@@ -3166,7 +3158,17 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
          ;
        /* fall through */
        else
-         return find_pc_line (BMSYMBOL_VALUE_ADDRESS (mfunsym), 0);
+         {
+           /* Detect an obvious case of infinite recursion.  If this
+              should occur, we'd like to know about it, so error out,
+              fatally.  */
+           if (BMSYMBOL_VALUE_ADDRESS (mfunsym) == pc)
+             internal_error (__FILE__, __LINE__,
+               _("Infinite recursion detected in find_pc_sect_line;"
+                 "please file a bug report"));
+
+           return find_pc_line (BMSYMBOL_VALUE_ADDRESS (mfunsym), 0);
+         }
       }
 
   symtab_and_line val;
@@ -3244,6 +3246,23 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
          best = prev;
          best_symtab = iter_s;
 
+         /* If during the binary search we land on a non-statement entry,
+            scan backward through entries at the same address to see if
+            there is an entry marked as is-statement.  In theory this
+            duplication should have been removed from the line table
+            during construction, this is just a double check.  If the line
+            table has had the duplication removed then this should be
+            pretty cheap.  */
+         if (!best->is_stmt)
+           {
+             struct linetable_entry *tmp = best;
+             while (tmp > first && (tmp - 1)->pc == tmp->pc
+                    && (tmp - 1)->line != 0 && !tmp->is_stmt)
+               --tmp;
+             if (tmp->is_stmt)
+               best = tmp;
+           }
+
          /* Discard BEST_END if it's before the PC of the current BEST.  */
          if (best_end <= best->pc)
            best_end = 0;
@@ -3274,6 +3293,7 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
     }
   else
     {
+      val.is_stmt = best->is_stmt;
       val.symtab = best_symtab;
       val.line = best->line;
       val.pc = best->pc;
@@ -3442,7 +3462,8 @@ find_pcs_for_symtab_line (struct symtab *symtab, int line,
        {
          struct linetable_entry *item = &SYMTAB_LINETABLE (symtab)->item[idx];
 
-         if (*best_item == NULL || item->line < (*best_item)->line)
+         if (*best_item == NULL
+             || (item->line < (*best_item)->line && item->is_stmt))
            *best_item = item;
 
          break;
@@ -3553,6 +3574,10 @@ find_line_common (struct linetable *l, int lineno,
     {
       struct linetable_entry *item = &(l->item[i]);
 
+      /* Ignore non-statements.  */
+      if (!item->is_stmt)
+       continue;
+
       if (item->line == lineno)
        {
          /* Return the first (lowest address) entry which matches.  */
@@ -4976,13 +5001,13 @@ symtab_symbol_info (bool quiet, bool exclude_minsyms,
    and 'info functions' commands.  These correspond to the -q, -t, and -n
    options.  */
 
-struct info_print_options
+struct info_vars_funcs_options
 {
   bool quiet = false;
   bool exclude_minsyms = false;
   char *type_regexp = nullptr;
 
-  ~info_print_options ()
+  ~info_vars_funcs_options ()
   {
     xfree (type_regexp);
   }
@@ -4991,24 +5016,25 @@ struct info_print_options
 /* The options used by the 'info variables' and 'info functions'
    commands.  */
 
-static const gdb::option::option_def info_print_options_defs[] = {
-  gdb::option::boolean_option_def<info_print_options> {
+static const gdb::option::option_def info_vars_funcs_options_defs[] = {
+  gdb::option::boolean_option_def<info_vars_funcs_options> {
     "q",
-    [] (info_print_options *opt) { return &opt->quiet; },
+    [] (info_vars_funcs_options *opt) { return &opt->quiet; },
     nullptr, /* show_cmd_cb */
     nullptr /* set_doc */
   },
 
-  gdb::option::boolean_option_def<info_print_options> {
+  gdb::option::boolean_option_def<info_vars_funcs_options> {
     "n",
-    [] (info_print_options *opt) { return &opt->exclude_minsyms; },
+    [] (info_vars_funcs_options *opt) { return &opt->exclude_minsyms; },
     nullptr, /* show_cmd_cb */
     nullptr /* set_doc */
   },
 
-  gdb::option::string_option_def<info_print_options> {
+  gdb::option::string_option_def<info_vars_funcs_options> {
     "t",
-    [] (info_print_options *opt) { return &opt->type_regexp; },
+    [] (info_vars_funcs_options *opt) { return &opt->type_regexp;
+  },
     nullptr, /* show_cmd_cb */
     nullptr /* set_doc */
   }
@@ -5018,20 +5044,20 @@ static const gdb::option::option_def info_print_options_defs[] = {
    functions'.  */
 
 static gdb::option::option_def_group
-make_info_print_options_def_group (info_print_options *opts)
+make_info_vars_funcs_options_def_group (info_vars_funcs_options *opts)
 {
-  return {{info_print_options_defs}, opts};
+  return {{info_vars_funcs_options_defs}, opts};
 }
 
 /* Command completer for 'info variables' and 'info functions'.  */
 
 static void
-info_print_command_completer (struct cmd_list_element *ignore,
-                             completion_tracker &tracker,
-                             const char *text, const char * /* word */)
+info_vars_funcs_command_completer (struct cmd_list_element *ignore,
+                                  completion_tracker &tracker,
+                                  const char *text, const char * /* word */)
 {
   const auto group
-    = make_info_print_options_def_group (nullptr);
+    = make_info_vars_funcs_options_def_group (nullptr);
   if (gdb::option::complete_options
       (tracker, &text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, group))
     return;
@@ -5045,8 +5071,8 @@ info_print_command_completer (struct cmd_list_element *ignore,
 static void
 info_variables_command (const char *args, int from_tty)
 {
-  info_print_options opts;
-  auto grp = make_info_print_options_def_group (&opts);
+  info_vars_funcs_options opts;
+  auto grp = make_info_vars_funcs_options_def_group (&opts);
   gdb::option::process_options
     (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, grp);
   if (args != nullptr && *args == '\0')
@@ -5061,8 +5087,9 @@ info_variables_command (const char *args, int from_tty)
 static void
 info_functions_command (const char *args, int from_tty)
 {
-  info_print_options opts;
-  auto grp = make_info_print_options_def_group (&opts);
+  info_vars_funcs_options opts;
+
+  auto grp = make_info_vars_funcs_options_def_group (&opts);
   gdb::option::process_options
     (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, grp);
   if (args != nullptr && *args == '\0')
@@ -5269,6 +5296,27 @@ completion_list_add_symbol (completion_tracker &tracker,
   completion_list_add_name (tracker, sym->language (),
                            sym->natural_name (),
                            lookup_name, text, word);
+
+  /* C++ function symbols include the parameters within both the msymbol
+     name and the symbol name.  The problem is that the msymbol name will
+     describe the parameters in the most basic way, with typedefs stripped
+     out, while the symbol name will represent the types as they appear in
+     the program.  This means we will see duplicate entries in the
+     completion tracker.  The following converts the symbol name back to
+     the msymbol name and removes the msymbol name from the completion
+     tracker.  */
+  if (sym->language () == language_cplus
+      && SYMBOL_DOMAIN (sym) == VAR_DOMAIN
+      && SYMBOL_CLASS (sym) == LOC_BLOCK)
+    {
+      /* The call to canonicalize returns the empty string if the input
+        string is already in canonical form, thanks to this we don't
+        remove the symbol we just added above.  */
+      std::string str
+       = cp_canonicalize_string_no_typedefs (sym->natural_name ());
+      if (!str.empty ())
+       tracker.remove_completion (str.c_str ());
+    }
 }
 
 /* completion_list_add_name wrapper for struct minimal_symbol.  */
@@ -6709,7 +6757,7 @@ Usage: info variables [-q] [-n] [-t TYPEREGEXP] [NAMEREGEXP]\n\
 Prints the global and static variables.\n"),
                                      _("global and static variables"),
                                      true));
-  set_cmd_completer_handle_brkchars (c, info_print_command_completer);
+  set_cmd_completer_handle_brkchars (c, info_vars_funcs_command_completer);
   if (dbx_commands)
     {
       c = add_com ("whereis", class_info, info_variables_command,
@@ -6719,7 +6767,7 @@ Usage: whereis [-q] [-n] [-t TYPEREGEXP] [NAMEREGEXP]\n\
 Prints the global and static variables.\n"),
                                         _("global and static variables"),
                                         true));
-      set_cmd_completer_handle_brkchars (c, info_print_command_completer);
+      set_cmd_completer_handle_brkchars (c, info_vars_funcs_command_completer);
     }
 
   c = add_info ("functions", info_functions_command,
@@ -6729,7 +6777,7 @@ Usage: info functions [-q] [-n] [-t TYPEREGEXP] [NAMEREGEXP]\n\
 Prints the functions.\n"),
                                      _("functions"),
                                      true));
-  set_cmd_completer_handle_brkchars (c, info_print_command_completer);
+  set_cmd_completer_handle_brkchars (c, info_vars_funcs_command_completer);
 
   c = add_info ("types", info_types_command, _("\
 All type names, or those matching REGEXP.\n\
This page took 0.028535 seconds and 4 git commands to generate.