* MAINTAINERS: Move Jim Blandy to past maintainers.
[deliverable/binutils-gdb.git] / gdb / linespec.c
index 6c0e7eded829878bc3df9b317287facd6a85a8e6..871d37d95364e52bc46bb338530cadbcf6681e51 100644 (file)
@@ -67,8 +67,7 @@ static struct symtabs_and_lines decode_compound (char **argptr,
                                                 int funfirstline,
                                                 struct linespec_result *canonical,
                                                 char *saved_arg,
-                                                char *p,
-                                                int *not_found_ptr);
+                                                char *p);
 
 static struct symbol *lookup_prefix_sym (char **argptr, char *p);
 
@@ -77,8 +76,7 @@ static struct symtabs_and_lines find_method (int funfirstline,
                                             char *saved_arg,
                                             char *copy,
                                             struct type *t,
-                                            struct symbol *sym_class,
-                                            int *not_found_ptr);
+                                            struct symbol *sym_class);
 
 static void cplusplus_error (const char *name, const char *fmt, ...)
      ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (2, 3);
@@ -108,8 +106,10 @@ static struct symtabs_and_lines decode_line_2 (struct symbol *[],
                                               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,
@@ -125,21 +125,22 @@ static struct symtabs_and_lines decode_dollar (char *copy,
                                               struct linespec_result *canonical,
                                               struct symtab *file_symtab);
 
-static int decode_label (char *copy, struct linespec_result *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,
                                                 struct linespec_result *canonical,
-                                                struct symtab *file_symtab,
-                                                int *not_found_ptr);
+                                                struct symtab *file_symtab);
 
 static struct
 symtabs_and_lines symbol_found (int funfirstline,
                                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,
@@ -311,20 +312,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);
@@ -372,7 +374,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);
 
@@ -778,12 +780,7 @@ keep_name_info (char *ptr)
 
    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
@@ -792,8 +789,7 @@ keep_name_info (char *ptr)
 
 struct symtabs_and_lines
 decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
-              int default_line, struct linespec_result *canonical,
-              int *not_found_ptr)
+              int default_line, struct linespec_result *canonical)
 {
   char *p;
   char *q;
@@ -813,8 +809,12 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
   /* 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.  */
 
@@ -876,7 +876,7 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
          if (is_quote_enclosed)
            ++saved_arg;
          values = decode_compound (argptr, funfirstline, canonical,
-                                   saved_arg, p, not_found_ptr);
+                                   saved_arg, p);
          if (is_quoted && **argptr == '\'')
            *argptr = *argptr + 1;
          return values;
@@ -885,8 +885,19 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
       /* 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,
-                                         not_found_ptr);
+      TRY_CATCH (file_exception, RETURN_MASK_ERROR)
+       {
+         file_symtab = symtab_from_filename (argptr, p, is_quote_enclosed);
+       }
+      /* If that failed, maybe we have `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)
@@ -900,6 +911,8 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
     }
 
   /* 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.  */
@@ -921,7 +934,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);
@@ -972,7 +986,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);
 
@@ -982,15 +996,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
@@ -1297,7 +1313,7 @@ decode_objc (char **argptr, int funfirstline, struct symtab *file_symtab,
 static struct symtabs_and_lines
 decode_compound (char **argptr, int funfirstline,
                 struct linespec_result *canonical,
-                char *the_real_saved_arg, char *p, int *not_found_ptr)
+                char *the_real_saved_arg, char *p)
 {
   struct symtabs_and_lines values;
   char *p2;
@@ -1532,7 +1548,7 @@ decode_compound (char **argptr, int funfirstline,
         we'll lookup the whole string in the symbol tables.  */
 
       values = find_method (funfirstline, canonical, saved_arg,
-                           copy, t, sym_class, not_found_ptr);
+                           copy, t, sym_class);
       if (saved_java_argptr != NULL && values.nelts == 1)
        {
          /* The user specified a specific return type for a java method.
@@ -1573,7 +1589,7 @@ decode_compound (char **argptr, int funfirstline,
   /* Look up entire name.  */
   sym = lookup_symbol (copy, get_selected_block (0), VAR_DOMAIN, 0);
   if (sym)
-    return symbol_found (funfirstline, canonical, copy, sym, NULL);
+    return symbol_found (funfirstline, canonical, copy, sym, NULL, NULL);
   else
     {
       struct minimal_symbol *msym;
@@ -1586,8 +1602,6 @@ decode_compound (char **argptr, int funfirstline,
     }    
 
   /* Couldn't find a minimal symbol, either, so give up.  */
-  if (not_found_ptr)
-    *not_found_ptr = 1;
   cplusplus_error (the_real_saved_arg,
                   "Can't find member of namespace, "
                   "class, struct, or union named \"%s\"\n",
@@ -1657,8 +1671,7 @@ lookup_prefix_sym (char **argptr, char *p)
 static struct symtabs_and_lines
 find_method (int funfirstline, struct linespec_result *canonical,
             char *saved_arg,
-            char *copy, struct type *t, struct symbol *sym_class,
-            int *not_found_ptr)
+            char *copy, struct type *t, struct symbol *sym_class)
 {
   struct symtabs_and_lines values;
   struct symbol *sym = NULL;
@@ -1746,8 +1759,6 @@ find_method (int funfirstline, struct linespec_result *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",
@@ -1762,14 +1773,10 @@ find_method (int funfirstline, struct linespec_result *canonical,
 \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;
@@ -1793,8 +1800,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.  "
@@ -1811,6 +1816,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
@@ -1945,7 +1988,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);
@@ -1981,6 +2024,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
@@ -1988,28 +2033,42 @@ 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, struct linespec_result *canonical,
+decode_label (struct symbol *function_symbol, char *copy,
+             struct linespec_result *canonical,
              struct symtabs_and_lines *result)
 {
   struct symbol *sym;
+  struct block *block;
 
-  sym = lookup_symbol (copy, get_selected_block (0), LABEL_DOMAIN, 0);
+  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, 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,
                 struct linespec_result *canonical,
-                struct symtab *file_symtab, int *not_found_ptr)
+                struct symtab *file_symtab)
 {
   struct symbol *sym;
   struct minimal_symbol *msymbol;
@@ -2022,16 +2081,13 @@ decode_variable (char *copy, int funfirstline,
                       VAR_DOMAIN, 0);
 
   if (sym != NULL)
-    return symbol_found (funfirstline, canonical, copy, sym, file_symtab);
+    return symbol_found (funfirstline, canonical, copy, sym, file_symtab, NULL);
 
   msymbol = lookup_minimal_symbol (copy, NULL, NULL);
 
   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 ())
@@ -2051,7 +2107,8 @@ decode_variable (char *copy, int funfirstline,
 
 static struct symtabs_and_lines
 symbol_found (int funfirstline, struct linespec_result *canonical, char *copy,
-             struct symbol *sym, struct symtab *file_symtab)
+             struct symbol *sym, struct symtab *file_symtab,
+             struct symbol *function_symbol)
 {
   struct symtabs_and_lines values;
   
@@ -2081,7 +2138,32 @@ symbol_found (int funfirstline, struct linespec_result *canonical, char *copy,
     }
   else
     {
-      if (funfirstline && SYMBOL_CLASS (sym) != LOC_LABEL)
+      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)
        error (_("\"%s\" is not a function"), copy);
       else if (SYMBOL_LINE (sym) != 0)
        {
This page took 0.030389 seconds and 4 git commands to generate.