* config/tc-mips.c (macro_build_jalr): Reverse a negative
[deliverable/binutils-gdb.git] / gdb / linespec.c
index 68859a8457dcb6d6708b553b9ec1712d7e3ea8f1..64ba8377d7ade61022e76b631966149cc168d75b 100644 (file)
 #include "mi/mi-cmds.h"
 #include "target.h"
 #include "arch-utils.h"
-
-/* We share this one with symtab.c, but it is not exported widely.  */
-
-extern char *operator_chars (char *, char **);
+#include <ctype.h>
+#include "cli/cli-utils.h"
+#include "filenames.h"
 
 /* Prototypes for local functions.  */
 
@@ -58,25 +57,26 @@ static char *locate_first_half (char **argptr, int *is_quote_enclosed);
 static struct symtabs_and_lines decode_objc (char **argptr,
                                             int funfirstline,
                                             struct symtab *file_symtab,
-                                            char ***canonical,
+                                            struct linespec_result *canonical,
                                             char *saved_arg);
 
 static struct symtabs_and_lines decode_compound (char **argptr,
                                                 int funfirstline,
-                                                char ***canonical,
+                                                struct linespec_result *canonical,
+                                                struct symtab *file_symtab,
                                                 char *saved_arg,
-                                                char *p,
-                                                int *not_found_ptr);
+                                                char *p);
 
-static struct symbol *lookup_prefix_sym (char **argptr, char *p);
+static struct symbol *lookup_prefix_sym (char **argptr, char *p,
+                                        struct symtab *);
 
 static struct symtabs_and_lines find_method (int funfirstline,
-                                            char ***canonical,
+                                            struct linespec_result *canonical,
                                             char *saved_arg,
                                             char *copy,
                                             struct type *t,
                                             struct symbol *sym_class,
-                                            int *not_found_ptr);
+                                            struct symtab *);
 
 static void cplusplus_error (const char *name, const char *fmt, ...)
      ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (2, 3);
@@ -84,7 +84,7 @@ static void cplusplus_error (const char *name, const char *fmt, ...)
 static int total_number_of_methods (struct type *type);
 
 static int find_methods (struct type *, char *,
-                        enum language, struct symbol **);
+                        enum language, struct symbol **, struct symtab *);
 
 static int add_matching_methods (int method_counter, struct type *t,
                                 enum language language,
@@ -95,48 +95,52 @@ static int add_constructors (int method_counter, struct type *t,
                             struct symbol **sym_arr);
 
 static void build_canonical_line_spec (struct symtab_and_line *,
-                                      char *, char ***);
+                                      char *, struct linespec_result *);
 
 static char *find_toplevel_char (char *s, char c);
 
 static int is_objc_method_format (const char *s);
 
 static struct symtabs_and_lines decode_line_2 (struct symbol *[],
-                                              int, int, char ***);
+                                              int, int,
+                                              struct linespec_result *);
 
 static struct symtab *symtab_from_filename (char **argptr,
-                                           char *p, int is_quote_enclosed,
-                                           int *not_found_ptr);
+                                           char *p, int is_quote_enclosed);
+
+static struct symbol *find_function_symbol (char **argptr, char *p,
+                                           int is_quote_enclosed);
 
 static struct
 symtabs_and_lines decode_all_digits (char **argptr,
                                     struct symtab *default_symtab,
                                     int default_line,
-                                    char ***canonical,
+                                    struct linespec_result *canonical,
                                     struct symtab *file_symtab,
                                     char *q);
 
 static struct symtabs_and_lines decode_dollar (char *copy,
                                               int funfirstline,
                                               struct symtab *default_symtab,
-                                              char ***canonical,
+                                              struct linespec_result *canonical,
                                               struct symtab *file_symtab);
 
-static int decode_label (char *copy, char ***canonical,
+static int decode_label (struct symbol *function_symbol,
+                        char *copy, struct linespec_result *canonical,
                         struct symtabs_and_lines *result);
 
 static struct symtabs_and_lines decode_variable (char *copy,
                                                 int funfirstline,
-                                                char ***canonical,
-                                                struct symtab *file_symtab,
-                                                int *not_found_ptr);
+                                                struct linespec_result *canonical,
+                                                struct symtab *file_symtab);
 
 static struct
 symtabs_and_lines symbol_found (int funfirstline,
-                               char ***canonical,
+                               struct linespec_result *canonical,
                                char *copy,
                                struct symbol *sym,
-                               struct symtab *file_symtab);
+                               struct symtab *file_symtab,
+                               struct symbol *function_symbol);
 
 static struct
 symtabs_and_lines minsym_found (int funfirstline,
@@ -199,6 +203,30 @@ total_number_of_methods (struct type *type)
   return count;
 }
 
