* remote.c (remote_write_bytes): Take a const buffer argument.
[deliverable/binutils-gdb.git] / gdb / block.c
index 8aa08fb175d68f9d311730a35db54499450e2878..abce515a6ef5c322b3f38940153ef293f794b9fa 100644 (file)
@@ -1,6 +1,6 @@
 /* Block-related functions for the GNU debugger, GDB.
 
-   Copyright 2003 Free Software Foundation, Inc.
+   Copyright (C) 2003 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 
    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.  */
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 #include "defs.h"
 #include "block.h"
 #include "symtab.h"
 #include "symfile.h"
+#include "gdb_obstack.h"
+#include "cp-support.h"
+
+/* This is used by struct block to store namespace-related info for
+   C++ files, namely using declarations and the current namespace in
+   scope.  */
+
+struct block_namespace_info
+{
+  const char *scope;
+  struct using_direct *using;
+};
+
+static void block_initialize_namespace (struct block *block,
+                                       struct obstack *obstack);
 
 /* Return Nonzero if block a is lexically nested within block b,
    or if a and b have the same pc range.
    Return zero otherwise. */
 
 int
-contained_in (struct block *a, struct block *b)
+contained_in (const struct block *a, const struct block *b)
 {
   if (!a || !b)
     return 0;
@@ -42,7 +57,7 @@ contained_in (struct block *a, struct block *b)
    lexical block, described by a struct block BL.  */
 
 struct symbol *
-block_function (struct block *bl)
+block_function (const struct block *bl)
 {
   while (BLOCK_FUNCTION (bl) == 0 && BLOCK_SUPERBLOCK (bl) != 0)
     bl = BLOCK_SUPERBLOCK (bl);
@@ -56,17 +71,18 @@ block_function (struct block *bl)
    is NULL, we don't pass this information back to the caller.  */
 
 struct blockvector *
-blockvector_for_pc_sect (register CORE_ADDR pc, struct sec *section,
+blockvector_for_pc_sect (CORE_ADDR pc, struct bfd_section *section,
                         int *pindex, struct symtab *symtab)
 {
-  register struct block *b;
-  register int bot, top, half;
+  struct block *b;
+  int bot, top, half;
   struct blockvector *bl;
 
   if (symtab == 0)             /* if no symtab specified by caller */
     {
       /* First search all symtabs for one whose file contains our pc */
-      if ((symtab = find_pc_sect_symtab (pc, section)) == 0)
+      symtab = find_pc_sect_symtab (pc, section);
+      if (symtab == 0)
        return 0;
     }
 
@@ -110,7 +126,7 @@ blockvector_for_pc_sect (register CORE_ADDR pc, struct sec *section,
    Backward compatibility, no section.  */
 
 struct blockvector *
-blockvector_for_pc (register CORE_ADDR pc, int *pindex)
+blockvector_for_pc (CORE_ADDR pc, int *pindex)
 {
   return blockvector_for_pc_sect (pc, find_pc_mapped_section (pc),
                                  pindex, NULL);
@@ -120,9 +136,9 @@ blockvector_for_pc (register CORE_ADDR pc, int *pindex)
    in the specified section, or 0 if there is none.  */
 
 struct block *
-block_for_pc_sect (register CORE_ADDR pc, struct sec *section)
+block_for_pc_sect (CORE_ADDR pc, struct bfd_section *section)
 {
-  register struct blockvector *bl;
+  struct blockvector *bl;
   int index;
 
   bl = blockvector_for_pc_sect (pc, section, &index, NULL);
@@ -135,7 +151,145 @@ block_for_pc_sect (register CORE_ADDR pc, struct sec *section)
    or 0 if there is none.  Backward compatibility, no section.  */
 
 struct block *
-block_for_pc (register CORE_ADDR pc)
+block_for_pc (CORE_ADDR pc)
 {
   return block_for_pc_sect (pc, find_pc_mapped_section (pc));
 }
+
+/* Now come some functions designed to deal with C++ namespace issues.
+   The accessors are safe to use even in the non-C++ case.  */
+
+/* This returns the namespace that BLOCK is enclosed in, or "" if it
+   isn't enclosed in a namespace at all.  This travels the chain of
+   superblocks looking for a scope, if necessary.  */
+
+const char *
+block_scope (const struct block *block)
+{
+  for (; block != NULL; block = BLOCK_SUPERBLOCK (block))
+    {
+      if (BLOCK_NAMESPACE (block) != NULL
+         && BLOCK_NAMESPACE (block)->scope != NULL)
+       return BLOCK_NAMESPACE (block)->scope;
+    }
+
+  return "";
+}
+
+/* Set BLOCK's scope member to SCOPE; if needed, allocate memory via
+   OBSTACK.  (It won't make a copy of SCOPE, however, so that already
+   has to be allocated correctly.)  */
+
+void
+block_set_scope (struct block *block, const char *scope,
+                struct obstack *obstack)
+{
+  block_initialize_namespace (block, obstack);
+
+  BLOCK_NAMESPACE (block)->scope = scope;
+}
+
+/* This returns the first using directives associated to 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)
+    return NULL;
+  else
+    return BLOCK_NAMESPACE (static_block)->using;
+}
+
+/* Set BLOCK's using member to USING; if needed, allocate memory via
+   OBSTACK.  (It won't make a copy of USING, however, so that already
+   has to be allocated correctly.)  */
+
+void
+block_set_using (struct block *block,
+                struct using_direct *using,
+                struct obstack *obstack)
+{
+  block_initialize_namespace (block, obstack);
+
+  BLOCK_NAMESPACE (block)->using = using;
+}
+
+/* If BLOCK_NAMESPACE (block) is NULL, allocate it via OBSTACK and
+   ititialize its members to zero.  */
+
+static void
+block_initialize_namespace (struct block *block, struct obstack *obstack)
+{
+  if (BLOCK_NAMESPACE (block) == NULL)
+    {
+      BLOCK_NAMESPACE (block)
+       = obstack_alloc (obstack, sizeof (struct block_namespace_info));
+      BLOCK_NAMESPACE (block)->scope = NULL;
+      BLOCK_NAMESPACE (block)->using = NULL;
+    }
+}
+
+/* Return the static block associated to BLOCK.  Return NULL if block
+   is NULL or if block is a global block.  */
+
+const struct block *
+block_static_block (const struct block *block)
+{
+  if (block == NULL || BLOCK_SUPERBLOCK (block) == NULL)
+    return NULL;
+
+  while (BLOCK_SUPERBLOCK (BLOCK_SUPERBLOCK (block)) != NULL)
+    block = BLOCK_SUPERBLOCK (block);
+
+  return block;
+}
+
+/* Return the static block associated to BLOCK.  Return NULL if block
+   is NULL.  */
+
+const struct block *
+block_global_block (const struct block *block)
+{
+  if (block == NULL)
+    return NULL;
+
+  while (BLOCK_SUPERBLOCK (block) != NULL)
+    block = BLOCK_SUPERBLOCK (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;
+  BLOCK_GCC_COMPILED (bl) = 0;
+
+  return bl;
+}
This page took 0.035541 seconds and 4 git commands to generate.