* config/tc-mips.c (macro_build_jalr): Reverse a negative
[deliverable/binutils-gdb.git] / gdb / linespec.c
index 534560b85f3210bd05098de4d3e175624cf5add9..64ba8377d7ade61022e76b631966149cc168d75b 100644 (file)
 #include "arch-utils.h"
 #include <ctype.h>
 #include "cli/cli-utils.h"
-
-/* We share this one with symtab.c, but it is not exported widely.  */
-
-extern char *operator_chars (char *, char **);
+#include "filenames.h"
 
 /* Prototypes for local functions.  */
 
@@ -249,7 +246,7 @@ find_methods (struct type *t, char *name, enum language language,
 
   /* NAME is typed by the user: it needs to be canonicalized before
      passing to lookup_symbol.  */
-  canon = cp_canonicalize_string (name);
+  canon = cp_canonicalize_string_no_typedefs (name);
   if (canon != NULL)
     {
       name = canon;
@@ -679,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 *)".
@@ -710,70 +715,55 @@ find_method_overload_end (char *p)
   return p;
 }
 
-/* Does P point to a sequence of characters which implies the end
-   of a name?  Terminals include "if" and "thread" clauses. */
-
-static int
-name_end (char *p)
-{
-  while (isspace (*p))
-    ++p;
-  if (*p == 'i' && p[1] == 'f'
-      && (isspace (p[2]) || p[2] == '\0' || p[2] == '('))
-    return 1;
-
-  if (strncmp (p, "thread", 6) == 0
-      && (isspace (p[6]) || p[6] == '\0'))
-    return 1;
-
-  return 0;
-}
-
 /* Keep important information used when looking up a name.  This includes
-   template parameters, overload information, and important keywords.  */
+   template parameters, overload information, and important keywords, including
+   the possible Java trailing type.  */
 
 static char *
-keep_name_info (char *ptr)
+keep_name_info (char *p, int on_boundary)
 {
-  char *p = ptr;
-  char *start = ptr;
+  const char *quotes = get_gdb_completer_quote_characters ();
+  char *saved_p = p;
+  int nest = 0;
 
-  /* Keep any template parameters.  */
-  if (name_end (ptr))
-    return remove_trailing_whitespace (start, ptr);
+  while (*p)
+    {
+      if (strchr (quotes, *p))
+       break;
 
-  p = skip_spaces (p);
-  if (*p == '<')
-    ptr = p = find_template_name_end (ptr);
+      if (*p == ',' && !nest)
+       break;
 
-  if (name_end (ptr))
-    return remove_trailing_whitespace (start, ptr);
+      if (on_boundary && !nest)
+       {
+         const char *const words[] = { "if", "thread", "task" };
+         int wordi;
 
-  /* Keep method overload information.  */
-  if (*p == '(')
-    ptr = p = find_method_overload_end (p);
+         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 (name_end (ptr))
-    return remove_trailing_whitespace (start, ptr);
+      if (*p == '(' || *p == '<' || *p == '[')
+       nest++;
+      else if ((*p == ')' || *p == '>' || *p == ']') && nest > 0)
+       nest--;
 
-  /* Keep important keywords.  */  
-  while (1)
-    {
-      char *quotes = get_gdb_completer_quote_characters ();
-      p = skip_spaces (p);
-      if (strncmp (p, "const", 5) == 0
-         && (isspace (p[5]) || p[5] == '\0'
-             || strchr (quotes, p[5]) != NULL))
-       ptr = p = p + 5;
-      else if (strncmp (p, "volatile", 8) == 0
-              && (isspace (p[8]) || p[8] == '\0'
-                  || strchr (quotes, p[8]) != NULL))
-       ptr = p = p + 8;
-      else
-       break;
+      p++;
+
+      /* The ',' check could fail on "operator ,".  */
+      p += cp_validate_operator (p);
+
+      on_boundary = is_linespec_boundary (p[-1]);
     }
 
-  return remove_trailing_whitespace (start, ptr);
+  while (p > saved_p && is_linespec_boundary (p[-1]))
+    p--;
+
+  return p;
 }
 
 \f
@@ -835,7 +825,7 @@ 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;
@@ -939,6 +929,9 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
          if (is_quote_enclosed)
            ++saved_arg;
 
+         /* 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,
@@ -1034,7 +1027,7 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
     }
 
   /* Keep any important naming information.  */
-  p = keep_name_info (p);
+  p = keep_name_info (p, p == saved_arg || is_linespec_boundary (p[-1]));
 
   copy = (char *) alloca (p - *argptr + 1);
   memcpy (copy, *argptr, p - *argptr);
@@ -1202,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] == '<')
@@ -1373,15 +1376,15 @@ decode_compound (char **argptr, int funfirstline,
                 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.  */
@@ -1558,31 +1561,7 @@ decode_compound (char **argptr, int funfirstline,
            }
 
          /* Keep any important naming information.  */
-         p = keep_name_info (p);
-
-         /* 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;
-               }
-           }
+         p = keep_name_info (p, 1);
        }
 
       /* Allocate our own copy of the substring between argptr and
@@ -1611,34 +1590,15 @@ decode_compound (char **argptr, int funfirstline,
         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, file_symtab);
-      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);
+  p = keep_name_info (p, 1);
 
   copy = (char *) alloca (p - saved_arg2 + 1);
   memcpy (copy, saved_arg2, p - saved_arg2);
@@ -1649,7 +1609,18 @@ decode_compound (char **argptr, int funfirstline,
   *argptr = (*p == '\'') ? p + 1 : p;
 
   /* Look up entire name.  */
-  sym = lookup_symbol (copy, 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_selected_block (0), VAR_DOMAIN, 0);
+  do_cleanups (cleanup);
   if (sym)
     return symbol_found (funfirstline, canonical, copy, sym, NULL, NULL);
   else
@@ -1748,7 +1719,10 @@ find_method (int funfirstline, struct linespec_result *canonical,
   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];
@@ -1792,7 +1766,7 @@ find_method (int funfirstline, struct linespec_result *canonical,
          strcpy (name, SYMBOL_NATURAL_NAME (sym_class));
          strcat (name, "::");
          strcat (name, copy);
-         canon = cp_canonicalize_string (name);
+         canon = cp_canonicalize_string_no_typedefs (name);
          if (canon != NULL)
            {
              xfree (name);
@@ -1872,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++;
@@ -2134,16 +2110,31 @@ 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, get_search_block (file_symtab),
-                      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, NULL);
+    {
+      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);
This page took 0.028619 seconds and 4 git commands to generate.