+/* Returns the block to be used for symbol searches for the given SYMTAB,
+   which may be NULL.  */
+
+static struct block *
+get_search_block (struct symtab *symtab)
+{
+  struct block *block;
+
+  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);
+    }
+
+  return block;
+}
+
 /* Recursive helper function for decode_line_1.
    Look for methods named NAME in type T.
    Return number of matches.
@@ -208,17 +236,30 @@ total_number_of_methods (struct type *type)
 
 static int
 find_methods (struct type *t, char *name, enum language language,
-             struct symbol **sym_arr)
+             struct symbol **sym_arr, struct symtab *file_symtab)
 {
   int i1 = 0;
   int ibase;
   char *class_name = type_name_no_tag (t);
+  struct cleanup *cleanup;
+  char *canon;
+
+  /* NAME is typed by the user: it needs to be canonicalized before
+     passing to lookup_symbol.  */
+  canon = cp_canonicalize_string_no_typedefs (name);
+  if (canon != NULL)
+    {
+      name = canon;
+      cleanup = make_cleanup (xfree, name);
+    }
+  else
+    cleanup = make_cleanup (null_cleanup, NULL);
 
   /* Ignore this class if it doesn't have a name.  This is ugly, but
      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_in_language (class_name, (struct block *) NULL,
+      && (lookup_symbol_in_language (class_name, get_search_block (file_symtab),
                         STRUCT_DOMAIN, language, (int *) NULL)))
     {
       int method_counter;
@@ -273,8 +314,9 @@ find_methods (struct type *t, char *name, enum language language,
   if (i1 == 0)
     for (ibase = 0; ibase < TYPE_N_BASECLASSES (t); ibase++)
       i1 += find_methods (TYPE_BASECLASS (t, ibase), name,
-                         language, sym_arr + i1);
+                         language, sym_arr + i1, file_symtab);
 
+  do_cleanups (cleanup);
   return i1;
 }
 
@@ -294,20 +336,21 @@ add_matching_methods (int method_counter, struct type *t,
        --field_counter)
     {
       struct fn_field *f;
-      char *phys_name;
+      const char *phys_name;
 
       f = TYPE_FN_FIELDLIST1 (t, method_counter);
 
       if (TYPE_FN_FIELD_STUB (f, field_counter))
        {
-         char *tmp_name;
+         char *tmp_name, *tmp2;
 
          tmp_name = gdb_mangle_name (t,
                                      method_counter,
                                      field_counter);
-         phys_name = alloca (strlen (tmp_name) + 1);
-         strcpy (phys_name, tmp_name);
+         tmp2 = alloca (strlen (tmp_name) + 1);
+         strcpy (tmp2, tmp_name);
          xfree (tmp_name);
+         phys_name = tmp2;
        }
       else
        phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter);
@@ -355,7 +398,7 @@ add_constructors (int method_counter, struct type *t,
        --field_counter)
     {
       struct fn_field *f;
-      char *phys_name;
+      const char *phys_name;
 
       f = TYPE_FN_FIELDLIST1 (t, method_counter);
 
@@ -389,7 +432,7 @@ add_constructors (int method_counter, struct type *t,
 
 static void
 build_canonical_line_spec (struct symtab_and_line *sal, char *symname,
-                          char ***canonical)
+                          struct linespec_result *canonical)
 {
   char **canonical_arr;
   char *canonical_name;
@@ -398,11 +441,11 @@ build_canonical_line_spec (struct symtab_and_line *sal, char *symname,
 
   if (s == (struct symtab *) NULL
       || s->filename == (char *) NULL
-      || canonical == (char ***) NULL)
+      || canonical == NULL)
     return;
 
   canonical_arr = (char **) xmalloc (sizeof (char *));
-  *canonical = canonical_arr;
+  canonical->canonical = canonical_arr;
 
   filename = s->filename;
   if (symname != NULL)
@@ -482,7 +525,7 @@ is_objc_method_format (const char *s)
 
 static struct symtabs_and_lines
 decode_line_2 (struct symbol *sym_arr[], int nelts, int funfirstline,
-              char ***canonical)
+              struct linespec_result *canonical)
 {
   struct symtabs_and_lines values, return_values;
   char *args, *arg1;
@@ -508,7 +551,7 @@ decode_line_2 (struct symbol *sym_arr[], int nelts, int funfirstline,
       canonical_arr = (char **) xmalloc (nelts * sizeof (char *));
       make_cleanup (xfree, canonical_arr);
       memset (canonical_arr, 0, nelts * sizeof (char *));
-      *canonical = canonical_arr;
+      canonical->canonical = canonical_arr;
     }
 
   i = 0;
@@ -633,6 +676,14 @@ decode_line_2 (struct symbol *sym_arr[], int nelts, int funfirstline,
   return return_values;
 }
 
+/* Valid delimiters for linespec keywords "if", "thread" or "task".  */
+
+static int
+is_linespec_boundary (char c)
+{
+  return c == ' ' || c == '\t' || c == '\0' || c == ',';
+}
+
 /* A helper function for decode_line_1 and friends which skips P
    past any method overload information at the beginning of P, e.g.,
    "(const struct foo *)".
@@ -663,6 +714,58 @@ find_method_overload_end (char *p)
 
   return p;
 }
+
+/* Keep important information used when looking up a name.  This includes
+   template parameters, overload information, and important keywords, including
+   the possible Java trailing type.  */
+
+static char *
+keep_name_info (char *p, int on_boundary)
+{
+  const char *quotes = get_gdb_completer_quote_characters ();
+  char *saved_p = p;
+  int nest = 0;
+
+  while (*p)
+    {
+      if (strchr (quotes, *p))
+       break;
+
+      if (*p == ',' && !nest)
+       break;
+
+      if (on_boundary && !nest)
+       {
+         const char *const words[] = { "if", "thread", "task" };
+         int wordi;
+
+         for (wordi = 0; wordi < ARRAY_SIZE (words); wordi++)
+           if (strncmp (p, words[wordi], strlen (words[wordi])) == 0
+               && is_linespec_boundary (p[strlen (words[wordi])]))
+             break;
+         if (wordi < ARRAY_SIZE (words))
+           break;
+       }
+
+      if (*p == '(' || *p == '<' || *p == '[')
+       nest++;
+      else if ((*p == ')' || *p == '>' || *p == ']') && nest > 0)
+       nest--;
+
+      p++;
+
+      /* The ',' check could fail on "operator ,".  */
+      p += cp_validate_operator (p);
+
+      on_boundary = is_linespec_boundary (p[-1]);
+    }
+
+  while (p > saved_p && is_linespec_boundary (p[-1]))
+    p--;
+
+  return p;
+}
+
 \f
 /* The parser of linespec itself.  */
 
@@ -702,12 +805,7 @@ find_method_overload_end (char *p)
 
    Note that it is possible to return zero for the symtab
    if no file is validly specified.  Callers must check that.
