daily update
[deliverable/binutils-gdb.git] / gdb / linespec.c
index 4156694bc4fb23f7871d2afc454252be308c6645..61e5377bc246c4c61138bd72cf8d769603ad509a 100644 (file)
@@ -1,6 +1,6 @@
 /* Parser for linespec for the GNU debugger, GDB.
 
-   Copyright (C) 1986-2005, 2007-2012 Free Software Foundation, Inc.
+   Copyright (C) 1986-2013 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -110,7 +110,7 @@ struct linespec
      currently precludes the use of other members.  */
 
   /* The expression entered by the user.  */
-  char *expression;
+  const char *expression;
 
   /* The resulting PC expression derived from evaluating EXPRESSION.  */
   CORE_ADDR expr_pc;
@@ -118,7 +118,7 @@ struct linespec
   /* Any specified file symtabs.  */
 
   /* The user-supplied source filename or NULL if none was specified.  */
-  char *source_filename;
+  const char *source_filename;
 
   /* The list of symtabs to search to which to limit the search.  May not
      be NULL.  If SOURCE_FILENAME is NULL (no user-specified filename),
@@ -130,7 +130,7 @@ struct linespec
 
   /* The user-specified function name.  If no function name was
      supplied, this may be NULL.  */
-  char *function_name;
+  const char *function_name;
 
   /* A list of matching function symbols and minimal symbols.  Both lists
      may be NULL if no matching symbols were found.  */
@@ -140,7 +140,7 @@ struct linespec
   /* The name of a label and matching symbols.  */
 
   /* The user-specified label name.  */
-  char *label_name;
+  const char *label_name;
 
   /* A structure of matching label symbols and the corresponding
      function symbol in which the label was found.  Both may be NULL
@@ -157,6 +157,21 @@ struct linespec
 };
 typedef struct linespec *linespec_p;
 
+/* A canonical linespec represented as a symtab-related string.
+
+   Each entry represents the "SYMTAB:SUFFIX" linespec string.
+   SYMTAB can be converted for example by symtab_to_fullname or
+   symtab_to_filename_for_display as needed.  */
+
+struct linespec_canonical_name
+{
+  /* Remaining text part of the linespec string.  */
+  char *suffix;
+
+  /* If NULL then SUFFIX is the whole linespec string.  */
+  struct symtab *symtab;
+};
+
 /* An instance of this is used to keep all state while linespec
    operates.  This instance is passed around as a 'this' pointer to
    the various implementation methods.  */
@@ -186,7 +201,7 @@ struct linespec_state
   struct linespec_result *canonical;
 
   /* Canonical strings that mirror the symtabs_and_lines result.  */
-  char **canonical_names;
+  struct linespec_canonical_name *canonical_names;
 
   /* This is a set of address_entry objects which is used to prevent
      duplicate symbols from being entered into the result.  */
@@ -286,6 +301,11 @@ struct ls_parser
   /* Is the entire linespec quote-enclosed?  */
   int is_quote_enclosed;
 
+  /* Is a keyword syntactically valid at this point?
+     In, e.g., "break thread thread 1", the leading "keyword" must not
+     be interpreted as such.  */
+  int keyword_ok;
+
   /* The state of the parse.  */
   struct linespec_state state;
 #define PARSER_STATE(PPTR) (&(PPTR)->state)
@@ -298,10 +318,15 @@ typedef struct ls_parser linespec_parser;
 
 /* Prototypes for local functions.  */
 
+static void iterate_over_file_blocks (struct symtab *symtab,
+                                     const char *name, domain_enum domain,
+                                     symbol_found_callback_ftype *callback,
+                                     void *data);
+
 static void initialize_defaults (struct symtab **default_symtab,
                                 int *default_line);
 
