* symtab.h (struct symtab) <includes, user>: New fields.
[binutils-gdb.git] / gdb / block.c
index abce515a6ef5c322b3f38940153ef293f794b9fa..38b64b33aff462139806e31acaad33eb4093d293 100644 (file)
@@ -1,12 +1,12 @@
 /* Block-related functions for the GNU debugger, GDB.
 
-   Copyright (C) 2003 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2007-2012 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    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,
@@ -15,9 +15,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 "block.h"
@@ -25,6 +23,9 @@
 #include "symfile.h"
 #include "gdb_obstack.h"
 #include "cp-support.h"
+#include "addrmap.h"
+#include "gdbtypes.h"
+#include "exceptions.h"
 
 /* This is used by struct block to store namespace-related info for
    C++ files, namely using declarations and the current namespace in
@@ -41,38 +42,75 @@ static void block_initialize_namespace (struct block *block,
 
 /* Return Nonzero if block a is lexically nested within block b,
    or if a and b have the same pc range.
-   Return zero otherwise. */
+   Return zero otherwise.  */
 
 int
 contained_in (const struct block *a, const struct block *b)
 {
   if (!a || !b)
     return 0;
-  return BLOCK_START (a) >= BLOCK_START (b)
-    && BLOCK_END (a) <= BLOCK_END (b);
+
+  do
+    {
+      if (a == b)
+       return 1;
+      /* If A is a function block, then A cannot be contained in B,
+         except if A was inlined.  */
+      if (BLOCK_FUNCTION (a) != NULL && !block_inlined_p (a))
+        return 0;
+      a = BLOCK_SUPERBLOCK (a);
+    }
+  while (a != NULL);
+
+  return 0;
 }
 
 
 /* Return the symbol for the function which contains a specified
-   lexical block, described by a struct block BL.  */
+   lexical block, described by a struct block BL.  The return value
+   will not be an inlined function; the containing function will be
+   returned instead.  */
 
 struct symbol *
-block_function (const struct block *bl)
+block_linkage_function (const struct block *bl)
 {
-  while (BLOCK_FUNCTION (bl) == 0 && BLOCK_SUPERBLOCK (bl) != 0)
+  while ((BLOCK_FUNCTION (bl) == NULL || block_inlined_p (bl))
+        && BLOCK_SUPERBLOCK (bl) != NULL)
     bl = BLOCK_SUPERBLOCK (bl);
 
   return BLOCK_FUNCTION (bl);
 }
 
-/* Return the blockvector immediately containing the innermost lexical block
-   containing the specified pc value and section, or 0 if there is none.
-   PINDEX is a pointer to the index value of the block.  If PINDEX
-   is NULL, we don't pass this information back to the caller.  */
+/* Return the symbol for the function which contains a specified
+   block, described by a struct block BL.  The return value will be
+   the closest enclosing function, which might be an inline
+   function.  */
+
+struct symbol *
+block_containing_function (const struct block *bl)
+{
+  while (BLOCK_FUNCTION (bl) == NULL && BLOCK_SUPERBLOCK (bl) != NULL)
+    bl = BLOCK_SUPERBLOCK (bl);
+
+  return BLOCK_FUNCTION (bl);
+}
+
+/* Return one if BL represents an inlined function.  */
+
+int
+block_inlined_p (const struct block *bl)
+{
+  return BLOCK_FUNCTION (bl) != NULL && SYMBOL_INLINED (BLOCK_FUNCTION (bl));
+}
+
+/* Return the blockvector immediately containing the innermost lexical
+   block containing the specified pc value and section, or 0 if there
+   is none.  PBLOCK is a pointer to the block.  If PBLOCK is NULL, we
+   don't pass this information back to the caller.  */
 
 struct blockvector *