-   Also, the line number returned may be invalid.  
-   If NOT_FOUND_PTR is not null, store a boolean true/false value at
-   the location, based on whether or not failure occurs due to an
-   unknown function or file.  In the case where failure does occur due
-   to an unknown function or file, do not issue an error message.  */
+   Also, the line number returned may be invalid.  */
 
 /* We allow single quotes in various places.  This is a hideous
    kludge, which exists because the completer can't yet deal with the
@@ -716,7 +814,7 @@ find_method_overload_end (char *p)
 
 struct symtabs_and_lines
 decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
-              int default_line, char ***canonical, int *not_found_ptr)
+              int default_line, struct linespec_result *canonical)
 {
   char *p;
   char *q;
@@ -727,17 +825,23 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
   /* This says whether or not something in *ARGPTR is quoted with
      completer_quotes (i.e. with single quotes).  */
   int is_quoted;
-  /* Is *ARGPTR is enclosed in double quotes?  */
+  /* Is *ARGPTR enclosed in double quotes?  */
   int is_quote_enclosed;
   int is_objc_method = 0;
   char *saved_arg = *argptr;
   /* If IS_QUOTED, the end of the quoted bit.  */
   char *end_quote = NULL;
+  /* Is *ARGPTR enclosed in single quotes?  */
+  int is_squote_enclosed = 0;
   /* The "first half" of the linespec.  */
   char *first_half;
 
-  if (not_found_ptr)
-    *not_found_ptr = 0;
+  /* If we are parsing `function:label', this holds the symbol for the
+     function.  */
+  struct symbol *function_symbol = NULL;
+  /* If FUNCTION_SYMBOL is not NULL, then this is the exception that
+     was thrown when trying to parse a filename.  */
+  volatile struct gdb_exception file_exception;
 
   /* Defaults have defaults.  */
 
@@ -752,7 +856,11 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
                       **argptr) != NULL);
 
   if (is_quoted)
-    end_quote = skip_quoted (*argptr);
+    {
+      end_quote = skip_quoted (*argptr);
+      if (*end_quote == '\0')
+       is_squote_enclosed = 1;
+    }
 
   /* Check to see if it's a multipart linespec (with colons or
      periods).  */
@@ -765,6 +873,26 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
 
   first_half = p = locate_first_half (argptr, &is_quote_enclosed);
 
+  /* First things first: if ARGPTR starts with a filename, get its
+     symtab and strip the filename from ARGPTR.  */
+  TRY_CATCH (file_exception, RETURN_MASK_ERROR)
+    {
+      file_symtab = symtab_from_filename (argptr, p, is_quote_enclosed);
+    }
+
+  if (file_exception.reason >= 0)
+    {
+      /* Check for single quotes on the non-filename part.  */
+      is_quoted = (**argptr
+                  && strchr (get_gdb_completer_quote_characters (),
+                             **argptr) != NULL);
+      if (is_quoted)
+       end_quote = skip_quoted (*argptr);
+
+      /* Locate the next "half" of the linespec.  */
+      first_half = p = locate_first_half (argptr, &is_quote_enclosed);
+    }
+
   /* Check if this is an Objective-C method (anything that starts with
      a '+' or '-' and a '[').  */
   if (is_objc_method_format (p))
@@ -775,7 +903,7 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
   {
     struct symtabs_and_lines values;
 
-    values = decode_objc (argptr, funfirstline, NULL,
+    values = decode_objc (argptr, funfirstline, file_symtab,
                          canonical, saved_arg);
     if (values.sals != NULL)
       return values;
@@ -795,34 +923,60 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
       if (p[0] == '.' || p[1] == ':')
        {
          struct symtabs_and_lines values;
+         volatile struct gdb_exception ex;
+         char *saved_argptr = *argptr;
 
          if (is_quote_enclosed)
            ++saved_arg;
-         values = decode_compound (argptr, funfirstline, canonical,
-                                   saved_arg, p, not_found_ptr);
-         if (is_quoted && **argptr == '\'')
+
+         /* Initialize it just to avoid a GCC false warning.  */
+         memset (&values, 0, sizeof (values));
+
+         TRY_CATCH (ex, RETURN_MASK_ERROR)
+           {
+             values = decode_compound (argptr, funfirstline, canonical,
+                                       file_symtab, saved_arg, p);
+           }
+         if ((is_quoted || is_squote_enclosed) && **argptr == '\'')
            *argptr = *argptr + 1;
-         return values;
-       }
 
-      /* No, the first part is a filename; set file_symtab to be that file's
-        symtab.  Also, move argptr past the filename.  */
+         if (ex.reason >= 0)
+           return values;
 
-      file_symtab = symtab_from_filename (argptr, p, is_quote_enclosed,
-                                         not_found_ptr);
+         if (ex.error != NOT_FOUND_ERROR)
+           throw_exception (ex);
 
-      /* Check for single quotes on the non-filename part.  */
-      if (!is_quoted)
+         *argptr = saved_argptr;
+       }
+      else
        {
-         is_quoted = (**argptr
-                      && strchr (get_gdb_completer_quote_characters (),
-                                 **argptr) != NULL);
-         if (is_quoted)
-           end_quote = skip_quoted (*argptr);
+         /* If there was an exception looking up a specified filename earlier,
+            then check whether we were really given `function:label'.   */
+         if (file_exception.reason < 0)
+           {
+             function_symbol = find_function_symbol (argptr, p,
+                                                     is_quote_enclosed);
+             /* If we did not find a function, re-throw the original
+                exception.  */
+             if (!function_symbol)
+               throw_exception (file_exception);
+           }
+
+         /* Check for single quotes on the non-filename part.  */
+         if (!is_quoted)
+           {
+             is_quoted = (**argptr
+                          && strchr (get_gdb_completer_quote_characters (),
+                                     **argptr) != NULL);
+             if (is_quoted)
+               end_quote = skip_quoted (*argptr);
+           }
        }
     }
 
   /* file_symtab is specified file's symtab, or 0 if no file specified.
+     If we are parsing `function:symbol', then FUNCTION_SYMBOL is the
+     function before the `:'.
      arg no longer contains the file name.  */
 
   /* If the filename was quoted, we must re-check the quotation.  */