-static CORE_ADDR linespec_expression_to_pc (char **exp_ptr);
+static CORE_ADDR linespec_expression_to_pc (const char **exp_ptr);
 
 static struct symtabs_and_lines decode_objc (struct linespec_state *self,
                                             linespec_p ls,
@@ -314,11 +339,11 @@ static VEC (symbolp) *find_label_symbols (struct linespec_state *self,
                                          VEC (symbolp) **label_funcs_ret,
                                          const char *name);
 
-void find_linespec_symbols (struct linespec_state *self,
-                           VEC (symtab_p) *file_symtabs,
-                           const char *name,
-                           VEC (symbolp) **symbols,
-                           VEC (minsym_and_objfile_d) **minsyms);
+static void find_linespec_symbols (struct linespec_state *self,
+                                  VEC (symtab_p) *file_symtabs,
+                                  const char *name,
+                                  VEC (symbolp) **symbols,
+                                  VEC (minsym_and_objfile_d) **minsyms);
 
 static struct line_offset
      linespec_parse_variable (struct linespec_state *self,
@@ -366,31 +391,42 @@ static const char *const linespec_quote_characters = "\"\'";
 /* Lexer functions.  */
 
 /* Lex a number from the input in PARSER.  This only supports
-   decimal numbers.  */
+   decimal numbers.
 
-static linespec_token
-linespec_lexer_lex_number (linespec_parser *parser)
-{
-  linespec_token token;
+   Return true if input is decimal numbers.  Return false if not.  */
 
-  token.type = LSTOKEN_NUMBER;
-  LS_TOKEN_STOKEN (token).length = 0;
-  LS_TOKEN_STOKEN (token).ptr = PARSER_STREAM (parser);
+static int
+linespec_lexer_lex_number (linespec_parser *parser, linespec_token *tokenp)
+{
+  tokenp->type = LSTOKEN_NUMBER;
+  LS_TOKEN_STOKEN (*tokenp).length = 0;
+  LS_TOKEN_STOKEN (*tokenp).ptr = PARSER_STREAM (parser);
 
   /* Keep any sign at the start of the stream.  */
   if (*PARSER_STREAM (parser) == '+' || *PARSER_STREAM (parser) == '-')
     {
-      ++LS_TOKEN_STOKEN (token).length;
+      ++LS_TOKEN_STOKEN (*tokenp).length;
       ++(PARSER_STREAM (parser));
     }
 
   while (isdigit (*PARSER_STREAM (parser)))
     {
-      ++LS_TOKEN_STOKEN (token).length;
+      ++LS_TOKEN_STOKEN (*tokenp).length;
       ++(PARSER_STREAM (parser));
     }
 
-  return token;
+  /* If the next character in the input buffer is not a space, comma,
+     quote, or colon, this input does not represent a number.  */
+  if (*PARSER_STREAM (parser) != '\0'
+      && !isspace (*PARSER_STREAM (parser)) && *PARSER_STREAM (parser) != ','
+      && *PARSER_STREAM (parser) != ':'
+      && !strchr (linespec_quote_characters, *PARSER_STREAM (parser)))
+    {
+      PARSER_STREAM (parser) = LS_TOKEN_STOKEN (*tokenp).ptr;
+      return 0;
+    }
+
+  return 1;
 }
 
 /* Does P represent one of the keywords?  If so, return
@@ -596,6 +632,10 @@ linespec_lexer_lex_string (linespec_parser *parser)
          if (isspace (*PARSER_STREAM (parser)))
            {
              p = skip_spaces (PARSER_STREAM (parser));
+             /* When we get here we know we've found something followed by
+                a space (we skip over parens and templates below).
+                So if we find a keyword now, we know it is a keyword and not,
+                say, a function name.  */
              if (linespec_lexer_lex_keyword (p) != NULL)
                {
                  LS_TOKEN_STOKEN (token).ptr = start;
@@ -705,8 +745,10 @@ linespec_lexer_lex_one (linespec_parser *parser)
       /* Skip any whitespace.  */
       PARSER_STREAM (parser) = skip_spaces (PARSER_STREAM (parser));
 
-      /* Check for a keyword.  */
-      keyword = linespec_lexer_lex_keyword (PARSER_STREAM (parser));
+      /* Check for a keyword, they end the linespec.  */
+      keyword = NULL;
+      if (parser->keyword_ok)
+       keyword = linespec_lexer_lex_keyword (PARSER_STREAM (parser));
       if (keyword != NULL)
        {
          parser->lexer.current.type = LSTOKEN_KEYWORD;
@@ -724,7 +766,8 @@ linespec_lexer_lex_one (linespec_parser *parser)
        case '+': case '-':
        case '0': case '1': case '2': case '3': case '4':
         case '5': case '6': case '7': case '8': case '9':
-          parser->lexer.current = linespec_lexer_lex_number (parser);
+           if (!linespec_lexer_lex_number (parser, &(parser->lexer.current)))
+            parser->lexer.current = linespec_lexer_lex_string (parser);
           break;
 
        case ':':
@@ -810,40 +853,51 @@ add_sal_to_sals_basic (struct symtabs_and_lines *sals,
 
 /* Add SAL to SALS, and also update SELF->CANONICAL_NAMES to reflect
    the new sal, if needed.  If not NULL, SYMNAME is the name of the
-   symbol to use when constructing the new canonical name.  */
+   symbol to use when constructing the new canonical name.
+
+   If LITERAL_CANONICAL is non-zero, SYMNAME will be used as the
+   canonical name for the SAL.  */
 
 static void
 add_sal_to_sals (struct linespec_state *self,
                 struct symtabs_and_lines *sals,
                 struct symtab_and_line *sal,
-                const char *symname)
+                const char *symname, int literal_canonical)
 {
   add_sal_to_sals_basic (sals, sal);
 
   if (self->canonical)
     {
-      char *canonical_name = NULL;
+      struct linespec_canonical_name *canonical;
 
       self->canonical_names = xrealloc (self->canonical_names,
-                                       sals->nelts * sizeof (char *));
-      if (sal->symtab && sal->symtab->filename)
+                                       (sals->nelts
+                                        * sizeof (*self->canonical_names)));
+      canonical = &self->canonical_names[sals->nelts - 1];
+      if (!literal_canonical && sal->symtab)
        {
-         char *filename = sal->symtab->filename;
+         const char *fullname = symtab_to_fullname (sal->symtab);
 
          /* Note that the filter doesn't have to be a valid linespec
             input.  We only apply the ":LINE" treatment to Ada for
             the time being.  */
          if (symname != NULL && sal->line != 0
              && self->language->la_language == language_ada)
-           canonical_name = xstrprintf ("%s:%s:%d", filename, symname,
-                                        sal->line);
+           canonical->suffix = xstrprintf ("%s:%d", symname, sal->line);
          else if (symname != NULL)
-           canonical_name = xstrprintf ("%s:%s", filename, symname);
+           canonical->suffix = xstrdup (symname);
          else
-           canonical_name = xstrprintf ("%s:%d", filename, sal->line);
+           canonical->suffix = xstrprintf ("%d", sal->line);
+         canonical->symtab = sal->symtab;
+       }
+      else
+       {
+         if (symname != NULL)
+           canonical->suffix = xstrdup (symname);
+         else
+           canonical->suffix = NULL;
+         canonical->symtab = NULL;
        }
-
-      self->canonical_names[sals->nelts - 1] = canonical_name;
     }
 }
 
@@ -990,22 +1044,20 @@ iterate_over_all_matching_symtabs (struct linespec_state *state,
 
       ALL_OBJFILE_PRIMARY_SYMTABS (objfile, symtab)
        {
-         struct block *block;
-
-         block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK);
-         LA_ITERATE_OVER_SYMBOLS (block, name, domain, callback, data);
+         iterate_over_file_blocks (symtab, name, domain, callback, data);
 
          if (include_inline)
            {
              struct symbol_and_data_callback cad = { callback, data };
+             struct block *block;
              int i;
 
              for (i = FIRST_LOCAL_BLOCK;
                   i < BLOCKVECTOR_NBLOCKS (BLOCKVECTOR (symtab)); i++)
                {
                  block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), i);
-                 LA_ITERATE_OVER_SYMBOLS (block, name, domain,
-                                          iterate_inline_only, &cad);
+                 state->language->la_iterate_over_symbols
+                   (block, name, domain, iterate_inline_only, &cad);
                }
            }
        }
@@ -1013,30 +1065,39 @@ iterate_over_all_matching_symtabs (struct linespec_state *state,
   }
 }
 
-/* Returns the block to be used for symbol searches for the given SYMTAB,
-   which may be NULL.  */
+/* Returns the block to be used for symbol searches from
+   the current location.  */
 
 static struct block *
-get_search_block (struct symtab *symtab)
+get_current_search_block (void)
 {
   struct block *block;
+  enum language save_language;
 
-  if (symtab != NULL)
-    block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK);
-  else
-    {
-      enum language save_language;
-
-      /* get_selected_block can change the current language when there is
-        no selected frame yet.  */
-      save_language = current_language->la_language;
-      block = get_selected_block (0);
-      set_language (save_language);
-    }
+  /* get_selected_block can change the current language when there is
+     no selected frame yet.  */
+  save_language = current_language->la_language;
+  block = get_selected_block (0);
+  set_language (save_language);
 
   return block;
 }
 