-blockvector_for_pc_sect (CORE_ADDR pc, struct bfd_section *section,
-                        int *pindex, struct symtab *symtab)
+blockvector_for_pc_sect (CORE_ADDR pc, struct obj_section *section,
+                        struct block **pblock, struct symtab *symtab)
 {
   struct block *b;
   int bot, top, half;
@@ -87,11 +125,27 @@ blockvector_for_pc_sect (CORE_ADDR pc, struct bfd_section *section,
     }
 
   bl = BLOCKVECTOR (symtab);
-  b = BLOCKVECTOR_BLOCK (bl, 0);
 
   /* Then search that symtab for the smallest block that wins.  */
-  /* Use binary search to find the last block that starts before PC.  */
 
+  /* If we have an addrmap mapping code addresses to blocks, then use
+     that.  */
+  if (BLOCKVECTOR_MAP (bl))
+    {
+      b = addrmap_find (BLOCKVECTOR_MAP (bl), pc);
+      if (b)
+        {
+          if (pblock)
+            *pblock = b;
+          return bl;
+        }
+      else
+        return 0;
+    }
+
+
+  /* Otherwise, use binary search to find the last block that starts
+     before PC.  */
   bot = 0;
   top = BLOCKVECTOR_NBLOCKS (bl);
 
@@ -112,8 +166,8 @@ blockvector_for_pc_sect (CORE_ADDR pc, struct bfd_section *section,
       b = BLOCKVECTOR_BLOCK (bl, bot);
       if (BLOCK_END (b) > pc)
        {
-         if (pindex)
-           *pindex = bot;
+         if (pblock)
+           *pblock = b;
          return bl;
        }
       bot--;
@@ -121,29 +175,61 @@ blockvector_for_pc_sect (CORE_ADDR pc, struct bfd_section *section,
   return 0;
 }
 
+/* Return call_site for specified PC in GDBARCH.  PC must match exactly, it
+   must be the next instruction after call (or after tail call jump).  Throw
+   NO_ENTRY_VALUE_ERROR otherwise.  This function never returns NULL.  */
+
+struct call_site *
+call_site_for_pc (struct gdbarch *gdbarch, CORE_ADDR pc)
+{
+  struct symtab *symtab;
+  void **slot = NULL;
+
+  /* -1 as tail call PC can be already after the compilation unit range.  */
+  symtab = find_pc_symtab (pc - 1);
+
+  if (symtab != NULL && symtab->call_site_htab != NULL)
+    slot = htab_find_slot (symtab->call_site_htab, &pc, NO_INSERT);
+
+  if (slot == NULL)
+    {
+      struct minimal_symbol *msym = lookup_minimal_symbol_by_pc (pc);
+
+      /* DW_TAG_gnu_call_site will be missing just if GCC could not determine
+        the call target.  */
+      throw_error (NO_ENTRY_VALUE_ERROR,
+                  _("DW_OP_GNU_entry_value resolving cannot find "
+                    "DW_TAG_GNU_call_site %s in %s"),
+                  paddress (gdbarch, pc),
+                  msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym));
+    }
+
+  return *slot;
+}
+
 /* Return the blockvector immediately containing the innermost lexical block
    containing the specified pc value, or 0 if there is none.
    Backward compatibility, no section.  */
 
 struct blockvector *
-blockvector_for_pc (CORE_ADDR pc, int *pindex)
+blockvector_for_pc (CORE_ADDR pc, struct block **pblock)
 {
   return blockvector_for_pc_sect (pc, find_pc_mapped_section (pc),
-                                 pindex, NULL);
+                                 pblock, NULL);
 }
 
 /* Return the innermost lexical block containing the specified pc value
    in the specified section, or 0 if there is none.  */
 
 struct block *
-block_for_pc_sect (CORE_ADDR pc, struct bfd_section *section)
+block_for_pc_sect (CORE_ADDR pc, struct obj_section *section)
 {
   struct blockvector *bl;
-  int index;
+  struct block *b;
 
-  bl = blockvector_for_pc_sect (pc, section, &index, NULL);
+  bl = blockvector_for_pc_sect (pc, section, &b, NULL);
   if (bl)
-    return BLOCKVECTOR_BLOCK (bl, index);
+    return b;
   return 0;
 }
 
@@ -189,25 +275,16 @@ block_set_scope (struct block *block, const char *scope,
   BLOCK_NAMESPACE (block)->scope = scope;
 }
 
-/* This returns the first using directives associated to BLOCK, if
+/* This returns the using directives list associated with BLOCK, if
    any.  */
 