@@ -844,7 +998,8 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
   while (*q >= '0' && *q <= '9')
     q++;
 
-  if (q != *argptr && (*q == 0 || *q == ' ' || *q == '\t' || *q == ','))
+  if (q != *argptr && (*q == 0 || *q == ' ' || *q == '\t' || *q == ',')
+      && function_symbol == NULL)
     /* We found a token consisting of all digits -- at least one digit.  */
     return decode_all_digits (argptr, default_symtab, default_line,
                              canonical, file_symtab, q);
@@ -855,7 +1010,7 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
   if (**argptr == '$')         /* May be a convenience variable.  */
     /* One or two $ chars possible.  */
     p = skip_quoted (*argptr + (((*argptr)[1] == '$') ? 2 : 1));
-  else if (is_quoted)
+  else if (is_quoted || is_squote_enclosed)
     {
       p = end_quote;
       if (p[-1] != '\'')
@@ -871,17 +1026,8 @@ 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);
-
-  /* Keep method overload information.  */
-  if (*p == '(')
-    p = find_method_overload_end (p);
-
-  /* Make sure we keep important kewords like "const".  */
-  if (strncmp (p, " const", 6) == 0)
-    p += 6;
+  /* Keep any important naming information.  */
+  p = keep_name_info (p, p == saved_arg || is_linespec_boundary (p[-1]));
 
   copy = (char *) alloca (p - *argptr + 1);
   memcpy (copy, *argptr, p - *argptr);
@@ -894,7 +1040,7 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
       copy[p - *argptr - 1] = '\0';
       copy++;
     }
-  else if (is_quoted)
+  else if (is_quoted || is_squote_enclosed)
     copy[p - *argptr - 1] = '\0';
   while (*p == ' ' || *p == '\t')
     p++;
@@ -904,7 +1050,7 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
      (e.g. HP-UX millicode routines such as $$dyncall), or it may
      be history value, or it may be a convenience variable.  */
 
-  if (*copy == '$')
+  if (*copy == '$' && function_symbol == NULL)
     return decode_dollar (copy, funfirstline, default_symtab,
                          canonical, file_symtab);
 
@@ -914,15 +1060,17 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
   if (!file_symtab)
     {
       struct symtabs_and_lines label_result;
-      if (decode_label (copy, canonical, &label_result))
+      if (decode_label (function_symbol, copy, canonical, &label_result))
        return label_result;
     }
 
+  if (function_symbol)
+    throw_exception (file_exception);
+
   /* Look up that token as a variable.
      If file specified, use that file's per-file block to start with.  */
 
-  return decode_variable (copy, funfirstline, canonical,
-                         file_symtab, not_found_ptr);
+  return decode_variable (copy, funfirstline, canonical, file_symtab);
 }
 
 \f
@@ -1047,6 +1195,16 @@ locate_first_half (char **argptr, int *is_quote_enclosed)
          ++p;
        }
     }
+
+
+  /* Check for a drive letter in the filename.  This is done on all hosts
+     to capture cross-compilation environments.  On Unixen, directory
+     separators are illegal in filenames, so if the user enters "e:/foo.c",
+     he is referring to a directory named "e:" and a source file named
+     "foo.c", and we still want to keep these two pieces together.  */
+  if (isalpha (p[0]) && p[1] == ':' && IS_DIR_SEPARATOR (p[2]))
+    p += 3;
+
   for (; *p; p++)
     {
       if (p[0] == '<')
@@ -1057,6 +1215,10 @@ locate_first_half (char **argptr, int *is_quote_enclosed)
            error (_("malformed template specification in command"));
          p = temp_end;
        }
+
+      if (p[0] == '(')
+       p = find_method_overload_end (p);
+
       /* Check for a colon and a plus or minus and a [ (which
          indicates an Objective-C method).  */
       if (is_objc_method_format (p))
@@ -1064,13 +1226,11 @@ locate_first_half (char **argptr, int *is_quote_enclosed)
          break;
        }
       /* Check for the end of the first half of the linespec.  End of
-         line, a tab, a double colon or the last single colon, or a
-         space.  But if enclosed in double quotes we do not break on
-         enclosed spaces.  */
+         line, a tab, a colon or a space.  But if enclosed in double
+        quotes we do not break on enclosed spaces.  */
       if (!*p
          || p[0] == '\t'
-         || ((p[0] == ':')
-             && ((p[1] == ':') || (strchr (p + 1, ':') == NULL)))
+         || (p[0] == ':')
          || ((p[0] == ' ') && !*is_quote_enclosed))
        break;
       if (p[0] == '.' && strchr (p, ':') == NULL)
