* configure.ac: Added gdb.modula2/Makefile to AC_OUTPUT.
[deliverable/binutils-gdb.git] / gdb / symtab.c
index f12834dd1cd12131643613855484f9b9147eeee7..eeddddd89d2312d87af11e1b7fb6448b2026086a 100644 (file)
@@ -8,7 +8,7 @@
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -17,9 +17,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 #include "symtab.h"
@@ -42,6 +40,7 @@
 #include "filenames.h"         /* for FILENAME_CMP */
 #include "objc-lang.h"
 #include "ada-lang.h"
+#include "p-lang.h"
 
 #include "hashtab.h"
 
@@ -57,6 +56,7 @@
 #include "cp-abi.h"
 #include "observer.h"
 #include "gdb_assert.h"
+#include "solist.h"
 
 /* Prototypes for local functions */
 
@@ -84,6 +84,7 @@ static struct symbol *lookup_symbol_aux (const char *name,
                                         const char *linkage_name,
                                         const struct block *block,
                                         const domain_enum domain,
+                                        enum language language,
                                         int *is_a_field_of_this,
                                         struct symtab **symtab);
 
@@ -108,19 +109,6 @@ struct symbol *lookup_symbol_aux_psymtabs (int block_index,
                                           const domain_enum domain,
                                           struct symtab **symtab);
 
-#if 0
-static
-struct symbol *lookup_symbol_aux_minsyms (const char *name,
-                                         const char *linkage_name,
-                                         const domain_enum domain,
-                                         int *is_a_field_of_this,
-                                         struct symtab **symtab);
-#endif
-
-/* This flag is used in hppa-tdep.c, and set in hp-symtab-read.c.
-   Signals the presence of objects compiled by HP compilers.  */
-int deprecated_hp_som_som_object_present = 0;
-
 static void fixup_section (struct general_symbol_info *, struct objfile *);
 
 static int file_matches (char *, char **, int);
@@ -704,6 +692,8 @@ init_sal (struct symtab_and_line *sal)
   sal->line = 0;
   sal->pc = 0;
   sal->end = 0;
+  sal->explicit_pc = 0;
+  sal->explicit_line = 0;
 }
 \f
 
@@ -1079,9 +1069,10 @@ fixup_psymbol_section (struct partial_symbol *psym, struct objfile *objfile)
    code).  */
 
 struct symbol *
