summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Carlton <carlton@bactrian.org>2002-11-21 01:04:22 +0000
committerDavid Carlton <carlton@bactrian.org>2002-11-21 01:04:22 +0000
commit50e3bbdd6b70da48169e722e5307a2b23f43f992 (patch)
tree5736bd8329d61975e43866fcb0c95555112ba999
parent83d1a0d30c48b0db4a9160ac403d3680393eedfb (diff)
downloadgdb-50e3bbdd6b70da48169e722e5307a2b23f43f992.tar.gz
2002-11-20 David Carlton <carlton@math.stanford.edu>
* dwarf2read.c (scan_partial_symbols): Move lowpc, highpc initial and final setting to dwarf2_build_psymtabs_hard. (dwarf2_build_psymtabs_hard): Set lowpc, highpc outside of scan_partial_symbols. (scan_partial_symbols): Handle namespaces by calling ourself recursively. * Makefile.in (cp-support.o): Depend on gdbcmd_h. * cp-support.c (_initialize_cp_support): New function. (maintenance_print_namespace): New function. #include "gdbcmd.h" * cp-support.h: Add opaque declaration for 'struct symbol'. * symfile.h: Add comment saying that you must first include symtab.h. * Makefile.in (cp-support.o): Depend on dictionary_h. * cp-support.c: #include "dictionary.h" * gdbtypes.h: Add TYPE_CODE_NAMESPACE to enum type_code. * cp-support.h: Add declaration for cp_check_namespace_symbol. * Makefile.in (cp-support.o): Depend on gdbtypes_h. * cp-support.c: New variable namespace_objfile. (get_namespace_objfile): New function. (cp_check_namespace_symbol): New function. #include "gdbtypes.h" * Makefile.in (cp-support.o): Depend on symfile_h, symtab_h, block_h, objfiles_h. * cp-support.c: Add declaration for find_last_component. #include "symfile.h", "symtab.h", "block.h", "objfiles.h". New variable namespace_block. (get_namespace_block): New function. (free_namespace_block): New function.
-rw-r--r--gdb/ChangeLog32
-rw-r--r--gdb/Makefile.in4
-rw-r--r--gdb/cp-support.c159
-rw-r--r--gdb/cp-support.h3
-rw-r--r--gdb/dwarf2read.c59
-rw-r--r--gdb/gdbtypes.h3
-rw-r--r--gdb/symfile.h2
7 files changed, 219 insertions, 43 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index cac8981d4c9..8b3908f4c91 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,35 @@
+2002-11-20 David Carlton <carlton@math.stanford.edu>
+
+ * dwarf2read.c (scan_partial_symbols): Move lowpc, highpc initial
+ and final setting to dwarf2_build_psymtabs_hard.
+ (dwarf2_build_psymtabs_hard): Set lowpc, highpc outside of
+ scan_partial_symbols.
+ (scan_partial_symbols): Handle namespaces by calling ourself
+ recursively.
+ * Makefile.in (cp-support.o): Depend on gdbcmd_h.
+ * cp-support.c (_initialize_cp_support): New function.
+ (maintenance_print_namespace): New function.
+ #include "gdbcmd.h"
+ * cp-support.h: Add opaque declaration for 'struct symbol'.
+ * symfile.h: Add comment saying that you must first include
+ symtab.h.
+ * Makefile.in (cp-support.o): Depend on dictionary_h.
+ * cp-support.c: #include "dictionary.h"
+ * gdbtypes.h: Add TYPE_CODE_NAMESPACE to enum type_code.
+ * cp-support.h: Add declaration for cp_check_namespace_symbol.
+ * Makefile.in (cp-support.o): Depend on gdbtypes_h.
+ * cp-support.c: New variable namespace_objfile.
+ (get_namespace_objfile): New function.
+ (cp_check_namespace_symbol): New function.
+ #include "gdbtypes.h"
+ * Makefile.in (cp-support.o): Depend on symfile_h, symtab_h,
+ block_h, objfiles_h.
+ * cp-support.c: Add declaration for find_last_component.
+ #include "symfile.h", "symtab.h", "block.h", "objfiles.h".
+ New variable namespace_block.
+ (get_namespace_block): New function.
+ (free_namespace_block): New function.
+
2002-11-19 David Carlton <carlton@math.stanford.edu>
* block.c: Whitespace cleanup.
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 5c027e51bfd..625fc1b46c6 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -1603,7 +1603,9 @@ corelow.o: corelow.c $(defs_h) $(gdb_string_h) $(frame_h) $(inferior_h) \
$(gdbthread_h) $(regcache_h) $(symfile_h)
cp-abi.o: cp-abi.c $(defs_h) $(value_h) $(cp_abi_h) $(gdb_string_h)
cp-support.o: cp-support.c $(defs_h) $(cp_support_h) $(gdb_string_h) \
- $(demangle_h) $(gdb_obstack_h) $(gdb_assert_h)
+ $(demangle_h) $(gdb_obstack_h) $(gdb_assert_h) $(symtab_h) \
+ $(symfile_h) $(block_h) $(objfiles_h) $(gdbtypes_h) $(dictionary_h) \
+ $(gdbcmd_h)
cp-valprint.o: cp-valprint.c $(defs_h) $(gdb_obstack_h) $(symtab_h) \
$(gdbtypes_h) $(expression_h) $(value_h) $(command_h) $(gdbcmd_h) \
$(demangle_h) $(annotate_h) $(gdb_string_h) $(c_lang_h) $(target_h) \
diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index a5a6db088ee..0efb1d85549 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -26,6 +26,32 @@
#include "demangle.h"
#include "gdb_obstack.h"
#include "gdb_assert.h"
+#include "symtab.h"
+#include "symfile.h"
+#include "block.h"
+#include "objfiles.h"
+#include "gdbtypes.h"
+#include "dictionary.h"
+#include "gdbcmd.h"
+
+static const char *find_last_component (const char *name);
+
+/* This block exists only to store symbols associated to namespaces.
+ Normally, try to avoid accessing it directly: instead, use
+ get_namespace_block if you can. Similarly with
+ namespace_objfile. */
+
+static struct block *namespace_block = NULL;
+
+static struct objfile *namespace_objfile = NULL;
+
+static struct block *get_namespace_block (void);
+
+static struct objfile *get_namespace_objfile (void);
+
+static void free_namespace_block (struct symtab *symtab);
+
+static void maintenance_print_namespace (char *args, int from_tty);
/* Here are some random pieces of trivia to keep in mind while trying
to take apart demangled names:
@@ -346,3 +372,136 @@ cp_find_first_component (const char *name)
}
}
}
+
+/* Locate the namespace_block, allocating it if necessary. */
+
+static struct block *
+get_namespace_block (void)
+{
+ if (namespace_block == NULL)
+ {
+ struct objfile *objfile = get_namespace_objfile ();
+ struct symtab *namespace_symtab;
+ struct blockvector *bv;
+ struct block *bl;
+
+ namespace_symtab = allocate_symtab ("<C++-namespaces>", objfile);
+ namespace_symtab->language = language_cplus;
+ namespace_symtab->free_code = free_nothing;
+ namespace_symtab->dirname = NULL;
+
+ bv = obstack_alloc (&objfile->symbol_obstack,
+ sizeof (struct blockvector));
+ BLOCKVECTOR_NBLOCKS (bv) = 1;
+ BLOCKVECTOR (namespace_symtab) = bv;
+
+ /* Allocate dummy STATIC_BLOCK. */
+ bl = obstack_alloc (&objfile->symbol_obstack, sizeof (struct block));
+ BLOCK_START (bl) = 0;
+ BLOCK_END (bl) = 0;
+ BLOCK_FUNCTION (bl) = NULL;
+ BLOCK_SUPERBLOCK (bl) = NULL;
+ BLOCK_DICT (bl) = dict_create_linear (&objfile->symbol_obstack,
+ NULL);
+ BLOCK_NAMESPACE (bl) = NULL;
+ BLOCK_GCC_COMPILED (bl) = 0;
+ BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK) = bl;
+
+ /* Allocate GLOBAL_BLOCK. */
+ bl = (struct block *)
+ obstack_alloc (&objfile->symbol_obstack, sizeof (struct block));
+ *bl = *BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+ BLOCK_DICT (bl) = dict_create_linear_expandable ();
+ BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK) = bl;
+ namespace_symtab->free_func = free_namespace_block;
+
+ namespace_block = bl;
+ }
+
+ return namespace_block;
+}
+
+/* Free the dictionary associated to the namespace block. */
+
+static void
+free_namespace_block (struct symtab *symtab)
+{
+ gdb_assert (namespace_block != NULL);
+ dict_free (BLOCK_DICT (namespace_block));
+ namespace_block = NULL;
+ namespace_objfile = NULL;
+}
+
+/* Locate the namespace objfile, allocating it if necessary. */
+
+static struct objfile *
+get_namespace_objfile (void)
+{
+ if (namespace_objfile == NULL)
+ {
+ namespace_objfile = allocate_objfile (NULL, 0);
+ }
+
+ return namespace_objfile;
+}
+
+/* Check to see if there's already a namespace symbol corresponding to
+ the initial substring of NAME whose length is LEN; if there isn't
+ one, allocate one and add it to the namespace symtab. Return the
+ symbol in question. */
+
+struct symbol *
+cp_check_namespace_symbol (const char *name, int len)
+{
+ struct objfile *objfile = get_namespace_objfile ();
+ char *name_copy = obsavestring (name, len, &objfile->symbol_obstack);
+ const struct block *block = get_namespace_block ();
+ struct symbol *sym = lookup_block_symbol (block, name_copy,
+ NULL, VAR_NAMESPACE);
+
+ if (sym == NULL)
+ {
+ struct type *type = alloc_type (objfile);
+ INIT_CPLUS_SPECIFIC (type);
+ TYPE_TAG_NAME (type) = obsavestring (name, len, &objfile->type_obstack);
+ TYPE_CODE (type) = TYPE_CODE_NAMESPACE;
+ TYPE_LENGTH (type) = 0;
+
+ sym = obstack_alloc (&objfile->symbol_obstack, sizeof (struct symbol));
+ memset (sym, 0, sizeof (struct symbol));
+ SYMBOL_LANGUAGE (sym) = language_cplus;
+ SYMBOL_NAME (sym) = name_copy;
+ SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+ SYMBOL_TYPE (sym) = type;
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+
+ dict_add_symbol (BLOCK_DICT (block), sym);
+ }
+ else
+ {
+ obstack_free (&objfile->symbol_obstack, name_copy);
+ }
+
+ return sym;
+}
+
+static void
+maintenance_print_namespace (char *args, int from_tty)
+{
+ const struct block *block = get_namespace_block ();
+ struct dict_iterator iter;
+ struct symbol *sym;
+
+ ALL_BLOCK_SYMBOLS (block, iter, sym)
+ {
+ printf_unfiltered ("%s\n", SYMBOL_BEST_NAME (sym));
+ }
+}
+
+void
+_initialize_cp_support (void)
+{
+ add_cmd ("namespace", class_maintenance, maintenance_print_namespace,
+ "Print the list of current known C++ namespaces.",
+ &maintenanceprintlist);
+}
diff --git a/gdb/cp-support.h b/gdb/cp-support.h
index 70963040f0a..5d7b4af8ea5 100644
--- a/gdb/cp-support.h
+++ b/gdb/cp-support.h
@@ -23,6 +23,7 @@
/* Opaque declarations. */
struct obstack;
+struct symbol;
extern char *class_name_from_physname (const char *physname);
@@ -96,3 +97,5 @@ struct using_direct_node *cp_copy_usings (struct using_direct_node *tocopy,
struct using_direct_node *tail);
extern void cp_free_usings (struct using_direct_node *using);
+
+extern struct symbol *cp_check_namespace_symbol (const char *name, int len);
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 13182f0b28f..281e2e996c2 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -1296,9 +1296,17 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
If not, there's no more debug_info for this comp unit. */
if (comp_unit_die.has_children)
{
+ lowpc = ((CORE_ADDR) -1);
+ highpc = ((CORE_ADDR) 0);
+
info_ptr = scan_partial_symbols (info_ptr, objfile, &lowpc, &highpc,
&cu_header);
+ /* If we didn't find a lowpc, set it to highpc to avoid
+ complaints from `maint check'. */
+ if (lowpc == ((CORE_ADDR) -1))
+ lowpc = highpc;
+
/* If the compilation unit didn't have an explicit address range,
then use the information extracted from its child dies. */
if (! comp_unit_die.has_pc_info)
@@ -1327,7 +1335,8 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
do_cleanups (back_to);
}
-/* Read in all interesting dies to the end of the compilation unit. */
+/* Read in all interesting dies to the end of the compilation unit or
+ to the end of the current namespace. */
static char *
scan_partial_symbols (char *info_ptr, struct objfile *objfile,
@@ -1345,20 +1354,6 @@ scan_partial_symbols (char *info_ptr, struct objfile *objfile,
int nesting_level = 1;
- /* We only want to read in symbols corresponding to variables or
- other similar objects that are global or static. Normally, these
- are all children of the DW_TAG_compile_unit die, so are all at
- level 1. But C++ namespaces give rise to DW_TAG_namespace dies
- whose children are global objects. So we keep track of what
- level we currently think of as referring to file scope; this
- should always equal 1 plus the number of namespaces that we are
- currently nested within. */
-
- int file_scope_level = 1;
-
- *lowpc = ((CORE_ADDR) -1);
- *highpc = ((CORE_ADDR) 0);
-
while (nesting_level)
{
info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu_header);
@@ -1378,7 +1373,7 @@ scan_partial_symbols (char *info_ptr, struct objfile *objfile,
{
*highpc = pdi.highpc;
}
- if ((pdi.is_external || nesting_level == file_scope_level)
+ if ((pdi.is_external || nesting_level == 1)
&& !pdi.is_declaration)
{
add_partial_symbol (&pdi, objfile, cu_header);
@@ -1391,7 +1386,7 @@ scan_partial_symbols (char *info_ptr, struct objfile *objfile,
case DW_TAG_structure_type:
case DW_TAG_union_type:
case DW_TAG_enumeration_type:
- if ((pdi.is_external || nesting_level == file_scope_level)
+ if ((pdi.is_external || nesting_level == 1)
&& !pdi.is_declaration)
{
add_partial_symbol (&pdi, objfile, cu_header);
@@ -1402,22 +1397,20 @@ scan_partial_symbols (char *info_ptr, struct objfile *objfile,
symbol table. They're children of the enumeration
type die, so they occur at a level one higher than we
normally look for. */
- if (nesting_level == file_scope_level + 1)
+ if (nesting_level == 2)
add_partial_symbol (&pdi, objfile, cu_header);
break;
case DW_TAG_base_type:
/* File scope base type definitions are added to the partial
symbol table. */
- if (nesting_level == file_scope_level)
+ if (nesting_level == 1)
add_partial_symbol (&pdi, objfile, cu_header);
break;
case DW_TAG_namespace:
- /* FIXME: carlton/2002-10-16: we're not yet doing
- anything useful with this, but for now make sure that
- these tags at least don't cause us to miss any
- important symbols. */
if (pdi.has_children)
- file_scope_level++;
+ info_ptr = scan_partial_symbols (info_ptr, objfile,
+ lowpc, highpc,
+ cu_header);
default:
break;
}
@@ -1425,8 +1418,8 @@ scan_partial_symbols (char *info_ptr, struct objfile *objfile,
/* If the die has a sibling, skip to the sibling. Do not skip
enumeration types, we want to record their enumerators. Do
- not skip namespaces, we want to record symbols inside
- them. */
+ not skip namespaces, the scan_partial_symbols call has
+ already updated info_ptr for us. */
if (pdi.sibling
&& pdi.tag != DW_TAG_enumeration_type
&& pdi.tag != DW_TAG_namespace)
@@ -1443,20 +1436,9 @@ scan_partial_symbols (char *info_ptr, struct objfile *objfile,
if (pdi.tag == 0)
{
nesting_level--;
- /* If this is the end of a DW_TAG_namespace entry, then
- decrease the file_scope_level, too. */
- if (nesting_level < file_scope_level)
- {
- file_scope_level--;
- gdb_assert (nesting_level == file_scope_level);
- }
}
}
- /* If we didn't find a lowpc, set it to highpc to avoid complaints
- from `maint check'. */
- if (*lowpc == ((CORE_ADDR) -1))
- *lowpc = *highpc;
return info_ptr;
}
@@ -2993,9 +2975,6 @@ read_common_block (struct die_info *die, struct objfile *objfile,
/* Read a C++ namespace. */
-/* FIXME: carlton/2002-10-16: For now, we don't actually do anything
- useful with the namespace data: we just process its children. */
-
static void
read_namespace (struct die_info *die, struct objfile *objfile,
const struct comp_unit_head *cu_header)
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index fe4b0f12bdc..450aac9302c 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -131,8 +131,9 @@ enum type_code
TYPE_CODE_TYPEDEF,
TYPE_CODE_TEMPLATE, /* C++ template */
- TYPE_CODE_TEMPLATE_ARG /* C++ template arg */
+ TYPE_CODE_TEMPLATE_ARG, /* C++ template arg */
+ TYPE_CODE_NAMESPACE, /* C++ namespace. */
};
/* For now allow source to use TYPE_CODE_CLASS for C++ classes, as an
diff --git a/gdb/symfile.h b/gdb/symfile.h
index fd4347c1f98..ec40f7b4e96 100644
--- a/gdb/symfile.h
+++ b/gdb/symfile.h
@@ -23,7 +23,7 @@
#if !defined (SYMFILE_H)
#define SYMFILE_H
-/* This file requires that you first include "bfd.h". */
+/* This file requires that you first include "bfd.h" and "symtab.h". */
/* Opaque declarations. */