daily update
[deliverable/binutils-gdb.git] / gdb / symtab.c
index a51126a1d8c10262c0b20a278d27c856eb63bf98..98c3250529c04f96a8fd806bc4cdbce3627f7911 100644 (file)
@@ -1,7 +1,8 @@
 /* Symbol table lookup for the GNU debugger, GDB.
-   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
-   1996, 1997, 1998, 1999, 2000, 2001
-   Free Software Foundation, Inc.
+
+   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
+   1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software
+   Foundation, Inc.
 
    This file is part of GDB.
 
@@ -37,6 +38,7 @@
 #include "demangle.h"
 #include "inferior.h"
 #include "linespec.h"
+#include "filenames.h"         /* for FILENAME_CMP */
 
 #include "obstack.h"
 
@@ -45,6 +47,7 @@
 #include "gdb_string.h"
 #include "gdb_stat.h"
 #include <ctype.h>
+#include "cp-abi.h"
 
 /* Prototype for one function in parser-defs.h,
    instead of including that entire file. */
@@ -77,13 +80,12 @@ static struct partial_symbol *lookup_partial_symbol (struct partial_symtab *,
                                                     const char *, int,
                                                     namespace_enum);
 
-static struct symtab *lookup_symtab_1 (char *);
-
-static struct symbol *lookup_symbol_aux (const char *name, const
-                                        struct block *block, const
-                                        namespace_enum namespace, int
-                                        *is_a_field_of_this, struct
-                                        symtab **symtab);
+static struct symbol *lookup_symbol_aux (const char *name,
+                                        const char *mangled_name,
+                                        const struct block *block,
+                                        const namespace_enum namespace,
+                                        int *is_a_field_of_this,
+                                        struct symtab **symtab);
 
 
 static struct symbol *find_active_alias (struct symbol *sym, CORE_ADDR addr);
@@ -135,36 +137,51 @@ cplusplus_hint (char *name)
    psymtabs.  *If* there is no '/' in the name, a match after a '/'
    in the symtab filename will also work.  */
 
-static struct symtab *
-lookup_symtab_1 (char *name)
+struct symtab *
+lookup_symtab (const char *name)
 {
   register struct symtab *s;
   register struct partial_symtab *ps;
-  register char *slash;
   register struct objfile *objfile;
+  char *real_path = NULL;
+
+  /* Here we are interested in canonicalizing an absolute path, not
+     absolutizing a relative path.  */
+  if (IS_ABSOLUTE_PATH (name))
+    real_path = gdb_realpath (name);
 
 got_symtab:
 
   /* First, search for an exact match */
 
   ALL_SYMTABS (objfile, s)
-    if (STREQ (name, s->filename))
-    return s;
+  {
+    if (FILENAME_CMP (name, s->filename) == 0)
+      {
+       xfree (real_path);
+       return s;
+      }
+    /* If the user gave us an absolute path, try to find the file in
+       this symtab and use its absolute path.  */
+    if (real_path != NULL)
+      {
+       char *rp = symtab_to_filename (s);
+       if (FILENAME_CMP (real_path, rp) == 0)
+         {
+           xfree (real_path);
+           return s;
+         }
+      }
+  }
 
-  slash = strchr (name, '/');
+  xfree (real_path);
 
   /* Now, search for a matching tail (only if name doesn't have any dirs) */
 
-  if (!slash)
+  if (lbasename (name) == name)
     ALL_SYMTABS (objfile, s)
     {
-      char *p = s->filename;
-      char *tail = strrchr (p, '/');
-
-      if (tail)
-       p = tail + 1;
-
-      if (STREQ (p, name))
+      if (FILENAME_CMP (lbasename (s->filename), name) == 0)
        return s;
     }
 
@@ -195,72 +212,52 @@ got_symtab:
   goto got_symtab;
 }
 
-/* Lookup the symbol table of a source file named NAME.  Try a couple
-   of variations if the first lookup doesn't work.  */
-
-struct symtab *
-lookup_symtab (char *name)
-{
-  register struct symtab *s;
-#if 0
-  register char *copy;
-#endif
-
-  s = lookup_symtab_1 (name);
-  if (s)
-    return s;
-
-#if 0
-  /* This screws c-exp.y:yylex if there is both a type "tree" and a symtab
-     "tree.c".  */
-
-  /* If name not found as specified, see if adding ".c" helps.  */
-  /* Why is this?  Is it just a user convenience?  (If so, it's pretty
-     questionable in the presence of C++, FORTRAN, etc.).  It's not in
-     the GDB manual.  */
-
-  copy = (char *) alloca (strlen (name) + 3);
-  strcpy (copy, name);
-  strcat (copy, ".c");
-  s = lookup_symtab_1 (copy);
-  if (s)
-    return s;
-#endif /* 0 */
-
-  /* We didn't find anything; die.  */
-  return 0;
-}
-
 /* Lookup the partial symbol table of a source file named NAME.
    *If* there is no '/' in the name, a match after a '/'
    in the psymtab filename will also work.  */
 
 struct partial_symtab *
