gdb/
[deliverable/binutils-gdb.git] / gdb / linespec.c
index d362f1cc5f0b3803eb912feaa84acf078e044ee4..3e943a18e74c088a22b9e870cb3ffac544032d68 100644 (file)
@@ -1,13 +1,14 @@
 /* Parser for linespec for the GNU debugger, GDB.
-   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
-   1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
-   Free Software Foundation, Inc.
+
+   Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+   1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008,
+   2009 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -16,9 +17,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 #include "symtab.h"
 #include "block.h"
 #include "objc-lang.h"
 #include "linespec.h"
+#include "exceptions.h"
+#include "language.h"
+#include "interps.h"
+#include "mi/mi-cmds.h"
+#include "target.h"
 
 /* We share this one with symtab.c, but it is not exported widely. */
 
@@ -61,7 +65,8 @@ static struct symtabs_and_lines decode_compound (char **argptr,
                                                 int funfirstline,
                                                 char ***canonical,
                                                 char *saved_arg,
-                                                char *p);
+                                                char *p,
+                                                int *not_found_ptr);
 
 static struct symbol *lookup_prefix_sym (char **argptr, char *p);
 
@@ -70,10 +75,8 @@ static struct symtabs_and_lines find_method (int funfirstline,
                                             char *saved_arg,
                                             char *copy,
                                             struct type *t,
-                                            struct symbol *sym_class);
-
-static int collect_methods (char *copy, struct type *t,
-                           struct symbol **sym_arr);
+                                            struct symbol *sym_class,
+                                            int *not_found_ptr);
 
 static NORETURN void cplusplus_error (const char *name,
                                      const char *fmt, ...)
@@ -81,12 +84,15 @@ static NORETURN void cplusplus_error (const char *name,
 
 static int total_number_of_methods (struct type *type);
 
-static int find_methods (struct type *, char *, struct symbol **);
+static int find_methods (struct type *, char *,
+                        enum language, struct symbol **);
 
 static int add_matching_methods (int method_counter, struct type *t,
+                                enum language language,
                                 struct symbol **sym_arr);
 
 static int add_constructors (int method_counter, struct type *t,
+                            enum language language,
                             struct symbol **sym_arr);
 
 static void build_canonical_line_spec (struct symtab_and_line *,
@@ -128,8 +134,7 @@ symtabs_and_lines symbol_found (int funfirstline,
                                char ***canonical,
                                char *copy,
                                struct symbol *sym,
-                               struct symtab *file_symtab,
-                               struct symtab *sym_symtab);
+                               struct symtab *file_symtab);
 
 static struct
 symtabs_and_lines minsym_found (int funfirstline,
@@ -145,6 +150,7 @@ static NORETURN void
 cplusplus_error (const char *name, const char *fmt, ...)
 {
   struct ui_file *tmp_stream;
+  char *message;
   tmp_stream = mem_fileopen ();
   make_cleanup_ui_file_delete (tmp_stream);
 
@@ -161,7 +167,10 @@ cplusplus_error (const char *name, const char *fmt, ...)
                      ("Hint: try '%s<TAB> or '%s<ESC-?>\n"
                       "(Note leading single quote.)"),
                      name, name);
-  error_stream (tmp_stream);
+
+  message = ui_file_xstrdup (tmp_stream, NULL);
+  make_cleanup (xfree, message);
+  throw_error (NOT_FOUND_ERROR, "%s", message);
 }
 
 /* Return the number of methods described for TYPE, including the
@@ -194,7 +203,8 @@ total_number_of_methods (struct type *type)
    Note that this function is g++ specific.  */
 
 static int
-find_methods (struct type *t, char *name, struct symbol **sym_arr)
+find_methods (struct type *t, char *name, enum language language,
+             struct symbol **sym_arr)
 {
   int i1 = 0;
   int ibase;
@@ -204,9 +214,8 @@ find_methods (struct type *t, char *name, struct symbol **sym_arr)
      unless we figure out how to get the physname without the name of
      the class, then the loop can't do any good.  */
   if (class_name
-      && (lookup_symbol (class_name, (struct block *) NULL,
-                        STRUCT_DOMAIN, (int *) NULL,
-                        (struct symtab **) NULL)))
+      && (lookup_symbol_in_language (class_name, (struct block *) NULL,
+                        STRUCT_DOMAIN, language, (int *) NULL)))
     {
       int method_counter;
       int name_len = strlen (name);
@@ -236,12 +245,12 @@ find_methods (struct type *t, char *name, struct symbol **sym_arr)
 
          if (strcmp_iw (name, method_name) == 0)
            /* Find all the overloaded methods with that name.  */
-           i1 += add_matching_methods (method_counter, t,
+           i1 += add_matching_methods (method_counter, t, language,
                                        sym_arr + i1);
          else if (strncmp (class_name, name, name_len) == 0
                   && (class_name[name_len] == '\0'
                       || class_name[name_len] == '<'))
-           i1 += add_constructors (method_counter, t,
+           i1 += add_constructors (method_counter, t, language,
                                    sym_arr + i1);
        }
     }
@@ -259,7 +268,8 @@ find_methods (struct type *t, char *name, struct symbol **sym_arr)
 
   if (i1 == 0)
     for (ibase = 0; ibase < TYPE_N_BASECLASSES (t); ibase++)
-      i1 += find_methods (TYPE_BASECLASS (t, ibase), name, sym_arr + i1);
+      i1 += find_methods (TYPE_BASECLASS (t, ibase), name,
+                         language, sym_arr + i1);
 
   return i1;
 }
@@ -270,7 +280,7 @@ find_methods (struct type *t, char *name, struct symbol **sym_arr)
 
 static int
 add_matching_methods (int method_counter, struct type *t,
-                     struct symbol **sym_arr)
+                     enum language language, struct symbol **sym_arr)
 {
   int field_counter;
   int i1 = 0;
@@ -297,16 +307,11 @@ add_matching_methods (int method_counter, struct type *t,
        }
       else
        phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter);
