2002-09-25 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gdb / linespec.c
index e23479035d3ce1bee619525e0ab3a289615a5938..5631fd31433a6a82c850da184a1bdd98edbfd60f 100644 (file)
@@ -26,6 +26,7 @@
 #include "command.h"
 #include "symfile.h"
 #include "objfiles.h"
+#include "source.h"
 #include "demangle.h"
 #include "value.h"
 #include "completer.h"
@@ -42,7 +43,7 @@ extern char *operator_chars (char *, char **);
 
 /* Prototypes for local functions */
 
-static void cplusplus_hint (char *name);
+static void cplusplus_error (const char *name, const char *fmt, ...) ATTR_FORMAT (printf, 2, 3);
 
 static int total_number_of_methods (struct type *type);
 
@@ -58,17 +59,31 @@ static struct symtabs_and_lines decode_line_2 (struct symbol *[],
 
 /* Helper functions. */
 
-/* While the C++ support is still in flux, issue a possibly helpful hint on
-   using the new command completion feature on single quoted demangled C++
-   symbols.  Remove when loose ends are cleaned up.   FIXME -fnf */
+/* Issue a helpful hint on using the command completion feature on
+   single quoted demangled C++ symbols as part of the completion
+   error.  */
 
 static void
-cplusplus_hint (char *name)
+cplusplus_error (const char *name, const char *fmt, ...)
 {
+  struct ui_file *tmp_stream;
+  tmp_stream = mem_fileopen ();
+  make_cleanup_ui_file_delete (tmp_stream);
+
+  {
+    va_list args;
+    va_start (args, fmt);
+    vfprintf_unfiltered (tmp_stream, fmt, args);
+    va_end (args);
+  }
+
   while (*name == '\'')
     name++;
-  printf_filtered ("Hint: try '%s<TAB> or '%s<ESC-?>\n", name, name);
-  printf_filtered ("(Note leading single quote.)\n");
+  fprintf_unfiltered (tmp_stream,
+                     ("Hint: try '%s<TAB> or '%s<ESC-?>\n"
+                      "(Note leading single quote.)"),
+                     name, name);
+  error_stream (tmp_stream);
 }
 
 /* Return the number of methods described for TYPE, including the
@@ -116,6 +131,7 @@ find_methods (struct type *t, char *name, struct symbol **sym_arr)
                         (struct symtab **) NULL)))
     {
       int method_counter;
+      int name_len = strlen (name);
 
       CHECK_TYPEDEF (t);
 
@@ -188,6 +204,41 @@ find_methods (struct type *t, char *name, struct symbol **sym_arr)
                     */
                  }
              }
+         else if (strncmp (class_name, name, name_len) == 0
+                  && (class_name[name_len] == '\0'
+                      || class_name[name_len] == '<'))
+           {
+             /* For GCC 3.x and stabs, constructors and destructors have names
+                like __base_ctor and __complete_dtor.  Check the physname for now
+                if we're looking for a constructor.  */
+             for (field_counter
+                    = TYPE_FN_FIELDLIST_LENGTH (t, method_counter) - 1;
+                  field_counter >= 0;
+                  --field_counter)
+               {
+                 struct fn_field *f;
+                 char *phys_name;
+                 
+                 f = TYPE_FN_FIELDLIST1 (t, method_counter);
+
+                 /* GCC 3.x will never produce stabs stub methods, so we don't need
+                    to handle this case.  */
+                 if (TYPE_FN_FIELD_STUB (f, field_counter))
+                   continue;
+                 phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter);
+                 if (! is_constructor_name (phys_name))
+                   continue;
+
+                 /* If this method is actually defined, include it in the
+                    list.  */
+                 sym_arr[i1] = lookup_symbol (phys_name,
+                                              NULL, VAR_NAMESPACE,
+                                              (int *) NULL,
+                                              (struct symtab **) NULL);
+                 if (sym_arr[i1])
+                   i1++;
+               }
+           }
        }
     }
 
@@ -251,7 +302,9 @@ build_canonical_line_spec (struct symtab_and_line *sal, char *symname,
 
 /* Find an instance of the character C in the string S that is outside
    of all parenthesis pairs, single-quoted strings, and double-quoted
-   strings.  */
+   strings.  Also, ignore the char within a template name, like a ','
+   within foo<int, int>.  */
+
 static char *
 find_toplevel_char (char *s, char c)
 {
@@ -274,9 +327,9 @@ find_toplevel_char (char *s, char c)
        return scan;
       else if (*scan == '"' || *scan == '\'')
        quoted = *scan;
-      else if (*scan == '(')
+      else if (*scan == '(' || *scan == '<')
        depth++;
-      else if (*scan == ')' && depth > 0)
+      else if ((*scan == ')' || *scan == '>') && depth > 0)
        depth--;
     }
 
@@ -493,8 +546,14 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
 
   if (default_symtab == 0)
     {
-      default_symtab = current_source_symtab;
-      default_line = current_source_line;
+      /* Use whatever we have for the default source line.  We don't use
+         get_current_or_default_symtab_and_line as it can recurse and call
+        us back! */
+      struct symtab_and_line cursal = 
+                       get_current_source_symtab_and_line ();
+      
+      default_symtab = cursal.symtab;
+      default_line = cursal.line;
     }
 
   /* See if arg is *PC */
@@ -722,10 +781,7 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
    opname = cplus_mangle_opname (tmp, DMGL_ANSI);
    if (opname == NULL)
    {
-   error_begin ();
-   printf_filtered ("no mangling for \"%s\"\n", tmp);
-   cplusplus_hint (saved_arg);
-   return_to_top_level (RETURN_ERROR);
+   cplusplus_error (saved_arg, "no mangling for \"%s\"\n", tmp);
    }
    copy = (char*) alloca (3 + strlen(opname));
    sprintf (copy, "__%s", opname);
@@ -810,17 +866,14 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
                        }
                      else
                        tmp = copy;