-/* FIXME: carlton/2003-04-23: This uses the fact that we currently
-   only have using directives in static blocks, because we only
-   generate using directives from anonymous namespaces.  Eventually,
-   when we support using directives everywhere, we'll want to replace
-   this by some iterator functions.  */
-
 struct using_direct *
 block_using (const struct block *block)
 {
-  const struct block *static_block = block_static_block (block);
-
-  if (static_block == NULL
-      || BLOCK_NAMESPACE (static_block) == NULL)
+  if (block == NULL || BLOCK_NAMESPACE (block) == NULL)
     return NULL;
   else
-    return BLOCK_NAMESPACE (static_block)->using;
+    return BLOCK_NAMESPACE (block)->using;
 }
 
 /* Set BLOCK's using member to USING; if needed, allocate memory via
@@ -289,7 +366,314 @@ allocate_block (struct obstack *obstack)
   BLOCK_SUPERBLOCK (bl) = NULL;
   BLOCK_DICT (bl) = NULL;
   BLOCK_NAMESPACE (bl) = NULL;
-  BLOCK_GCC_COMPILED (bl) = 0;
 
   return bl;
 }
+
+/* Allocate a global block.  */
+
+struct block *
+allocate_global_block (struct obstack *obstack)
+{
+  struct global_block *bl = OBSTACK_ZALLOC (obstack, struct global_block);
+
+  return &bl->block;
+}
+
+/* Set the symtab of the global block.  */
+
+void
+set_block_symtab (struct block *block, struct symtab *symtab)
+{
+  struct global_block *gb;
+
+  gdb_assert (BLOCK_SUPERBLOCK (block) == NULL);
+  gb = (struct global_block *) block;
+  gdb_assert (gb->symtab == NULL);
+  gb->symtab = symtab;
+}
+
+/* Return the symtab of the global block.  */
+
+static struct symtab *
+get_block_symtab (const struct block *block)
+{
+  struct global_block *gb;
+
+  gdb_assert (BLOCK_SUPERBLOCK (block) == NULL);
+  gb = (struct global_block *) block;
+  gdb_assert (gb->symtab != NULL);
+  return gb->symtab;
+}
+
+\f
+
+/* Initialize a block iterator, either to iterate over a single block,
+   or, for static and global blocks, all the included symtabs as
+   well.  */
+
+static void
+initialize_block_iterator (const struct block *block,
+                          struct block_iterator *iter)
+{
+  enum block_enum which;
+  struct symtab *symtab;
+
+  iter->idx = -1;
+
+  if (BLOCK_SUPERBLOCK (block) == NULL)
+    {
+      which = GLOBAL_BLOCK;
+      symtab = get_block_symtab (block);
+    }
+  else if (BLOCK_SUPERBLOCK (BLOCK_SUPERBLOCK (block)) == NULL)
+    {
+      which = STATIC_BLOCK;
+      symtab = get_block_symtab (BLOCK_SUPERBLOCK (block));
+    }
+  else
+    {
+      iter->d.block = block;
+      /* A signal value meaning that we're iterating over a single
+        block.  */
+      iter->which = FIRST_LOCAL_BLOCK;
+      return;
+    }
+
+  /* If this is an included symtab, find the canonical includer and
+     use it instead.  */
+  while (symtab->user != NULL)
+    symtab = symtab->user;
+
+  /* Putting this check here simplifies the logic of the iterator
+     functions.  If there are no included symtabs, we only need to
+     search a single block, so we might as well just do that
+     directly.  */
+  if (symtab->includes == NULL)
+    {
+      iter->d.block = block;
+      /* A signal value meaning that we're iterating over a single
+        block.  */
+      iter->which = FIRST_LOCAL_BLOCK;
+    }
+  else
+    {
+      iter->d.symtab = symtab;
+      iter->which = which;
+    }
+}
+
+/* A helper function that finds the current symtab over whose static
+   or global block we should iterate.  */
+
+static struct symtab *
+find_iterator_symtab (struct block_iterator *iterator)
+{
+  if (iterator->idx == -1)
+    return iterator->d.symtab;
+  return iterator->d.symtab->includes[iterator->idx];
+}
+
+/* Perform a single step for a plain block iterator, iterating across
+   symbol tables as needed.  Returns the next symbol, or NULL when
+   iteration is complete.  */
+
+static struct symbol *
+block_iterator_step (struct block_iterator *iterator, int first)
+{
+  struct symbol *sym;
+
+  gdb_assert (iterator->which != FIRST_LOCAL_BLOCK);
+
+  while (1)
+    {
+      if (first)
+       {
+         struct symtab *symtab = find_iterator_symtab (iterator);
+         const struct block *block;
+
+         /* Iteration is complete.  */
+         if (symtab == NULL)
+           return  NULL;
+
+         block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), iterator->which);
+         sym = dict_iterator_first (BLOCK_DICT (block), &iterator->dict_iter);
+       }
+      else
+       sym = dict_iterator_next (&iterator->dict_iter);
+
+      if (sym != NULL)
+       return sym;
+
+      /* We have finished iterating the appropriate block of one
+        symtab.  Now advance to the next symtab and begin iteration
+        there.  */
+      ++iterator->idx;
+      first = 1;
+    }
+}
+
+/* See block.h.  */
+
+struct symbol *
+block_iterator_first (const struct block *block,
+                     struct block_iterator *iterator)
+{
+  initialize_block_iterator (block, iterator);
+
+  if (iterator->which == FIRST_LOCAL_BLOCK)
+    return dict_iterator_first (block->dict, &iterator->dict_iter);
+
+  return block_iterator_step (iterator, 1);
+}
+
+/* See block.h.  */
+
+struct symbol *
+block_iterator_next (struct block_iterator *iterator)
+{
+  if (iterator->which == FIRST_LOCAL_BLOCK)
+    return dict_iterator_next (&iterator->dict_iter);
+
+  return block_iterator_step (iterator, 0);
+}
+
+/* Perform a single step for a "name" block iterator, iterating across
+   symbol tables as needed.  Returns the next symbol, or NULL when
+   iteration is complete.  */
+
+static struct symbol *
+block_iter_name_step (struct block_iterator *iterator, const char *name,
+                     int first)
+{
+  struct symbol *sym;
+
+  gdb_assert (iterator->which != FIRST_LOCAL_BLOCK);
+
+  while (1)
+    {
+      if (first)
+       {
+         struct symtab *symtab = find_iterator_symtab (iterator);
+         const struct block *block;
+
+         /* Iteration is complete.  */
+         if (symtab == NULL)
+           return  NULL;
+
+         block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), iterator->which);
+         sym = dict_iter_name_first (BLOCK_DICT (block), name,
+                                     &iterator->dict_iter);
+       }
+      else
+       sym = dict_iter_name_next (name, &iterator->dict_iter);
+
+      if (sym != NULL)
+       return sym;
+
+      /* We have finished iterating the appropriate block of one
+        symtab.  Now advance to the next symtab and begin iteration
+        there.  */
+      ++iterator->idx;
+      first = 1;
+    }
+}
+
+/* See block.h.  */
+
+struct symbol *
+block_iter_name_first (const struct block *block,
+                      const char *name,
+                      struct block_iterator *iterator)
+{
+  initialize_block_iterator (block, iterator);
+
+  if (iterator->which == FIRST_LOCAL_BLOCK)
+    return dict_iter_name_first (block->dict, name, &iterator->dict_iter);
+
+  return block_iter_name_step (iterator, name, 1);
+}
+
+/* See block.h.  */
+
+struct symbol *
+block_iter_name_next (const char *name, struct block_iterator *iterator)
+{
+  if (iterator->which == FIRST_LOCAL_BLOCK)
+    return dict_iter_name_next (name, &iterator->dict_iter);
+
+  return block_iter_name_step (iterator, name, 0);
+}
+
+/* Perform a single step for a "match" block iterator, iterating
+   across symbol tables as needed.  Returns the next symbol, or NULL
+   when iteration is complete.  */
+
+static struct symbol *
+block_iter_match_step (struct block_iterator *iterator,
+                      const char *name,
+                      symbol_compare_ftype *compare,
+                      int first)
+{
+  struct symbol *sym;
+
+  gdb_assert (iterator->which != FIRST_LOCAL_BLOCK);
+
+  while (1)
+    {
+      if (first)
+       {
+         struct symtab *symtab = find_iterator_symtab (iterator);
+         const struct block *block;
+
+         /* Iteration is complete.  */
+         if (symtab == NULL)
+           return  NULL;
+
+         block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), iterator->which);
+         sym = dict_iter_match_first (BLOCK_DICT (block), name,
+                                      compare, &iterator->dict_iter);
+       }
+      else
+       sym = dict_iter_match_next (name, compare, &iterator->dict_iter);
+
+      if (sym != NULL)
+       return sym;
+
+      /* We have finished iterating the appropriate block of one
+        symtab.  Now advance to the next symtab and begin iteration
+        there.  */
+      ++iterator->idx;
+      first = 1;
+    }
+}
+
+/* See block.h.  */
+
+struct symbol *
+block_iter_match_first (const struct block *block,
+                       const char *name,
+                       symbol_compare_ftype *compare,
+                       struct block_iterator *iterator)
+{
+  initialize_block_iterator (block, iterator);
+
+  if (iterator->which == FIRST_LOCAL_BLOCK)
+    return dict_iter_match_first (block->dict, name, compare,
+                                 &iterator->dict_iter);
+
+  return block_iter_match_step (iterator, name, compare, 1);
+}
+
+/* See block.h.  */
+
+struct symbol *
+block_iter_match_next (const char *name,
+                      symbol_compare_ftype *compare,
+                      struct block_iterator *iterator)
+{
+  if (iterator->which == FIRST_LOCAL_BLOCK)
+    return dict_iter_match_next (name, compare, &iterator->dict_iter);
+
+  return block_iter_match_step (iterator, name, compare, 0);
+}