-lookup_symbol (const char *name, const struct block *block,
-              const domain_enum domain, int *is_a_field_of_this,
-              struct symtab **symtab)
+lookup_symbol_in_language (const char *name, const struct block *block,
+                          const domain_enum domain, enum language lang,
+                          int *is_a_field_of_this,
+                          struct symtab **symtab)
 {
   char *demangled_name = NULL;
   const char *modified_name = NULL;
@@ -1093,7 +1084,7 @@ lookup_symbol (const char *name, const struct block *block,
 
   /* If we are using C++ or Java, demangle the name before doing a lookup, so
      we can always binary search. */
-  if (current_language->la_language == language_cplus)
+  if (lang == language_cplus)
     {
       demangled_name = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS);
       if (demangled_name)
@@ -1103,7 +1094,7 @@ lookup_symbol (const char *name, const struct block *block,
          needtofreename = 1;
        }
     }
-  else if (current_language->la_language == language_java)
+  else if (lang == language_java)
     {
       demangled_name = cplus_demangle (name, 
                                       DMGL_ANSI | DMGL_PARAMS | DMGL_JAVA);
@@ -1129,7 +1120,8 @@ lookup_symbol (const char *name, const struct block *block,
     }
 
   returnval = lookup_symbol_aux (modified_name, mangled_name, block,
-                                domain, is_a_field_of_this, symtab);
+                                domain, lang,
+                                is_a_field_of_this, symtab);
   if (needtofreename)
     xfree (demangled_name);
 
@@ -1140,7 +1132,20 @@ lookup_symbol (const char *name, const struct block *block,
   return returnval;     
 }
 
-/* Behave like lookup_symbol_aux except that NAME is the natural name
+/* Behave like lookup_symbol_in_language, but performed with the
+   current language.  */
+
+struct symbol *
+lookup_symbol (const char *name, const struct block *block,
+              domain_enum domain, int *is_a_field_of_this,
+              struct symtab **symtab)
+{
+  return lookup_symbol_in_language (name, block, domain,
+                                   current_language->la_language,
+                                   is_a_field_of_this, symtab);
+}
+
+/* Behave like lookup_symbol except that NAME is the natural name
    of the symbol that we're looking for and, if LINKAGE_NAME is
    non-NULL, ensure that the symbol's linkage name matches as
    well.  */
@@ -1148,9 +1153,11 @@ lookup_symbol (const char *name, const struct block *block,
 static struct symbol *
 lookup_symbol_aux (const char *name, const char *linkage_name,
                   const struct block *block, const domain_enum domain,
+                  enum language language,
                   int *is_a_field_of_this, struct symtab **symtab)
 {
   struct symbol *sym;
+  const struct language_defn *langdef;
 
   /* 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
@@ -1168,13 +1175,15 @@ lookup_symbol_aux (const char *name, const char *linkage_name,
   if (sym != NULL)
     return sym;
 
-  /* If requested to do so by the caller and if appropriate for the
-     current language, check to see if NAME is a field of `this'. */
+  /* If requested to do so by the caller and if appropriate for LANGUAGE,
+     check to see if NAME is a field of `this'. */
 
-  if (current_language->la_value_of_this != NULL
+  langdef = language_def (language);
+
+  if (langdef->la_value_of_this != NULL
       && is_a_field_of_this != NULL)
     {
-      struct value *v = current_language->la_value_of_this (0);
+      struct value *v = langdef->la_value_of_this (0);
 
       if (v && check_field (v, name))
        {
@@ -1185,12 +1194,11 @@ lookup_symbol_aux (const char *name, const char *linkage_name,
        }
     }
 
-  /* Now do whatever is appropriate for the current language to look
+  /* Now do whatever is appropriate for LANGUAGE to look
      up static and global variables.  */
 
-  sym = current_language->la_lookup_symbol_nonlocal (name, linkage_name,
-                                                    block, domain,
-                                                    symtab);
+  sym = langdef->la_lookup_symbol_nonlocal (name, linkage_name,
+                                            block, domain, symtab);
   if (sym != NULL)
     return sym;
 
@@ -1246,6 +1254,26 @@ lookup_symbol_aux_local (const char *name, const char *linkage_name,
   return NULL;
 }
 
+/* Look up OBJFILE to BLOCK.  */
+
+static struct objfile *
+lookup_objfile_from_block (const struct block *block)
+{
+  struct objfile *obj;
+  struct symtab *s;
+
+  if (block == NULL)
+    return NULL;
+
+  block = block_global_block (block);
+  /* Go through SYMTABS.  */
+  ALL_SYMTABS (obj, s)
+    if (block == BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK))
+      return obj;
+
+  return NULL;
+}
+
 /* Look up a symbol in a block; if found, locate its symtab, fixup the
    symbol, and set block_found appropriately.  */
 
@@ -1287,6 +1315,57 @@ lookup_symbol_aux_block (const char *name, const char *linkage_name,
   return NULL;
 }
 
+/* Check all global symbols in OBJFILE in symtabs and
+   psymtabs.  */
+
+struct symbol *
+lookup_global_symbol_from_objfile (const struct objfile *objfile,
+                                  const char *name,
+                                  const char *linkage_name,
+                                  const domain_enum domain,
+                                  struct symtab **symtab)
+{
+  struct symbol *sym;
+  struct blockvector *bv;
+  const struct block *block;
+  struct symtab *s;
+  struct partial_symtab *ps;
+
+  /* Go through symtabs.  */
+  ALL_OBJFILE_SYMTABS (objfile, s)
+  {
+    bv = BLOCKVECTOR (s);
+    block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+    sym = lookup_block_symbol (block, name, linkage_name, domain);
+    if (sym)
+      {
+       block_found = block;
+       if (symtab != NULL)
+         *symtab = s;
+       return fixup_symbol_section (sym, (struct objfile *)objfile);
+      }
+  }
+
+  /* Now go through psymtabs.  */
+  ALL_OBJFILE_PSYMTABS (objfile, ps)
+  {
+    if (!ps->readin
+       && lookup_partial_symbol (ps, name, linkage_name,
+                                 1, domain))
+      {
+       s = PSYMTAB_TO_SYMTAB (ps);
+       bv = BLOCKVECTOR (s);
+       block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+       sym = lookup_block_symbol (block, name, linkage_name, domain);
+       if (symtab != NULL)
+         *symtab = s;
+       return fixup_symbol_section (sym, (struct objfile *)objfile);
+      }
+  }
+
+  return NULL;
+}
+
 /* Check to see if the symbol is defined in one of the symtabs.
    BLOCK_INDEX should be either GLOBAL_BLOCK or STATIC_BLOCK,
    depending on whether or not we want to search global symbols or
@@ -1381,132 +1460,6 @@ lookup_symbol_aux_psymtabs (int block_index, const char *name,
   return NULL;
 }
 
-#if 0
-/* Check for the possibility of the symbol being a function or a
-   mangled variable that is stored in one of the minimal symbol
-   tables.  Eventually, all global symbols might be resolved in this
-   way.  */
-
-/* NOTE: carlton/2002-12-05: At one point, this function was part of
-   lookup_symbol_aux, and what are now 'return' statements within
-   lookup_symbol_aux_minsyms returned from lookup_symbol_aux, even if
-   sym was NULL.  As far as I can tell, this was basically accidental;
-   it didn't happen every time that msymbol was non-NULL, but only if
-   some additional conditions held as well, and it caused problems
-   with HP-generated symbol tables.  */
-
-/* NOTE: carlton/2003-05-14: This function was once used as part of
-   lookup_symbol.  It is currently unnecessary for correctness
-   reasons, however, and using it doesn't seem to be any faster than
-   using lookup_symbol_aux_psymtabs, so I'm commenting it out.  */
-
-static struct symbol *
-lookup_symbol_aux_minsyms (const char *name,
-                          const char *linkage_name,
-                          const domain_enum domain,
-                          int *is_a_field_of_this,
-                          struct symtab **symtab)
-{
-  struct symbol *sym;
-  struct blockvector *bv;
-  const struct block *block;
-  struct minimal_symbol *msymbol;
-  struct symtab *s;
-
-  if (domain == VAR_DOMAIN)
-    {
-      msymbol = lookup_minimal_symbol (name, NULL, NULL);
-
-      if (msymbol != NULL)
-       {
-         /* OK, we found a minimal symbol in spite of not finding any
-            symbol. There are various possible explanations for
-            this. One possibility is the symbol exists in code not
-            compiled -g. Another possibility is that the 'psymtab'
-            isn't doing its job.  A third possibility, related to #2,
-            is that we were confused by name-mangling. For instance,
-            maybe the psymtab isn't doing its job because it only
-            know about demangled names, but we were given a mangled
-            name...  */
-
-         /* We first use the address in the msymbol to try to locate
-            the appropriate symtab. Note that find_pc_sect_symtab()
-            has a side-effect of doing psymtab-to-symtab expansion,
-            for the found symtab.  */
-         s = find_pc_sect_symtab (SYMBOL_VALUE_ADDRESS (msymbol),
-                                  SYMBOL_BFD_SECTION (msymbol));
-         if (s != NULL)
-           {
-             /* This is a function which has a symtab for its address.  */
-             bv = BLOCKVECTOR (s);
-             block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
-
-             /* This call used to pass `SYMBOL_LINKAGE_NAME (msymbol)' as the
-                `name' argument to lookup_block_symbol.  But the name
-                of a minimal symbol is always mangled, so that seems
-                to be clearly the wrong thing to pass as the
-                unmangled name.  */
-             sym =
-               lookup_block_symbol (block, name, linkage_name, domain);
-             /* 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, name,
-                                            linkage_name, domain);
-               }
-
-             /* NOTE: carlton/2002-12-04: The following comment was
-                taken from a time when two versions of this function
-                were part of the body of lookup_symbol_aux: this
-                comment was taken from the version of the function
-                that was #ifdef HPUXHPPA, and the comment was right
-                before the 'return NULL' part of lookup_symbol_aux.
-                (Hence the "Fall through and return 0" comment.)
-                Elena did some digging into the situation for
-                Fortran, and she reports:
-
-                "I asked around (thanks to Jeff Knaggs), and I think
-                the story for Fortran goes like this:
-
-                "Apparently, in older Fortrans, '_' was not part of
-                the user namespace.  g77 attached a final '_' to
-                procedure names as the exported symbols for linkage
-                (foo_) , but the symbols went in the debug info just
-                like 'foo'. The rationale behind this is not
-                completely clear, and maybe it was done to other
-                symbols as well, not just procedures."  */
-
-             /* If we get here with sym == 0, the symbol was 
-                found in the minimal symbol table
-                but not in the symtab.
-                Fall through and return 0 to use the msymbol 
-                definition of "foo_".
-                (Note that outer code generally follows up a call
-                to this routine with a call to lookup_minimal_symbol(),
-                so a 0 return means we'll just flow into that other routine).
-
-                This happens for Fortran  "foo_" symbols,
-                which are "foo" in the symtab.
-
-                This can also happen if "asm" is used to make a
-                regular symbol but not a debugging symbol, e.g.
-                asm(".globl _main");
-                asm("_main:");
-              */
-
-             if (symtab != NULL && sym != NULL)
-               *symtab = s;
-             return fixup_symbol_section (sym, s->objfile);
-           }
-       }
-    }
-
-  return NULL;
-}
-#endif /* 0 */
-
 /* A default version of lookup_symbol_nonlocal for use by languages
    that can't think of anything better to do.  This implements the C
    lookup rules.  */
@@ -1552,7 +1505,7 @@ basic_lookup_symbol_nonlocal (const char *name,
   if (sym != NULL)
     return sym;
 
-  return lookup_symbol_global (name, linkage_name, domain, symtab);
+  return lookup_symbol_global (name, linkage_name, block, domain, symtab);
 }
 
 /* Lookup a symbol in the static block associated to BLOCK, if there
@@ -1580,10 +1533,19 @@ lookup_symbol_static (const char *name,
 struct symbol *
 lookup_symbol_global (const char *name,
                      const char *linkage_name,
+                     const struct block *block,
                      const domain_enum domain,
                      struct symtab **symtab)
 {
-  struct symbol *sym;
+  struct symbol *sym = NULL;
+  struct objfile *objfile = NULL;
+
+  /* Call library-specific lookup procedure.  */
+  objfile = lookup_objfile_from_block (block);
+  if (objfile != NULL)
+    sym = solib_global_lookup (objfile, name, linkage_name, domain, symtab);
+  if (sym != NULL)
+    return sym;
 
   sym = lookup_symbol_aux_symtabs (GLOBAL_BLOCK, name, linkage_name,
                                   domain, symtab);
@@ -2506,20 +2468,21 @@ find_function_start_sal (struct symbol *sym, int funfirstline)
     {                          /* skip "first line" of function (which is actually its prologue) */
       asection *section = SYMBOL_BFD_SECTION (sym);
       /* If function is in an unmapped overlay, use its unmapped LMA
-         address, so that SKIP_PROLOGUE has something unique to work on */
+         address, so that gdbarch_skip_prologue has something unique to work
+         on */
       if (section_is_overlay (section) &&
          !section_is_mapped (section))
        pc = overlay_unmapped_address (pc, section);
 
-      pc += DEPRECATED_FUNCTION_START_OFFSET;
-      pc = SKIP_PROLOGUE (pc);
+      pc += gdbarch_deprecated_function_start_offset (current_gdbarch);
+      pc = gdbarch_skip_prologue (current_gdbarch, pc);
 
       /* For overlays, map pc back into its mapped VMA range */
       pc = overlay_mapped_address (pc, section);
     }
   sal = find_pc_sect_line (pc, SYMBOL_BFD_SECTION (sym), 0);
 
-  /* Check if SKIP_PROLOGUE left us in mid-line, and the next
+  /* Check if gdbarch_skip_prologue left us in mid-line, and the next
      line is still part of the same function.  */
   if (sal.pc != pc
       && BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) <= sal.end
@@ -3070,7 +3033,8 @@ search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[],
                        || lookup_symbol (SYMBOL_LINKAGE_NAME (msymbol),
                                          (struct block *) NULL,
                                          VAR_DOMAIN,
-                                       0, (struct symtab **) NULL) == NULL)
+                                         0, (struct symtab **) NULL)
+                       == NULL)
                      found_misc = 1;
                  }
              }