-                     error_begin ();
                      if (tmp[0] == '~')
-                       printf_filtered
-                         ("the class `%s' does not have destructor defined\n",
-                          SYMBOL_SOURCE_NAME (sym_class));
+                       cplusplus_error (saved_arg,
+                                        "the class `%s' does not have destructor defined\n",
+                                        SYMBOL_SOURCE_NAME (sym_class));
                      else
-                       printf_filtered
-                         ("the class %s does not have any method named %s\n",
-                          SYMBOL_SOURCE_NAME (sym_class), tmp);
-                     cplusplus_hint (saved_arg);
-                     return_to_top_level (RETURN_ERROR);
+                       cplusplus_error (saved_arg,
+                                        "the class %s does not have any method named %s\n",
+                                        SYMBOL_SOURCE_NAME (sym_class), tmp);
                    }
                }
 
@@ -873,12 +926,10 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
            goto symbol_found;
 
          /* Couldn't find any interpretation as classes/namespaces, so give up */
-         error_begin ();
          /* The quotes are important if copy is empty.  */
-         printf_filtered
-           ("Can't find member of namespace, class, struct, or union named \"%s\"\n", copy);
-         cplusplus_hint (saved_arg);
-         return_to_top_level (RETURN_ERROR);
+         cplusplus_error (saved_arg,
+                          "Can't find member of namespace, class, struct, or union named \"%s\"\n",
+                          copy);
        }
       /*  end of C++  */
 
@@ -890,20 +941,12 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
       if ((*p == '"') && is_quote_enclosed)
        --p;
       copy = (char *) alloca (p - *argptr + 1);
-      if ((**argptr == '"') && is_quote_enclosed)
-       {
-         memcpy (copy, *argptr + 1, p - *argptr - 1);
-         /* It may have the ending quote right after the file name */
-         if (copy[p - *argptr - 2] == '"')
-           copy[p - *argptr - 2] = 0;
-         else
-           copy[p - *argptr - 1] = 0;
-       }
+      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] = 0;
       else
-       {
-         memcpy (copy, *argptr, p - *argptr);
-         copy[p - *argptr] = 0;
-       }
+       copy[p - *argptr] = 0;
 
       /* Find that file's data.  */
       s = lookup_symtab (copy);
@@ -984,13 +1027,19 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
       /* This is where we need to make sure that we have good defaults.
          We must guarantee that this section of code is never executed
          when we are called with just a function name, since
-         select_source_symtab calls us with such an argument  */
+        set_default_source_symtab_and_line uses
+         select_source_symtab that calls us with such an argument  */
 
       if (s == 0 && default_symtab == 0)
        {
-         select_source_symtab (0);
-         default_symtab = current_source_symtab;
-         default_line = current_source_line;
+          struct symtab_and_line cursal;
+
+         /* Make sure we have at least a default source file. */
+         set_default_source_symtab_and_line ();
+          cursal = get_current_source_symtab_and_line ();
+      
+          default_symtab = cursal.symtab;
+          default_line = cursal.line;
        }
 
       if (**argptr == '+')
@@ -1082,7 +1131,7 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
 
   if (*copy == '$')
     {
-      value_ptr valx;
+      struct value *valx;
       int index = 0;
       int need_canonical = 0;
 
@@ -1115,7 +1164,7 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
            goto symbol_found;
 
          /* If symbol was not found, look in minimal symbol tables */
-         msymbol = lookup_minimal_symbol (copy, 0, 0);
+         msymbol = lookup_minimal_symbol (copy, NULL, NULL);
          /* Min symbol was found --> jump to minsym processing. */
          if (msymbol)
            goto minimal_symbol_found;
@@ -1148,7 +1197,7 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
 
   sym = lookup_symbol (copy,
                       (s ? BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK)
-                       : get_selected_block ()),
+                       : get_selected_block (0)),
                       VAR_NAMESPACE, 0, &sym_symtab);
 
 symbol_found:                  /* We also jump here from inside the C++ class/namespace 
@@ -1174,7 +1223,7 @@ symbol_found:                     /* We also jump here from inside the C++ class/namespace
            {
              struct blockvector *bv = BLOCKVECTOR (sym_symtab);
              struct block *b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
-             if (lookup_block_symbol (b, copy, VAR_NAMESPACE) != NULL)
+             if (lookup_block_symbol (b, copy, NULL, VAR_NAMESPACE) != NULL)
                build_canonical_line_spec (values.sals, copy, canonical);
            }
          return values;
This page took 0.02745 seconds and 4 git commands to generate.