+/* Iterate over static and global blocks.  */
+
+static void
+iterate_over_file_blocks (struct symtab *symtab,
+                         const char *name, domain_enum domain,
+                         symbol_found_callback_ftype *callback, void *data)
+{
+  struct block *block;
+
+  for (block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK);
+       block != NULL;
+       block = BLOCK_SUPERBLOCK (block))
+    LA_ITERATE_OVER_SYMBOLS (block, name, domain, callback, data);
+}
+
 /* A helper for find_method.  This finds all methods in type T which
    match NAME.  It adds matching symbol names to RESULT_NAMES, and
    adds T's direct superclasses to SUPERCLASSES.  */
@@ -1046,7 +1107,6 @@ find_methods (struct type *t, const char *name,
              VEC (const_char_ptr) **result_names,
              VEC (typep) **superclasses)
 {
-  int i1 = 0;
   int ibase;
   const char *class_name = type_name_no_tag (t);
 
@@ -1056,7 +1116,6 @@ find_methods (struct type *t, const char *name,
   if (class_name)
     {
       int method_counter;
-      int name_len = strlen (name);
 
       CHECK_TYPEDEF (t);
 
@@ -1173,6 +1232,19 @@ find_toplevel_string (const char *haystack, const char *needle)
   return NULL;
 }
 
+/* Convert CANONICAL to its string representation using
+   symtab_to_fullname for SYMTAB.  The caller must xfree the result.  */
+
+static char *
+canonical_to_fullform (const struct linespec_canonical_name *canonical)
+{
+  if (canonical->symtab == NULL)
+    return xstrdup (canonical->suffix);
+  else
+    return xstrprintf ("%s:%s", symtab_to_fullname (canonical->symtab),
+                      canonical->suffix);
+}
+
 /* Given FILTERS, a list of canonical names, filter the sals in RESULT
    and store the result in SELF->CANONICAL.  */
 
@@ -1193,8 +1265,18 @@ filter_results (struct linespec_state *self,
 
       for (j = 0; j < result->nelts; ++j)
        {
-         if (strcmp (name, self->canonical_names[j]) == 0)
+         const struct linespec_canonical_name *canonical;
+         char *fullform;
+         struct cleanup *cleanup;
+
+         canonical = &self->canonical_names[j];
+         fullform = canonical_to_fullform (canonical);
+         cleanup = make_cleanup (xfree, fullform);
+
+         if (strcmp (name, fullform) == 0)
            add_sal_to_sals_basic (&lsal.sals, &result->sals[j]);
+
+         do_cleanups (cleanup);
        }
 
       if (lsal.sals.nelts > 0)
@@ -1220,6 +1302,44 @@ convert_results_to_lsals (struct linespec_state *self,
   VEC_safe_push (linespec_sals, self->canonical->sals, &lsal);
 }
 
+/* A structure that contains two string representations of a struct
+   linespec_canonical_name:
+     - one where the the symtab's fullname is used;
+     - one where the filename followed the "set filename-display"
+       setting.  */
+
+struct decode_line_2_item
+{
+  /* The form using symtab_to_fullname.
+     It must be xfree'ed after use.  */
+  char *fullform;
+
+  /* The form using symtab_to_filename_for_display.
+     It must be xfree'ed after use.  */
+  char *displayform;
+
+  /* Field is initialized to zero and it is set to one if the user
+     requested breakpoint for this entry.  */
+  unsigned int selected : 1;
+};
+
+/* Helper for qsort to sort decode_line_2_item entries by DISPLAYFORM and
+   secondarily by FULLFORM.  */
+
+static int
+decode_line_2_compare_items (const void *ap, const void *bp)
+{
+  const struct decode_line_2_item *a = ap;
+  const struct decode_line_2_item *b = bp;
+  int retval;
+
+  retval = strcmp (a->displayform, b->displayform);
+  if (retval != 0)
+    return retval;
+
+  return strcmp (a->fullform, b->fullform);
+}
+
 /* Handle multiple results in RESULT depending on SELECT_MODE.  This
    will either return normally, throw an exception on multiple
    results, or present a menu to the user.  On return, the SALS vector
@@ -1230,58 +1350,80 @@ decode_line_2 (struct linespec_state *self,
               struct symtabs_and_lines *result,
               const char *select_mode)
 {
-  const char *iter;
   char *args, *prompt;
   int i;
   struct cleanup *old_chain;
-  VEC (const_char_ptr) *item_names = NULL, *filters = NULL;
+  VEC (const_char_ptr) *filters = NULL;
   struct get_number_or_range_state state;
+  struct decode_line_2_item *items;
+  int items_count;
 
   gdb_assert (select_mode != multiple_symbols_all);
   gdb_assert (self->canonical != NULL);
+  gdb_assert (result->nelts >= 1);
 
-  old_chain = make_cleanup (VEC_cleanup (const_char_ptr), &item_names);
-  make_cleanup (VEC_cleanup (const_char_ptr), &filters);
-  for (i = 0; i < result->nelts; ++i)
+  old_chain = make_cleanup (VEC_cleanup (const_char_ptr), &filters);
+
+  /* Prepare ITEMS array.  */
+  items_count = result->nelts;
+  items = xmalloc (sizeof (*items) * items_count);
+  make_cleanup (xfree, items);
+  for (i = 0; i < items_count; ++i)
     {
-      int j, found = 0;
-      const char *iter;
+      const struct linespec_canonical_name *canonical;
+      struct decode_line_2_item *item;
+
+      canonical = &self->canonical_names[i];
+      gdb_assert (canonical->suffix != NULL);
+      item = &items[i];
 
-      gdb_assert (self->canonical_names[i] != NULL);
-      for (j = 0; VEC_iterate (const_char_ptr, item_names, j, iter); ++j)
+      item->fullform = canonical_to_fullform (canonical);
+      make_cleanup (xfree, item->fullform);
+
+      if (canonical->symtab == NULL)
+       item->displayform = canonical->suffix;
+      else
        {
-         if (strcmp (iter, self->canonical_names[i]) == 0)
-           {
-             found = 1;
-             break;
-           }
+         const char *fn_for_display;
+
+         fn_for_display = symtab_to_filename_for_display (canonical->symtab);
+         item->displayform = xstrprintf ("%s:%s", fn_for_display,
+                                         canonical->suffix);
+         make_cleanup (xfree, item->displayform);
        }
 
-      if (!found)
-       VEC_safe_push (const_char_ptr, item_names, self->canonical_names[i]);
+      item->selected = 0;
+    }
+
+  /* Sort the list of method names.  */
+  qsort (items, items_count, sizeof (*items), decode_line_2_compare_items);
+
+  /* Remove entries with the same FULLFORM.  */
+  if (items_count >= 2)
+    {
+      struct decode_line_2_item *dst, *src;
+
+      dst = items;
+      for (src = &items[1]; src < &items[items_count]; src++)
+       if (strcmp (src->fullform, dst->fullform) != 0)
+         *++dst = *src;
+      items_count = dst + 1 - items;
     }
 
-  if (select_mode == multiple_symbols_cancel
-      && VEC_length (const_char_ptr, item_names) > 1)
+  if (select_mode == multiple_symbols_cancel && items_count > 1)
     error (_("canceled because the command is ambiguous\n"
             "See set/show multiple-symbol."));
   
-  if (select_mode == multiple_symbols_all
-      || VEC_length (const_char_ptr, item_names) == 1)
+  if (select_mode == multiple_symbols_all || items_count == 1)
     {
       do_cleanups (old_chain);
       convert_results_to_lsals (self, result);
       return;
     }
 
-  /* Sort the list of method names alphabetically.  */
-  qsort (VEC_address (const_char_ptr, item_names),
-        VEC_length (const_char_ptr, item_names),
-        sizeof (const_char_ptr), compare_strings);
-
   printf_unfiltered (_("[0] cancel\n[1] all\n"));
-  for (i = 0; VEC_iterate (const_char_ptr, item_names, i, iter); ++i)
-    printf_unfiltered ("[%d] %s\n", i + 2, iter);
+  for (i = 0; i < items_count; i++)
+    printf_unfiltered ("[%d] %s\n", i + 2, items[i].displayform);
 
   prompt = getenv ("PS2");
   if (prompt == NULL)
@@ -1316,21 +1458,21 @@ decode_line_2 (struct linespec_state *self,
        }
 
       num -= 2;
-      if (num >= VEC_length (const_char_ptr, item_names))
+      if (num >= items_count)
        printf_unfiltered (_("No choice number %d.\n"), num);
       else
        {
-         const char *elt = VEC_index (const_char_ptr, item_names, num);
+         struct decode_line_2_item *item = &items[num];
 
-         if (elt != NULL)
+         if (!item->selected)
            {
-             VEC_safe_push (const_char_ptr, filters, elt);
-             VEC_replace (const_char_ptr, item_names, num, NULL);
+             VEC_safe_push (const_char_ptr, filters, item->fullform);
+             item->selected = 1;
            }
          else
            {
              printf_unfiltered (_("duplicate request for %d ignored.\n"),
-                                num);
+                                num + 2);
            }
        }
     }
@@ -1347,7 +1489,7 @@ decode_line_2 (struct linespec_state *self,
    FILENAME).  */
 
 static void ATTRIBUTE_NORETURN
-symbol_not_found_error (char *symbol, char *filename)
+symbol_not_found_error (const char *symbol, const char *filename)
 {
   if (symbol == NULL)
     symbol = "";
@@ -1420,7 +1562,7 @@ unexpected_linespec_error (linespec_parser *parser)
 /* Parse and return a line offset in STRING.  */
 
 static struct line_offset
-linespec_parse_line_offset (char *string)
+linespec_parse_line_offset (const char *string)
 {
   struct line_offset line_offset = {0, LINE_OFFSET_NONE};
 
@@ -1695,22 +1837,24 @@ create_sals_line_offset (struct linespec_state *self,
 
   /* This is where we need to make sure we have good defaults.
      We must guarantee that this section of code is never executed
-     when we are called with just a function anme, since
+     when we are called with just a function name, since
      set_default_source_symtab_and_line uses
      select_source_symtab that calls us with such an argument.  */
 
   if (VEC_length (symtab_p, ls->file_symtabs) == 1
       && VEC_index (symtab_p, ls->file_symtabs, 0) == NULL)
     {
+      const char *fullname;
+
       set_current_program_space (self->program_space);
 
       /* Make sure we have at least a default source line.  */
       set_default_source_symtab_and_line ();
       initialize_defaults (&self->default_symtab, &self->default_line);
+      fullname = symtab_to_fullname (self->default_symtab);
       VEC_pop (symtab_p, ls->file_symtabs);
       VEC_free (symtab_p, ls->file_symtabs);
-      ls->file_symtabs
-       = collect_symtabs_from_filename (self->default_symtab->filename);
+      ls->file_symtabs = collect_symtabs_from_filename (fullname);
       use_default = 1;
     }
 
@@ -1809,7 +1953,7 @@ create_sals_line_offset (struct linespec_state *self,
               found.  */
            intermediate_results.sals[i].line = val.line;
            add_sal_to_sals (self, &values, &intermediate_results.sals[i],
-                            sym ? SYMBOL_NATURAL_NAME (sym) : NULL);
+                            sym ? SYMBOL_NATURAL_NAME (sym) : NULL, 0);
          }
 
       do_cleanups (cleanup);
@@ -1837,13 +1981,14 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls)
 
   if (ls->expression != NULL)
     {
+      struct symtab_and_line sal;
+
       /* We have an expression.  No other attribute is allowed.  */
-      sals.sals = XMALLOC (struct symtab_and_line);
-      sals.nelts = 1;
-      sals.sals[0] = find_pc_line (ls->expr_pc, 0);
-      sals.sals[0].pc = ls->expr_pc;
-      sals.sals[0].section = find_pc_overlay (ls->expr_pc);
-      sals.sals[0].explicit_pc = 1;
+      sal = find_pc_line (ls->expr_pc, 0);
+      sal.pc = ls->expr_pc;
+      sal.section = find_pc_overlay (ls->expr_pc);
+      sal.explicit_pc = 1;
+      add_sal_to_sals (state, &sals, &sal, ls->expression, 1);
     }
   else if (ls->labels.label_symbols != NULL)
     {
@@ -1854,9 +1999,9 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls)
 
       for (i = 0; VEC_iterate (symbolp, ls->labels.label_symbols, i, sym); ++i)
        {
-         symbol_to_sal (&sal, state->funfirstline, sym);
-         add_sal_to_sals (state, &sals, &sal,
-                          SYMBOL_NATURAL_NAME (sym));
+         if (symbol_to_sal (&sal, state->funfirstline, sym))
+           add_sal_to_sals (state, &sals, &sal,
+                            SYMBOL_NATURAL_NAME (sym), 0);
        }
     }
   else if (ls->function_symbols != NULL || ls->minimal_symbols != NULL)
@@ -1880,9 +2025,10 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls)
            {
              pspace = SYMTAB_PSPACE (SYMBOL_SYMTAB (sym));
              set_current_program_space (pspace);
-             symbol_to_sal (&sal, state->funfirstline, sym);
-             if (maybe_add_address (state->addr_set, pspace, sal.pc))
-               add_sal_to_sals (state, &sals, &sal, SYMBOL_NATURAL_NAME (sym));
+             if (symbol_to_sal (&sal, state->funfirstline, sym)
+                 && maybe_add_address (state->addr_set, pspace, sal.pc))
+               add_sal_to_sals (state, &sals, &sal,
+                                SYMBOL_NATURAL_NAME (sym), 0);
            }
        }
 
