2002-10-24 Elena Zannoni <ezannoni@redhat.com>
[deliverable/binutils-gdb.git] / gdb / linespec.c
index 35f225cf2da0062ebf0bff1246eb7cdd5c0b78c1..94f3b731c0e18b4ad1e326990c3f052167e6d4df 100644 (file)
 #include "command.h"
 #include "symfile.h"
 #include "objfiles.h"
+#include "source.h"
 #include "demangle.h"
 #include "value.h"
 #include "completer.h"
-
-/* Prototype for one function in parser-defs.h,
-   instead of including that entire file. */
-
-extern char *find_template_name_end (char *);
+#include "cp-abi.h"
+#include "parser-defs.h"
 
 /* We share this one with symtab.c, but it is not exported widely. */
 
@@ -41,7 +39,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);
 
@@ -57,17 +55,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
@@ -115,6 +127,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);
 
@@ -166,7 +179,7 @@ find_methods (struct type *t, char *name, struct symbol **sym_arr)
                  phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter);
                
                /* Destructor is handled by caller, dont add it to the list */
-               if (DESTRUCTOR_PREFIX_P (phys_name))
+               if (is_destructor_name (phys_name) != 0)
                  continue;
 
                sym_arr[i1] = lookup_symbol (phys_name,
@@ -187,6 +200,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++;
+               }
+           }
        }
     }
 
@@ -250,7 +298,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)
 {
@@ -273,9 +323,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--;
     }
 
@@ -317,8 +367,8 @@ decode_line_2 (struct symbol *sym_arr[], int nelts, int funfirstline,
   printf_unfiltered ("[0] cancel\n[1] all\n");
   while (i < nelts)
     {
-      INIT_SAL (&return_values.sals[i]);       /* initialize to zeroes */
-      INIT_SAL (&values.sals[i]);
+      init_sal (&return_values.sals[i]);       /* initialize to zeroes */
+      init_sal (&values.sals[i]);
       if (sym_arr[i] && SYMBOL_CLASS (sym_arr[i]) == LOC_BLOCK)
        {
          values.sals[i] = find_function_start_sal (sym_arr[i], funfirstline);
@@ -486,14 +536,20 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
   char *saved_arg = *argptr;
   extern char *gdb_completer_quote_characters;
 
-  INIT_SAL (&val);             /* initialize to zeroes */
+  init_sal (&val);             /* initialize to zeroes */
 
   /* Defaults have defaults.  */
 
   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 */
@@ -721,10 +777,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);
@@ -801,7 +854,7 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
                    {
                      char *tmp;
 
-                     if (OPNAME_PREFIX_P (copy))
+                     if (is_operator_name (copy))
                        {
                          tmp = (char *) alloca (strlen (copy + 3) + 9);
                          strcpy (tmp, "operator ");
@@ -809,17 +862,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);
                    }
                }
 
@@ -872,12 +922,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++  */
 
@@ -889,20 +937,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);
@@ -983,13 +1023,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 == '+')
@@ -1081,7 +1127,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;
 
@@ -1114,7 +1160,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;
@@ -1147,7 +1193,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 
@@ -1173,7 +1219,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.032161 seconds and 4 git commands to generate.