COFF changes for dealing better with EPI 29K C compiler output.
authorJohn Gilmore <gnu@cygnus>
Sun, 21 Jun 1992 02:20:30 +0000 (02:20 +0000)
committerJohn Gilmore <gnu@cygnus>
Sun, 21 Jun 1992 02:20:30 +0000 (02:20 +0000)
* coffread.c (record_minimal_symbol):  Pass the minsym type to it.
Callers changed.
(coff_end_symtab):  Sort blocks if needed.  Complain if misordered.
(read_coff_symtab):  Move patch_opaque_types call from
coff_symfile_read.  Restrict it to symtabs from this objfile.
(process_coff_symbol: C_TPDEF):  Don't put ordinary foward
references on opaque type chain; just let coff_lookup_type handle 'em.
(decode_type):  Complain about tagndx values on
non-struct/union/enum types, which the EPI compiler tends to produce.

* symtab.c (list_symbols):  Make minimal symbol variable-finding work.

* tm-68k.h (FIX_CALL_DUMMY): Avoid alignment and byte order
dependency.

* elfread.c (elf_symfile_read):  Update bfd_elf_find_section
usage to match new prototype.  Include libbfd.h to get prototype.

gdb/ChangeLog
gdb/coffread.c
gdb/elfread.c
gdb/symtab.c
gdb/tm-68k.h

index 338af7d..88723e1 100644 (file)
@@ -1,3 +1,25 @@
+Sat Jun 20 19:19:52 1992  John Gilmore  (gnu at cygnus.com)
+
+       COFF changes for dealing better with EPI 29K C compiler output.
+
+       * coffread.c (record_minimal_symbol):  Pass the minsym type to it.
+       Callers changed.
+       (coff_end_symtab):  Sort blocks if needed.  Complain if misordered.
+       (read_coff_symtab):  Move patch_opaque_types call from
+       coff_symfile_read.  Restrict it to symtabs from this objfile.
+       (process_coff_symbol: C_TPDEF):  Don't put ordinary foward
+       references on opaque type chain; just let coff_lookup_type handle 'em.
+       (decode_type):  Complain about tagndx values on
+       non-struct/union/enum types, which the EPI compiler tends to produce.
+
+       * symtab.c (list_symbols):  Make minimal symbol variable-finding work.
+
+       * tm-68k.h (FIX_CALL_DUMMY): Avoid alignment and byte order
+       dependency.
+
+       * elfread.c (elf_symfile_read):  Update bfd_elf_find_section
+       usage to match new prototype.  Include libbfd.h to get prototype.
+
 Sat Jun 20 16:28:39 1992  Fred Fish  (fnf@cygnus.com)
 
        * infcmd.c (jump_command):  Use cleanups to avoid memory leaks.
@@ -10,9 +32,6 @@ Fri Jun 19 19:06:41 1992  John Gilmore  (gnu at cygnus.com)
 
        * tm-29k.h (SDB_REG_TO_REGNUM):  Add for EPI 29K C compiler.
 
-       * elfread.c (elf_symfile_read):  Update bfd_elf_find_section
-       usage to match new prototype.  Include libbfd.h to get prototype.
-
 Fri Jun 19 15:30:15 1992  Stu Grossman  (grossman at cygnus.com)
 
        * configure.in, dbxread.c, hppa-coredep.c, hppa-pinsn.c,
index f61d806..ee9b9e8 100644 (file)
@@ -183,6 +183,12 @@ struct complaint unexpected_type_complaint =
 struct complaint bad_sclass_complaint =
   {"Bad n_sclass for symbol %s", 0, 0};
 
+struct complaint misordered_blocks_complaint =
+  {"Blocks out of order at address %x", 0, 0};
+
+struct complaint tagndx_bad_complaint =
+  {"Symbol table entry for %s has bad tagndx value", 0, 0};
+
 /* Simplified internal version of coff symbol table information */
 
 struct coff_symbol {
@@ -220,8 +226,8 @@ static struct symbol *
 process_coff_symbol PARAMS ((struct coff_symbol *, union internal_auxent *,
                             struct objfile *));
 
-static PTR
-patch_opaque_types PARAMS ((struct objfile *, struct symtab *, PTR, PTR, PTR));
+static void
+patch_opaque_types PARAMS ((struct symtab *));
 
 static void
 patch_type PARAMS ((struct type *, struct type *));
@@ -249,7 +255,7 @@ read_one_sym PARAMS ((struct coff_symbol *, struct internal_syment *,
                      union internal_auxent *));
 
 static void
-read_coff_symtab PARAMS ((int, int, struct objfile *));
+read_coff_symtab PARAMS ((long, int, struct objfile *));
 
 static void
 find_linenos PARAMS ((bfd *, sec_ptr, PTR));
@@ -267,7 +273,7 @@ static void
 coff_symfile_finish PARAMS ((struct objfile *));
 
 static void
-record_minimal_symbol PARAMS ((char *, CORE_ADDR));
+record_minimal_symbol PARAMS ((char *, CORE_ADDR, enum minimal_symbol_type));
 
 static void
 coff_end_symtab PARAMS ((struct objfile *));
@@ -411,7 +417,7 @@ coff_finish_block (symbol, listhead, old_blocks, start, end, objfile)
   for (next = *listhead; next; next = next1)
     {
       next1 = next->next;
-      free (next);
+      free ((PTR)next);
     }
   *listhead = 0;
 
@@ -475,7 +481,7 @@ make_blockvector (objfile)
   for (next = pending_blocks; next; next = next1)
     {
       next1 = next->next;
-      free (next);
+      free ((PTR)next);
     }
   pending_blocks = 0;
 
@@ -521,7 +527,7 @@ coff_start_symtab ()
   /* Initialize the source file line number information for this file.  */
 
   if (line_vector)             /* Unlikely, but maybe possible? */
-    free (line_vector);
+    free ((PTR)line_vector);
   line_vector_index = 0;
   line_vector_length = 1000;
   prev_line_number = -2;       /* Force first line number to be explicit */
@@ -576,19 +582,49 @@ coff_end_symtab (objfile)
       /* Make a block for the local symbols within.  */
       coff_finish_block (cstk->name, &coff_local_symbols, cstk->old_blocks,
                    cstk->start_addr, cur_src_end_addr, objfile);
-      free (cstk);
+      free ((PTR)cstk);
     }
 
   /* Ignore a file that has no functions with real debugging info.  */
   if (pending_blocks == 0 && coff_file_symbols == 0 && coff_global_symbols == 0)
     {
-      free (line_vector);
+      free ((PTR)line_vector);
       line_vector = 0;
       line_vector_length = -1;
       last_source_file = 0;
       return;
     }
 