@@ -1910,7 +2056,15 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls)
 
        /* Make sure we have a filename for canonicalization.  */
        if (ls->source_filename == NULL)
-         ls->source_filename = xstrdup (state->default_symtab->filename);
+         {
+           const char *fullname = symtab_to_fullname (state->default_symtab);
+
+           /* It may be more appropriate to keep DEFAULT_SYMTAB in its symtab
+              form so that displaying SOURCE_FILENAME can follow the current
+              FILENAME_DISPLAY_STRING setting.  But as it is used only rarely
+              it has been kept for code simplicity only in absolute form.  */
+           ls->source_filename = xstrdup (fullname);
+         }
     }
   else
     {
@@ -2006,6 +2160,10 @@ parse_linespec (linespec_parser *parser, char **argptr)
        }
     }
 
+  /* A keyword at the start cannot be interpreted as such.
+     Consider "b thread thread 42".  */
+  parser->keyword_ok = 0;
+
   parser->lexer.saved_arg = *argptr;
   parser->lexer.stream = argptr;
   file_exception.reason = 0;
@@ -2027,7 +2185,8 @@ parse_linespec (linespec_parser *parser, char **argptr)
   /* It must be either LSTOKEN_STRING or LSTOKEN_NUMBER.  */
   if (token.type == LSTOKEN_STRING && *LS_TOKEN_STOKEN (token).ptr == '*')
     {
-      char *expr, *copy;
+      char *expr;
+      const char *copy;
 
       /* User specified an expression, *EXPR.  */
       copy = expr = copy_token_string (token);
@@ -2062,24 +2221,24 @@ parse_linespec (linespec_parser *parser, char **argptr)
       cleanup = make_cleanup (xfree, var);
       PARSER_RESULT (parser)->line_offset
        = linespec_parse_variable (PARSER_STATE (parser), var);
+      do_cleanups (cleanup);
 
       /* If a line_offset wasn't found (VAR is the name of a user
         variable/function), then skip to normal symbol processing.  */
       if (PARSER_RESULT (parser)->line_offset.sign != LINE_OFFSET_UNKNOWN)
        {
-         discard_cleanups (cleanup);
-
          /* Consume this token.  */
          linespec_lexer_consume_token (parser);
 
          goto convert_to_sals;
        }
-
-      do_cleanups (cleanup);
     }
   else if (token.type != LSTOKEN_STRING && token.type != LSTOKEN_NUMBER)
     unexpected_linespec_error (parser);
 
