* cli-out.c (cli_table_begin, cli_table_body, cli_table_end)
[deliverable/binutils-gdb.git] / gdb / block.c
index 98b6ccbb84b43903f495e262baf9cd0f4b12e195..48ac21bd629df33a1f20dc0f93f602af897521b4 100644 (file)
@@ -1,12 +1,12 @@
 /* Block-related functions for the GNU debugger, GDB.
 
-   Copyright 2003 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2007, 2008, 2009, 2010 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., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 #include "block.h"
@@ -25,6 +23,7 @@
 #include "symfile.h"
 #include "gdb_obstack.h"
 #include "cp-support.h"
+#include "addrmap.h"
 
 /* This is used by struct block to store namespace-related info for
    C++ files, namely using declarations and the current namespace in
@@ -48,31 +47,54 @@ 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 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 sec *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 +109,27 @@ blockvector_for_pc_sect (CORE_ADDR pc, struct sec *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 +150,8 @@ blockvector_for_pc_sect (CORE_ADDR pc, struct sec *section,
       b = BLOCKVECTOR_BLOCK (bl, bot);
       if (BLOCK_END (b) > pc)
        {
-         if (pindex)
-           *pindex = bot;
+         if (pblock)
+           *pblock = b;
          return bl;
        }
       bot--;
@@ -126,24 +164,24 @@ blockvector_for_pc_sect (CORE_ADDR pc, struct sec *section,
    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 sec *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 +227,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
@@ -268,3 +297,27 @@ block_global_block (const struct block *block)
 
   return block;
 }
+
+/* Allocate a block on OBSTACK, and initialize its elements to
+   zero/NULL.  This is useful for creating "dummy" blocks that don't
+   correspond to actual source files.
+
+   Warning: it sets the block's BLOCK_DICT to NULL, which isn't a
+   valid value.  If you really don't want the block to have a
+   dictionary, then you should subsequently set its BLOCK_DICT to
+   dict_create_linear (obstack, NULL).  */
+
+struct block *
+allocate_block (struct obstack *obstack)
+{
+  struct block *bl = obstack_alloc (obstack, sizeof (struct block));
+
+  BLOCK_START (bl) = 0;
+  BLOCK_END (bl) = 0;
+  BLOCK_FUNCTION (bl) = NULL;
+  BLOCK_SUPERBLOCK (bl) = NULL;
+  BLOCK_DICT (bl) = NULL;
+  BLOCK_NAMESPACE (bl) = NULL;
+
+  return bl;
+}
This page took 0.025436 seconds and 4 git commands to generate.