+  /* It is unfortunate that in amdcoff, pending blocks might not be ordered
+     in this stage. Especially, blocks for static functions will show up at
+     the end.  We need to sort them, so tools like `find_pc_function' and
+     `find_pc_block' can work reliably. */
+  if (pending_blocks) {
+    /* FIXME!  Remove this horrid bubble sort and use qsort!!! */
+    int swapped;
+    do {
+      struct pending_block *pb, *pbnext;
+
+      pb = pending_blocks, pbnext = pb->next;
+      swapped = 0;
+
+      while ( pbnext ) {
+
+         /* swap blocks if unordered! */
+
+         if (BLOCK_START(pb->block) < BLOCK_START(pbnext->block)) {
+           struct block *tmp = pb->block;
+           complain (&misordered_blocks_complaint, BLOCK_START (pb->block));
+           pb->block = pbnext->block;
+           pbnext->block = tmp;
+           swapped = 1;
+         }
+         pb = pbnext;
+         pbnext = pbnext->next;
+      }
+    } while (swapped);
+  }
+
   /* Create the two top-level blocks for this file (STATIC_BLOCK and
      GLOBAL_BLOCK).  */
   coff_finish_block (0, &coff_file_symbols, 0, cur_src_start_addr, cur_src_end_addr, objfile);
@@ -621,9 +657,10 @@ coff_end_symtab (objfile)
 }
 \f
 static void
-record_minimal_symbol (name, address)
+record_minimal_symbol (name, address, type)
      char *name;
      CORE_ADDR address;
+     enum minimal_symbol_type type;
 {
   /* We don't want TDESC entry points in the minimal symbol table */
   if (name[0] == '@') return;
@@ -632,7 +669,7 @@ record_minimal_symbol (name, address)
      is, so this guess is more useful than mst_unknown.  */
   prim_record_minimal_symbol (savestring (name, strlen (name)),
                             address,
-                            (int)mst_text);
+                            type);
 }
 \f
 /* coff_symfile_init ()
@@ -669,7 +706,8 @@ coff_symfile_init (objfile)
   init_entry_point_info (objfile);
 
   /* Save the section number for the text section */
-  if (section = bfd_get_section_by_name(abfd,".text"))
+  section = bfd_get_section_by_name(abfd,".text");
+  if (section)
     text_bfd_scnum = section->index;
   else
     text_bfd_scnum = -1; 
@@ -737,6 +775,7 @@ coff_symfile_read (objfile, addr, mainline)
   int num_symbols;
   int symtab_offset;
   int stringtab_offset;
+  struct symtab *s;
 
   info = (struct coff_symfile_info *) objfile -> sym_private;
   symfile_bfd = abfd;                  /* Kludge for swap routines */
@@ -770,7 +809,7 @@ coff_symfile_read (objfile, addr, mainline)
   /* Read the line number table, all at once.  */
   info->min_lineno_offset = 0;
   info->max_lineno_offset = 0;
-  bfd_map_over_sections (abfd, find_linenos, info);
+  bfd_map_over_sections (abfd, find_linenos, (PTR)info);
 
   val = init_lineno (desc, info->min_lineno_offset, 
                     info->max_lineno_offset - info->min_lineno_offset);
@@ -784,21 +823,13 @@ coff_symfile_read (objfile, addr, mainline)
     error ("\"%s\": can't get string table", name);
   make_cleanup (free_stringtab, 0);
 
-  /* Position to read the symbol table.  Do not read it all at once. */
-  val = lseek (desc, (long)symtab_offset, 0);
-  if (val < 0)
-    perror_with_name (name);
-
   init_minimal_symbol_collection ();
   make_cleanup (discard_minimal_symbols, 0);
 
   /* Now that the executable file is positioned at symbol table,
      process it and define symbols accordingly.  */
 
-  read_coff_symtab (desc, num_symbols, objfile);
-
-  iterate_over_symtabs (patch_opaque_types, (PTR) NULL, (PTR) NULL,
-                       (PTR) NULL);
+  read_coff_symtab ((long)symtab_offset, num_symbols, objfile);
 
   /* Sort symbols alphabetically within each block.  */
 
@@ -811,8 +842,8 @@ coff_symfile_read (objfile, addr, mainline)
 }
 
 static void
-coff_new_init (objfile)
-     struct objfile *objfile;
+coff_new_init (ignore)
+     struct objfile *ignore;
 {
        /* Nothin' to do */
 }
@@ -839,12 +870,11 @@ coff_symfile_finish (objfile)
    We read them one at a time using read_one_sym ().  */
 
 static void