-lookup_partial_symtab (char *name)
+lookup_partial_symtab (const char *name)
 {
   register struct partial_symtab *pst;
   register struct objfile *objfile;
+  char *real_path = NULL;
+
+  /* Here we are interested in canonicalizing an absolute path, not
+     absolutizing a relative path.  */
+  if (IS_ABSOLUTE_PATH (name))
+    real_path = gdb_realpath (name);
 
   ALL_PSYMTABS (objfile, pst)
   {
-    if (STREQ (name, pst->filename))
+    if (FILENAME_CMP (name, pst->filename) == 0)
       {
+       xfree (real_path);
        return (pst);
       }
+    /* If the user gave us an absolute path, try to find the file in
+       this symtab and use its absolute path.  */
+    if (real_path != NULL)
+      {
+       if (pst->fullname == NULL)
+         source_full_path_of (pst->filename, &pst->fullname);
+       if (pst->fullname != NULL
+           && FILENAME_CMP (real_path, pst->fullname) == 0)
+         {
+           xfree (real_path);
+           return pst;
+         }
+      }
   }
 
+  xfree (real_path);
+
   /* Now, search for a matching tail (only if name doesn't have any dirs) */
 
-  if (!strchr (name, '/'))
+  if (lbasename (name) == name)
     ALL_PSYMTABS (objfile, pst)
     {
-      char *p = pst->filename;
-      char *tail = strrchr (p, '/');
-
-      if (tail)
-       p = tail + 1;
-
-      if (STREQ (p, name))
+      if (FILENAME_CMP (lbasename (pst->filename), name) == 0)
        return (pst);
     }
 
@@ -288,20 +285,20 @@ gdb_mangle_name (struct type *type, int method_id, int signature_id)
   int is_full_physname_constructor;
 
   int is_constructor;
-  int is_destructor = DESTRUCTOR_PREFIX_P (physname);
+  int is_destructor = is_destructor_name (physname);
   /* Need a new type prefix.  */
   char *const_prefix = method->is_const ? "C" : "";
   char *volatile_prefix = method->is_volatile ? "V" : "";
   char buf[20];
   int len = (newname == NULL ? 0 : strlen (newname));
 
-  if (OPNAME_PREFIX_P (field_name))
+  /* Nothing to do if physname already contains a fully mangled v3 abi name
+     or an operator name.  */
+  if ((physname[0] == '_' && physname[1] == 'Z')
+      || is_operator_name (field_name))
     return xstrdup (physname);
 
-  is_full_physname_constructor =
-    ((physname[0] == '_' && physname[1] == '_' &&
-      (isdigit (physname[2]) || physname[2] == 'Q' || physname[2] == 't'))
-     || (strncmp (physname, "__ct", 4) == 0));
+  is_full_physname_constructor = is_constructor_name (physname);
 
   is_constructor =
     is_full_physname_constructor || (newname && STREQ (field_name, newname));
@@ -362,12 +359,24 @@ find_pc_sect_psymtab (CORE_ADDR pc, asection *section)
 {
   register struct partial_symtab *pst;
   register struct objfile *objfile;
+  struct minimal_symbol *msymbol;
+
+  /* If we know that this is not a text address, return failure.  This is
+     necessary because we loop based on texthigh and textlow, which do
+     not include the data ranges.  */
+  msymbol = lookup_minimal_symbol_by_pc_section (pc, section);
+  if (msymbol
+      && (msymbol->type == mst_data
+         || msymbol->type == mst_bss
+         || msymbol->type == mst_abs
+         || msymbol->type == mst_file_data
+         || msymbol->type == mst_file_bss))
+    return NULL;
 
   ALL_PSYMTABS (objfile, pst)
   {
     if (pc >= pst->textlow && pc < pst->texthigh)
       {
-       struct minimal_symbol *msymbol;
        struct partial_symtab *tpst;
 
        /* An objfile that has its functions reordered might have
@@ -378,7 +387,6 @@ find_pc_sect_psymtab (CORE_ADDR pc, asection *section)
            section == 0)       /* can't validate section this way */
          return (pst);
 
-       msymbol = lookup_minimal_symbol_by_pc_section (pc, section);
        if (msymbol == NULL)
          return (pst);
 
@@ -563,6 +571,7 @@ lookup_symbol (const char *name, const struct block *block,
 {
   char *modified_name = NULL;
   char *modified_name2 = NULL;
+  const char *mangled_name = NULL;
   int needtofreename = 0;
   struct symbol *returnval;
 
@@ -588,13 +597,14 @@ lookup_symbol (const char *name, const struct block *block,
       modified_name2 = cplus_demangle (modified_name, DMGL_ANSI | DMGL_PARAMS);
       if (modified_name2)
        {
+         mangled_name = name;
          modified_name = modified_name2;
          needtofreename = 1;
        }
     }
 
-  returnval = lookup_symbol_aux (modified_name, block, namespace,
-                                is_a_field_of_this, symtab);
+  returnval = lookup_symbol_aux (modified_name, mangled_name, block,
+                                namespace, is_a_field_of_this, symtab);
   if (needtofreename)
     xfree (modified_name2);
 
@@ -602,9 +612,9 @@ lookup_symbol (const char *name, const struct block *block,
 }
 
 static struct symbol *
-lookup_symbol_aux (const char *name, const struct block *block,
-              const namespace_enum namespace, int *is_a_field_of_this,
-              struct symtab **symtab)
+lookup_symbol_aux (const char *name, const char *mangled_name,
+                  const struct block *block, const namespace_enum namespace,
+                  int *is_a_field_of_this, struct symtab **symtab)
 {
   register struct symbol *sym;
   register struct symtab *s = NULL;
@@ -619,7 +629,7 @@ lookup_symbol_aux (const char *name, const struct block *block,
 
   while (block != 0)
     {
-      sym = lookup_block_symbol (block, name, namespace);
+      sym = lookup_block_symbol (block, name, mangled_name, namespace);
       if (sym)
        {
          block_found = block;
@@ -672,7 +682,7 @@ lookup_symbol_aux (const char *name, const struct block *block,
        if (BLOCK_START (b) <= BLOCK_START (block)
            && BLOCK_END (b) > BLOCK_START (block))
          {
-           sym = lookup_block_symbol (b, name, VAR_NAMESPACE);
+           sym = lookup_block_symbol (b, name, mangled_name, VAR_NAMESPACE);
            if (sym)
              {
                block_found = b;
@@ -710,7 +720,7 @@ lookup_symbol_aux (const char *name, const struct block *block,
   {
     bv = BLOCKVECTOR (s);
     block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
-    sym = lookup_block_symbol (block, name, namespace);
+    sym = lookup_block_symbol (block, name, mangled_name, namespace);
     if (sym)
       {
        block_found = block;
@@ -739,14 +749,14 @@ lookup_symbol_aux (const char *name, const struct block *block,
              bv = BLOCKVECTOR (s);
              block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
              sym = lookup_block_symbol (block, SYMBOL_NAME (msymbol),
-                                        namespace);
+                                        mangled_name, namespace);
              /* We kept static functions in minimal symbol table as well as
                 in static scope. We want to find them in the symbol table. */
              if (!sym)
                {
                  block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
                  sym = lookup_block_symbol (block, SYMBOL_NAME (msymbol),
-                                            namespace);
+                                            mangled_name, namespace);
                }
 
              /* sym == 0 if symbol was found in the minimal symbol table
@@ -772,7 +782,7 @@ lookup_symbol_aux (const char *name, const struct block *block,
            {
              /* This is a mangled variable, look it up by its
                 mangled name.  */
-             return lookup_symbol_aux (SYMBOL_NAME (msymbol), block,
+             return lookup_symbol_aux (SYMBOL_NAME (msymbol), mangled_name, block,
                                        namespace, is_a_field_of_this, symtab);
            }
          /* There are no debug symbols for this file, or we are looking
@@ -790,7 +800,7 @@ lookup_symbol_aux (const char *name, const struct block *block,
        s = PSYMTAB_TO_SYMTAB (ps);
        bv = BLOCKVECTOR (s);
        block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
-       sym = lookup_block_symbol (block, name, namespace);
+       sym = lookup_block_symbol (block, name, mangled_name, namespace);
        if (!sym)
          {
            /* This shouldn't be necessary, but as a last resort
@@ -799,7 +809,7 @@ lookup_symbol_aux (const char *name, const struct block *block,
             * the psymtab gets it wrong in some cases.
             */
            block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
-           sym = lookup_block_symbol (block, name, namespace);
+           sym = lookup_block_symbol (block, name, mangled_name, namespace);
            if (!sym)
              error ("Internal: global symbol `%s' found in %s psymtab but not in symtab.\n\
 %s may be an inlined function, or may be a template function\n\
@@ -823,7 +833,7 @@ lookup_symbol_aux (const char *name, const struct block *block,
   {
     bv = BLOCKVECTOR (s);
     block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
-    sym = lookup_block_symbol (block, name, namespace);
+    sym = lookup_block_symbol (block, name, mangled_name, namespace);
     if (sym)
       {
        block_found = block;
@@ -840,7 +850,7 @@ lookup_symbol_aux (const char *name, const struct block *block,
        s = PSYMTAB_TO_SYMTAB (ps);
        bv = BLOCKVECTOR (s);
        block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
-       sym = lookup_block_symbol (block, name, namespace);
+       sym = lookup_block_symbol (block, name, mangled_name, namespace);
        if (!sym)
          {
            /* This shouldn't be necessary, but as a last resort
@@ -849,7 +859,7 @@ lookup_symbol_aux (const char *name, const struct block *block,
             * the psymtab gets it wrong in some cases.
             */
            block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
-           sym = lookup_block_symbol (block, name, namespace);
+           sym = lookup_block_symbol (block, name, mangled_name, namespace);
            if (!sym)
              error ("Internal: static symbol `%s' found in %s psymtab but not in symtab.\n\
 %s may be an inlined function, or may be a template function\n\
@@ -906,14 +916,14 @@ lookup_symbol_aux (const char *name, const struct block *block,
              bv = BLOCKVECTOR (s);
              block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
              sym = lookup_block_symbol (block, SYMBOL_NAME (msymbol),
-                                        namespace);
+                                        mangled_name, namespace);
              /* We kept static functions in minimal symbol table as well as
                 in static scope. We want to find them in the symbol table. */
              if (!sym)
                {
                  block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
                  sym = lookup_block_symbol (block, SYMBOL_NAME (msymbol),
-                                            namespace);
+                                            mangled_name, namespace);
                }
              /* If we found one, return it */
              if (sym)
@@ -950,8 +960,9 @@ lookup_symbol_aux (const char *name, const struct block *block,
                   && MSYMBOL_TYPE (msymbol) != mst_file_text
                   && !STREQ (name, SYMBOL_NAME (msymbol)))
            {
-             return lookup_symbol_aux (SYMBOL_NAME (msymbol), block,
-                                       namespace, is_a_field_of_this, symtab);
+             return lookup_symbol_aux (SYMBOL_NAME (msymbol), mangled_name,
+                                       block, namespace, is_a_field_of_this,
+                                       symtab);
            }
        }
     }
@@ -1077,7 +1088,7 @@ lookup_transparent_type (const char *name)
   {
     bv = BLOCKVECTOR (s);
     block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
-    sym = lookup_block_symbol (block, name, STRUCT_NAMESPACE);
+    sym = lookup_block_symbol (block, name, NULL, STRUCT_NAMESPACE);
     if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
       {
        return SYMBOL_TYPE (sym);
@@ -1091,7 +1102,7 @@ lookup_transparent_type (const char *name)
        s = PSYMTAB_TO_SYMTAB (ps);
        bv = BLOCKVECTOR (s);
        block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
-       sym = lookup_block_symbol (block, name, STRUCT_NAMESPACE);
+       sym = lookup_block_symbol (block, name, NULL, STRUCT_NAMESPACE);
        if (!sym)
          {
            /* This shouldn't be necessary, but as a last resort
@@ -1100,7 +1111,7 @@ lookup_transparent_type (const char *name)
             * the psymtab gets it wrong in some cases.
             */
            block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
-           sym = lookup_block_symbol (block, name, STRUCT_NAMESPACE);
+           sym = lookup_block_symbol (block, name, NULL, STRUCT_NAMESPACE);
            if (!sym)
              error ("Internal: global symbol `%s' found in %s psymtab but not in symtab.\n\
 %s may be an inlined function, or may be a template function\n\
@@ -1124,7 +1135,7 @@ lookup_transparent_type (const char *name)
   {
     bv = BLOCKVECTOR (s);
     block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
-    sym = lookup_block_symbol (block, name, STRUCT_NAMESPACE);
+    sym = lookup_block_symbol (block, name, NULL, STRUCT_NAMESPACE);
     if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
       {
        return SYMBOL_TYPE (sym);
@@ -1138,7 +1149,7 @@ lookup_transparent_type (const char *name)
        s = PSYMTAB_TO_SYMTAB (ps);
        bv = BLOCKVECTOR (s);
        block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
-       sym = lookup_block_symbol (block, name, STRUCT_NAMESPACE);
+       sym = lookup_block_symbol (block, name, NULL, STRUCT_NAMESPACE);
        if (!sym)
          {
            /* This shouldn't be necessary, but as a last resort
@@ -1147,7 +1158,7 @@ lookup_transparent_type (const char *name)
             * the psymtab gets it wrong in some cases.
             */
            block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
-           sym = lookup_block_symbol (block, name, STRUCT_NAMESPACE);
+           sym = lookup_block_symbol (block, name, NULL, STRUCT_NAMESPACE);
            if (!sym)
              error ("Internal: static symbol `%s' found in %s psymtab but not in symtab.\n\
 %s may be an inlined function, or may be a template function\n\
@@ -1174,7 +1185,7 @@ find_main_psymtab (void)
 
   ALL_PSYMTABS (objfile, pst)
   {
-    if (lookup_partial_symbol (pst, "main", 1, VAR_NAMESPACE))
+    if (lookup_partial_symbol (pst, main_name (), 1, VAR_NAMESPACE))
       {
        return (pst);
       }
@@ -1191,10 +1202,15 @@ find_main_psymtab (void)
    binary search terminates, we drop through and do a straight linear
    search on the symbols.  Each symbol which is marked as being a C++
    symbol (language_cplus set) has both the encoded and non-encoded names
-   tested for a match. */
+   tested for a match.
+
+   If MANGLED_NAME is non-NULL, verify that any symbol we find has this
+   particular mangled name.
+*/
 
 struct symbol *
 lookup_block_symbol (register const struct block *block, const char *name,
+                    const char *mangled_name,
                     const namespace_enum namespace)
 {
   register int bot, top, inc;
@@ -1254,24 +1270,33 @@ lookup_block_symbol (register const struct block *block, const char *name,
          return the first one; I believe it is now impossible for us
          to encounter two symbols with the same name and namespace
          here, because blocks containing argument symbols are no
-         longer sorted.  */
+         longer sorted.  The exception is for C++, where multiple functions
+        (cloned constructors / destructors, in particular) can have
+        the same demangled name.  So if we have a particular
+        mangled name to match, try to do so.  */
 
       top = BLOCK_NSYMS (block);
       while (bot < top)
        {
          sym = BLOCK_SYM (block, bot);
-         if (SYMBOL_NAMESPACE (sym) == namespace &&
-             SYMBOL_MATCHES_NAME (sym, name))
+         if (SYMBOL_NAMESPACE (sym) == namespace
+             && (mangled_name
+                 ? strcmp (SYMBOL_NAME (sym), mangled_name) == 0
+                 : SYMBOL_MATCHES_NAME (sym, name)))
            {
              return sym;
            }
+          if (SYMBOL_SOURCE_NAME (sym)[0] > name[0])
+            {
+              break;
+            }
          bot++;
        }
     }
 
   /* Here if block isn't sorted, or we fail to find a match during the
      binary search above.  If during the binary search above, we find a
-     symbol which is a C++ symbol, then we have re-enabled the linear
+     symbol which is a Java symbol, then we have re-enabled the linear
      search flag which was reset when starting the binary search.
 
      This loop is equivalent to the loop above, but hacked greatly for speed.
@@ -1289,8 +1314,10 @@ lookup_block_symbol (register const struct block *block, const char *name,
       while (bot < top)
        {
          sym = BLOCK_SYM (block, bot);
-         if (SYMBOL_NAMESPACE (sym) == namespace &&
-             SYMBOL_MATCHES_NAME (sym, name))
+         if (SYMBOL_NAMESPACE (sym) == namespace
+             && (mangled_name
+                 ? strcmp (SYMBOL_NAME (sym), mangled_name) == 0
+                 : SYMBOL_MATCHES_NAME (sym, name)))
            {
              /* If SYM has aliases, then use any alias that is active
                 at the current PC.  If no alias is active at the current
@@ -1389,6 +1416,21 @@ find_pc_sect_symtab (CORE_ADDR pc, asection *section)
   register struct partial_symtab *ps;
   register struct objfile *objfile;
   CORE_ADDR distance = 0;
+  struct minimal_symbol *msymbol;
+
+  /* If we know that this is not a text address, return failure.  This is
+     necessary because we loop based on the block's high and low code
+     addresses, which do not include the data ranges, and because
+     we call find_pc_sect_psymtab which has a similar restriction based
+     on the partial_symtab's texthigh and textlow.  */
+  msymbol = lookup_minimal_symbol_by_pc_section (pc, section);
+  if (msymbol
+      && (msymbol->type == mst_data
+         || msymbol->type == mst_bss
+         || msymbol->type == mst_abs
+         || msymbol->type == mst_file_data
+         || msymbol->type == mst_file_bss))
+    return NULL;
 
   /* Search all symtabs for the one whose file contains our address, and which
      is the smallest of all the ones containing the address.  This is designed
@@ -1620,6 +1662,13 @@ find_pc_sect_line (CORE_ADDR pc, struct sec *section, int notcurrent)
 
   INIT_SAL (&val);             /* initialize to zeroes */
 
+  /* It's tempting to assume that, if we can't find debugging info for
+     any function enclosing PC, that we shouldn't search for line
+     number info, either.  However, GAS can emit line number info for
+     assembly files --- very helpful when debugging hand-written
+     assembly code.  In such a case, we'd have no debug info for the
+     function, but we would have line info.  */
+
   if (notcurrent)
     pc -= 1;
 
@@ -1793,6 +1842,13 @@ find_pc_sect_line (CORE_ADDR pc, struct sec *section, int notcurrent)
          val.end = alt->pc;
        }
     }
+  else if (best->line == 0)
+    {
+      /* If our best fit is in a range of PC's for which no line
+        number info is available (line number is zero) then we didn't
+        find any valid line information. */
+      val.pc = pc;
+    }
   else
     {
       val.symtab = best_symtab;
@@ -2117,102 +2173,173 @@ operator_chars (char *p, char **end)
       return p;
     }
 
-  switch (*p)
-    {
-    case '!':
-    case '=':
-    case '*':
-    case '/':
-    case '%':
-    case '^':
-      if (p[1] == '=')
-       *end = p + 2;
-      else
+  while (*p)
+    switch (*p)
+      {
+      case '\\':                       /* regexp quoting */
+       if (p[1] == '*')
+         {
+           if (p[2] == '=')    /* 'operator\*=' */
+             *end = p + 3;
+           else                        /* 'operator\*'  */
+             *end = p + 2;
+           return p;
+         }
+       else if (p[1] == '[')
+         {
+           if (p[2] == ']')
+             error ("mismatched quoting on brackets, try 'operator\\[\\]'");
+           else if (p[2] == '\\' && p[3] == ']')
+             {
+               *end = p + 4;   /* 'operator\[\]' */
+               return p;
+             }
+           else
+             error ("nothing is allowed between '[' and ']'");
+         }
+       else 
+         {
+           /* Gratuitous qoute: skip it and move on. */
+           p++;
+           continue;
+         }
+       break;
+      case '!':
+      case '=':
+      case '*':
+      case '/':
+      case '%':
+      case '^':
+       if (p[1] == '=')
+         *end = p + 2;
+       else
+         *end = p + 1;
+       return p;
+      case '<':
+      case '>':
+      case '+':
+      case '-':
+      case '&':
+      case '|':
+       if (p[0] == '-' && p[1] == '>')
+         {
+           /* Struct pointer member operator 'operator->'. */
+           if (p[2] == '*')
+             {
+               *end = p + 3;   /* 'operator->*' */
+               return p;
+             }
+           else if (p[2] == '\\')
+             {
+               *end = p + 4;   /* Hopefully 'operator->\*' */
+               return p;
+             }
+           else
+             {
+               *end = p + 2;   /* 'operator->' */
+               return p;
+             }
+         }
+       if (p[1] == '=' || p[1] == p[0])
+         *end = p + 2;
+       else
+         *end = p + 1;
+       return p;
+      case '~':
+      case ',':
        *end = p + 1;
-      return p;
-    case '<':
-    case '>':
-    case '+':
-    case '-':
-    case '&':
-    case '|':
-      if (p[1] == '=' || p[1] == p[0])
+       return p;
+      case '(':
+       if (p[1] != ')')
+         error ("`operator ()' must be specified without whitespace in `()'");
        *end = p + 2;
-      else
-       *end = p + 1;
-      return p;
-    case '~':
-    case ',':
-      *end = p + 1;
-      return p;
-    case '(':
-      if (p[1] != ')')
-       error ("`operator ()' must be specified without whitespace in `()'");
-      *end = p + 2;
-      return p;
-    case '?':
-      if (p[1] != ':')
-       error ("`operator ?:' must be specified without whitespace in `?:'");
-      *end = p + 2;
-      return p;
-    case '[':
-      if (p[1] != ']')
-       error ("`operator []' must be specified without whitespace in `[]'");
-      *end = p + 2;
-      return p;
-    default:
-      error ("`operator %s' not supported", p);
-      break;
-    }
+       return p;
+      case '?':
+       if (p[1] != ':')
+         error ("`operator ?:' must be specified without whitespace in `?:'");
+       *end = p + 2;
+       return p;
+      case '[':
+       if (p[1] != ']')
+         error ("`operator []' must be specified without whitespace in `[]'");
+       *end = p + 2;
+       return p;
+      default:
+       error ("`operator %s' not supported", p);
+       break;
+      }
+
   *end = "";
   return *end;
 }
 \f
 
-/* Slave routine for sources_info.  Force line breaks at ,'s.
-   NAME is the name to print and *FIRST is nonzero if this is the first
-   name printed.  Set *FIRST to zero.  */
-static void
-output_source_filename (char *name, int *first)
+/* If FILE is not already in the table of files, return zero;
+   otherwise return non-zero.  Optionally add FILE to the table if ADD
+   is non-zero.  If *FIRST is non-zero, forget the old table
+   contents.  */
+static int
+filename_seen (const char *file, int add, int *first)
 {
-  /* 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
-     some are not, it gets printed both under "Source files for which
-     symbols have been read" and "Source files for which symbols will
-     be read in on demand".  I consider this a reasonable way to deal
-     with the situation.  I'm not sure whether this can also happen for
-     symtabs; it doesn't hurt to check.  */
-  static char **tab = NULL;
+  /* Table of files seen so far.  */
+  static const char **tab = NULL;
   /* Allocated size of tab in elements.
      Start with one 256-byte block (when using GNU malloc.c).
      24 is the malloc overhead when range checking is in effect.  */
   static int tab_alloc_size = (256 - 24) / sizeof (char *);
   /* Current size of tab in elements.  */
   static int tab_cur_size;
-
-  char **p;
+  const char **p;
 
   if (*first)
     {
       if (tab == NULL)
-       tab = (char **) xmalloc (tab_alloc_size * sizeof (*tab));
+       tab = (const char **) xmalloc (tab_alloc_size * sizeof (*tab));
       tab_cur_size = 0;
     }
 
-  /* Is NAME in tab?  */
+  /* Is FILE in tab?  */
   for (p = tab; p < tab + tab_cur_size; p++)
-    if (STREQ (*p, name))
-      /* Yes; don't print it again.  */
-      return;
-  /* No; add it to tab.  */
-  if (tab_cur_size == tab_alloc_size)
+    if (strcmp (*p, file) == 0)
+      return 1;
+
+  /* No; maybe add it to tab.  */
+  if (add)
     {
-      tab_alloc_size *= 2;
-      tab = (char **) xrealloc ((char *) tab, tab_alloc_size * sizeof (*tab));
+      if (tab_cur_size == tab_alloc_size)
+       {
+         tab_alloc_size *= 2;
+         tab = (const char **) xrealloc ((char *) tab,
+                                         tab_alloc_size * sizeof (*tab));
+       }
+      tab[tab_cur_size++] = file;
     }
-  tab[tab_cur_size++] = name;
 
+  return 0;
+}
+
+/* Slave routine for sources_info.  Force line breaks at ,'s.
+   NAME is the name to print and *FIRST is nonzero if this is the first
+   name printed.  Set *FIRST to zero.  */
+static void
+output_source_filename (char *name, int *first)
+{
+  /* 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 some are not, it gets
+     printed both under "Source files for which symbols have been
+     read" and "Source files for which symbols will be read in on
+     demand".  I consider this a reasonable way to deal with the
+     situation.  I'm not sure whether this can also happen for
+     symtabs; it doesn't hurt to check.  */
+
+  /* Was NAME already seen?  */
+  if (filename_seen (name, 1, first))
+    {
+      /* Yes; don't print it again.  */
+      return;
+    }
+  /* No; print it and reset *FIRST.  */
   if (*first)
     {
       *first = 0;
@@ -2270,7 +2397,7 @@ file_matches (char *file, char *files[], int nfiles)
     {
       for (i = 0; i < nfiles; i++)
        {
-         if (strcmp (files[i], basename (file)) == 0)
+         if (strcmp (files[i], lbasename (file)) == 0)
            return 1;
        }
     }
@@ -2305,6 +2432,52 @@ make_cleanup_free_search_symbols (struct symbol_search *symbols)
   return make_cleanup (do_free_search_symbols_cleanup, symbols);
 }
 
+/* Helper function for sort_search_symbols and qsort.  Can only
+   sort symbols, not minimal symbols.  */
+static int
+compare_search_syms (const void *sa, const void *sb)
+{
+  struct symbol_search **sym_a = (struct symbol_search **) sa;
+  struct symbol_search **sym_b = (struct symbol_search **) sb;
+
+  return strcmp (SYMBOL_SOURCE_NAME ((*sym_a)->symbol),
+                SYMBOL_SOURCE_NAME ((*sym_b)->symbol));
+}
+
+/* Sort the ``nfound'' symbols in the list after prevtail.  Leave
+   prevtail where it is, but update its next pointer to point to
+   the first of the sorted symbols.  */
+static struct symbol_search *
+sort_search_symbols (struct symbol_search *prevtail, int nfound)
+{
+  struct symbol_search **symbols, *symp, *old_next;
+  int i;
+
+  symbols = (struct symbol_search **) xmalloc (sizeof (struct symbol_search *)
+                                              * nfound);
+  symp = prevtail->next;
+  for (i = 0; i < nfound; i++)
+    {
+      symbols[i] = symp;
+      symp = symp->next;
+    }
+  /* Generally NULL.  */
+  old_next = symp;
+
+  qsort (symbols, nfound, sizeof (struct symbol_search *),
+        compare_search_syms);
+
+  symp = prevtail;
+  for (i = 0; i < nfound; i++)
+    {
+      symp->next = symbols[i];
+      symp = symp->next;
+    }
+  symp->next = old_next;
+
+  xfree (symbols);
+  return symp;
+}
 
 /* Search the symbol table for matches to the regular expression REGEXP,
    returning the results in *MATCHES.
@@ -2317,6 +2490,9 @@ make_cleanup_free_search_symbols (struct symbol_search *symbols)
    and constants (enums)
 
    free_search_symbols should be called when *MATCHES is no longer needed.
+
+   The results are sorted locally; each symtab's global and static blocks are
+   separately alphabetized.
  */
 void
 search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[],
@@ -2393,7 +2569,7 @@ search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[],
          /* If wrong number of spaces, fix it. */
          if (fix >= 0)
            {
-             char *tmp = (char *) alloca (opend - opname + 10);
+             char *tmp = (char *) alloca (8 + fix + strlen (opname) + 1);
              sprintf (tmp, "operator%.*s%s", fix, " ", opname);
              regexp = tmp;
            }
@@ -2506,10 +2682,9 @@ search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[],
     if (bv != prev_bv)
       for (i = GLOBAL_BLOCK; i <= STATIC_BLOCK; i++)
        {
+         struct symbol_search *prevtail = tail;
+         int nfound = 0;
          b = BLOCKVECTOR_BLOCK (bv, i);
-         /* Skip the sort if this block is always sorted.  */
-         if (!BLOCK_SHOULD_SORT (b))
-           sort_block_syms (b);
          for (j = 0; j < BLOCK_NSYMS (b); j++)
            {
              QUIT;
@@ -2531,14 +2706,27 @@ search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[],
                  psr->msymbol = NULL;
                  psr->next = NULL;
                  if (tail == NULL)
-                   {
-                     sr = psr;
-                     old_chain = make_cleanup_free_search_symbols (sr);
-                   }
+                   sr = psr;
                  else
                    tail->next = psr;
                  tail = psr;
+                 nfound ++;
+               }
+           }
+         if (nfound > 0)
+           {
+             if (prevtail == NULL)
+               {
+                 struct symbol_search dummy;
+
+                 dummy.next = sr;
+                 tail = sort_search_symbols (&dummy, nfound);
+                 sr = dummy.next;
+
+                 old_chain = make_cleanup_free_search_symbols (sr);
                }
+             else
+               tail = sort_search_symbols (prevtail, nfound);
            }
        }
     prev_bv = bv;
@@ -2660,9 +2848,17 @@ print_symbol_info (namespace_enum kind, struct symtab *s, struct symbol *sym,
 static void
 print_msymbol_info (struct minimal_symbol *msymbol)
 {
-  printf_filtered ("   %08lx  %s\n",
-                  (unsigned long) SYMBOL_VALUE_ADDRESS (msymbol),
-                  SYMBOL_SOURCE_NAME (msymbol));
+  char *tmp;
+
+  if (TARGET_ADDR_BIT <= 32)
+    tmp = longest_local_hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol)
+                                          & (CORE_ADDR) 0xffffffff,
+                                          "08l");
+  else
+    tmp = longest_local_hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol),
+                                          "016l");
+  printf_filtered ("%s  %s\n",
+                  tmp, SYMBOL_SOURCE_NAME (msymbol));
 }
 
 /* This is the guts of the commands "info functions", "info types", and
@@ -2747,13 +2943,13 @@ methods_info (char *regexp)
 #endif /* 0 */
 
 /* Breakpoint all functions matching regular expression. */
-#ifdef UI_OUT
+
 void
 rbreak_command_wrapper (char *regexp, int from_tty)
 {
   rbreak_command (regexp, from_tty);
 }
-#endif
+
 static void
 rbreak_command (char *regexp, int from_tty)
 {
@@ -2844,17 +3040,6 @@ completion_list_add_name (char *symname, char *sym_text, int sym_text_len,
       return;
     }
 
-  /* Clip any symbol names that we've already considered.  (This is a
-     time optimization)  */
-
-  for (i = 0; i < return_val_index; ++i)
-    {
-      if (STREQ (symname, return_val[i]))
-       {
-         return;
-       }
-    }
-
   /* We have a match for a completion, so add SYMNAME to the current list
      of matches. Note that the name is moved to freshly malloc'd space. */
 
@@ -2880,19 +3065,6 @@ completion_list_add_name (char *symname, char *sym_text, int sym_text_len,
        strcat (new, symname);
       }
 
-    /* Recheck for duplicates if we intend to add a modified symbol.  */
-    if (word != sym_text)
-      {
-       for (i = 0; i < return_val_index; ++i)
-         {
-           if (STREQ (new, return_val[i]))
-             {
-               xfree (new);
-               return;
-             }
-         }
-      }
-
     if (return_val_index + 3 > return_val_size)
       {
        newsize = (return_val_size *= 2) * sizeof (char *);
@@ -2903,9 +3075,9 @@ completion_list_add_name (char *symname, char *sym_text, int sym_text_len,
   }
 }
 
-/* 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.
+/* 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.  */
@@ -2959,7 +3131,11 @@ make_symbol_completion_list (char *text, char *word)
     else if (quote_found == '"')
       /* A double-quoted string is never a symbol, nor does it make sense
          to complete it any other way.  */
-      return NULL;
+      {
+       return_val = (char **) xmalloc (sizeof (char *));
+       return_val[0] = NULL;
+       return return_val;
+      }
     else
       {
        /* It is not a quoted string.  Break it based on the characters
@@ -3036,9 +3212,8 @@ make_symbol_completion_list (char *text, char *word)
       /* 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++)
+      ALL_BLOCK_SYMBOLS (b, i, sym)
        {
-         sym = BLOCK_SYM (b, i);
          COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
          if (SYMBOL_CLASS (sym) == LOC_TYPEDEF)
            {
@@ -3067,9 +3242,8 @@ make_symbol_completion_list (char *text, char *word)
   {
     QUIT;
     b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
-    for (i = 0; i < BLOCK_NSYMS (b); i++)
+    ALL_BLOCK_SYMBOLS (b, i, sym)
       {
-       sym = BLOCK_SYM (b, i);
        COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
       }
   }
@@ -3081,9 +3255,8 @@ make_symbol_completion_list (char *text, char *word)
     /* Don't do this block twice.  */
     if (b == surrounding_static_block)
       continue;
-    for (i = 0; i < BLOCK_NSYMS (b); i++)
+    ALL_BLOCK_SYMBOLS (b, i, sym)
       {
-       sym = BLOCK_SYM (b, i);
        COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
       }
   }
@@ -3091,6 +3264,275 @@ make_symbol_completion_list (char *text, char *word)
   return (return_val);
 }
 
+/* Like make_symbol_completion_list, but returns a list of symbols
+   defined in a source file FILE.  */
+
+char **
+make_file_symbol_completion_list (char *text, char *word, char *srcfile)
+{
+  register struct symbol *sym;
+  register struct symtab *s;
+  register struct block *b;
+  register int i;
+  /* The symbol we are completing on.  Points in same buffer as text.  */
+  char *sym_text;
+  /* Length of sym_text.  */
+  int sym_text_len;
+
+  /* Now look for the symbol we are supposed to complete on.
+     FIXME: This should be language-specific.  */
+  {
+    char *p;
+    char quote_found;
+    char *quote_pos = NULL;
+
+    /* First see if this is a quoted string.  */
+    quote_found = '\0';
+    for (p = text; *p != '\0'; ++p)
+      {
+       if (quote_found != '\0')
+         {
+           if (*p == quote_found)
+             /* Found close quote.  */
+             quote_found = '\0';
+           else if (*p == '\\' && p[1] == quote_found)
+             /* A backslash followed by the quote character
+                doesn't end the string.  */
+             ++p;
+         }
+       else if (*p == '\'' || *p == '"')
+         {
+           quote_found = *p;
+           quote_pos = p;
+         }
+      }
+    if (quote_found == '\'')
+      /* A string within single quotes can be a symbol, so complete on it.  */
+      sym_text = quote_pos + 1;
+    else if (quote_found == '"')
+      /* A double-quoted string is never a symbol, nor does it make sense
+         to complete it any other way.  */
+      {
+       return_val = (char **) xmalloc (sizeof (char *));
+       return_val[0] = NULL;
+       return return_val;
+      }
+    else
+      {
+       /* It is not a quoted string.  Break it based on the characters
+          which are in symbols.  */
+       while (p > text)
+         {
+           if (isalnum (p[-1]) || p[-1] == '_' || p[-1] == '\0')
+             --p;
+           else
+             break;
+         }
+       sym_text = p;
+      }
+  }
+
+  sym_text_len = strlen (sym_text);
+
+  return_val_size = 10;
+  return_val_index = 0;
+  return_val = (char **) xmalloc ((return_val_size + 1) * sizeof (char *));
+  return_val[0] = NULL;
+
+  /* Find the symtab for SRCFILE (this loads it if it was not yet read
+     in).  */
+  s = lookup_symtab (srcfile);
+  if (s == NULL)
+    {
+      /* Maybe they typed the file with leading directories, while the
+        symbol tables record only its basename.  */
+      const char *tail = lbasename (srcfile);
+
+      if (tail > srcfile)
+       s = lookup_symtab (tail);
+    }
+
+  /* If we have no symtab for that file, return an empty list.  */
+  if (s == NULL)
+    return (return_val);
+
+  /* Go through this symtab and check the externs and statics for
+     symbols which match.  */
+
+  b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
+  ALL_BLOCK_SYMBOLS (b, i, sym)
+    {
+      COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
+    }
+
+  b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
+  ALL_BLOCK_SYMBOLS (b, i, sym)
+    {
+      COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
+    }
+
+  return (return_val);
+}
+
+/* A helper function for make_source_files_completion_list.  It adds
+   another file name to a list of possible completions, growing the
+   list as necessary.  */
+
+static void
+add_filename_to_list (const char *fname, char *text, char *word,
+                     char ***list, int *list_used, int *list_alloced)
+{
+  char *new;
+  size_t fnlen = strlen (fname);
+
+  if (*list_used + 1 >= *list_alloced)
+    {
+      *list_alloced *= 2;
+      *list = (char **) xrealloc ((char *) *list,
+                                 *list_alloced * sizeof (char *));
+    }
+
+  if (word == text)
+    {
+      /* Return exactly fname.  */
+      new = xmalloc (fnlen + 5);
+      strcpy (new, fname);
+    }
+  else if (word > text)
+    {
+      /* Return some portion of fname.  */
+      new = xmalloc (fnlen + 5);
+      strcpy (new, fname + (word - text));
+    }
+  else
+    {
+      /* Return some of TEXT plus fname.  */
+      new = xmalloc (fnlen + (text - word) + 5);
+      strncpy (new, word, text - word);
+      new[text - word] = '\0';
+      strcat (new, fname);
+    }
+  (*list)[*list_used] = new;
+  (*list)[++*list_used] = NULL;
+}
+
+static int
+not_interesting_fname (const char *fname)
+{
+  static const char *illegal_aliens[] = {
+    "_globals_",       /* inserted by coff_symtab_read */
+    NULL
+  };
+  int i;
+
+  for (i = 0; illegal_aliens[i]; i++)
+    {
+      if (strcmp (fname, illegal_aliens[i]) == 0)
+       return 1;
+    }
+  return 0;
+}
+
+/* Return a NULL terminated array of all source files whose names
+   begin with matching TEXT.  The file names are looked up in the
+   symbol tables of this program.  If the answer is no matchess, then
+   the return value is an array which contains only a NULL pointer.  */
+
+char **
+make_source_files_completion_list (char *text, char *word)
+{
+  register struct symtab *s;
+  register struct partial_symtab *ps;
+  register struct objfile *objfile;
+  int first = 1;
+  int list_alloced = 1;
+  int list_used = 0;
+  size_t text_len = strlen (text);
+  char **list = (char **) xmalloc (list_alloced * sizeof (char *));
+  const char *base_name;
+
+  list[0] = NULL;
+
+  if (!have_full_symbols () && !have_partial_symbols ())
+    return list;
+
+  ALL_SYMTABS (objfile, s)
+    {
+      if (not_interesting_fname (s->filename))
+       continue;
+      if (!filename_seen (s->filename, 1, &first)
+#if HAVE_DOS_BASED_FILE_SYSTEM
+         && strncasecmp (s->filename, text, text_len) == 0
+#else
+         && strncmp (s->filename, text, text_len) == 0
+#endif
+         )
+       {
+         /* This file matches for a completion; add it to the current
+            list of matches.  */
+         add_filename_to_list (s->filename, text, word,
+                               &list, &list_used, &list_alloced);
+       }
+      else
+       {
+         /* NOTE: We allow the user to type a base name when the
+            debug info records leading directories, but not the other
+            way around.  This is what subroutines of breakpoint
+            command do when they parse file names.  */
+         base_name = lbasename (s->filename);
+         if (base_name != s->filename
+             && !filename_seen (base_name, 1, &first)
+#if HAVE_DOS_BASED_FILE_SYSTEM
+             && strncasecmp (base_name, text, text_len) == 0
+#else
+             && strncmp (base_name, text, text_len) == 0
+#endif
+             )
+           add_filename_to_list (base_name, text, word,
+                                 &list, &list_used, &list_alloced);
+       }
+    }
+
+  ALL_PSYMTABS (objfile, ps)
+    {
+      if (not_interesting_fname (ps->filename))
+       continue;
+      if (!ps->readin)
+       {
+         if (!filename_seen (ps->filename, 1, &first)
+#if HAVE_DOS_BASED_FILE_SYSTEM
+             && strncasecmp (ps->filename, text, text_len) == 0
+#else
+             && strncmp (ps->filename, text, text_len) == 0
+#endif
+             )
+           {
+             /* This file matches for a completion; add it to the
+                current list of matches.  */
+             add_filename_to_list (ps->filename, text, word,
+                                   &list, &list_used, &list_alloced);
+
+           }
+         else
+           {
+             base_name = lbasename (ps->filename);
+             if (base_name != ps->filename
+                 && !filename_seen (base_name, 1, &first)
+#if HAVE_DOS_BASED_FILE_SYSTEM
+                 && strncasecmp (base_name, text, text_len) == 0
+#else
+                 && strncmp (base_name, text, text_len) == 0
+#endif
+                 )
+               add_filename_to_list (base_name, text, word,
+                                     &list, &list_used, &list_alloced);
+           }
+       }
+    }
+
+  return list;
+}
+
 /* Determine if PC is in the prologue of a function.  The prologue is the area
    between the first instruction of a function, and the first executable line.
    Returns 1 if PC *might* be in prologue, 0 if definately *not* in prologue.
@@ -3303,9 +3745,8 @@ make_symbol_overload_list (struct symbol *fsym)
       /* 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++)
+      ALL_BLOCK_SYMBOLS (b, i, sym)
        {
-         sym = BLOCK_SYM (b, i);
          overload_list_add_symbol (sym, oload_name);
        }
     }
@@ -3317,9 +3758,8 @@ make_symbol_overload_list (struct symbol *fsym)
   {
     QUIT;
     b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
-    for (i = 0; i < BLOCK_NSYMS (b); i++)
+    ALL_BLOCK_SYMBOLS (b, i, sym)
       {
-       sym = BLOCK_SYM (b, i);
        overload_list_add_symbol (sym, oload_name);
       }
   }
@@ -3331,9 +3771,8 @@ make_symbol_overload_list (struct symbol *fsym)
     /* Don't do this block twice.  */
     if (b == surrounding_static_block)
       continue;
-    for (i = 0; i < BLOCK_NSYMS (b); i++)
+    ALL_BLOCK_SYMBOLS (b, i, sym)
       {
-       sym = BLOCK_SYM (b, i);
        overload_list_add_symbol (sym, oload_name);
       }
   }
@@ -3359,6 +3798,33 @@ decode_line_spec (char *string, int funfirstline)
   return sals;
 }
 
+/* Track MAIN */
+static char *name_of_main;
+
+void
+set_main_name (const char *name)
+{
+  if (name_of_main != NULL)
+    {
+      xfree (name_of_main);
+      name_of_main = NULL;
+    }
+  if (name != NULL)
+    {
+      name_of_main = xstrdup (name);
+    }
+}
+
+char *
+main_name (void)
+{
+  if (name_of_main != NULL)
+    return name_of_main;
+  else
+    return "main";
+}
+
+
 void
 _initialize_symtab (void)
 {
This page took 0.042982 seconds and 4 git commands to generate.