]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/symtab.c
2011-01-05 Michael Snyder <msnyder@vmware.com>
[thirdparty/binutils-gdb.git] / gdb / symtab.c
index b10cdc8620c20a849490d707a4ca6c7533d17fc0..bdf34d6d3ade8a2a22d83247abdbf1d54c9eb06e 100644 (file)
@@ -2,7 +2,7 @@
 
    Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
    1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007, 2008, 2009,
-   2010 Free Software Foundation, Inc.
+   2010, 2011 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -39,6 +39,7 @@
 #include "source.h"
 #include "filenames.h"         /* for FILENAME_CMP */
 #include "objc-lang.h"
+#include "d-lang.h"
 #include "ada-lang.h"
 #include "p-lang.h"
 #include "addrmap.h"
@@ -190,6 +191,7 @@ got_symtab:
     if (full_path != NULL)
       {
         const char *fp = symtab_to_fullname (s);
+
         if (fp != NULL && FILENAME_CMP (full_path, fp) == 0)
           {
             return s;
@@ -199,9 +201,11 @@ got_symtab:
     if (real_path != NULL)
       {
         char *fullname = symtab_to_fullname (s);
+
         if (fullname != NULL)
           {
             char *rp = gdb_realpath (fullname);
+
             make_cleanup (xfree, rp);
             if (FILENAME_CMP (real_path, rp) == 0)
               {
@@ -287,8 +291,8 @@ gdb_mangle_name (struct type *type, int method_id, int signature_id)
 
   is_full_physname_constructor = is_constructor_name (physname);
 
-  is_constructor =
-    is_full_physname_constructor || (newname && strcmp (field_name, newname) == 0);
+  is_constructor = is_full_physname_constructor 
+    || (newname && strcmp (field_name, newname) == 0);
 
   if (!is_destructor)
     is_destructor = (strncmp (physname, "__dt", 4) == 0);
@@ -319,13 +323,12 @@ gdb_mangle_name (struct type *type, int method_id, int signature_id)
   mangled_name_len = ((is_constructor ? 0 : strlen (field_name))
                      + strlen (buf) + len + strlen (physname) + 1);
 
-    {
-      mangled_name = (char *) xmalloc (mangled_name_len);
-      if (is_constructor)
-       mangled_name[0] = '\0';
-      else
-       strcpy (mangled_name, field_name);
-    }
+  mangled_name = (char *) xmalloc (mangled_name_len);
+  if (is_constructor)
+    mangled_name[0] = '\0';
+  else
+    strcpy (mangled_name, field_name);
+
   strcat (mangled_name, buf);
   /* If the class doesn't have a name, i.e. newname NULL, then we just
      mangle it using 0 for the length of the class.  Thus it gets mangled
@@ -337,20 +340,74 @@ gdb_mangle_name (struct type *type, int method_id, int signature_id)
   return (mangled_name);
 }
 
+/* Initialize the cplus_specific structure.  'cplus_specific' should
+   only be allocated for use with cplus symbols.  */
+
+static void
+symbol_init_cplus_specific (struct general_symbol_info *gsymbol,
+                           struct objfile *objfile)
+{
+  /* A language_specific structure should not have been previously
+     initialized.  */
+  gdb_assert (gsymbol->language_specific.cplus_specific == NULL);
+  gdb_assert (objfile != NULL);
+
+  gsymbol->language_specific.cplus_specific =
+      OBSTACK_ZALLOC (&objfile->objfile_obstack, struct cplus_specific);
+}
+
+/* Set the demangled name of GSYMBOL to NAME.  NAME must be already
+   correctly allocated.  For C++ symbols a cplus_specific struct is
+   allocated so OBJFILE must not be NULL. If this is a non C++ symbol
+   OBJFILE can be NULL.  */
+void
+symbol_set_demangled_name (struct general_symbol_info *gsymbol,
+                           char *name,
+                           struct objfile *objfile)
+{
+  if (gsymbol->language == language_cplus)
+    {
+      if (gsymbol->language_specific.cplus_specific == NULL)
+       symbol_init_cplus_specific (gsymbol, objfile);
+
+      gsymbol->language_specific.cplus_specific->demangled_name = name;
+    }
+  else
+    gsymbol->language_specific.mangled_lang.demangled_name = name;
+}
+
+/* Return the demangled name of GSYMBOL.  */
+char *
+symbol_get_demangled_name (const struct general_symbol_info *gsymbol)
+{
+  if (gsymbol->language == language_cplus)
+    {
+      if (gsymbol->language_specific.cplus_specific != NULL)
+       return gsymbol->language_specific.cplus_specific->demangled_name;
+      else
+       return NULL;
+    }
+  else
+    return gsymbol->language_specific.mangled_lang.demangled_name;
+}
+
 \f
 /* Initialize the language dependent portion of a symbol
    depending upon the language for the symbol. */
 void
-symbol_init_language_specific (struct general_symbol_info *gsymbol,
-                              enum language language)
+symbol_set_language (struct general_symbol_info *gsymbol,
+                     enum language language)
 {
   gsymbol->language = language;
-  if (gsymbol->language == language_cplus
+  if (gsymbol->language == language_d
       || gsymbol->language == language_java
-      || gsymbol->language == language_objc)
+      || gsymbol->language == language_objc
+      || gsymbol->language == language_fortran)
     {
-      gsymbol->language_specific.cplus_specific.demangled_name = NULL;
+      symbol_set_demangled_name (gsymbol, NULL, NULL);
     }
+  else if (gsymbol->language == language_cplus)
+    gsymbol->language_specific.cplus_specific = NULL;
   else
     {
       memset (&gsymbol->language_specific, 0,
@@ -372,6 +429,7 @@ static hashval_t
 hash_demangled_name_entry (const void *data)
 {
   const struct demangled_name_entry *e = data;
+
   return htab_hash_string (e->mangled);
 }
 
@@ -381,6 +439,7 @@ eq_demangled_name_entry (const void *a, const void *b)
 {
   const struct demangled_name_entry *da = a;
   const struct demangled_name_entry *db = b;
+
   return strcmp (da->mangled, db->mangled) == 0;
 }
 
@@ -449,6 +508,21 @@ symbol_find_demangled_name (struct general_symbol_info *gsymbol,
          return demangled;
        }
     }
+  if (gsymbol->language == language_d
+      || gsymbol->language == language_auto)
+    {
+      demangled = d_demangle(mangled, 0);
+      if (demangled != NULL)
+       {
+         gsymbol->language = language_d;
+         return demangled;
+       }
+    }
+  /* We could support `gsymbol->language == language_fortran' here to provide
+     module namespaces also for inferiors with only minimal symbol table (ELF
+     symbols).  Just the mangling standard is not standardized across compilers
+     and there is no DW_AT_producer available for inferiors with only the ELF
+     symbols to check the mangling kind.  */
   return NULL;
 }
 
@@ -515,7 +589,7 @@ symbol_set_names (struct general_symbol_info *gsymbol,
          memcpy (gsymbol->name, linkage_name, len);
          gsymbol->name[len] = '\0';
        }
-      gsymbol->language_specific.cplus_specific.demangled_name = NULL;
+      symbol_set_demangled_name (gsymbol, NULL, NULL);
 
       return;
     }
@@ -529,8 +603,8 @@ symbol_set_names (struct general_symbol_info *gsymbol,
   if (gsymbol->language == language_java)
     {
       char *alloc_name;
-      lookup_len = len + JAVA_PREFIX_LEN;
 
+      lookup_len = len + JAVA_PREFIX_LEN;
       alloc_name = alloca (lookup_len + 1);
       memcpy (alloc_name, JAVA_PREFIX, JAVA_PREFIX_LEN);
       memcpy (alloc_name + JAVA_PREFIX_LEN, linkage_name, len);
@@ -542,8 +616,8 @@ symbol_set_names (struct general_symbol_info *gsymbol,
   else if (linkage_name[len] != '\0')
     {
       char *alloc_name;
-      lookup_len = len;
 
+      lookup_len = len;
       alloc_name = alloca (lookup_len + 1);
       memcpy (alloc_name, linkage_name, len);
       alloc_name[lookup_len] = '\0';
@@ -578,7 +652,7 @@ symbol_set_names (struct general_symbol_info *gsymbol,
         
         It turns out that it is actually important to still save such
         an entry in the hash table, because storing this name gives
-        us better backache hit rates for partial symbols.  */
+        us better bcache hit rates for partial symbols.  */
       if (!copy_name && lookup_name == linkage_name)
        {
          *slot = obstack_alloc (&objfile->objfile_obstack,
@@ -611,10 +685,9 @@ symbol_set_names (struct general_symbol_info *gsymbol,
 
   gsymbol->name = (*slot)->mangled + lookup_len - len;
   if ((*slot)->demangled[0] != '\0')
-    gsymbol->language_specific.cplus_specific.demangled_name
-      = (*slot)->demangled;
+    symbol_set_demangled_name (gsymbol, (*slot)->demangled, objfile);
   else
-    gsymbol->language_specific.cplus_specific.demangled_name = NULL;
+    symbol_set_demangled_name (gsymbol, NULL, objfile);
 }
 
 /* Return the source code name of a symbol.  In languages where
@@ -626,14 +699,16 @@ symbol_natural_name (const struct general_symbol_info *gsymbol)
   switch (gsymbol->language)
     {
     case language_cplus:
+    case language_d:
     case language_java:
     case language_objc:
-      if (gsymbol->language_specific.cplus_specific.demangled_name != NULL)
-       return gsymbol->language_specific.cplus_specific.demangled_name;
+    case language_fortran:
+      if (symbol_get_demangled_name (gsymbol) != NULL)
+       return symbol_get_demangled_name (gsymbol);
       break;
     case language_ada:
-      if (gsymbol->language_specific.cplus_specific.demangled_name != NULL)
-       return gsymbol->language_specific.cplus_specific.demangled_name;
+      if (symbol_get_demangled_name (gsymbol) != NULL)
+       return symbol_get_demangled_name (gsymbol);
       else
        return ada_decode_symbol (gsymbol);
       break;
@@ -651,14 +726,16 @@ symbol_demangled_name (const struct general_symbol_info *gsymbol)
   switch (gsymbol->language)
     {
     case language_cplus:
+    case language_d:
     case language_java:
     case language_objc:
-      if (gsymbol->language_specific.cplus_specific.demangled_name != NULL)
-       return gsymbol->language_specific.cplus_specific.demangled_name;
+    case language_fortran:
+      if (symbol_get_demangled_name (gsymbol) != NULL)
+       return symbol_get_demangled_name (gsymbol);
       break;
     case language_ada:
-      if (gsymbol->language_specific.cplus_specific.demangled_name != NULL)
-       return gsymbol->language_specific.cplus_specific.demangled_name;
+      if (symbol_get_demangled_name (gsymbol) != NULL)
+       return symbol_get_demangled_name (gsymbol);
       else
        return ada_decode_symbol (gsymbol);
       break;
@@ -782,6 +859,7 @@ find_pc_sect_symtab_via_partial (CORE_ADDR pc, struct obj_section *section)
   ALL_OBJFILES (objfile)
   {
     struct symtab *result = NULL;
+
     if (objfile->sf)
       result = objfile->sf->qf->find_pc_sect_symtab (objfile, msymbol,
                                                     pc, section, 0);
@@ -851,6 +929,7 @@ fixup_section (struct general_symbol_info *ginfo,
         a search of the section table.  */
 
       struct obj_section *s;
+
       ALL_OBJFILE_OSECTIONS (objfile, s)
        {
          int idx = s->the_bfd_section->index;
@@ -940,8 +1019,8 @@ lookup_symbol_in_language (const char *name, const struct block *block,
 
   modified_name = name;
 
-  /* If we are using C++ or Java, demangle the name before doing a lookup, so
-     we can always binary search. */
+  /* If we are using C++, D, or Java, demangle the name before doing a
+     lookup, so we can always binary search. */
   if (lang == language_cplus)
     {
       demangled_name = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS);
@@ -972,6 +1051,15 @@ lookup_symbol_in_language (const char *name, const struct block *block,
          make_cleanup (xfree, demangled_name);
        }
     }
+  else if (lang == language_d)
+    {
+      demangled_name = d_demangle (name, 0);
+      if (demangled_name)
+       {
+         modified_name = demangled_name;
+         make_cleanup (xfree, demangled_name);
+       }
+    }
 
   if (case_sensitivity == case_sensitive_off)
     {
@@ -1017,7 +1105,6 @@ lookup_symbol_aux (const char *name, const struct block *block,
 {
   struct symbol *sym;
   const struct language_defn *langdef;
-  struct objfile *objfile;
 
   /* Make sure we do something sensible with is_a_field_of_this, since
      the callers that set this parameter to some non-null value will
@@ -1044,6 +1131,7 @@ lookup_symbol_aux (const char *name, const struct block *block,
     {
       struct symbol *sym = NULL;
       const struct block *function_block = block;
+
       /* 'this' is only defined in the function's block, so find the
         enclosing function block.  */
       for (; function_block && !BLOCK_FUNCTION (function_block);
@@ -1084,10 +1172,21 @@ lookup_symbol_aux (const char *name, const struct block *block,
     return sym;
 
   /* Now search all static file-level symbols.  Not strictly correct,
-     but more useful than an error.  Do the symtabs first, then check
-     the psymtabs.  If a psymtab indicates the existence of the
-     desired name as a file-level static, then do psymtab-to-symtab
-     conversion on the fly and return the found symbol. */
+     but more useful than an error.  */
+
+  return lookup_static_symbol_aux (name, domain);
+}
+
+/* Search all static file-level symbols for NAME from DOMAIN.  Do the symtabs
+   first, then check the psymtabs.  If a psymtab indicates the existence of the
+   desired name as a file-level static, then do psymtab-to-symtab conversion on
+   the fly and return the found symbol. */
+
+struct symbol *
+lookup_static_symbol_aux (const char *name, const domain_enum domain)
+{
+  struct objfile *objfile;
+  struct symbol *sym;
 
   sym = lookup_symbol_aux_symtabs (STATIC_BLOCK, name, domain);
   if (sym != NULL)
@@ -1126,14 +1225,10 @@ lookup_symbol_aux_local (const char *name, const struct block *block,
       if (sym != NULL)
        return sym;
 
-      if (language == language_cplus)
+      if (language == language_cplus || language == language_fortran)
         {
-          sym = cp_lookup_symbol_imports (scope,
-                                          name,
-                                          block,
-                                          domain,
-                                          1,
-                                          1);
+          sym = cp_lookup_symbol_imports_or_template (scope, name, block,
+                                                     domain);
           if (sym != NULL)
             return sym;
         }
@@ -1150,7 +1245,7 @@ lookup_symbol_aux_local (const char *name, const struct block *block,
 
 /* Look up OBJFILE to BLOCK.  */
 
-static struct objfile *
+struct objfile *
 lookup_objfile_from_block (const struct block *block)
 {
   struct objfile *obj;
@@ -1247,16 +1342,25 @@ lookup_symbol_aux_symtabs (int block_index, const char *name,
   const struct block *block;
   struct symtab *s;
 
-  ALL_PRIMARY_SYMTABS (objfile, s)
+  ALL_OBJFILES (objfile)
   {
-    bv = BLOCKVECTOR (s);
-    block = BLOCKVECTOR_BLOCK (bv, block_index);
-    sym = lookup_block_symbol (block, name, domain);
-    if (sym)
-      {
-       block_found = block;
-       return fixup_symbol_section (sym, objfile);
-      }
+    if (objfile->sf)
+      objfile->sf->qf->pre_expand_symtabs_matching (objfile,
+                                                   block_index,
+                                                   name, domain);
+
+    ALL_OBJFILE_SYMTABS (objfile, s)
+      if (s->primary)
+       {
+         bv = BLOCKVECTOR (s);
+         block = BLOCKVECTOR_BLOCK (bv, block_index);
+         sym = lookup_block_symbol (block, name, domain);
+         if (sym)
+           {
+             block_found = block;
+             return fixup_symbol_section (sym, objfile);
+           }
+       }
   }
 
   return NULL;
@@ -1272,7 +1376,6 @@ lookup_symbol_aux_quick (struct objfile *objfile, int kind,
   struct symtab *symtab;
   struct blockvector *bv;
   const struct block *block;
-  struct partial_symtab *ps;
   struct symbol *sym;
 
   if (!objfile->sf)
@@ -1302,7 +1405,10 @@ lookup_symbol_aux_quick (struct objfile *objfile, int kind,
                                 STATIC_BLOCK : GLOBAL_BLOCK);
       sym = lookup_block_symbol (block, name, domain);
       if (!sym)
-       error (_("Internal: %s symbol `%s' found in %s psymtab but not in symtab.\n%s may be an inlined function, or may be a template function\n(if a template, try specifying an instantiation: %s<type>)."),
+       error (_("\
+Internal: %s symbol `%s' found in %s psymtab but not in symtab.\n\
+%s may be an inlined function, or may be a template function\n\
+(if a template, try specifying an instantiation: %s<type>)."),
               kind == GLOBAL_BLOCK ? "global" : "static",
               name, symtab->filename, name, name);
     }
@@ -1412,6 +1518,7 @@ symbol_matches_domain (enum language symbol_language,
      A Java class declaration also defines a typedef for the class.
      Similarly, any Ada type declaration implicitly defines a typedef.  */
   if (symbol_language == language_cplus
+      || symbol_language == language_d
       || symbol_language == language_java
       || symbol_language == language_ada)
     {
@@ -1467,7 +1574,8 @@ basic_lookup_transparent_type_quick (struct objfile *objfile, int kind,
       sym = lookup_block_symbol (block, name, STRUCT_DOMAIN);
       if (!sym)
        /* FIXME; error is wrong in one case */
-       error (_("Internal: global symbol `%s' found in %s psymtab but not in symtab.\n\
+       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\
 (if a template, try specifying an instantiation: %s<type>)."),
               name, symtab->filename, name, name);
@@ -1499,15 +1607,24 @@ basic_lookup_transparent_type (const char *name)
      of the desired name as a global, then do psymtab-to-symtab
      conversion on the fly and return the found symbol.  */
 
-  ALL_PRIMARY_SYMTABS (objfile, s)
+  ALL_OBJFILES (objfile)
   {
-    bv = BLOCKVECTOR (s);
-    block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
-    sym = lookup_block_symbol (block, name, STRUCT_DOMAIN);
-    if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
-      {
-       return SYMBOL_TYPE (sym);
-      }
+    if (objfile->sf)
+      objfile->sf->qf->pre_expand_symtabs_matching (objfile,
+                                                   GLOBAL_BLOCK,
+                                                   name, STRUCT_DOMAIN);
+
+    ALL_OBJFILE_SYMTABS (objfile, s)
+      if (s->primary)
+       {
+         bv = BLOCKVECTOR (s);
+         block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+         sym = lookup_block_symbol (block, name, STRUCT_DOMAIN);
+         if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
+           {
+             return SYMBOL_TYPE (sym);
+           }
+       }
   }
 
   ALL_OBJFILES (objfile)
@@ -1525,14 +1642,21 @@ basic_lookup_transparent_type (const char *name)
      conversion on the fly and return the found symbol.
    */
 
-  ALL_PRIMARY_SYMTABS (objfile, s)
+  ALL_OBJFILES (objfile)
   {
-    bv = BLOCKVECTOR (s);
-    block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
-    sym = lookup_block_symbol (block, name, STRUCT_DOMAIN);
-    if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
+    if (objfile->sf)
+      objfile->sf->qf->pre_expand_symtabs_matching (objfile, STATIC_BLOCK,
+                                                   name, STRUCT_DOMAIN);
+
+    ALL_OBJFILE_SYMTABS (objfile, s)
       {
-       return SYMBOL_TYPE (sym);
+       bv = BLOCKVECTOR (s);
+       block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+       sym = lookup_block_symbol (block, name, STRUCT_DOMAIN);
+       if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
+         {
+           return SYMBOL_TYPE (sym);
+         }
       }
   }
 
@@ -1551,14 +1675,16 @@ basic_lookup_transparent_type (const char *name)
 /* FIXME:  What about languages without main() or specially linked
    executables that have no main() ? */
 
-char *
+const char *
 find_main_filename (void)
 {
   struct objfile *objfile;
-  char *result, *name = main_name ();
+  char *name = main_name ();
 
   ALL_OBJFILES (objfile)
   {
+    const char *result;
+
     if (!objfile->sf)
       continue;
     result = objfile->sf->qf->find_symbol_file (objfile, name);
@@ -1637,7 +1763,6 @@ find_pc_sect_symtab (CORE_ADDR pc, struct obj_section *section)
   struct blockvector *bv;
   struct symtab *s = NULL;
   struct symtab *best_s = NULL;
-  struct partial_symtab *ps;
   struct objfile *objfile;
   struct program_space *pspace;
   CORE_ADDR distance = 0;
@@ -1693,6 +1818,7 @@ find_pc_sect_symtab (CORE_ADDR pc, struct obj_section *section)
        if ((objfile->flags & OBJF_REORDERED) && objfile->sf)
          {
            struct symtab *result;
+
            result
              = objfile->sf->qf->find_pc_sect_symtab (objfile,
                                                      msymbol,
@@ -1726,6 +1852,7 @@ find_pc_sect_symtab (CORE_ADDR pc, struct obj_section *section)
   ALL_OBJFILES (objfile)
   {
     struct symtab *result;
+
     if (!objfile->sf)
       continue;
     result = objfile->sf->qf->find_pc_sect_symtab (objfile,
@@ -1877,12 +2004,15 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
           * so of course we can't find the real func/line info,
           * but the "break" still works, and the warning is annoying.
           * So I commented out the warning. RT */
-         /* warning ("In stub for %s; unable to find real function/line info", SYMBOL_LINKAGE_NAME (msymbol)) */ ;
+         /* warning ("In stub for %s; unable to find real function/line info",
+            SYMBOL_LINKAGE_NAME (msymbol)) */ ;
        /* fall through */
-       else if (SYMBOL_VALUE_ADDRESS (mfunsym) == SYMBOL_VALUE_ADDRESS (msymbol))
+       else if (SYMBOL_VALUE_ADDRESS (mfunsym)
+                == SYMBOL_VALUE_ADDRESS (msymbol))
          /* Avoid infinite recursion */
          /* See above comment about why warning is commented out */
-         /* warning ("In stub for %s; unable to find real function/line info", SYMBOL_LINKAGE_NAME (msymbol)) */ ;
+         /* warning ("In stub for %s; unable to find real function/line info",
+            SYMBOL_LINKAGE_NAME (msymbol)) */ ;
        /* fall through */
        else
          return find_pc_line (SYMBOL_VALUE_ADDRESS (mfunsym), 0);
@@ -2025,7 +2155,8 @@ find_pc_line (CORE_ADDR pc, int notcurrent)
    If not found, return NULL.  */
 
 struct symtab *
-find_line_symtab (struct symtab *symtab, int line, int *index, int *exact_match)
+find_line_symtab (struct symtab *symtab, int line,
+                 int *index, int *exact_match)
 {
   int exact = 0;  /* Initialized here to avoid a compiler warning.  */
 
@@ -2234,6 +2365,7 @@ int
 find_pc_line_pc_range (CORE_ADDR pc, CORE_ADDR *startptr, CORE_ADDR *endptr)
 {
   struct symtab_and_line sal;
+
   sal = find_pc_line (pc, 0);
   *startptr = sal.pc;
   *endptr = sal.end;
@@ -2249,9 +2381,7 @@ skip_prologue_using_lineinfo (CORE_ADDR func_addr, struct symtab *symtab)
 {
   CORE_ADDR func_start, func_end;
   struct linetable *l;
-  int ind, i, len;
-  int best_lineno = 0;
-  CORE_ADDR best_pc = func_addr;
+  int i;
 
   /* Give up if this symbol has no lineinfo table.  */
   l = LINETABLE (symtab);
@@ -2295,6 +2425,18 @@ find_function_start_sal (struct symbol *sym, int funfirstline)
   sal = find_pc_sect_line (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)),
                           SYMBOL_OBJ_SECTION (sym), 0);
 
+  /* We always should have a line for the function start address.
+     If we don't, something is odd.  Create a plain SAL refering
+     just the PC and hope that skip_prologue_sal (if requested)
+     can find a line number for after the prologue.  */
+  if (sal.pc < BLOCK_START (SYMBOL_BLOCK_VALUE (sym)))
+    {
+      init_sal (&sal);
+      sal.pspace = current_program_space;
+      sal.pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
+      sal.section = SYMBOL_OBJ_SECTION (sym);
+    }
+
   if (funfirstline)
     skip_prologue_sal (&sal);
 
@@ -2339,6 +2481,7 @@ skip_prologue_sal (struct symtab_and_line *sal)
     {
       struct minimal_symbol *msymbol
         = lookup_minimal_symbol_by_pc_section (sal->pc, sal->section);
+
       if (msymbol == NULL)
        {
          do_cleanups (old_chain);
@@ -2474,6 +2617,7 @@ operator_chars (char *p, char **end)
   if (isalpha (*p) || *p == '_' || *p == '$')
     {
       char *q = p + 1;
+
       while (isalnum (*q) || *q == '_' || *q == '$')
        q++;
       *end = q;
@@ -2486,7 +2630,7 @@ operator_chars (char *p, char **end)
       case '\\':                       /* regexp quoting */
        if (p[1] == '*')
          {
-           if (p[2] == '=')    /* 'operator\*=' */
+           if (p[2] == '=')            /* 'operator\*=' */
              *end = p + 3;
            else                        /* 'operator\*'  */
              *end = p + 2;
@@ -2495,7 +2639,8 @@ operator_chars (char *p, char **end)
        else if (p[1] == '[')
          {
            if (p[2] == ']')
-             error (_("mismatched quoting on brackets, try 'operator\\[\\]'"));
+             error (_("mismatched quoting on brackets, "
+                      "try 'operator\\[\\]'"));
            else if (p[2] == '\\' && p[3] == ']')
              {
                *end = p + 4;   /* 'operator\[\]' */
@@ -2558,17 +2703,20 @@ operator_chars (char *p, char **end)
        return p;
       case '(':
        if (p[1] != ')')
-         error (_("`operator ()' must be specified without whitespace in `()'"));
+         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 `?:'"));
+         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 `[]'"));
+         error (_("`operator []' must be specified "
+                  "without whitespace in `[]'"));
        *end = p + 2;
        return p;
       default:
@@ -2672,7 +2820,6 @@ static void
 sources_info (char *ignore, int from_tty)
 {
   struct symtab *s;
-  struct partial_symtab *ps;
   struct objfile *objfile;
   int first;
 
@@ -2687,11 +2834,13 @@ sources_info (char *ignore, int from_tty)
   ALL_SYMTABS (objfile, s)
   {
     const char *fullname = symtab_to_fullname (s);
+
     output_source_filename (fullname ? fullname : s->filename, &first);
   }
   printf_filtered ("\n\n");
 
-  printf_filtered ("Source files for which symbols will be read in on demand:\n\n");
+  printf_filtered ("Source files for which symbols "
+                  "will be read in on demand:\n\n");
 
   first = 1;
   map_partial_symbol_filenames (output_partial_symbol_filename, &first);
@@ -2803,6 +2952,7 @@ static int
 search_symbols_file_matches (const char *filename, void *user_data)
 {
   struct search_symbols_data *data = user_data;
+
   return file_matches (filename, data->files, data->nfiles);
 }
 
@@ -2811,6 +2961,7 @@ static int
 search_symbols_name_matches (const char *symname, void *user_data)
 {
   struct search_symbols_data *data = user_data;
+
   return data->regexp == NULL || re_exec (symname);
 }
 
@@ -2842,18 +2993,14 @@ search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[],
   struct minimal_symbol *msymbol;
   char *val;
   int found_misc = 0;
-  static enum minimal_symbol_type types[]
-  =
-  {mst_data, mst_text, mst_abs, mst_unknown};
-  static enum minimal_symbol_type types2[]
-  =
-  {mst_bss, mst_file_text, mst_abs, mst_unknown};
-  static enum minimal_symbol_type types3[]
-  =
-  {mst_file_data, mst_solib_trampoline, mst_abs, mst_unknown};
-  static enum minimal_symbol_type types4[]
-  =
-  {mst_file_bss, mst_text, mst_abs, mst_unknown};
+  static const enum minimal_symbol_type types[]
+    = {mst_data, mst_text, mst_abs, mst_unknown};
+  static const enum minimal_symbol_type types2[]
+    = {mst_bss, mst_file_text, mst_abs, mst_unknown};
+  static const enum minimal_symbol_type types3[]
+    = {mst_file_data, mst_solib_trampoline, mst_abs, mst_unknown};
+  static const enum minimal_symbol_type types4[]
+    = {mst_file_bss, mst_text, mst_abs, mst_unknown};
   enum minimal_symbol_type ourtype;
   enum minimal_symbol_type ourtype2;
   enum minimal_symbol_type ourtype3;
@@ -2883,9 +3030,12 @@ search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[],
          and <TYPENAME> or <OPERATOR>. */
       char *opend;
       char *opname = operator_chars (regexp, &opend);
+
       if (*opname)
        {
-         int fix = -1;         /* -1 means ok; otherwise number of spaces needed. */
+         int fix = -1;         /* -1 means ok; otherwise number of
+                                    spaces needed.  */
+
          if (isalpha (*opname) || *opname == '_' || *opname == '$')
            {
              /* There should 1 space between 'operator' and 'TYPENAME'. */
@@ -2902,6 +3052,7 @@ search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[],
          if (fix >= 0)
            {
              char *tmp = (char *) alloca (8 + fix + strlen (opname) + 1);
+
              sprintf (tmp, "operator%.*s%s", fix, " ", opname);
              regexp = tmp;
            }
@@ -2982,24 +3133,35 @@ search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[],
        {
          struct symbol_search *prevtail = tail;
          int nfound = 0;
+
          b = BLOCKVECTOR_BLOCK (bv, i);
          ALL_BLOCK_SYMBOLS (b, iter, sym)
            {
              struct symtab *real_symtab = SYMBOL_SYMTAB (sym);
+
              QUIT;
 
              if (file_matches (real_symtab->filename, files, nfiles)
                  && ((regexp == NULL
                       || re_exec (SYMBOL_NATURAL_NAME (sym)) != 0)
-                     && ((kind == VARIABLES_DOMAIN && SYMBOL_CLASS (sym) != LOC_TYPEDEF
+                     && ((kind == VARIABLES_DOMAIN
+                          && SYMBOL_CLASS (sym) != LOC_TYPEDEF
                           && SYMBOL_CLASS (sym) != LOC_UNRESOLVED
                           && SYMBOL_CLASS (sym) != LOC_BLOCK
-                          && SYMBOL_CLASS (sym) != LOC_CONST)
-                         || (kind == FUNCTIONS_DOMAIN && SYMBOL_CLASS (sym) == LOC_BLOCK)
-                         || (kind == TYPES_DOMAIN && SYMBOL_CLASS (sym) == LOC_TYPEDEF))))
+                          /* LOC_CONST can be used for more than just enums,
+                             e.g., c++ static const members.
+                             We only want to skip enums here.  */
+                          && !(SYMBOL_CLASS (sym) == LOC_CONST
+                               && TYPE_CODE (SYMBOL_TYPE (sym))
+                               == TYPE_CODE_ENUM))
+                         || (kind == FUNCTIONS_DOMAIN 
+                             && SYMBOL_CLASS (sym) == LOC_BLOCK)
+                         || (kind == TYPES_DOMAIN
+                             && SYMBOL_CLASS (sym) == LOC_TYPEDEF))))
                {
                  /* match */
-                 psr = (struct symbol_search *) xmalloc (sizeof (struct symbol_search));
+                 psr = (struct symbol_search *)
+                   xmalloc (sizeof (struct symbol_search));
                  psr->block = i;
                  psr->symtab = real_symtab;
                  psr->symbol = sym;
@@ -3058,7 +3220,8 @@ search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[],
                         == NULL)
                      {
                        /* match */
-                       psr = (struct symbol_search *) xmalloc (sizeof (struct symbol_search));
+                       psr = (struct symbol_search *)
+                         xmalloc (sizeof (struct symbol_search));
                        psr->block = i;
                        psr->msymbol = msymbol;
                        psr->symtab = NULL;
@@ -3148,9 +3311,8 @@ print_msymbol_info (struct minimal_symbol *msymbol)
 static void
 symtab_symbol_info (char *regexp, domain_enum kind, int from_tty)
 {
-  static char *classnames[]
-  =
-  {"variable", "function", "type", "method"};
+  static const char * const classnames[] =
+    {"variable", "function", "type", "method"};
   struct symbol_search *symbols;
   struct symbol_search *p;
   struct cleanup *old_chain;
@@ -3236,8 +3398,32 @@ rbreak_command (char *regexp, int from_tty)
   struct cleanup *old_chain;
   char *string = NULL;
   int len = 0;
+  char **files = NULL;
+  int nfiles = 0;
+
+  if (regexp)
+    {
+      char *colon = strchr (regexp, ':');
+
+      if (colon && *(colon + 1) != ':')
+       {
+         int colon_index;
+         char * file_name;
+
+         colon_index = colon - regexp;
+         file_name = alloca (colon_index + 1);
+         memcpy (file_name, regexp, colon_index);
+         file_name[colon_index--] = 0;
+         while (isspace (file_name[colon_index]))
+           file_name[colon_index--] = 0; 
+         files = &file_name;
+         nfiles = 1;
+         regexp = colon + 1;
+         while (isspace (*regexp))  regexp++; 
+       }
+    }
 
-  search_symbols (regexp, FUNCTIONS_DOMAIN, 0, (char **) NULL, &ss);
+  search_symbols (regexp, FUNCTIONS_DOMAIN, nfiles, files, &ss);
   old_chain = make_cleanup_free_search_symbols (ss);
   make_cleanup (free_current_contents, &string);
 
@@ -3250,6 +3436,7 @@ rbreak_command (char *regexp, int from_tty)
          int newlen = (strlen (p->symtab->filename)
                        + strlen (SYMBOL_LINKAGE_NAME (p->symbol))
                        + 4);
+
          if (newlen > len)
            {
              string = xrealloc (string, newlen);
@@ -3268,8 +3455,8 @@ rbreak_command (char *regexp, int from_tty)
        }
       else
        {
-         int newlen = (strlen (SYMBOL_LINKAGE_NAME (p->msymbol))
-                       + 3);
+         int newlen = (strlen (SYMBOL_LINKAGE_NAME (p->msymbol)) + 3);
+
          if (newlen > len)
            {
              string = xrealloc (string, newlen);
@@ -3308,7 +3495,6 @@ completion_list_add_name (char *symname, char *sym_text, int sym_text_len,
                          char *text, char *word)
 {
   int newsize;
-  int i;
 
   /* clip symbols that cannot match */
 
@@ -3322,6 +3508,7 @@ completion_list_add_name (char *symname, char *sym_text, int sym_text_len,
 
   {
     char *new;
+
     if (word == sym_text)
       {
        new = xmalloc (strlen (symname) + 5);
@@ -3493,6 +3680,7 @@ add_macro_name (const char *name, const struct macro_definition *ignore,
                void *user_data)
 {
   struct add_name_data *datum = (struct add_name_data *) user_data;
+
   completion_list_add_name ((char *) name,
                            datum->sym_text, datum->sym_text_len,
                            datum->text, datum->word);
@@ -3503,13 +3691,15 @@ static void
 add_partial_symbol_name (const char *name, void *user_data)
 {
   struct add_name_data *datum = (struct add_name_data *) user_data;
+
   completion_list_add_name ((char *) name,
                            datum->sym_text, datum->sym_text_len,
                            datum->text, datum->word);
 }
 
 char **
-default_make_symbol_completion_list (char *text, char *word)
+default_make_symbol_completion_list_break_on (char *text, char *word,
+                                             const char *break_on)
 {
   /* Problem: All of the symbols have to be copied because readline
      frees them.  I'm not going to worry about this; hopefully there
@@ -3572,7 +3762,7 @@ default_make_symbol_completion_list (char *text, char *word)
        while (p > text)
          {
            if (isalnum (p[-1]) || p[-1] == '_' || p[-1] == '\0'
-               || p[-1] == ':')
+               || p[-1] == ':' || strchr (break_on, p[-1]) != NULL)
              --p;
            else
              break;
@@ -3698,6 +3888,12 @@ default_make_symbol_completion_list (char *text, char *word)
   return (return_val);
 }
 
+char **
+default_make_symbol_completion_list (char *text, char *word)
+{
+  return default_make_symbol_completion_list_break_on (text, word, "");
+}
+
 /* 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.  */
@@ -3894,7 +4090,7 @@ struct add_partial_filename_data
 
 /* A callback for map_partial_symbol_filenames.  */
 static void
-maybe_add_partial_symtab_filename (const char *fullname, const char *filename,
+maybe_add_partial_symtab_filename (const char *filename, const char *fullname,
                                   void *user_data)
 {
   struct add_partial_filename_data *data = user_data;
@@ -3917,6 +4113,7 @@ maybe_add_partial_symtab_filename (const char *fullname, const char *filename,
   else
     {
       const char *base_name = lbasename (filename);
+
       if (base_name != filename
          && !filename_seen (base_name, 1, data->first)
 #if HAVE_DOS_BASED_FILE_SYSTEM
@@ -4116,7 +4313,6 @@ skip_prologue_using_sal (struct gdbarch *gdbarch, CORE_ADDR func_addr)
       if (prologue_sal.symtab->language != language_asm)
        {
          struct linetable *linetable = LINETABLE (prologue_sal.symtab);
-         int exact;
          int idx = 0;
 
          /* Skip any earlier lines, and any end-of-sequence marker
@@ -4211,6 +4407,7 @@ decode_line_spec (char *string, int funfirstline)
 
 /* Track MAIN */
 static char *name_of_main;
+enum language language_of_main = language_unknown;
 
 void
 set_main_name (const char *name)
@@ -4219,10 +4416,12 @@ set_main_name (const char *name)
     {
       xfree (name_of_main);
       name_of_main = NULL;
+      language_of_main = language_unknown;
     }
   if (name != NULL)
     {
       name_of_main = xstrdup (name);
+      language_of_main = language_unknown;
     }
 }
 
@@ -4336,6 +4535,7 @@ append_exact_match_to_sals (char *filename, char *fullname, int lineno,
        {
          struct linetable *l;
          int len;
+
          if (fullname != NULL
              && symtab_to_fullname (symtab) != NULL
              && FILENAME_CMP (fullname, symtab->fullname) != 0)
@@ -4376,11 +4576,9 @@ append_exact_match_to_sals (char *filename, char *fullname, int lineno,
 struct symtabs_and_lines
 expand_line_sal (struct symtab_and_line sal)
 {
-  struct symtabs_and_lines ret, this_line;
+  struct symtabs_and_lines ret;
   int i, j;
   struct objfile *objfile;
-  struct partial_symtab *psymtab;
-  struct symtab *symtab;
   int lineno;
   int deleted = 0;
   struct block **blocks = NULL;
@@ -4460,9 +4658,6 @@ expand_line_sal (struct symtab_and_line sal)
   blocks = alloca (ret.nelts * sizeof (struct block *));
   for (i = 0; i < ret.nelts; ++i)
     {
-      struct blockvector *bl;
-      struct block *b;
-
       set_current_program_space (ret.sals[i].pspace);
 
       filter[i] = 1;