-read_coff_symtab (desc, nsyms, objfile)
-     int desc;
+read_coff_symtab (symtab_offset, nsyms, objfile)
+     long symtab_offset;
      int nsyms;
      struct objfile *objfile;
 {
-  int newfd;                   /* Avoid multiple closes on same desc */
   FILE *stream; 
   register struct coff_context_stack *new;
   struct coff_symbol coff_symbol;
@@ -854,7 +884,8 @@ read_coff_symtab (desc, nsyms, objfile)
   struct coff_symbol fcn_cs_saved;
   static struct internal_syment fcn_sym_saved;
   static union internal_auxent fcn_aux_saved;
-
+  struct symtab *s;
+  
   /* A .file is open.  */
   int in_source_file = 0;
   int num_object_files = 0;
@@ -862,18 +893,22 @@ read_coff_symtab (desc, nsyms, objfile)
 
   /* Name of the current file.  */
   char *filestring = "";
-  int depth;
-  int fcn_first_line;
-  int fcn_last_line;
-  int fcn_start_addr;
-  long fcn_line_ptr;
+  int depth = 0;
+  int fcn_first_line = 0;
+  int fcn_last_line = 0;
+  int fcn_start_addr = 0;
+  long fcn_line_ptr = 0;
   struct cleanup *old_chain;
+  int val;
 
+  stream = fopen (objfile->name, FOPEN_RB);
+  if (!stream)
+   perror_with_name(objfile->name);
 
-  newfd = dup (desc);
-  if (newfd == -1)
-    fatal ("Too many open files");
-  stream = fdopen (newfd, "r");
+  /* Position to read the symbol table. */
+  val = fseek (stream, (long)symtab_offset, 0);
+  if (val < 0)
+    perror_with_name (objfile->name);
 
   /* These cleanups will be discarded below if we succeed.  */
   old_chain = make_cleanup (free_objfile, objfile);
@@ -886,7 +921,7 @@ read_coff_symtab (desc, nsyms, objfile)
   bzero (opaque_type_chain, sizeof opaque_type_chain);
 
   if (type_vector)                     /* Get rid of previous one */
-    free (type_vector);
+    free ((PTR)type_vector);
   type_vector_length = 160;
   type_vector = (struct type **)
                xmalloc (type_vector_length * sizeof (struct type *));
@@ -928,7 +963,7 @@ read_coff_symtab (desc, nsyms, objfile)
          /* record as a minimal symbol.  if we get '.bf' next,
           * then we undo this step
           */
-         record_minimal_symbol (cs->c_name, cs->c_value);
+         record_minimal_symbol (cs->c_name, cs->c_value, mst_text);
 
          fcn_line_ptr = main_aux.x_sym.x_fcnary.x_fcn.x_lnnoptr;
          fcn_start_addr = cs->c_value;
@@ -1013,10 +1048,13 @@ read_coff_symtab (desc, nsyms, objfile)
                record this symbol as a function in the minimal symbol table.
                But why are absolute syms recorded as functions, anyway?  */
                    if (cs->c_secnum <= text_bfd_scnum+1) {/* text or abs */
-                           record_minimal_symbol (cs->c_name, cs->c_value);
+                           record_minimal_symbol (cs->c_name, cs->c_value,
+                                                  mst_text);
                            break;
                    } else {
-                           cs->c_type = T_INT;
+                           record_minimal_symbol (cs->c_name, cs->c_value,
+                                                  mst_data);
+                           break;
                    }
            }
            (void) process_coff_symbol (cs, &main_aux, objfile);
@@ -1087,7 +1125,7 @@ read_coff_symtab (desc, nsyms, objfile)
                              );
                coff_context_stack = 0;
                within_function = 0;
-               free (new);
+               free ((PTR)new);
              }
            break;
 
@@ -1121,7 +1159,7 @@ read_coff_symtab (desc, nsyms, objfile)
                depth--;
                coff_local_symbols = new->locals;
                coff_context_stack = new->next;
-               free (new);
+               free ((PTR)new);
              }
            break;
 
@@ -1134,6 +1172,12 @@ read_coff_symtab (desc, nsyms, objfile)
   if (last_source_file)
     coff_end_symtab (objfile);
   fclose (stream);
+
+  /* Patch up any opaque types (references to types that are not defined
+     in the file where they are referenced, e.g. "struct foo *bar").  */
+  ALL_OBJFILE_SYMTABS (objfile, s)
+    patch_opaque_types (s);
+
   discard_cleanups (old_chain);
   current_objfile = NULL;
 }
@@ -1451,20 +1495,11 @@ patch_type (type, real_type)
 }
 
 /* Patch up all appropriate typedef symbols in the opaque_type_chains
-   so that they can be used to print out opaque data structures properly.
-
-   This is called via iterate_over_symtabs, and thus simply returns NULL
-   for each time it is called, to indicate that the iteration should
-   continue. */
+   so that they can be used to print out opaque data structures properly.  */
 
-/* ARGSUSED */
-static PTR
-patch_opaque_types (objfile, s, arg1, arg2, arg3)
-     struct objfile *objfile;
+static void
+patch_opaque_types (s)
      struct symtab *s;
-     PTR arg1;
-     PTR arg2;
-     PTR arg3;
 {
   register struct block *b;
   register int i;
@@ -1522,7 +1557,6 @@ patch_opaque_types (objfile, s, arg1, arg2, arg3)
            }
        }
     }
-  return (NULL);
 }
 \f
 static struct symbol *
@@ -1670,9 +1704,14 @@ process_coff_symbol (cs, aux, objfile)
              TYPE_NAME (SYMBOL_TYPE (sym)) = concat (SYMBOL_NAME (sym), NULL);
 
            /* Keep track of any type which points to empty structured type,
-               so it can be filled from a definition from another file */
+               so it can be filled from a definition from another file.  A
+               simple forward reference (TYPE_CODE_UNDEF) is not an
+               empty structured type, though; the forward references
+               work themselves out via the magic of coff_lookup_type.  */
            if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR &&