@@ -1117,7 +1277,7 @@ locate_first_half (char **argptr, int *is_quote_enclosed)
 
 struct symtabs_and_lines
 decode_objc (char **argptr, int funfirstline, struct symtab *file_symtab,
-            char ***canonical, char *saved_arg)
+            struct linespec_result *canonical, char *saved_arg)
 {
   struct symtabs_and_lines values;
   struct symbol **sym_arr = NULL;
@@ -1129,20 +1289,8 @@ decode_objc (char **argptr, int funfirstline, struct symtab *file_symtab,
   values.sals = NULL;
   values.nelts = 0;
 
-  if (file_symtab != NULL)
-    block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (file_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);
-    }
-
-  find_imps (file_symtab, block, *argptr, NULL, &i1, &i2); 
+  find_imps (file_symtab, get_search_block (file_symtab), *argptr,
+            NULL, &i1, &i2); 
     
   if (i1 > 0)
     {
@@ -1223,18 +1371,36 @@ decode_objc (char **argptr, int funfirstline, struct symtab *file_symtab,
    pointing to "AAA::inA::fun" and P pointing to "::inA::fun".  */
 
 static struct symtabs_and_lines
-decode_compound (char **argptr, int funfirstline, char ***canonical,
-                char *saved_arg, char *p, int *not_found_ptr)
+decode_compound (char **argptr, int funfirstline,
+                struct linespec_result *canonical, struct symtab *file_symtab,
+                char *the_real_saved_arg, char *p)
 {
   struct symtabs_and_lines values;
-  char *p2;
+  char *p2, *name, *canon;
   char *saved_arg2 = *argptr;
   char *temp_end;
   struct symbol *sym;
   char *copy;
   struct symbol *sym_class;
   struct type *t;
-  char *saved_java_argptr = NULL;
+  char *saved_arg;
+  struct cleanup *cleanup;
+
+  /* If the user specified any completer quote characters in the input,
+     strip them.  They are superfluous.  */
+  saved_arg = alloca (strlen (the_real_saved_arg) + 1);
+  {
+    char *dst = saved_arg;
+    char *src = the_real_saved_arg;
+    char *quotes = get_gdb_completer_quote_characters ();
+    while (*src != '\0')
+      {
+       if (strchr (quotes, *src) == NULL)
+         *dst++ = *src;
+       ++src;
+      }
+    *dst = '\0';
+  }
 
   /* First check for "global" namespace specification, of the form
      "::foo".  If found, skip over the colons and jump to normal
@@ -1251,8 +1417,10 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
         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.
+        user made a typo, AAA::inA is the name of a namespace, or it is
+        the name of a minimal symbol.
+        We just look up AAA::inA::fun with lookup_symbol.  If that fails,
+        try lookup_minimal_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
@@ -1273,6 +1441,8 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
 
   while (1)
     {
+      static char *break_characters = " \t(";
+
       /* Move pointer up to next possible class/namespace token.  */
 
       p = p2 + 1;      /* Restart with old value +1.  */
@@ -1283,8 +1453,9 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
       /* PASS2: p2->"::fun", p->":fun" */
 
       /* Move pointer ahead to next double-colon.  */
-      while (*p && (p[0] != ' ') && (p[0] != '\t') && (p[0] != '\'')
-            && (*p != '('))
+      while (*p
+            && strchr (break_characters, *p) == NULL
+            && strchr (get_gdb_completer_quote_characters (), *p) == NULL)
        {
          if (current_language->la_language == language_cplus)
            p += cp_validate_operator (p);
@@ -1308,9 +1479,19 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
          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++;
+           {
+             /* PASS2: We'll keep getting here, until P points to one of the
+                break characters, at which point we exit this loop.  */
+             if (*p)
+               {
+                 if (p[1] == '('
+                     && strncmp (&p[1], CP_ANONYMOUS_NAMESPACE_STR,
+                                 CP_ANONYMOUS_NAMESPACE_LEN) == 0)
+                   p += CP_ANONYMOUS_NAMESPACE_LEN;
+                 else if (strchr (break_characters, *p) == NULL)
+                   ++p;
+               }
+           }
        }
 
       if (*p != ':')
@@ -1319,7 +1500,7 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
                           unsuccessfully all the components of the
                           string, and p->""(PASS2).  */
 
-      /* We get here if p points to ' ', '\t', '\'', "::" or ""(i.e
+      /* We get here if p points to one of the break characters or "" (i.e.,
         string ended).  */
       /* Save restart for next time around.  */
       p2 = p;
@@ -1339,7 +1520,7 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
   /* 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);
+  sym_class = lookup_prefix_sym (argptr, p2, file_symtab);
 
   /* 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
@@ -1379,42 +1560,8 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
              p += cp_validate_operator (p - 8) - 8;
            }
 
-         /* Keep any template parameters.  */
-         if (*p == '<')
-           p = find_template_name_end (p);
-
-         /* Keep method overload information.  */
-         a = strchr (p, '(');
-         if (a != NULL)
-           p = find_method_overload_end (a);
-
-         /* Make sure we keep important kewords like "const".  */
-         if (strncmp (p, " const", 6) == 0)
-           p += 6;
-
-         /* Java may append typenames,  so assume that if there is
-            anything else left in *argptr, it must be a typename.  */
-         if (*p && current_language->la_language == language_java)
-           {
-             struct type *type;
-
-             p2 = p;
-             while (*p2)
-               ++p2;
-             copy = (char *) alloca (p2 - p + 1);
-             memcpy (copy, p, p2 - p);
-             copy[p2 - p] = '\0';
-             type = lookup_typename (current_language, get_current_arch (),
-                                     copy, NULL, 1);
-             if (type != NULL)
-               {
-                 /* Save the location of this just in case this
-                    method/type combination isn't actually defined.
-                    It will be checked later.  */
-                 saved_java_argptr = p;
-                 p = p2;
-               }
-           }
+         /* Keep any important naming information.  */
+         p = keep_name_info (p, 1);
        }
 
       /* Allocate our own copy of the substring between argptr and
@@ -1443,33 +1590,16 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
         here, we return.  If not, and we are at the and of the string,
         we'll lookup the whole string in the symbol tables.  */
 
-      values = find_method (funfirstline, canonical, saved_arg,
-                           copy, t, sym_class, not_found_ptr);
-      if (saved_java_argptr != NULL && values.nelts == 1)
-       {
-         /* The user specified a specific return type for a java method.
-            Double-check that it really is the one the user specified.
-            [This is a necessary evil because strcmp_iw_ordered stops
-            comparisons too prematurely.]  */
-         sym = find_pc_sect_function (values.sals[0].pc,
-                                      values.sals[0].section);
-         /* We just found a SAL, we had better be able to go backwards!  */
-         gdb_assert (sym != NULL);
-         if (strcmp_iw (SYMBOL_LINKAGE_NAME (sym), saved_arg) != 0)
-           {
-             xfree (values.sals);
-             error (_("the class `%s' does not have "
-                      "any method instance named %s"),
-                    SYMBOL_PRINT_NAME (sym_class), copy);
-           }
-       }
-      return values;
+      return find_method (funfirstline, canonical, saved_arg, copy, t,
+                         sym_class, file_symtab);
     } /* 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.  */
 
+  p = keep_name_info (p, 1);
+
   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
@@ -1479,15 +1609,33 @@ 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);
+  name = copy;
+
+  cleanup = make_cleanup (null_cleanup, NULL);
+  canon = cp_canonicalize_string_no_typedefs (copy);
+  if (canon != NULL)
+    {
+      name = canon;
+      make_cleanup (xfree, name);
+    }
+
+  sym = lookup_symbol (name, get_selected_block (0), VAR_DOMAIN, 0);
+  do_cleanups (cleanup);
   if (sym)
-    return symbol_found (funfirstline, canonical, copy, sym, NULL);
+    return symbol_found (funfirstline, canonical, copy, sym, NULL, NULL);
+  else
+    {
+      struct minimal_symbol *msym;
 
-  /* 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,
+      /* Couldn't find any interpretation as classes/namespaces.  As a last
+        resort, try the minimal symbol tables.  */
+      msym = lookup_minimal_symbol (copy, NULL, NULL);
+      if (msym != NULL)
+       return minsym_found (funfirstline, msym);
+    }    
+
+  /* Couldn't find a minimal symbol, either, so give up.  */
+  cplusplus_error (the_real_saved_arg,
                   "Can't find member of namespace, "
                   "class, struct, or union named \"%s\"\n",
                   copy);
@@ -1503,7 +1651,7 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
    example, say ARGPTR is "AAA::inA::fun" and P is "::inA::fun".  */
 
 static struct symbol *
-lookup_prefix_sym (char **argptr, char *p)
+lookup_prefix_sym (char **argptr, char *p, struct symtab *file_symtab)
 {
   char *p1;
   char *copy;
@@ -1526,7 +1674,7 @@ lookup_prefix_sym (char **argptr, char *p)
   /* At this point p1->"::inA::fun", p->"inA::fun" copy->"AAA",
      argptr->"inA::fun".  */
 
-  sym = lookup_symbol (copy, 0, STRUCT_DOMAIN, 0);
+  sym = lookup_symbol (copy, get_search_block (file_symtab), STRUCT_DOMAIN, 0);
   if (sym == NULL)
     {
       /* Typedefs are in VAR_DOMAIN so the above symbol lookup will
@@ -1554,9 +1702,10 @@ lookup_prefix_sym (char **argptr, char *p)
    symbol is SYM_CLASS.  */
 
 static struct symtabs_and_lines
-find_method (int funfirstline, char ***canonical, char *saved_arg,
+find_method (int funfirstline, struct linespec_result *canonical,
+            char *saved_arg,
             char *copy, struct type *t, struct symbol *sym_class,
-            int *not_found_ptr)
+            struct symtab *file_symtab)
 {
   struct symtabs_and_lines values;
   struct symbol *sym = NULL;
@@ -1567,9 +1716,13 @@ find_method (int funfirstline, char ***canonical, char *saved_arg,
   /* Find all methods with a matching name, and put them in
      sym_arr.  */
 
-  i1 = find_methods (t, copy, SYMBOL_LANGUAGE (sym_class), sym_arr);
+  i1 = find_methods (t, copy, SYMBOL_LANGUAGE (sym_class), sym_arr,
+                    file_symtab);
 
-  if (i1 == 1)
+  /* If we were given a specific overload instance in COPY, defer the field
+     acceptance till the strcmp_iw verification below, even if we found just
+     a single field with that name.  */
+  if (i1 == 1 && strchr (copy, '(') == NULL)
     {
       /* There is exactly one field with that name.  */
       sym = sym_arr[0];
@@ -1594,20 +1747,32 @@ find_method (int funfirstline, char ***canonical, char *saved_arg,
       /* If we were given a specific overload instance, use that
         (or error if no matches were found).  Otherwise ask the user
         which one to use.  */
-      if (strchr (saved_arg, '(') != NULL)
+      if (strchr (copy, '('))
        {
          int i;
-         char *name = saved_arg;
-         char *canon = cp_canonicalize_string (name);
+         char *name;
+         char *canon;
          struct cleanup *cleanup;
 
+         /* Construct the proper search name based on SYM_CLASS and COPY.
+            SAVED_ARG may contain a valid name, but that name might not be
+            what is actually stored in the symbol table.  For example,
+            if SAVED_ARG (and SYM_CLASS) were found via an import
+            ("using namespace" in C++), then the physname of
+            SYM_CLASS ("A::myclass") may not be the same as SAVED_ARG
+            ("myclass").  */
+         name = xmalloc (strlen (SYMBOL_NATURAL_NAME (sym_class))
+                         + 2 /* "::" */ + strlen (copy) + 1);
+         strcpy (name, SYMBOL_NATURAL_NAME (sym_class));
+         strcat (name, "::");
+         strcat (name, copy);
+         canon = cp_canonicalize_string_no_typedefs (name);
          if (canon != NULL)
            {
+             xfree (name);
              name = canon;
-             cleanup = make_cleanup (xfree, canon);
            }
-         else
-           cleanup = make_cleanup (null_cleanup, NULL);
+         cleanup = make_cleanup (xfree, name);
 
          for (i = 0; i < i1; ++i)
            {
@@ -1623,17 +1788,15 @@ find_method (int funfirstline, char ***canonical, char *saved_arg,
                }
            }
 
-         error (_("the class `%s' does not have "
-                  "any method instance named %s"),
-                SYMBOL_PRINT_NAME (sym_class), copy);
+         cplusplus_error (saved_arg, _("the class `%s' does not have "
+                                       "any method instance named %s"),
+                                     SYMBOL_PRINT_NAME (sym_class), copy);
        }
 
       return decode_line_2 (sym_arr, i1, funfirstline, canonical);
     }
   else
     {
-      if (not_found_ptr)
-        *not_found_ptr = 1;
       if (copy[0] == '~')
        cplusplus_error (saved_arg,
                         "the class `%s' does not have destructor defined\n",
@@ -1648,14 +1811,10 @@ find_method (int funfirstline, char ***canonical, char *saved_arg,
 \f
 
 /* Return the symtab associated to the filename given by the substring
-   of *ARGPTR ending at P, and advance ARGPTR past that filename.  If
-   NOT_FOUND_PTR is not null and the source file is not found, store
-   boolean true at the location pointed to and do not issue an
-   error message.  */
+   of *ARGPTR ending at P, and advance ARGPTR past that filename.  */
 
 static struct symtab *
-symtab_from_filename (char **argptr, char *p, int is_quote_enclosed, 
-                     int *not_found_ptr)
+symtab_from_filename (char **argptr, char *p, int is_quote_enclosed)
 {
   char *p1;
   char *copy;
@@ -1679,8 +1838,6 @@ symtab_from_filename (char **argptr, char *p, int is_quote_enclosed,
   file_symtab = lookup_symtab (copy);
   if (file_symtab == 0)
     {
-      if (not_found_ptr)
-       *not_found_ptr = 1;
       if (!have_full_symbols () && !have_partial_symbols ())
        throw_error (NOT_FOUND_ERROR,
                     _("No symbol table is loaded.  "
@@ -1689,6 +1846,8 @@ symtab_from_filename (char **argptr, char *p, int is_quote_enclosed,
     }
 
   /* Discard the file name from the arg.  */
+  if (*p1 == '\0')
+    return file_symtab;
   p = p1 + 1;
   while (*p == ' ' || *p == '\t')
     p++;
@@ -1697,6 +1856,44 @@ symtab_from_filename (char **argptr, char *p, int is_quote_enclosed,
   return file_symtab;
 }
 
+/* Look up a function symbol in *ARGPTR.  If found, advance *ARGPTR
+   and return the symbol.  If not found, return NULL.  */
+
+static struct symbol *
+find_function_symbol (char **argptr, char *p, int is_quote_enclosed)
+{
+  char *p1;
+  char *copy;
+  struct symbol *function_symbol;
+
+  p1 = p;
+  while (p != *argptr && p[-1] == ' ')
+    --p;
+  if ((*p == '"') && is_quote_enclosed)
+    --p;
+  copy = (char *) alloca (p - *argptr + 1);
+  memcpy (copy, *argptr, p - *argptr);
+  /* It may have the ending quote right after the file name.  */
+  if ((is_quote_enclosed && copy[p - *argptr - 1] == '"')
+      || copy[p - *argptr - 1] == '\'')
+    copy[p - *argptr - 1] = 0;
+  else
+    copy[p - *argptr] = 0;
+
+  function_symbol = lookup_symbol (copy, get_selected_block (0),
+                                  VAR_DOMAIN, 0);
+  if (!function_symbol || SYMBOL_CLASS (function_symbol) != LOC_BLOCK)
+    return NULL;
+
+  /* Discard the file name from the arg.  */
+  p = p1 + 1;
+  while (*p == ' ' || *p == '\t')
+    p++;
+  *argptr = p;
+
+  return function_symbol;
+}
+
 \f
 
 /* This decodes a line where the argument is all digits (possibly
@@ -1705,7 +1902,7 @@ symtab_from_filename (char **argptr, char *p, int is_quote_enclosed,
 
 static struct symtabs_and_lines
 decode_all_digits (char **argptr, struct symtab *default_symtab,
-                  int default_line, char ***canonical,
+                  int default_line, struct linespec_result *canonical,
                   struct symtab *file_symtab, char *q)
 
 {
@@ -1794,7 +1991,7 @@ decode_all_digits (char **argptr, struct symtab *default_symtab,
 
 static struct symtabs_and_lines
 decode_dollar (char *copy, int funfirstline, struct symtab *default_symtab,
-              char ***canonical, struct symtab *file_symtab)
+              struct linespec_result *canonical, struct symtab *file_symtab)
 {
   LONGEST valx;
   int index = 0;
@@ -1831,7 +2028,7 @@ decode_dollar (char *copy, int funfirstline, struct symtab *default_symtab,
       need_canonical = 1;
       /* Symbol was found --> jump to normal symbol processing.  */
       if (sym)
-       return symbol_found (funfirstline, canonical, copy, sym, NULL);
+       return symbol_found (funfirstline, canonical, copy, sym, NULL, NULL);
 
       /* If symbol was not found, look in minimal symbol tables.  */
       msymbol = lookup_minimal_symbol (copy, NULL, NULL);
@@ -1867,6 +2064,8 @@ decode_dollar (char *copy, int funfirstline, struct symtab *default_symtab,
 
 /* A helper for decode_line_1 that tries to find a label.  The label
    is searched for in the current block.
+   FUNCTION_SYMBOL is the enclosing function; or NULL if none
+   specified.
    COPY is the name of the label to find.
    CANONICAL is the same as the "canonical" argument to decode_line_1.
    RESULT is a pointer to a symtabs_and_lines structure which will be
@@ -1874,48 +2073,72 @@ decode_dollar (char *copy, int funfirstline, struct symtab *default_symtab,
    This function returns 1 if a label was found, 0 otherwise.  */
 
 static int
-decode_label (char *copy, char ***canonical, struct symtabs_and_lines *result)
+decode_label (struct symbol *function_symbol, char *copy,
+             struct linespec_result *canonical,
+             struct symtabs_and_lines *result)
 {
   struct symbol *sym;
+  struct block *block;
+
+  if (function_symbol)
+    block = SYMBOL_BLOCK_VALUE (function_symbol);
+  else
+    {
+      block = get_selected_block (0);
+      for (;
+          block && !BLOCK_FUNCTION (block);
+          block = BLOCK_SUPERBLOCK (block))
+       ;
+      if (!block)
+       return 0;
+      function_symbol = BLOCK_FUNCTION (block);
+    }
 
-  sym = lookup_symbol (copy, get_selected_block (0), LABEL_DOMAIN, 0);
+  sym = lookup_symbol (copy, block, LABEL_DOMAIN, 0);
 
   if (sym != NULL)
-    *result = symbol_found (0, canonical, copy, sym, NULL);
+    *result = symbol_found (0, canonical, copy, sym, NULL, function_symbol);
 
   return sym != NULL;
 }
 
 /* Decode a linespec that's a variable.  If FILE_SYMTAB is non-NULL,
-   look in that symtab's static variables first.  If NOT_FOUND_PTR is
-   not NULL and the function cannot be found, store boolean true in
-   the location pointed to and do not issue an error message.  */ 
+   look in that symtab's static variables first.  */ 
 
 static struct symtabs_and_lines
-decode_variable (char *copy, int funfirstline, char ***canonical,
-                struct symtab *file_symtab, int *not_found_ptr)
+decode_variable (char *copy, int funfirstline,
+                struct linespec_result *canonical,
+                struct symtab *file_symtab)
 {
+  char *name, *canon;
   struct symbol *sym;
+  struct cleanup *cleanup;
   struct minimal_symbol *msymbol;
 
-  sym = lookup_symbol (copy,
-                      (file_symtab
-                       ? BLOCKVECTOR_BLOCK (BLOCKVECTOR (file_symtab),
-                                            STATIC_BLOCK)
-                       : get_selected_block (0)),
-                      VAR_DOMAIN, 0);
+  name = copy;
+  cleanup = make_cleanup (null_cleanup, NULL);
+  canon = cp_canonicalize_string_no_typedefs (copy);
+  if (canon != NULL)
+    {
+      name = canon;
+      make_cleanup (xfree, name);
+    }
+
+  sym = lookup_symbol (name, get_search_block (file_symtab), VAR_DOMAIN, 0);
 
   if (sym != NULL)
-    return symbol_found (funfirstline, canonical, copy, sym, file_symtab);
+    {
+      do_cleanups (cleanup);
+      return symbol_found (funfirstline, canonical, copy, sym,
+                          file_symtab, NULL);
+    }
 
-  msymbol = lookup_minimal_symbol (copy, NULL, NULL);
+  msymbol = lookup_minimal_symbol (name, NULL, NULL);
+  do_cleanups (cleanup);
 
   if (msymbol != NULL)
     return minsym_found (funfirstline, msymbol);
 
-  if (not_found_ptr)
-    *not_found_ptr = 1;
-
   if (!have_full_symbols ()
       && !have_partial_symbols ()
       && !have_minimal_symbols ())
@@ -1934,8 +2157,9 @@ decode_variable (char *copy, int funfirstline, char ***canonical,
    corresponding struct symtabs_and_lines.  */
 
 static struct symtabs_and_lines
-symbol_found (int funfirstline, char ***canonical, char *copy,
-             struct symbol *sym, struct symtab *file_symtab)
+symbol_found (int funfirstline, struct linespec_result *canonical, char *copy,
+             struct symbol *sym, struct symtab *file_symtab,
+             struct symbol *function_symbol)
 {
   struct symtabs_and_lines values;
   
@@ -1965,8 +2189,38 @@ symbol_found (int funfirstline, char ***canonical, char *copy,
     }
   else
     {
-      if (funfirstline && SYMBOL_CLASS (sym) != LOC_LABEL)
-       error (_("\"%s\" is not a function"), copy);
+      if (SYMBOL_CLASS (sym) == LOC_LABEL && SYMBOL_VALUE_ADDRESS (sym) != 0)
+       {
+         /* We know its line number.  */
+         values.sals = (struct symtab_and_line *)
+           xmalloc (sizeof (struct symtab_and_line));
+         values.nelts = 1;
+         init_sal (&values.sals[0]);
+         values.sals[0].symtab = SYMBOL_SYMTAB (sym);
+         values.sals[0].line = SYMBOL_LINE (sym);
+         values.sals[0].pc = SYMBOL_VALUE_ADDRESS (sym);
+         values.sals[0].pspace = SYMTAB_PSPACE (SYMBOL_SYMTAB (sym));
+         values.sals[0].explicit_pc = 1;
+
+         if (canonical)
+           {
+             canonical->special_display = 1;
+             canonical->canonical = xmalloc (sizeof (char *));
+             canonical->canonical[0]
+               = xstrprintf ("%s:%s",
+                             SYMBOL_NATURAL_NAME (function_symbol),
+                             SYMBOL_NATURAL_NAME (sym));
+           }
+
+         return values;
+       }
+      else if (funfirstline)
+       {
+         /* NOT_FOUND_ERROR is not correct but it ensures COPY will be
+            searched also as a minimal symbol.  */
+
+         throw_error (NOT_FOUND_ERROR, _("\"%s\" is not a function"), copy);
+       }
       else if (SYMBOL_LINE (sym) != 0)
        {
          /* We know its line number.  */
@@ -2020,3 +2274,9 @@ minsym_found (int funfirstline, struct minimal_symbol *msymbol)
   values.nelts = 1;
   return values;
 }
+
+void
+init_linespec_result (struct linespec_result *lr)
+{
+  memset (lr, 0, sizeof (*lr));
+}
This page took 0.038668 seconds and 4 git commands to generate.