-               
-      /* Destructor is handled by caller, don't add it to
-        the list.  */
-      if (is_destructor_name (phys_name) != 0)
-       continue;
 
-      sym_arr[i1] = lookup_symbol (phys_name,
+      sym_arr[i1] = lookup_symbol_in_language (phys_name,
                                   NULL, VAR_DOMAIN,
-                                  (int *) NULL,
-                                  (struct symtab **) NULL);
+                                  language,
+                                  (int *) NULL);
       if (sym_arr[i1])
        i1++;
       else
@@ -331,7 +336,7 @@ add_matching_methods (int method_counter, struct type *t,
 
 static int
 add_constructors (int method_counter, struct type *t,
-                 struct symbol **sym_arr)
+                 enum language language, struct symbol **sym_arr)
 {
   int field_counter;
   int i1 = 0;
@@ -347,7 +352,7 @@ add_constructors (int method_counter, struct type *t,
     {
       struct fn_field *f;
       char *phys_name;
-                 
+
       f = TYPE_FN_FIELDLIST1 (t, method_counter);
 
       /* GCC 3.x will never produce stabs stub methods, so
@@ -360,10 +365,10 @@ add_constructors (int method_counter, struct type *t,
 
       /* If this method is actually defined, include it in the
         list.  */
-      sym_arr[i1] = lookup_symbol (phys_name,
+      sym_arr[i1] = lookup_symbol_in_language (phys_name,
                                   NULL, VAR_DOMAIN,
-                                  (int *) NULL,
-                                  (struct symtab **) NULL);
+                                  language,
+                                  (int *) NULL);
       if (sym_arr[i1])
        i1++;
     }
@@ -482,7 +487,13 @@ decode_line_2 (struct symbol *sym_arr[], int nelts, int funfirstline,
   char *symname;
   struct cleanup *old_chain;
   char **canonical_arr = (char **) NULL;
+  const char *select_mode = multiple_symbols_select_mode ();
 
+  if (select_mode == multiple_symbols_cancel)
+    error (_("\
+canceled because the command is ambiguous\n\
+See set/show multiple-symbol."));
+  
   values.sals = (struct symtab_and_line *)
     alloca (nelts * sizeof (struct symtab_and_line));
   return_values.sals = (struct symtab_and_line *)
@@ -498,41 +509,56 @@ decode_line_2 (struct symbol *sym_arr[], int nelts, int funfirstline,
     }
 
   i = 0;
-  printf_unfiltered ("[0] cancel\n[1] all\n");
   while (i < nelts)
     {
       init_sal (&return_values.sals[i]);       /* Initialize to zeroes.  */
       init_sal (&values.sals[i]);
       if (sym_arr[i] && SYMBOL_CLASS (sym_arr[i]) == LOC_BLOCK)
-       {
-         values.sals[i] = find_function_start_sal (sym_arr[i], funfirstline);
-         if (values.sals[i].symtab)
-           printf_unfiltered ("[%d] %s at %s:%d\n",
-                              (i + 2),
-                              SYMBOL_PRINT_NAME (sym_arr[i]),
-                              values.sals[i].symtab->filename,
-                              values.sals[i].line);
-         else
-           printf_unfiltered ("[%d] %s at ?FILE:%d [No symtab? Probably broken debug info...]\n",
-                              (i + 2),
-                              SYMBOL_PRINT_NAME (sym_arr[i]),
-                              values.sals[i].line);
-
-       }
-      else
-       printf_unfiltered ("?HERE\n");
+       values.sals[i] = find_function_start_sal (sym_arr[i], funfirstline);
       i++;
     }
 
-  prompt = getenv ("PS2");
-  if (prompt == NULL)
+  /* If select_mode is "all", then do not print the multiple-choice
+     menu and act as if the user had chosen choice "1" (all).  */
+  if (select_mode == multiple_symbols_all
+      || ui_out_is_mi_like_p (interp_ui_out (top_level_interpreter ())))
+    args = "1";
+  else
     {
-      prompt = "> ";
+      i = 0;
+      printf_unfiltered (_("[0] cancel\n[1] all\n"));
+      while (i < nelts)
+        {
+          if (sym_arr[i] && SYMBOL_CLASS (sym_arr[i]) == LOC_BLOCK)
+            {
+              if (values.sals[i].symtab)
+                printf_unfiltered ("[%d] %s at %s:%d\n",
+                                   (i + 2),
+                                   SYMBOL_PRINT_NAME (sym_arr[i]),
+                                   values.sals[i].symtab->filename,
+                                   values.sals[i].line);
+              else
+                printf_unfiltered (_("[%d] %s at ?FILE:%d [No symtab? Probably broken debug info...]\n"),
+                                   (i + 2),
+                                   SYMBOL_PRINT_NAME (sym_arr[i]),
+                                   values.sals[i].line);
+
+            }
+          else
+            printf_unfiltered (_("?HERE\n"));
+          i++;
+        }
+
+      prompt = getenv ("PS2");
+      if (prompt == NULL)
+        {
+          prompt = "> ";
+        }
+      args = command_line_input (prompt, 0, "overload-choice");
     }
-  args = command_line_input (prompt, 0, "overload-choice");
 
   if (args == 0 || *args == 0)
-    error_no_arg ("one or more choice numbers");
+    error_no_arg (_("one or more choice numbers"));
 
   i = 0;
   while (*args)
@@ -543,12 +569,12 @@ decode_line_2 (struct symbol *sym_arr[], int nelts, int funfirstline,
       while (*arg1 >= '0' && *arg1 <= '9')
        arg1++;
       if (*arg1 && *arg1 != ' ' && *arg1 != '\t')
-       error ("Arguments must be choice numbers.");
+       error (_("Arguments must be choice numbers."));
 
       num = atoi (args);
 
       if (num == 0)
-       error ("canceled");
+       error (_("canceled"));
       else if (num == 1)
        {
          if (canonical_arr)
@@ -557,8 +583,8 @@ decode_line_2 (struct symbol *sym_arr[], int nelts, int funfirstline,
                {
                  if (canonical_arr[i] == NULL)
                    {
-                     symname = DEPRECATED_SYMBOL_NAME (sym_arr[i]);
-                     canonical_arr[i] = savestring (symname, strlen (symname));
+                     symname = SYMBOL_LINKAGE_NAME (sym_arr[i]);
+                     canonical_arr[i] = xstrdup (symname);
                    }
                }
            }
@@ -571,7 +597,7 @@ decode_line_2 (struct symbol *sym_arr[], int nelts, int funfirstline,
 
       if (num >= nelts + 2)
        {
-         printf_unfiltered ("No choice number %d.\n", num);
+         printf_unfiltered (_("No choice number %d.\n"), num);
        }
       else
        {
@@ -580,16 +606,16 @@ decode_line_2 (struct symbol *sym_arr[], int nelts, int funfirstline,
            {
              if (canonical_arr)
                {
-                 symname = DEPRECATED_SYMBOL_NAME (sym_arr[num]);
+                 symname = SYMBOL_LINKAGE_NAME (sym_arr[num]);
                  make_cleanup (xfree, symname);
-                 canonical_arr[i] = savestring (symname, strlen (symname));
+                 canonical_arr[i] = xstrdup (symname);
                }
              return_values.sals[i++] = values.sals[num];
              values.sals[num].pc = 0;
            }
          else
            {
-             printf_unfiltered ("duplicate request for %d ignored.\n", num);
+             printf_unfiltered (_("duplicate request for %d ignored.\n"), num);
            }
        }
 
@@ -736,9 +762,9 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
        
       if (p[0] == '.' || p[1] == ':')
        return decode_compound (argptr, funfirstline, canonical,
-                               saved_arg, p);
+                               saved_arg, p, not_found_ptr);
 
-      /* No, the first part is a filename; set s to be that file's
+      /* No, the first part is a filename; set file_symtab to be that file's
         symtab.  Also, move argptr past the filename.  */
 
       file_symtab = symtab_from_filename (argptr, p, is_quote_enclosed, 
@@ -767,19 +793,18 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
       copy = (char *) alloca (p - *argptr + 1);
       memcpy (copy, *argptr, p - *argptr);
       copy[p - *argptr] = '\000';
-      sym = lookup_symbol (copy, 0, VAR_DOMAIN, 0, &sym_symtab);
+      sym = lookup_symbol (copy, 0, VAR_DOMAIN, 0);
       if (sym)
        {
          *argptr = (*p == '\'') ? p + 1 : p;
-         return symbol_found (funfirstline, canonical, copy, sym,
-                              NULL, sym_symtab);
+         return symbol_found (funfirstline, canonical, copy, sym, NULL);
        }
       /* Otherwise fall out from here and go to file/line spec
          processing, etc. */
     }
 #endif
 
-  /* S is specified file's symtab, or 0 if no file specified.
+  /* file_symtab is specified file's symtab, or 0 if no file specified.
      arg no longer contains the file name.  */
 
   /* Check whether arg is all digits (and sign).  */
@@ -805,7 +830,7 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
     {
       p = skip_quoted (*argptr);
       if (p[-1] != '\'')
-       error ("Unmatched single quote.");
+       error (_("Unmatched single quote."));
     }
   else if (is_objc_method)
     {
@@ -821,6 +846,10 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
       p = skip_quoted (*argptr);
     }
 
+  /* Keep any template parameters */
+  if (*p == '<')
+    p = find_template_name_end (p);
+
   copy = (char *) alloca (p - *argptr + 1);
   memcpy (copy, *argptr, p - *argptr);
   copy[p - *argptr] = '\0';
@@ -954,6 +983,7 @@ decode_indirect (char **argptr)
   values.sals[0] = find_pc_line (pc, 0);
   values.sals[0].pc = pc;
   values.sals[0].section = find_pc_overlay (pc);
+  values.sals[0].explicit_pc = 1;
 
   return values;
 }
@@ -1010,7 +1040,7 @@ locate_first_half (char **argptr, int *is_quote_enclosed)
        {
          char *temp_end = find_template_name_end (p);
          if (!temp_end)
-           error ("malformed template specification in command");
+           error (_("malformed template specification in command"));
          p = temp_end;
        }
       /* Check for a colon and a plus or minus and a [ (which
@@ -1078,8 +1108,8 @@ decode_objc (char **argptr, int funfirstline, struct symtab *file_symtab,
   struct symbol *sym = NULL;
   char *copy = NULL;
   struct block *block = NULL;
-  int i1 = 0;
-  int i2 = 0;
+  unsigned i1 = 0;
+  unsigned i2 = 0;
 
   values.sals = NULL;
   values.nelts = 0;
@@ -1087,14 +1117,22 @@ decode_objc (char **argptr, int funfirstline, struct symtab *file_symtab,
   if (file_symtab != NULL)
     block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (file_symtab), STATIC_BLOCK);
   else
-    block = get_selected_block (0);
-    
+    {
+      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);
+    }
+
   copy = find_imps (file_symtab, block, *argptr, NULL, &i1, &i2); 
     
   if (i1 > 0)
     {
       sym_arr = (struct symbol **) alloca ((i1 + 1) * sizeof (struct symbol *));
-      sym_arr[i1] = 0;
+      sym_arr[i1] = NULL;
 
       copy = find_imps (file_symtab, block, *argptr, sym_arr, &i1, &i2); 
       *argptr = copy;
@@ -1117,7 +1155,7 @@ decode_objc (char **argptr, int funfirstline, struct symtab *file_symtab,
          sym = find_pc_function (SYMBOL_VALUE_ADDRESS (sym_arr[0]));
          if ((sym != NULL) && strcmp (SYMBOL_LINKAGE_NAME (sym_arr[0]), SYMBOL_LINKAGE_NAME (sym)) != 0)
            {
-             warning ("debugging symbol \"%s\" does not match selector; ignoring", SYMBOL_LINKAGE_NAME (sym));
+             warning (_("debugging symbol \"%s\" does not match selector; ignoring"), SYMBOL_LINKAGE_NAME (sym));
              sym = NULL;
            }
        }
@@ -1134,7 +1172,7 @@ decode_objc (char **argptr, int funfirstline, struct symtab *file_symtab,
       else
        {
          /* The only match was a non-debuggable symbol.  */
-         values.sals[0].symtab = 0;
+         values.sals[0].symtab = NULL;
          values.sals[0].line = 0;
          values.sals[0].end = 0;
          values.sals[0].pc = SYMBOL_VALUE_ADDRESS (sym_arr[0]);
@@ -1158,15 +1196,13 @@ decode_objc (char **argptr, int funfirstline, struct symtab *file_symtab,
 
 static struct symtabs_and_lines
 decode_compound (char **argptr, int funfirstline, char ***canonical,
-                char *saved_arg, char *p)
+                char *saved_arg, char *p, int *not_found_ptr)
 {
   struct symtabs_and_lines values;
   char *p2;
   char *saved_arg2 = *argptr;
   char *temp_end;
   struct symbol *sym;
-  /* The symtab that SYM was found in.  */
-  struct symtab *sym_symtab;
   char *copy;
   struct symbol *sym_class;
   struct symbol **sym_arr;
@@ -1180,25 +1216,19 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
       && ((*argptr == p) || (p[-1] == ' ') || (p[-1] == '\t')))
     saved_arg2 += 2;
 
-  /* We have what looks like a class or namespace
-     scope specification (A::B), possibly with many
-     levels of namespaces or classes (A::B::C::D).
-
-     Some versions of the HP ANSI C++ compiler (as also possibly
-     other compilers) generate class/function/member names with
-     embedded double-colons if they are inside namespaces. To
-     handle this, we loop a few times, considering larger and
-     larger prefixes of the string as though they were single
-     symbols.  So, if the initially supplied string is
-     A::B::C::D::foo, we have to look up "A", then "A::B",
-     then "A::B::C", then "A::B::C::D", and finally
-     "A::B::C::D::foo" as single, monolithic symbols, because
-     A, B, C or D may be namespaces.
-
-     Note that namespaces can nest only inside other
-     namespaces, and not inside classes.  So we need only
-     consider *prefixes* of the string; there is no need to look up
-     "B::C" separately as a symbol in the previous example.  */
+  /* Given our example "AAA::inA::fun", we have two cases to consider:
+
+     1) AAA::inA is the name of a class.  In that case, presumably it
+        has a method called "fun"; we then look up that method using
+        find_method.
+
+     2) AAA::inA isn't the name of a class.  In that case, either the
+        user made a typo or AAA::inA is the name of a namespace.
+        Either way, we just look up AAA::inA::fun with lookup_symbol.
+
+     Thus, our first task is to find everything before the last set of
+     double-colons and figure out if it's the name of a class.  So we
+     first loop through all of the double-colons.  */
 
   p2 = p;              /* Save for restart.  */
 
@@ -1215,78 +1245,6 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
 
   while (1)
     {
-
-      /* Start of lookup in the symbol tables. */
-
-      /* Lookup in the symbol table the substring between argptr and
-        p. Note, this call changes the value of argptr.  */
-      /* PASS1: Before the call, argptr->"AAA::inA::fun",
-        p->"::inA::fun".  After the call: argptr->"inA::fun", p
-        unchanged.  */
-      /* PASS2: Before the call, argptr->"AAA::inA::fun", p->"::fun".
-        After the call: argptr->"fun", p->"::fun".  */
-      sym_class = lookup_prefix_sym (argptr, p);
-
-      /* PASS1: assume sym_class == NULL. Skip the whole if-stmt. */
-      /* PASS2: assume sym_class has been found, i.e. "AAA::inA" is a
-        class. Enter the if-stmt.  */
-      if (sym_class &&
-         (t = check_typedef (SYMBOL_TYPE (sym_class)),
-          (TYPE_CODE (t) == TYPE_CODE_STRUCT
-           || TYPE_CODE (t) == TYPE_CODE_UNION)))
-       {
-         /* Arg token is not digits => try it as a function name.
-            Find the next token (everything up to end or next
-            blank).  */
-         if (**argptr
-             && strchr (get_gdb_completer_quote_characters (),
-                        **argptr) != NULL)
-           {
-             p = skip_quoted (*argptr);
-             *argptr = *argptr + 1;
-           }
-         else
-           {
-             /* PASS2: at this point argptr->"fun".  */
-             p = *argptr;
-             while (*p && *p != ' ' && *p != '\t' && *p != ',' && *p != ':')
-               p++;
-             /* PASS2: at this point p->"".  String ended.  */
-           }
-
-         /* Allocate our own copy of the substring between argptr and
-            p. */
-         copy = (char *) alloca (p - *argptr + 1);
-         memcpy (copy, *argptr, p - *argptr);
-         copy[p - *argptr] = '\0';
-         if (p != *argptr
-             && copy[p - *argptr - 1]
-             && strchr (get_gdb_completer_quote_characters (),
-                        copy[p - *argptr - 1]) != NULL)
-           copy[p - *argptr - 1] = '\0';
-
-         /* PASS2: At this point copy->"fun", p->"" */
-
-         /* No line number may be specified.  */
-         while (*p == ' ' || *p == '\t')
-           p++;
-         *argptr = p;
-
-         /* Look for copy as a method of sym_class. */
-         /* PASS2: at this point copy->"fun", sym_class is "AAA:inA".
-            This concludes the scanning of the string for possible
-            components matches.  If we find it here, we return. If
-            not, and we are at the and of the string, we'll get out
-            of the loop and lookup the whole string in the symbol
-            tables.  */
-
-         return find_method (funfirstline, canonical, saved_arg,
-                             copy, t, sym_class);
-       } /* End if symbol found */
-
-      /* End of lookup in the symbol tables.  */
-
-      /* Prepare for next run through the loop.  */
       /* Move pointer up to next possible class/namespace token.  */
 
       p = p2 + 1;      /* Restart with old value +1.  */
@@ -1294,6 +1252,7 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
       /* PASS1: at this point p2->"::inA::fun", so p->":inA::fun",
         i.e. if there is a double-colon, p will now point to the
         second colon. */
+      /* PASS2: p2->"::fun", p->":fun" */
 
       /* Move pointer ahead to next double-colon.  */
       while (*p && (p[0] != ' ') && (p[0] != '\t') && (p[0] != '\''))
@@ -1302,7 +1261,7 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
            {
              temp_end = find_template_name_end (p);
              if (!temp_end)
-               error ("malformed template specification in command");
+               error (_("malformed template specification in command"));
              p = temp_end;
            }
          /* Note that, since, at the start of this loop, p would be
@@ -1313,9 +1272,12 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
             the beginning of this loop (PASS1), we had
             p->":inA::fun", we'll trigger this when p has been
             advanced to point to "::fun".  */
+         /* PASS2: we will not trigger this. */
          else if ((p[0] == ':') && (p[1] == ':'))
            break;      /* Found double-colon.  */
          else
+           /* PASS2: We'll keep getting here, until p->"", at which point
+              we exit this loop.  */
            p++;
        }
 
@@ -1323,7 +1285,7 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
        break;          /* Out of the while (1).  This would happen
                           for instance if we have looked up
                           unsuccessfully all the components of the
-                          string, and p->"".  */
+                          string, and p->""(PASS2)  */
 
       /* We get here if p points to ' ', '\t', '\'', "::" or ""(i.e
         string ended). */
@@ -1331,14 +1293,84 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
       p2 = p;
       /* Restore argptr as it was on entry to this function.  */
       *argptr = saved_arg2;
-      /* PASS1: at this point p->"::fun" argptr->"AAA::inA::fun".  */
+      /* PASS1: at this point p->"::fun" argptr->"AAA::inA::fun",
+        p2->"::fun".  */
 
       /* All ready for next pass through the loop.  */
     }                  /* while (1) */
 
-  /* Last chance attempt -- check entire name as a symbol.  Use "copy"
-     in preparation for jumping out of this block, to be consistent
-     with usage following the jump target.  */
+
+  /* Start of lookup in the symbol tables. */
+
+  /* Lookup in the symbol table the substring between argptr and
+     p. Note, this call changes the value of argptr.  */
+  /* Before the call, argptr->"AAA::inA::fun",
+     p->"", p2->"::fun".  After the call: argptr->"fun", p, p2
+     unchanged.  */
+  sym_class = lookup_prefix_sym (argptr, p2);
+
+  /* If sym_class has been found, and if "AAA::inA" is a class, then
+     we're in case 1 above.  So we look up "fun" as a method of that
+     class.  */
+  if (sym_class &&
+      (t = check_typedef (SYMBOL_TYPE (sym_class)),
+       (TYPE_CODE (t) == TYPE_CODE_STRUCT
+       || TYPE_CODE (t) == TYPE_CODE_UNION)))
+    {
+      /* Arg token is not digits => try it as a function name.
+        Find the next token (everything up to end or next
+        blank).  */
+      if (**argptr
+         && strchr (get_gdb_completer_quote_characters (),
+                    **argptr) != NULL)
+       {
+         p = skip_quoted (*argptr);
+         *argptr = *argptr + 1;
+       }
+      else
+       {
+         /* At this point argptr->"fun".  */
+         p = *argptr;
+         while (*p && *p != ' ' && *p != '\t' && *p != ',' && *p != ':')
+           p++;
+         /* At this point p->"".  String ended.  */
+       }
+
+      /* Allocate our own copy of the substring between argptr and
+        p. */
+      copy = (char *) alloca (p - *argptr + 1);
+      memcpy (copy, *argptr, p - *argptr);
+      copy[p - *argptr] = '\0';
+      if (p != *argptr
+         && copy[p - *argptr - 1]
+         && strchr (get_gdb_completer_quote_characters (),
+                    copy[p - *argptr - 1]) != NULL)
+       copy[p - *argptr - 1] = '\0';
+
+      /* At this point copy->"fun", p->"" */
+
+      /* No line number may be specified.  */
+      while (*p == ' ' || *p == '\t')
+       p++;
+      *argptr = p;
+      /* At this point arptr->"".  */
+
+      /* Look for copy as a method of sym_class. */
+      /* At this point copy->"fun", sym_class is "AAA:inA",
+        saved_arg->"AAA::inA::fun".  This concludes the scanning of
+        the string for possible components matches.  If we find it
+        here, we return. If not, and we are at the and of the string,
+        we'll lookup the whole string in the symbol tables.  */
+
+      return find_method (funfirstline, canonical, saved_arg,
+                         copy, t, sym_class, not_found_ptr);
+
+    } /* End if symbol found */
+
+
+  /* We couldn't find a class, so we're in case 2 above.  We check the
+     entire name as a symbol instead.  */
+
   copy = (char *) alloca (p - saved_arg2 + 1);
   memcpy (copy, saved_arg2, p - saved_arg2);
   /* Note: if is_quoted should be true, we snuff out quote here
@@ -1348,13 +1380,14 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
   *argptr = (*p == '\'') ? p + 1 : p;
 
   /* Look up entire name */
-  sym = lookup_symbol (copy, 0, VAR_DOMAIN, 0, &sym_symtab);
+  sym = lookup_symbol (copy, 0, VAR_DOMAIN, 0);
   if (sym)
-    return symbol_found (funfirstline, canonical, copy, sym,
-                        NULL, sym_symtab);
+    return symbol_found (funfirstline, canonical, copy, sym, NULL);
 
   /* Couldn't find any interpretation as classes/namespaces, so give
      up.  The quotes are important if copy is empty.  */
+  if (not_found_ptr)
+    *not_found_ptr = 1;
   cplusplus_error (saved_arg,
                   "Can't find member of namespace, class, struct, or union named \"%s\"\n",
                   copy);
@@ -1392,8 +1425,7 @@ lookup_prefix_sym (char **argptr, char *p)
   /* At this point p1->"::inA::fun", p->"inA::fun" copy->"AAA",
      argptr->"inA::fun" */
 
-  return lookup_symbol (copy, 0, STRUCT_DOMAIN, 0,
-                       (struct symtab **) NULL);
+  return lookup_symbol (copy, 0, STRUCT_DOMAIN, 0);
 }
 
 /* This finds the method COPY in the class whose type is T and whose
@@ -1401,10 +1433,10 @@ lookup_prefix_sym (char **argptr, char *p)
 
 static struct symtabs_and_lines
 find_method (int funfirstline, char ***canonical, char *saved_arg,
-            char *copy, struct type *t, struct symbol *sym_class)
+            char *copy, struct type *t, struct symbol *sym_class, int *not_found_ptr)
 {
   struct symtabs_and_lines values;
-  struct symbol *sym = 0;
+  struct symbol *sym = NULL;
   int i1;      /*  Counter for the symbol array.  */
   struct symbol **sym_arr =  alloca (total_number_of_methods (t)
                                     * sizeof (struct symbol *));
@@ -1412,7 +1444,7 @@ find_method (int funfirstline, char ***canonical, char *saved_arg,
   /* Find all methods with a matching name, and put them in
      sym_arr.  */
 
-  i1 = collect_methods (copy, t, sym_arr);
+  i1 = find_methods (t, copy, SYMBOL_LANGUAGE (sym_class), sym_arr);
 
   if (i1 == 1)
     {
@@ -1429,6 +1461,7 @@ find_method (int funfirstline, char ***canonical, char *saved_arg,
        }
       else
        {
+         values.sals = NULL;
          values.nelts = 0;
        }
       return values;
@@ -1451,6 +1484,8 @@ find_method (int funfirstline, char ***canonical, char *saved_arg,
        }
       else
        tmp = copy;
+      if (not_found_ptr)
+        *not_found_ptr = 1;
       if (tmp[0] == '~')
        cplusplus_error (saved_arg,
                         "the class `%s' does not have destructor defined\n",
@@ -1462,38 +1497,6 @@ find_method (int funfirstline, char ***canonical, char *saved_arg,
     }
 }
 
-/* Find all methods named COPY in the class whose type is T, and put
-   them in SYM_ARR.  Return the number of methods found.  */
-
-static int
-collect_methods (char *copy, struct type *t,
-                struct symbol **sym_arr)
-{
-  int i1 = 0;  /*  Counter for the symbol array.  */
-
-  if (destructor_name_p (copy, t))
-    {
-      /* Destructors are a special case.  */
-      int m_index, f_index;
-
-      if (get_destructor_fn_field (t, &m_index, &f_index))
-       {
-         struct fn_field *f = TYPE_FN_FIELDLIST1 (t, m_index);
-
-         sym_arr[i1] =
-           lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, f_index),
-                          NULL, VAR_DOMAIN, (int *) NULL,
-                          (struct symtab **) NULL);
-         if (sym_arr[i1])
-           i1++;
-       }
-    }
-  else
-    i1 = find_methods (t, copy, sym_arr);
-
-  return i1;
-}
-
 \f
 
 /* Return the symtab associated to the filename given by the substring
@@ -1527,21 +1530,12 @@ symtab_from_filename (char **argptr, char *p, int is_quote_enclosed,
   file_symtab = lookup_symtab (copy);
   if (file_symtab == 0)
     {
-      if (!have_full_symbols () && !have_partial_symbols ())
-       error ("No symbol table is loaded.  Use the \"file\" command.");
       if (not_found_ptr)
-       {
-         *not_found_ptr = 1;
-         /* The caller has indicated that it wishes quiet notification of any
-            error where the function or file is not found.  A call to 
-            error_silent causes an error to occur, but it does not issue 
-            the supplied message.  The message can be manually output by
-            the caller, if desired.  This is used, for example, when 
-            attempting to set breakpoints for functions in shared libraries 
-            that have not yet been loaded.  */
-         error_silent ("No source file named %s.", copy);
-       }
-      error ("No source file named %s.", copy);
+       *not_found_ptr = 1;
+      if (!have_full_symbols () && !have_partial_symbols ())
+       throw_error (NOT_FOUND_ERROR,
+                    _("No symbol table is loaded.  Use the \"file\" command."));
+      throw_error (NOT_FOUND_ERROR, _("No source file named %s."), copy);
     }
 
   /* Discard the file name from the arg.  */
@@ -1575,7 +1569,7 @@ decode_all_digits (char **argptr, struct symtab *default_symtab,
   sign = none;
 
   /* We might need a canonical line spec if no file was specified.  */
-  int need_canonical = (file_symtab == 0) ? 1 : 0;
+  int need_canonical = (file_symtab == NULL) ? 1 : 0;
 
   init_sal (&val);
 
@@ -1637,6 +1631,7 @@ decode_all_digits (char **argptr, struct symtab *default_symtab,
   values.nelts = 1;
   if (need_canonical)
     build_canonical_line_spec (values.sals, NULL, canonical);
+  values.sals[0].explicit_line = 1;
   return values;
 }
 
@@ -1648,15 +1643,13 @@ static struct symtabs_and_lines
 decode_dollar (char *copy, int funfirstline, struct symtab *default_symtab,
               char ***canonical, struct symtab *file_symtab)
 {
-  struct value *valx;
+  LONGEST valx;
   int index = 0;
   int need_canonical = 0;
   struct symtabs_and_lines values;
   struct symtab_and_line val;
   char *p;
   struct symbol *sym;
-  /* The symtab that SYM was found in.  */
-  struct symtab *sym_symtab;
   struct minimal_symbol *msymbol;
 
   p = (copy[1] == '$') ? copy + 2 : copy + 1;
@@ -1665,10 +1658,12 @@ decode_dollar (char *copy, int funfirstline, struct symtab *default_symtab,
   if (!*p)             /* Reached end of token without hitting non-digit.  */
     {
       /* We have a value history reference.  */
+      struct value *val_history;
       sscanf ((copy[1] == '$') ? copy + 2 : copy + 1, "%d", &index);
-      valx = access_value_history ((copy[1] == '$') ? -index : index);
-      if (TYPE_CODE (VALUE_TYPE (valx)) != TYPE_CODE_INT)
-       error ("History values used in line specs must have integer values.");
+      val_history = access_value_history ((copy[1] == '$') ? -index : index);
+      if (TYPE_CODE (value_type (val_history)) != TYPE_CODE_INT)
+       error (_("History values used in line specs must have integer values."));
+      valx = value_as_long (val_history);
     }
   else
     {
@@ -1676,13 +1671,12 @@ decode_dollar (char *copy, int funfirstline, struct symtab *default_symtab,
         convenience variable.  */
 
       /* Look up entire name as a symbol first.  */
-      sym = lookup_symbol (copy, 0, VAR_DOMAIN, 0, &sym_symtab);
-      file_symtab = (struct symtab *) 0;
+      sym = lookup_symbol (copy, 0, VAR_DOMAIN, 0);
+      file_symtab = (struct symtab *) NULL;
       need_canonical = 1;
       /* Symbol was found --> jump to normal symbol processing.  */
       if (sym)
-       return symbol_found (funfirstline, canonical, copy, sym,
-                            NULL, sym_symtab);
+       return symbol_found (funfirstline, canonical, copy, sym, NULL);
 
       /* If symbol was not found, look in minimal symbol tables.  */
       msymbol = lookup_minimal_symbol (copy, NULL, NULL);
@@ -1691,17 +1685,15 @@ decode_dollar (char *copy, int funfirstline, struct symtab *default_symtab,
        return minsym_found (funfirstline, msymbol);
 
       /* Not a user variable or function -- must be convenience variable.  */
-      need_canonical = (file_symtab == 0) ? 1 : 0;
-      valx = value_of_internalvar (lookup_internalvar (copy + 1));
-      if (TYPE_CODE (VALUE_TYPE (valx)) != TYPE_CODE_INT)
-       error ("Convenience variables used in line specs must have integer values.");
+      if (!get_internalvar_integer (lookup_internalvar (copy + 1), &valx))
+       error (_("Convenience variables used in line specs must have integer values."));
     }
 
   init_sal (&val);
 
   /* Either history value or convenience value from above, in valx.  */
   val.symtab = file_symtab ? file_symtab : default_symtab;
-  val.line = value_as_long (valx);
+  val.line = valx;
   val.pc = 0;
 
   values.sals = (struct symtab_and_line *) xmalloc (sizeof val);
@@ -1726,8 +1718,6 @@ decode_variable (char *copy, int funfirstline, char ***canonical,
                 struct symtab *file_symtab, int *not_found_ptr)
 {
   struct symbol *sym;
-  /* The symtab that SYM was found in.  */
-  struct symtab *sym_symtab;
 
   struct minimal_symbol *msymbol;
 
@@ -1736,35 +1726,25 @@ decode_variable (char *copy, int funfirstline, char ***canonical,
                        ? BLOCKVECTOR_BLOCK (BLOCKVECTOR (file_symtab),
                                             STATIC_BLOCK)
                        : get_selected_block (0)),
-                      VAR_DOMAIN, 0, &sym_symtab);
+                      VAR_DOMAIN, 0);
 
   if (sym != NULL)
-    return symbol_found (funfirstline, canonical, copy, sym,
-                        file_symtab, sym_symtab);
+    return symbol_found (funfirstline, canonical, copy, sym, file_symtab);
 
   msymbol = lookup_minimal_symbol (copy, NULL, NULL);
 
   if (msymbol != NULL)
     return minsym_found (funfirstline, msymbol);
 
-  if (!have_full_symbols () &&
-      !have_partial_symbols () && !have_minimal_symbols ())
-    error ("No symbol table is loaded.  Use the \"file\" command.");
-
   if (not_found_ptr)
-    {
-      *not_found_ptr = 1;
-      /* The caller has indicated that it wishes quiet notification of any
-        error where the function or file is not found.  A call to 
-        error_silent causes an error to occur, but it does not issue 
-        the supplied message.  The message can be manually output by
-        the caller, if desired.  This is used, for example, when 
-        attempting to set breakpoints for functions in shared libraries 
-        that have not yet been loaded.  */
-      error_silent ("Function \"%s\" not defined.", copy);
-    }
-  
-  error ("Function \"%s\" not defined.", copy);
+    *not_found_ptr = 1;
+
+  if (!have_full_symbols ()
+      && !have_partial_symbols ()
+      && !have_minimal_symbols ())
+    throw_error (NOT_FOUND_ERROR,
+                _("No symbol table is loaded.  Use the \"file\" command."));
+  throw_error (NOT_FOUND_ERROR, _("Function \"%s\" not defined."), copy);
 }
 
 
@@ -1778,8 +1758,7 @@ decode_variable (char *copy, int funfirstline, char ***canonical,
 
 static struct symtabs_and_lines
 symbol_found (int funfirstline, char ***canonical, char *copy,
-             struct symbol *sym, struct symtab *file_symtab,
-             struct symtab *sym_symtab)
+             struct symbol *sym, struct symtab *file_symtab)
 {
   struct symtabs_and_lines values;
   
@@ -1799,7 +1778,7 @@ symbol_found (int funfirstline, char ***canonical, char *copy,
         function.  */
       if (file_symtab == 0)
        {
-         struct blockvector *bv = BLOCKVECTOR (sym_symtab);
+         struct blockvector *bv = BLOCKVECTOR (SYMBOL_SYMTAB (sym));
          struct block *b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
          if (lookup_block_symbol (b, copy, NULL, VAR_DOMAIN) != NULL)
            build_canonical_line_spec (values.sals, copy, canonical);
@@ -1809,7 +1788,7 @@ symbol_found (int funfirstline, char ***canonical, char *copy,
   else
     {
       if (funfirstline)
-       error ("\"%s\" is not a function", copy);
+       error (_("\"%s\" is not a function"), copy);
       else if (SYMBOL_LINE (sym) != 0)
        {
          /* We know its line number.  */
@@ -1817,7 +1796,7 @@ symbol_found (int funfirstline, char ***canonical, char *copy,
            xmalloc (sizeof (struct symtab_and_line));
          values.nelts = 1;
          memset (&values.sals[0], 0, sizeof (values.sals[0]));
-         values.sals[0].symtab = sym_symtab;
+         values.sals[0].symtab = SYMBOL_SYMTAB (sym);
          values.sals[0].line = SYMBOL_LINE (sym);
          return values;
        }
@@ -1827,7 +1806,7 @@ symbol_found (int funfirstline, char ***canonical, char *copy,
        /* FIXME: Shouldn't we just set .line and .symtab to zero
           and return?  For example, "info line foo" could print
           the address.  */
-       error ("Line number not known for symbol \"%s\"", copy);
+       error (_("Line number not known for symbol \"%s\""), copy);
     }
 }
 
@@ -1837,18 +1816,47 @@ symbol_found (int funfirstline, char ***canonical, char *copy,
 static struct symtabs_and_lines
 minsym_found (int funfirstline, struct minimal_symbol *msymbol)
 {
+  struct objfile *objfile = msymbol_objfile (msymbol);
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
   struct symtabs_and_lines values;
+  CORE_ADDR pc;
 
   values.sals = (struct symtab_and_line *)
     xmalloc (sizeof (struct symtab_and_line));
   values.sals[0] = find_pc_sect_line (SYMBOL_VALUE_ADDRESS (msymbol),
-                                     (struct bfd_section *) 0, 0);
-  values.sals[0].section = SYMBOL_BFD_SECTION (msymbol);
+                                     (struct obj_section *) 0, 0);
+  values.sals[0].section = SYMBOL_OBJ_SECTION (msymbol);
+
+  /* The minimal symbol might point to a function descriptor;
+     resolve it to the actual code address instead.  */
+  pc = gdbarch_convert_from_func_ptr_addr (gdbarch,
+                                           values.sals[0].pc,
+                                           &current_target);
+  if (pc != values.sals[0].pc)
+    values.sals[0] = find_pc_sect_line (pc, NULL, 0);
+
   if (funfirstline)
     {
-      values.sals[0].pc += FUNCTION_START_OFFSET;
-      values.sals[0].pc = SKIP_PROLOGUE (values.sals[0].pc);
+      struct symtab_and_line sal;
+
+      values.sals[0].pc = find_function_start_pc (gdbarch,
+                                                 values.sals[0].pc,
+                                                 values.sals[0].section);
+
+      sal = find_pc_sect_line (values.sals[0].pc, values.sals[0].section, 0);
+
+      /* Check if SKIP_PROLOGUE left us in mid-line, and the next
+        line is still part of the same function.  If there is no
+        line information here, sal.pc will be the passed in PC.  */
+      if (sal.pc != values.sals[0].pc
+         && (lookup_minimal_symbol_by_pc_section (values.sals[0].pc,
+                                                  values.sals[0].section)
+             == lookup_minimal_symbol_by_pc_section (sal.end,
+                                                     values.sals[0].section)))
+       /* Recalculate the line number (might not be N+1).  */
+       values.sals[0] = find_pc_sect_line (sal.end, values.sals[0].section, 0);
     }
+
   values.nelts = 1;
   return values;
 }
This page took 0.037033 seconds and 4 git commands to generate.