-               TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) == 0)
+               TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) == 0 &&
+               TYPE_CODE   (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) !=
+                                               TYPE_CODE_UNDEF)
              {
                register int i = hashname (SYMBOL_NAME (sym));
 
@@ -1765,11 +1804,23 @@ decode_type (cs, c_type, aux)
       return type;
     }
 
-  /* Reference to existing type */
+  /* Reference to existing type.  This only occurs with the
+     struct, union, and enum types.  EPI a29k coff
+     fakes us out by producing aux entries with a nonzero
+     x_tagndx for definitions of structs, unions, and enums, so we
+     have to check the c_sclass field.  */
   if (cs->c_naux > 0 && aux->x_sym.x_tagndx.l != 0)
     {
-      type = coff_alloc_type (aux->x_sym.x_tagndx.l);
-      return type;
+      if  (cs->c_sclass != C_STRTAG
+       && cs->c_sclass != C_UNTAG
+       && cs->c_sclass != C_ENTAG)
+       {
+         type = coff_alloc_type (aux->x_sym.x_tagndx.l);
+         return type;
+       } else {
+         complain (&tagndx_bad_complaint, cs->c_name);
+         /* And fall through to decode_base_type... */
+       }
     }
 
   return decode_base_type (cs, BTYPE (c_type), aux);
index bc997ef..d9c76d8 100644 (file)
@@ -37,6 +37,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "elf/external.h"
 #include "elf/internal.h"
 #include "bfd.h"
+#include "libbfd.h"            /* For bfd_elf_find_section */
 #include "symtab.h"
 #include "symfile.h"
 #include "objfiles.h"
@@ -354,8 +355,9 @@ elf_symfile_read (objfile, addr, mainline)
         sections visible to the caller.  So we have to search the
         ELF section table, not the BFD section table, for the string
         table.  */
-      Elf_Internal_Shdr *elf_sect = bfd_elf_find_section (abfd, ".stabstr");
+      struct elf_internal_shdr *elf_sect;
 
+      elf_sect = bfd_elf_find_section (abfd, ".stabstr");
       if (elf_sect)
        elfstab_build_psymtabs (objfile,
          addr, /* We really pass the text seg addr, not the offset, here. */
index a709101..82a0413 100644 (file)
@@ -32,6 +32,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "regex.h"
 #include "expression.h"
 #include "language.h"
+#include "demangle.h"
 
 #include <obstack.h>
 #include <assert.h>
@@ -44,11 +45,14 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 /* Prototypes for local functions */
 
+static char *
+expensive_mangler PARAMS ((const char *));
+
 extern int
 find_methods PARAMS ((struct type *, char *, char **, struct symbol **));
 
 static void
-completion_list_add_symbol PARAMS ((char *));
+completion_list_add_symbol PARAMS ((char *, char *, int));
 
 static struct symtabs_and_lines
 decode_line_2 PARAMS ((struct symbol *[], int, int));
@@ -107,6 +111,18 @@ const struct block *block_found;
 
 char no_symtab_msg[] = "No symbol table is loaded.  Use the \"file\" command.";
 
+/* 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 */
+
+void
+cplusplus_hint (name)
+     char *name;
+{
+  printf ("Hint: try '%s<TAB> or '%s<ESC-?>\n", name, name);
+  printf ("(Note leading single quote.)\n");
+}
+
 /* Check for a symtab of a specific name; first in symtabs, then in
    psymtabs.  *If* there is no '/' in the name, a match after a '/'
    in the symtab filename will also work.  */
@@ -359,6 +375,20 @@ lookup_symbol (name, block, namespace, is_a_field_of_this, symtab)
   register struct objfile *objfile;
   register struct block *b;
   register struct minimal_symbol *msymbol;
+  char *temp;
+  extern char *gdb_completer_word_break_characters;
+
+  /* If NAME contains any characters from gdb_completer_word_break_characters
+     then it is probably from a quoted name string.  So check to see if it
+     has a C++ mangled equivalent, and if so, use the mangled equivalent. */
+
+  if (strpbrk (name, gdb_completer_word_break_characters) != NULL)
+    {
+      if ((temp = expensive_mangler (name)) != NULL)
+       {
+         name = temp;
+       }
+    }
 
   /* Search specified block and its superiors.  */
 
@@ -466,29 +496,22 @@ found:
          /* Test each minimal symbol to see if the minimal symbol's name
             is a C++ mangled name that matches a user visible name.  */
 
-          int matchcount = strlen (name);
          char *demangled;
 
          ALL_MSYMBOLS (objfile, msymbol)
            {
-             if (strncmp (msymbol -> name, name, matchcount) == 0)
+             demangled = demangle_and_match (msymbol -> name, name, 0);
+             if (demangled != NULL)
                {
-                 demangled = cplus_demangle (msymbol -> name, -1);
-                 if (demangled != NULL)
-                   {
-                     if (strcmp (demangled, name) == 0)
-                       {
-                         free (demangled);
-                         goto found_msym;
-                       }
-                     free (demangled);
-                   }
+                 free (demangled);
+                 goto found_msym;
                }
            }
+         msymbol = NULL;               /* Not found */
         }
 
 found_msym:
-      if (msymbol != NULL && msymbol -> name != NULL)
+      if (msymbol != NULL)
        {
          s = find_pc_symtab (msymbol -> address);
          /* If S is NULL, there are no debug symbols for this file.
@@ -624,32 +647,29 @@ lookup_demangled_block_symbol (block, name)
      register const struct block *block;
      const char *name;
 {
-  register int bot, top, inc;
+  register int bot, top;
   register struct symbol *sym;
+  char *demangled;
 
   bot = 0;
   top = BLOCK_NSYMS (block);
-  inc = name[0];
 
   while (bot < top)
     {
       sym = BLOCK_SYM (block, bot);
-      if (SYMBOL_NAME (sym)[0] == inc
-         && SYMBOL_NAMESPACE (sym) == VAR_NAMESPACE)
+      if (SYMBOL_NAMESPACE (sym) == VAR_NAMESPACE)
        {
-         char *demangled = cplus_demangle(SYMBOL_NAME (sym), -1);
+         demangled = demangle_and_match (SYMBOL_NAME (sym), name, 0);
          if (demangled != NULL)
            {
-             int cond = strcmp (demangled, name);
              free (demangled);
-             if (!cond)
-               return sym;
+             return (sym);
            }
        }
       bot++;
     }
 
-  return 0;
+  return (NULL);
 }
 
 /* Look, in partial_symtab PST, for static mangled symbol NAME. */
@@ -661,7 +681,7 @@ lookup_demangled_partial_symbol (pst, name)
 {
   struct partial_symbol *start, *psym;
   int length = pst->n_static_syms;
-  register int inc = name[0];
+  char *demangled;
 
   if (!length)
     return (struct partial_symbol *) 0;
@@ -669,21 +689,18 @@ lookup_demangled_partial_symbol (pst, name)
   start = pst->objfile->static_psymbols.list + pst->statics_offset;
   for (psym = start; psym < start + length; psym++)
     {
-      if (SYMBOL_NAME (psym)[0] == inc
-         && SYMBOL_NAMESPACE (psym) == VAR_NAMESPACE)
+      if (SYMBOL_NAMESPACE (psym) == VAR_NAMESPACE)
        {
-         char *demangled = cplus_demangle(SYMBOL_NAME (psym), -1);
+         demangled = demangle_and_match (SYMBOL_NAME (psym), name, 0);
          if (demangled != NULL)
            {
-             int cond = strcmp (demangled, name);
              free (demangled);
-             if (!cond)
-               return psym;
+             return (psym);
            }
        }
     }
 
-  return (struct partial_symbol *) 0;
+  return (NULL);
 }
 
 /* Look, in partial_symtab PST, for symbol NAME.  Check the global
@@ -1344,7 +1361,7 @@ find_methods (t, name, physnames, sym_arr)
                else
                  {
                    fputs_filtered("(Cannot find method ", stdout);
-                   fputs_demangled(phys_name, stdout, 0);
+                   fputs_demangled(phys_name, stdout, DMGL_PARAMS);
                    fputs_filtered(" - possibly inlined.)\n", stdout);
                  }
              }
@@ -1415,6 +1432,8 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
   struct symbol **sym_arr;
   struct type *t;
   char **physnames;
+  char *saved_arg = *argptr;
+  extern char *gdb_completer_quote_characters;
   
   /* Defaults have defaults.  */
 
@@ -1424,11 +1443,27 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
       default_line = current_source_line;
     }
 
-  /* See if arg is *PC */
 
-  if (**argptr == '*')
+  /* Check to see if *ARGPTR points to a string that has been quoted with
+     gdb_completer_quote_characters.  If so, P will be left pointing at
+     someplace other than *ARGPTR */
+
+  if (((p = skip_quoted (*argptr)) != *argptr) &&
+      ((*(p - 1) != **argptr) ||
+       (strchr (gdb_completer_quote_characters, **argptr) == NULL)))
     {
-      (*argptr)++;
+      /* Not quoted symbol string specification, reset P */
+      p = *argptr;
+    }
+
+  /* See if arg is *PC or '<some symbol specifier string>' */
+
+  if ((**argptr == '*') || (p != *argptr))
+    {
+      if (**argptr == '*')
+       {
+         (*argptr)++;
+       }
       pc = parse_and_eval_address_1 (argptr);
       values.sals = (struct symtab_and_line *)
        xmalloc (sizeof (struct symtab_and_line));
@@ -1488,7 +1523,11 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
                  tmp[q1 - q] = '\0';
                  opname = cplus_mangle_opname (tmp, 1);
                  if (opname == NULL)
-                   error ("No mangling for \"%s\"", tmp);
+                   {
+                     warning ("no mangling for \"%s\"", tmp);
+                     cplusplus_hint (saved_arg);
+                     return_to_top_level ();
+                   }
                  copy = (char*) alloca (3 + strlen(opname));
                  sprintf (copy, "__%s", opname);
                  p = q1;
@@ -1566,16 +1605,23 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
                  else
                    tmp = copy;
                  if (tmp[0] == '~')
-                   error ("The class `%s' does not have destructor defined",
-                          sym_class->name);
+                   warning ("the class `%s' does not have destructor defined",
+                            sym_class->name);
                  else
-                   error ("The class %s does not have any method named %s",
-                          sym_class->name, tmp);
+                   warning ("the class %s does not have any method named %s",
+                            sym_class->name, tmp);
+                 cplusplus_hint (saved_arg);
+                 return_to_top_level ();
                }
            }
          else
-           /* The quotes are important if copy is empty.  */
-           error("No class, struct, or union named \"%s\"", copy );
+           {
+             /* The quotes are important if copy is empty.  */
+             warning ("can't find class, struct, or union named \"%s\"",
+                      copy);
+             cplusplus_hint (saved_arg);
+             return_to_top_level ();
+           }
        }
       /*  end of C++  */
 
@@ -1669,11 +1715,21 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
   /* Arg token is not digits => try it as a variable name
      Find the next token (everything up to end or next whitespace).  */
 
-  p = *argptr;
-  while (*p && *p != ' ' && *p != '\t' && *p != ',') p++;
+  p = skip_quoted (*argptr);
   copy = (char *) alloca (p - *argptr + 1);
   bcopy (*argptr, copy, p - *argptr);