@@ -3229,7 +3193,7 @@ print_msymbol_info (struct minimal_symbol *msymbol)
 {
   char *tmp;
 
-  if (TARGET_ADDR_BIT <= 32)
+  if (gdbarch_addr_bit (current_gdbarch) <= 32)
     tmp = hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol)
                             & (CORE_ADDR) 0xffffffff,
                             8);
@@ -4006,7 +3970,7 @@ in_prologue (CORE_ADDR pc, CORE_ADDR func_start)
      - The minimal symbols and partial symbols, which can usually tell
        us the starting and ending addresses of a function.
      - If we know the function's start address, we can call the
-       architecture-defined SKIP_PROLOGUE function to analyze the
+       architecture-defined gdbarch_skip_prologue function to analyze the
        instruction stream and guess where the prologue ends.
      - Our `func_start' argument; if non-zero, this is the caller's
        best guess as to the function's entry point.  At the time of
@@ -4024,7 +3988,7 @@ in_prologue (CORE_ADDR pc, CORE_ADDR func_start)
       if (! func_start)
        return 1;               /* We *might* be in a prologue.  */
 
-      prologue_end = SKIP_PROLOGUE (func_start);
+      prologue_end = gdbarch_skip_prologue (current_gdbarch, func_start);
 
       return func_start <= pc && pc < prologue_end;
     }
@@ -4048,7 +4012,8 @@ in_prologue (CORE_ADDR pc, CORE_ADDR func_start)
       /* We don't have any good line number info, so use the minsym
         information, together with the architecture-specific prologue
         scanning code.  */
-      CORE_ADDR prologue_end = SKIP_PROLOGUE (func_addr);
+      CORE_ADDR prologue_end = gdbarch_skip_prologue
+                                (current_gdbarch, func_addr);
 
       return func_addr <= pc && pc < prologue_end;
     }
@@ -4083,7 +4048,7 @@ skip_prologue_using_sal (CORE_ADDR func_addr)
 
   /* Get an initial range for the function.  */
   find_pc_partial_function (func_addr, NULL, &start_pc, &end_pc);
-  start_pc += DEPRECATED_FUNCTION_START_OFFSET;
+  start_pc += gdbarch_deprecated_function_start_offset (current_gdbarch);
 
   prologue_sal = find_pc_line (start_pc, 0);
   if (prologue_sal.line != 0)
@@ -4091,8 +4056,8 @@ skip_prologue_using_sal (CORE_ADDR func_addr)
       /* If there is only one sal that covers the entire function,
         then it is probably a single line function, like
         "foo(){}". */
-      if (prologue_sal.end == end_pc)
-       return start_pc;
+      if (prologue_sal.end >= end_pc)
+       return 0;
       while (prologue_sal.end < end_pc)
        {
          struct symtab_and_line sal;
@@ -4162,7 +4127,7 @@ set_main_name (const char *name)
 static void
 find_main_name (void)
 {
-  char *new_main_name;
+  const char *new_main_name;
 
   /* Try to see if the main procedure is in Ada.  */
   /* FIXME: brobecker/2005-03-07: Another way of doing this would
@@ -4187,6 +4152,13 @@ find_main_name (void)
       return;
     }
 
+  new_main_name = pascal_main_name ();
+  if (new_main_name != NULL)
+    { 
+      set_main_name (new_main_name);
+      return;
+    }
+
   /* The languages above didn't identify the name of the main procedure.
      Fallback to "main".  */
   set_main_name ("main");
@@ -4210,6 +4182,166 @@ symtab_observer_executable_changed (void *unused)
   set_main_name (NULL);
 }
 
+/* Helper to expand_line_sal below.  Appends new sal to SAL,
+   initializing it from SYMTAB, LINENO and PC.  */
+static void
+append_expanded_sal (struct symtabs_and_lines *sal,
+                    struct symtab *symtab,
+                    int lineno, CORE_ADDR pc)
+{
+  CORE_ADDR func_addr, func_end;
+  
+  sal->sals = xrealloc (sal->sals, 
+                       sizeof (sal->sals[0]) 
+                       * (sal->nelts + 1));
+  init_sal (sal->sals + sal->nelts);
+  sal->sals[sal->nelts].symtab = symtab;
+  sal->sals[sal->nelts].section = NULL;
+  sal->sals[sal->nelts].end = 0;
+  sal->sals[sal->nelts].line = lineno;  
+  sal->sals[sal->nelts].pc = pc;
+  ++sal->nelts;      
+}
+
+/* Compute a set of all sals in
+   the entire program that correspond to same file
+   and line as SAL and return those.  If there
+   are several sals that belong to the same block,
+   only one sal for the block is included in results.  */
+   
+struct symtabs_and_lines
+expand_line_sal (struct symtab_and_line sal)
+{
+  struct symtabs_and_lines ret, this_line;
+  int i, j;
+  struct objfile *objfile;
+  struct partial_symtab *psymtab;
+  struct symtab *symtab;
+  int lineno;
+  int deleted = 0;
+  struct block **blocks = NULL;
+  int *filter;
+
+  ret.nelts = 0;
+  ret.sals = NULL;
+
+  if (sal.symtab == NULL || sal.line == 0 || sal.pc != 0)
+    {
+      ret.sals = xmalloc (sizeof (struct symtab_and_line));
+      ret.sals[0] = sal;
+      ret.nelts = 1;
+      return ret;
+    }
+  else
+    {
+      struct linetable_entry *best_item = 0;
+      struct symtab *best_symtab = 0;
+      int exact = 0;
+
+      lineno = sal.line;
+
+      /* We meed to find all symtabs for a file which name
+        is described by sal. We cannot just directly 
+        iterate over symtabs, since a symtab might not be
+        yet created. We also cannot iterate over psymtabs,
+        calling PSYMTAB_TO_SYMTAB and working on that symtab,
+        since PSYMTAB_TO_SYMTAB will return NULL for psymtab
+        corresponding to an included file. Therefore, we do
+        first pass over psymtabs, reading in those with
+        the right name.  Then, we iterate over symtabs, knowing
+        that all symtabs we're interested in are loaded.  */
+
+      ALL_PSYMTABS (objfile, psymtab)
+       {
+         if (strcmp (sal.symtab->filename,
+                     psymtab->filename) == 0)
+           PSYMTAB_TO_SYMTAB (psymtab);
+       }
+
+        
+      /* For each symtab, we add all pcs to ret.sals. I'm actually
+        not sure what to do if we have exact match in one symtab,
+        and non-exact match on another symtab.
+      */
+      ALL_SYMTABS (objfile, symtab)
+       {
+         if (strcmp (sal.symtab->filename,
+                     symtab->filename) == 0)
+           {
+             struct linetable *l;
+             int len;
+             l = LINETABLE (symtab);
+             if (!l)
+               continue;
+             len = l->nitems;
+
+             for (j = 0; j < len; j++)
+               {
+                 struct linetable_entry *item = &(l->item[j]);
+
+                 if (item->line == lineno)
+                   {
+                     exact = 1;
+                     append_expanded_sal (&ret, symtab, lineno, item->pc);
+                   }      
+                 else if (!exact && item->line > lineno
+                          && (best_item == NULL || item->line < best_item->line))
+                 
+                   {
+                     best_item = item;
+                     best_symtab = symtab;
+                   }
+               }
+           }
+       }
+      if (!exact && best_item)
+       append_expanded_sal (&ret, best_symtab, lineno, best_item->pc);
+    }
+
+  /* For optimized code, compiler can scatter one source line accross
+     disjoint ranges of PC values, even when no duplicate functions
+     or inline functions are involved.  For example, 'for (;;)' inside
+     non-template non-inline non-ctor-or-dtor function can result
+     in two PC ranges.  In this case, we don't want to set breakpoint
+     on first PC of each range.  To filter such cases, we use containing
+     blocks -- for each PC found above we see if there are other PCs
+     that are in the same block.  If yes, the other PCs are filtered out.  */  
+
+  filter = xmalloc (ret.nelts * sizeof (int));
+  blocks = xmalloc (ret.nelts * sizeof (struct block *));
+  for (i = 0; i < ret.nelts; ++i)
+    {
+      filter[i] = 1;
+      blocks[i] = block_for_pc (ret.sals[i].pc);
+    }
+
+  for (i = 0; i < ret.nelts; ++i)
+    if (blocks[i] != NULL)
+      for (j = i+1; j < ret.nelts; ++j)
+       if (blocks[j] == blocks[i])
+         {
+           filter[j] = 0;
+           ++deleted;
+           break;
+         }
+  
+  {
+    struct symtab_and_line *final = 
+      xmalloc (sizeof (struct symtab_and_line) * (ret.nelts-deleted));
+    
+    for (i = 0, j = 0; i < ret.nelts; ++i)
+      if (filter[i])
+       final[j++] = ret.sals[i];
+    
+    ret.nelts -= deleted;
+    xfree (ret.sals);
+    ret.sals = final;
+  }
+
+  return ret;
+}
+
+
 void
 _initialize_symtab (void)
 {
This page took 0.041602 seconds and 4 git commands to generate.