+  /* Now we can recognize keywords.  */
+  parser->keyword_ok = 1;
+
   /* Shortcut: If the next token is not LSTOKEN_COLON, we know that
      this token cannot represent a filename.  */
   token = linespec_lexer_peek_token (parser);
@@ -2220,14 +2379,10 @@ linespec_parser_delete (void *arg)
 {
   linespec_parser *parser = (linespec_parser *) arg;
 
-  if (PARSER_RESULT (parser)->expression)
-    xfree (PARSER_RESULT (parser)->expression);
-  if (PARSER_RESULT (parser)->source_filename)
-    xfree (PARSER_RESULT (parser)->source_filename);
-  if (PARSER_RESULT (parser)->label_name)
-    xfree (PARSER_RESULT (parser)->label_name);
-  if (PARSER_RESULT (parser)->function_name)
-    xfree (PARSER_RESULT (parser)->function_name);
+  xfree ((char *) PARSER_RESULT (parser)->expression);
+  xfree ((char *) PARSER_RESULT (parser)->source_filename);
+  xfree ((char *) PARSER_RESULT (parser)->label_name);
+  xfree ((char *) PARSER_RESULT (parser)->function_name);
 
   if (PARSER_RESULT (parser)->file_symtabs != NULL)
     VEC_free (symtab_p, PARSER_RESULT (parser)->file_symtabs);
@@ -2258,7 +2413,6 @@ decode_line_full (char **argptr, int flags,
 {
   struct symtabs_and_lines result;
   struct cleanup *cleanups;
-  char *arg_start = *argptr;
   VEC (const_char_ptr) *filters = NULL;
   linespec_parser parser;
   struct linespec_state *state;
@@ -2284,20 +2438,16 @@ decode_line_full (char **argptr, int flags,
   gdb_assert (canonical->addr_string != NULL);
   canonical->pre_expanded = 1;
 
-  /* Fill in the missing canonical names.  */
+  /* Arrange for allocated canonical names to be freed.  */
   if (result.nelts > 0)
     {
       int i;
 
-      if (state->canonical_names == NULL)
-       state->canonical_names = xcalloc (result.nelts, sizeof (char *));
       make_cleanup (xfree, state->canonical_names);
       for (i = 0; i < result.nelts; ++i)
        {
-         if (state->canonical_names[i] == NULL)
-           state->canonical_names[i] = savestring (arg_start,
-                                                   *argptr - arg_start);
-         make_cleanup (xfree, state->canonical_names[i]);
+         gdb_assert (state->canonical_names[i].suffix != NULL);
+         make_cleanup (xfree, state->canonical_names[i].suffix);
        }
     }
 
@@ -2420,7 +2570,7 @@ initialize_defaults (struct symtab **default_symtab, int *default_line)
    advancing EXP_PTR past any parsed text.  */
 
 static CORE_ADDR
-linespec_expression_to_pc (char **exp_ptr)
+linespec_expression_to_pc (const char **exp_ptr)
 {
   if (current_program_space->executing_startup)
     /* The error message doesn't really matter, because this case
@@ -2478,6 +2628,7 @@ decode_objc (struct linespec_state *self, linespec_p ls, char **argptr)
       memcpy (saved_arg, *argptr, new_argptr - *argptr);
       saved_arg[new_argptr - *argptr] = '\0';
 
+      ls->function_name = xstrdup (saved_arg);
       ls->function_symbols = info.result.symbols;
       ls->minimal_symbols = info.result.minimal_symbols;
       values = convert_linespec_to_sals (self, ls);
@@ -2576,17 +2727,14 @@ lookup_prefix_sym (struct linespec_state *state, VEC (symtab_p) *file_symtabs,
        }
       else
        {
-         struct block *search_block;
-
          /* Program spaces that are executing startup should have
             been filtered out earlier.  */
          gdb_assert (!SYMTAB_PSPACE (elt)->executing_startup);
          set_current_program_space (SYMTAB_PSPACE (elt));
-         search_block = get_search_block (elt);
-         LA_ITERATE_OVER_SYMBOLS (search_block, class_name, STRUCT_DOMAIN,
-                                  collect_one_symbol, &collector);
-         LA_ITERATE_OVER_SYMBOLS (search_block, class_name, VAR_DOMAIN,
-                                  collect_one_symbol, &collector);
+         iterate_over_file_blocks (elt, class_name, STRUCT_DOMAIN,
+                                   collect_one_symbol, &collector);
+         iterate_over_file_blocks (elt, class_name, VAR_DOMAIN,
+                                   collect_one_symbol, &collector);
        }
     }
 
@@ -2923,17 +3071,16 @@ find_function_symbols (struct linespec_state *state,
 /* Find all symbols named NAME in FILE_SYMTABS, returning debug symbols
    in SYMBOLS and minimal symbols in MINSYMS.  */
 
-void
+static void
 find_linespec_symbols (struct linespec_state *state,
                       VEC (symtab_p) *file_symtabs,
                       const char *name,
                       VEC (symbolp) **symbols,
                       VEC (minsym_and_objfile_d) **minsyms)
 {
-  char *klass, *method, *canon;
-  const char *lookup_name, *last, *p, *scope_op;
   struct cleanup *cleanup;
-  VEC (symbolp) *classes;
+  char *canon;
+  const char *lookup_name;
   volatile struct gdb_exception except;
 
   cleanup = demangle_for_lookup (name, state->language->la_language,
@@ -2950,78 +3097,92 @@ find_linespec_symbols (struct linespec_state *state,
   if (canon != NULL)
     {
       lookup_name = canon;
-      cleanup = make_cleanup (xfree, canon);
-    }
-
-  /* See if we can find a scope operator and break this symbol
-     name into namespaces${SCOPE_OPERATOR}class_name and method_name.  */
-  scope_op = "::";
-  p = find_toplevel_string (lookup_name, scope_op);
-  if (p == NULL)
-    {
-      /* No C++ scope operator.  Try Java.  */
-      scope_op = ".";
+      make_cleanup (xfree, canon);
+    }
+
+  /* It's important to not call expand_symtabs_matching unnecessarily
+     as it can really slow things down (by unnecessarily expanding
+     potentially 1000s of symtabs, which when debugging some apps can
+     cost 100s of seconds).  Avoid this to some extent by *first* calling
+     find_function_symbols, and only if that doesn't find anything
+     *then* call find_method.  This handles two important cases:
+     1) break (anonymous namespace)::foo
+     2) break class::method where method is in class (and not a baseclass)  */
+
+  find_function_symbols (state, file_symtabs, lookup_name,
+                        symbols, minsyms);
+
+  /* If we were unable to locate a symbol of the same name, try dividing
+     the name into class and method names and searching the class and its
+     baseclasses.  */
+  if (VEC_empty (symbolp, *symbols)
+      && VEC_empty (minsym_and_objfile_d, *minsyms))
+    {
+      char *klass, *method;
+      const char *last, *p, *scope_op;
+      VEC (symbolp) *classes;
+
+      /* See if we can find a scope operator and break this symbol
+        name into namespaces${SCOPE_OPERATOR}class_name and method_name.  */
+      scope_op = "::";
       p = find_toplevel_string (lookup_name, scope_op);
-    }
-
-  last = NULL;
-  while (p != NULL)
-    {
-      last = p;
-      p = find_toplevel_string (p + strlen (scope_op), scope_op);
-    }
-
-  /* If no scope operator was found, lookup the name as a symbol.  */
-  if (last == NULL)
-    {
-      find_function_symbols (state, file_symtabs, lookup_name,
-                            symbols, minsyms);
-      do_cleanups (cleanup);
-      return;
-    }
-
-  /* NAME points to the class name.
-     LAST points to the method name.  */
-  klass = xmalloc ((last - lookup_name + 1) * sizeof (char));
-  make_cleanup (xfree, klass);
-  strncpy (klass, lookup_name, last - lookup_name);
-  klass[last - lookup_name] = '\0';
-
-  /* Skip past the scope operator.  */
-  last += strlen (scope_op);
-  method = xmalloc ((strlen (last) + 1) * sizeof (char));
-  make_cleanup (xfree, method);
-  strcpy (method, last);
+      if (p == NULL)
+       {
+         /* No C++ scope operator.  Try Java.  */
+         scope_op = ".";
+         p = find_toplevel_string (lookup_name, scope_op);
+       }
 
-  /* Find a list of classes named KLASS.  */
-  classes = lookup_prefix_sym (state, file_symtabs, klass);
-  make_cleanup (VEC_cleanup (symbolp), &classes);
-  if (!VEC_empty (symbolp, classes))
-    {
-      /* Now locate a list of suitable methods named METHOD.  */
-      TRY_CATCH (except, RETURN_MASK_ERROR)
+      last = NULL;
+      while (p != NULL)
        {
-         find_method (state, file_symtabs, klass, method, classes,
-                      symbols, minsyms);
+         last = p;
+         p = find_toplevel_string (p + strlen (scope_op), scope_op);
        }
 
-      /* If successful, we're done.  If NOT_FOUND_ERROR
-        was not thrown, rethrow the exception that we did get.
-        Otherwise, fall back to looking up the entire name as a symbol.
-        This can happen with namespace::function.  */
-      if (except.reason >= 0)
+      /* If no scope operator was found, there is nothing more we can do;
+        we already attempted to lookup the entire name as a symbol
+        and failed.  */
+      if (last == NULL)
        {
          do_cleanups (cleanup);
          return;
        }
-      else if (except.error != NOT_FOUND_ERROR)
-       throw_exception (except);
+
+      /* LOOKUP_NAME points to the class name.
+        LAST points to the method name.  */
+      klass = xmalloc ((last - lookup_name + 1) * sizeof (char));
+      make_cleanup (xfree, klass);
+      strncpy (klass, lookup_name, last - lookup_name);
+      klass[last - lookup_name] = '\0';
+
+      /* Skip past the scope operator.  */
+      last += strlen (scope_op);
+      method = xmalloc ((strlen (last) + 1) * sizeof (char));
+      make_cleanup (xfree, method);
+      strcpy (method, last);
+
+      /* Find a list of classes named KLASS.  */
+      classes = lookup_prefix_sym (state, file_symtabs, klass);
+      make_cleanup (VEC_cleanup (symbolp), &classes);
+
+      if (!VEC_empty (symbolp, classes))
+       {
+         /* Now locate a list of suitable methods named METHOD.  */
+         TRY_CATCH (except, RETURN_MASK_ERROR)
+           {
+             find_method (state, file_symtabs, klass, method, classes,
+                          symbols, minsyms);
+           }
+
+         /* If successful, we're done.  If NOT_FOUND_ERROR
+            was not thrown, rethrow the exception that we did get.  */
+         if (except.reason < 0 && except.error != NOT_FOUND_ERROR)
+           throw_exception (except);
+       }
     }
 
-  /* We couldn't find a class, so we check the entire name as a symbol
-     instead.  */
-   find_function_symbols (state, file_symtabs, lookup_name, symbols, minsyms);
-   do_cleanups (cleanup);
+  do_cleanups (cleanup);
 }
 
 /* Return all labels named NAME in FUNCTION_SYMBOLS.  Return the
@@ -3041,7 +3202,7 @@ find_label_symbols (struct linespec_state *self,
   if (function_symbols == NULL)
     {
       set_current_program_space (self->program_space);
-      block = get_search_block (NULL);
+      block = get_current_search_block ();
 
       for (;
           block && !BLOCK_FUNCTION (block);
@@ -3110,7 +3271,7 @@ decode_digits_list_mode (struct linespec_state *self,
       val.pc = 0;
       val.explicit_line = 1;
 
-      add_sal_to_sals (self, values, &val, NULL);
+      add_sal_to_sals (self, values, &val, NULL, 0);
     }
 }
 
@@ -3242,7 +3403,7 @@ minsym_found (struct linespec_state *self, struct objfile *objfile,
 
   sal = find_pc_sect_line (SYMBOL_VALUE_ADDRESS (msymbol),
                           (struct obj_section *) 0, 0);
-  sal.section = SYMBOL_OBJ_SECTION (msymbol);
+  sal.section = SYMBOL_OBJ_SECTION (objfile, msymbol);
 
   /* The minimal symbol might point to a function descriptor;
      resolve it to the actual code address instead.  */
@@ -3254,7 +3415,7 @@ minsym_found (struct linespec_state *self, struct objfile *objfile,
     skip_prologue_sal (&sal);
 
   if (maybe_add_address (self->addr_set, objfile->pspace, sal.pc))
-    add_sal_to_sals (self, result, &sal, SYMBOL_NATURAL_NAME (msymbol));
+    add_sal_to_sals (self, result, &sal, SYMBOL_NATURAL_NAME (msymbol), 0);
 }
 
 /* A helper struct to pass some data through
@@ -3445,9 +3606,8 @@ add_matching_symbols_to_info (const char *name,
             been filtered out earlier.  */
          gdb_assert (!SYMTAB_PSPACE (elt)->executing_startup);
          set_current_program_space (SYMTAB_PSPACE (elt));
-         LA_ITERATE_OVER_SYMBOLS (get_search_block (elt), name,
-                                  VAR_DOMAIN, collect_symbols,
-                                  info);
+         iterate_over_file_blocks (elt, name, VAR_DOMAIN,
+                                   collect_symbols, info);
        }
     }
 }
This page took 0.037123 seconds and 4 git commands to generate.