-  copy[p - *argptr] = 0;
+  copy[p - *argptr] = '\0';
+  if ((copy[0] == copy [p - *argptr - 1])
+      && strchr (gdb_completer_quote_characters, copy[0]) != NULL)
+    {
+      char *temp;
+      copy [p - *argptr - 1] = '\0';
+      copy++;
+      if ((temp = expensive_mangler (copy)) != NULL)
+       {
+         copy = temp;
+       }
+    }
   while (*p == ' ' || *p == '\t') p++;
   *argptr = p;
 
@@ -1757,7 +1813,7 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
       !have_partial_symbols () && !have_minimal_symbols ())
     error (no_symtab_msg);
 
-  error ("Function %s not defined.", copy);
+  error ("Function \"%s\" not defined.", copy);
   return values;       /* for lint */
 }
 
@@ -1882,7 +1938,6 @@ output_source_filename (name, first)
      char *name;
      int *first;
 {
-  static unsigned int column;
   /* Table of files printed so far.  Since a single source file can
      result in several partial symbol tables, we need to avoid printing
      it more than once.  Note: if some of the psymtabs are read in and
@@ -1923,27 +1978,15 @@ output_source_filename (name, first)
 
   if (*first)
     {
-      column = 0;
       *first = 0;
     }
   else
     {
-      printf_filtered (",");
-      column++;
+      printf_filtered (", ");
     }
 
-  if (column != 0 && column + strlen (name) >= 70)
-    {
-      printf_filtered ("\n");
-      column = 0;
-    }
-  else if (column != 0)
-    {
-      printf_filtered (" ");
-      column++;
-    }
+  wrap_here ("");
   fputs_filtered (name, stdout);
-  column += strlen (name);
 }  
 
 static void
@@ -1984,17 +2027,17 @@ sources_info (ignore, from_tty)
 }
 
 static int
-name_match(name)
+name_match (name)
      char *name;
 {
-  char *demangled = cplus_demangle(name, -1);
+  char *demangled = cplus_demangle (name, 0);
   if (demangled != NULL)
     {
       int cond = re_exec (demangled);
       free (demangled);
-      return cond;
+      return (cond);
     }
-  return re_exec(name);
+  return (re_exec (name));
 }
 #define NAME_MATCH(NAME) name_match(NAME)
 
@@ -2245,8 +2288,8 @@ list_symbols (regexp, class, bpt)
              if (regexp == 0 || NAME_MATCH (msymbol -> name))
                {
                  /* Functions:  Look up by address. */
-                 if (class != 1 &&
-                     (find_pc_symtab (msymbol -> address) != NULL))
+                 if (class != 1 ||
+                     (0 == find_pc_symtab (msymbol -> address)))
                    {
                      /* Variables/Absolutes:  Look up by name */
                      if (lookup_symbol (msymbol -> name, 
@@ -2329,51 +2372,79 @@ contained_in (a, b)
 \f
 /* Helper routine for make_symbol_completion_list.  */
 
-int return_val_size, return_val_index;
-char **return_val;
+static int return_val_size;
+static int return_val_index;
+static char **return_val;
+
+/*  Test to see if the symbol specified by SYMNAME (or it's demangled
+    equivalent) matches TEXT in the first TEXT_LEN characters.  If so,
+    add it to the current completion list. */
 
 static void
-completion_list_add_symbol (symname)
+completion_list_add_symbol (symname, text, text_len)
      char *symname;
+     char *text;
+     int text_len;
 {
-  if (return_val_index + 3 > return_val_size)
-    return_val = (char **) xrealloc ((char *) return_val,
-                                    (return_val_size *= 2) * sizeof (char *));
-  
-  return_val[return_val_index] =
-    (char *)xmalloc (1 + strlen (symname));
-  
-  strcpy (return_val[return_val_index], symname);
-  
-  return_val[++return_val_index] = (char *)NULL;
+  char *demangled;
+  int newsize;
+
+  /* First see if SYMNAME is a C++ mangled name, and if so, use the
+     demangled name instead, including any parameters. */
+
+  if ((demangled = cplus_demangle (symname, DMGL_PARAMS | DMGL_ANSI)) != NULL)
+    {
+      symname = demangled;
+    }
+
+  /* If we have a match for a completion, then add SYMNAME to the current
+     list of matches. Note that we always make a copy of the string, even
+     if it is one that was returned from cplus_demangle and is already
+     in malloc'd memory. */
+
+  if (strncmp (symname, text, text_len) == 0)
+    {
+      if (return_val_index + 3 > return_val_size)
+       {
+         newsize = (return_val_size *= 2) * sizeof (char *);
+         return_val = (char **) xrealloc ((char *) return_val, newsize);
+       }
+      return_val[return_val_index++] = savestring (symname, strlen (symname));
+      return_val[return_val_index] = NULL;
+    }
+
+  if (demangled != NULL)
+    {
+      free (demangled);
+    }
 }
 
 /* Return a NULL terminated array of all symbols (regardless of class) which
    begin by matching TEXT.  If the answer is no symbols, then the return value
    is an array which contains only a NULL pointer.
 
-   Problem: All of the symbols have to be copied because readline
-   frees them.  I'm not going to worry about this; hopefully there
-   won't be that many.  */
+   Problem: All of the symbols have to be copied because readline frees them.
+   I'm not going to worry about this; hopefully there won't be that many.  */
 
 char **
 make_symbol_completion_list (text)
   char *text;
 {
+  register struct symbol *sym;
   register struct symtab *s;
   register struct partial_symtab *ps;
   register struct minimal_symbol *msymbol;
   register struct objfile *objfile;
   register struct block *b, *surrounding_static_block = 0;
   register int i, j;
+  int text_len;
   struct partial_symbol *psym;
 
-  int text_len = strlen (text);
+  text_len = strlen (text);
   return_val_size = 100;
   return_val_index = 0;
-  return_val =
-    (char **)xmalloc ((1 + return_val_size) *sizeof (char *));
-  return_val[0] = (char *)NULL;
+  return_val = (char **) xmalloc ((return_val_size + 1) * sizeof (char *));
+  return_val[0] = NULL;
 
   /* Look through the partial symtabs for all symbols which begin
      by matching TEXT.  Add each one that you find to the list.  */
@@ -2389,9 +2460,9 @@ make_symbol_completion_list (text)
                   + ps->n_global_syms);
           psym++)
        {
-         QUIT;                 /* If interrupted, then quit. */
-         if ((strncmp (SYMBOL_NAME (psym), text, text_len) == 0))
-           completion_list_add_symbol (SYMBOL_NAME (psym));
+         /* If interrupted, then quit. */
+         QUIT;
+         completion_list_add_symbol (SYMBOL_NAME (psym), text, text_len);
        }
       
       for (psym = objfile->static_psymbols.list + ps->statics_offset;
@@ -2400,8 +2471,7 @@ make_symbol_completion_list (text)
           psym++)
        {
          QUIT;
-         if ((strncmp (SYMBOL_NAME (psym), text, text_len) == 0))
-           completion_list_add_symbol (SYMBOL_NAME (psym));
+         completion_list_add_symbol (SYMBOL_NAME (psym), text, text_len);
        }
     }
 
@@ -2412,14 +2482,151 @@ make_symbol_completion_list (text)
 
   ALL_MSYMBOLS (objfile, msymbol)
     {
-      if (strncmp (text, msymbol -> name, text_len) == 0)
-       {
-         completion_list_add_symbol (msymbol -> name);
-       }
+      QUIT;
+      completion_list_add_symbol (msymbol -> name, text, text_len);
     }
 
   /* Search upwards from currently selected frame (so that we can
      complete on local vars.  */
+
+  for (b = get_selected_block (); b != NULL; b = BLOCK_SUPERBLOCK (b))
+    {
+      if (!BLOCK_SUPERBLOCK (b))
+       {
+         surrounding_static_block = b;         /* For elmin of dups */
+       }
+      
+      /* Also catch fields of types defined in this places which match our
+        text string.  Only complete on types visible from current context. */
+
+      for (i = 0; i < BLOCK_NSYMS (b); i++)
+       {
+         sym = BLOCK_SYM (b, i);
+         completion_list_add_symbol (SYMBOL_NAME (sym), text, text_len);
+         if (SYMBOL_CLASS (sym) == LOC_TYPEDEF)
+           {
+             struct type *t = SYMBOL_TYPE (sym);
+             enum type_code c = TYPE_CODE (t);
+
+             if (c == TYPE_CODE_UNION || c == TYPE_CODE_STRUCT)
+               {
+                 for (j = TYPE_N_BASECLASSES (t); j < TYPE_NFIELDS (t); j++)
+                   {
+                     if (TYPE_FIELD_NAME (t, j))
+                       {
+                         completion_list_add_symbol (TYPE_FIELD_NAME (t, j),
+                                                     text, text_len);
+                       }
+                   }
+               }
+           }
+       }
+    }
+
+  /* Go through the symtabs and check the externs and statics for
+     symbols which match.  */
+
+  ALL_SYMTABS (objfile, s)
+    {
+      QUIT;
+      b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
+      for (i = 0; i < BLOCK_NSYMS (b); i++)
+       {
+         sym = BLOCK_SYM (b, i);
+         completion_list_add_symbol (SYMBOL_NAME (sym), text, text_len);
+       }
+    }
+
+  ALL_SYMTABS (objfile, s)
+    {
+      QUIT;
+      b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
+      /* Don't do this block twice.  */
+      if (b == surrounding_static_block) continue;
+      for (i = 0; i < BLOCK_NSYMS (b); i++)
+       {
+         sym = BLOCK_SYM (b, i);
+         completion_list_add_symbol (SYMBOL_NAME (sym), text, text_len);
+       }
+    }
+
+  return (return_val);
+}
+
+\f
+/* Find a mangled symbol that corresponds to LOOKFOR using brute force.
+   Basically we go munging through available symbols, demangling each one,
+   looking for a match on the demangled result. */
+
+static char *
+expensive_mangler (lookfor)
+     const char *lookfor;
+{
+  register struct symbol *sym;
+  register struct symtab *s;
+  register struct partial_symtab *ps;
+  register struct minimal_symbol *msymbol;
+  register struct objfile *objfile;
+  register struct block *b, *surrounding_static_block = 0;
+  register int i, j;
+  struct partial_symbol *psym;
+  char *demangled;
+
+  /* Look through the partial symtabs for a symbol that matches */
+
+  ALL_PSYMTABS (objfile, ps)
+    {
+      /* If the psymtab's been read in we'll get it when we search
+        through the blockvector.  */
+      if (ps->readin) continue;
+      
+      for (psym = objfile->global_psymbols.list + ps->globals_offset;
+          psym < (objfile->global_psymbols.list + ps->globals_offset
+                  + ps->n_global_syms);
+          psym++)
+       {
+         QUIT;                 /* If interrupted, then quit. */
+         demangled = demangle_and_match (SYMBOL_NAME (psym), lookfor,
+                                         DMGL_PARAMS | DMGL_ANSI);
+         if (demangled != NULL)
+           {
+             free (demangled);
+             return (SYMBOL_NAME (psym));
+           }
+       }
+      
+      for (psym = objfile->static_psymbols.list + ps->statics_offset;
+          psym < (objfile->static_psymbols.list + ps->statics_offset
+                  + ps->n_static_syms);
+          psym++)
+       {
+         QUIT;
+         demangled = demangle_and_match (SYMBOL_NAME (psym), lookfor,
+                                         DMGL_PARAMS | DMGL_ANSI);
+         if (demangled != NULL)
+           {
+             free (demangled);
+             return (SYMBOL_NAME (psym));
+           }
+       }
+    }
+
+  /* Scan through the misc symbol vectors looking for a match. */
+
+  ALL_MSYMBOLS (objfile, msymbol)
+    {
+      QUIT;
+      demangled = demangle_and_match (msymbol -> name, lookfor,
+                                     DMGL_PARAMS | DMGL_ANSI);
+      if (demangled != NULL)
+       {
+         free (demangled);
+         return (msymbol -> name);
+       }
+    }
+
+  /* Search upwards from currently selected frame looking for a match */
+
   for (b = get_selected_block (); b; b = BLOCK_SUPERBLOCK (b))
     {
       if (!BLOCK_SUPERBLOCK (b))
@@ -2430,21 +2637,37 @@ make_symbol_completion_list (text)
         from current context.  */
       for (i = 0; i < BLOCK_NSYMS (b); i++)
        {
-         register struct symbol *sym = BLOCK_SYM (b, i);
-         
-         if (!strncmp (SYMBOL_NAME (sym), text, text_len))
-           completion_list_add_symbol (SYMBOL_NAME (sym));
-
+         sym = BLOCK_SYM (b, i);
+         demangled = demangle_and_match (SYMBOL_NAME (sym), lookfor,
+                                         DMGL_PARAMS | DMGL_ANSI);
+         if (demangled != NULL)
+           {
+             free (demangled);
+             return (SYMBOL_NAME (sym));
+           }
          if (SYMBOL_CLASS (sym) == LOC_TYPEDEF)
            {
              struct type *t = SYMBOL_TYPE (sym);
              enum type_code c = TYPE_CODE (t);
 
              if (c == TYPE_CODE_UNION || c == TYPE_CODE_STRUCT)
-               for (j = TYPE_N_BASECLASSES (t); j < TYPE_NFIELDS (t); j++)
-                 if (TYPE_FIELD_NAME (t, j) &&
-                     !strncmp (TYPE_FIELD_NAME (t, j), text, text_len))
-                   completion_list_add_symbol (TYPE_FIELD_NAME (t, j));
+               {
+                 for (j = TYPE_N_BASECLASSES (t); j < TYPE_NFIELDS (t); j++)
+                   {
+                     if (TYPE_FIELD_NAME (t, j))
+                       {
+                         demangled =
+                           demangle_and_match (TYPE_FIELD_NAME (t, j),
+                                               lookfor,
+                                               DMGL_PARAMS | DMGL_ANSI);
+                         if (demangled != NULL)
+                           {
+                             free (demangled);
+                             return (TYPE_FIELD_NAME (t, j));
+                           }
+                       }
+                   }
+               }
            }
        }
     }
@@ -2454,27 +2677,43 @@ make_symbol_completion_list (text)
 
   ALL_SYMTABS (objfile, s)
     {
+      QUIT;
       b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
-      
       for (i = 0; i < BLOCK_NSYMS (b); i++)
-       if (!strncmp (SYMBOL_NAME (BLOCK_SYM (b, i)), text, text_len))
-         completion_list_add_symbol (SYMBOL_NAME (BLOCK_SYM (b, i)));
+       {
+         sym = BLOCK_SYM (b, i);
+         demangled = demangle_and_match (SYMBOL_NAME (sym), lookfor,
+                                         DMGL_PARAMS | DMGL_ANSI);
+         if (demangled != NULL)
+           {
+             free (demangled);
+             return (SYMBOL_NAME (sym));
+           }
+       }
     }
 
   ALL_SYMTABS (objfile, s)
     {
+      QUIT;
       b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
-      
       /* Don't do this block twice.  */
       if (b == surrounding_static_block) continue;
-      
       for (i = 0; i < BLOCK_NSYMS (b); i++)
-       if (!strncmp (SYMBOL_NAME (BLOCK_SYM (b, i)), text, text_len))
-         completion_list_add_symbol (SYMBOL_NAME (BLOCK_SYM (b, i)));
+       {
+         sym = BLOCK_SYM (b, i);
+         demangled = demangle_and_match (SYMBOL_NAME (sym), lookfor,
+                                         DMGL_PARAMS | DMGL_ANSI);
+         if (demangled != NULL)
+           {
+             free (demangled);
+             return (SYMBOL_NAME (sym));
+           }
+       }
     }
 
-  return (return_val);
+  return (NULL);
 }
+
 \f
 #if 0
 /* Add the type of the symbol sym to the type of the current
index 6a926e0..96d71de 100644 (file)
@@ -501,11 +501,12 @@ extern const struct ext_format ext_format_68881;
 #endif /* HAVE_68881 */
 
 /* Insert the specified number of args and function address
-   into a call sequence of the above form stored at DUMMYNAME.  */
+   into a call sequence of the above form stored at DUMMYNAME.
+   We use the BFD routines to store a big-endian value of known size.  */
 
 #define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p)     \
-{ *(int *)((char *) dummyname + CALL_DUMMY_START_OFFSET + 2) = fun;  \
-  *(int *)((char *) dummyname + CALL_DUMMY_START_OFFSET + 8) = nargs * 4; }
+{ _do_putb32 (fun,     (char *) dummyname + CALL_DUMMY_START_OFFSET + 2);  \
+  _do_putb32 (nargs*4, (char *) dummyname + CALL_DUMMY_START_OFFSET + 8); }
 
 /* Push an empty stack frame, to record the current PC, etc.  */