diff options
author | David Carlton <carlton@bactrian.org> | 2002-11-21 01:04:22 +0000 |
---|---|---|
committer | David Carlton <carlton@bactrian.org> | 2002-11-21 01:04:22 +0000 |
commit | 50e3bbdd6b70da48169e722e5307a2b23f43f992 (patch) | |
tree | 5736bd8329d61975e43866fcb0c95555112ba999 | |
parent | 83d1a0d30c48b0db4a9160ac403d3680393eedfb (diff) | |
download | gdb-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/ChangeLog | 32 | ||||
-rw-r--r-- | gdb/Makefile.in | 4 | ||||
-rw-r--r-- | gdb/cp-support.c | 159 | ||||
-rw-r--r-- | gdb/cp-support.h | 3 | ||||
-rw-r--r-- | gdb/dwarf2read.c | 59 | ||||
-rw-r--r-- | gdb/gdbtypes.h | 3 | ||||
-rw-r--r-- | gdb/symfile.h | 2 |
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. */ |