aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2read.c
diff options
context:
space:
mode:
authorTom Tromey <tromey@redhat.com>2012-09-26 19:38:32 +0000
committerTom Tromey <tromey@redhat.com>2012-09-26 19:38:32 +0000
commit4357ac6c6f95606fff49f976d9ebc11965967bc3 (patch)
tree3a36925d75fcc2c7f5bc401d1b7d727fb0c7bbad /gdb/dwarf2read.c
parent965f07a88d697b5361258b1e771c616f54678461 (diff)
downloadgdb-4357ac6c6f95606fff49f976d9ebc11965967bc3.zip
gdb-4357ac6c6f95606fff49f976d9ebc11965967bc3.tar.gz
gdb-4357ac6c6f95606fff49f976d9ebc11965967bc3.tar.bz2
2012-09-26 Jan Kratochvil <jan.kratochvil@redhat.com>
Tom Tromey <tromey@redhat.com> * dwarf2read.c (read_common_block): Rewrite. (new_symbol_full): Handle DW_TAG_common_block. * f-lang.c (head_common_list, find_common_for_function): Remove. * f-lang.h (struct common_entry, struct saved_f77_common, SAVED_F77_COMMON, SAVED_F77_COMMON_PTR, COMMON_ENTRY, COMMON_ENTRY_PTR, head_common_list, find_common_for_function, BLANK_COMMON_NAME_LOCAL): Remove. (struct common_block): New. * f-valprint.c (list_all_visible_commons): Remove. (info_common_command_for_block): New function. (info_common_command): Use it. * stack.c (iterate_over_block_locals): Special case for COMMON_BLOCK_DOMAIN. * symtab.h (enum domain_enum_tag) <COMMON_BLOCK_DOMAIN>: New constant. (struct general_symbol_info) <value.common_block>: New field. (SYMBOL_VALUE_COMMON_BLOCK): New define. gdb/testsuite 2012-09-26 Jan Kratochvil <jan.kratochvil@redhat.com> * gdb.fortran/common-block.exp: New file. * gdb.fortran/common-block.f90: New file.
Diffstat (limited to 'gdb/dwarf2read.c')
-rw-r--r--gdb/dwarf2read.c80
1 files changed, 45 insertions, 35 deletions
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 758bd3b..87285e3 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -65,6 +65,7 @@
#include "gdb/gdb-index.h"
#include <ctype.h>
#include "gdb_bfd.h"
+#include "f-lang.h"
#include <fcntl.h>
#include "gdb_string.h"
@@ -11063,50 +11064,47 @@ read_set_type (struct die_info *die, struct dwarf2_cu *cu)
return set_die_type (die, set_type, cu);
}
-/* First cut: install each common block member as a global variable. */
+/* Create appropriate locally-scoped variables for all the
+ DW_TAG_common_block entries. Also create a struct common_block
+ listing all such variables for `info common'. COMMON_BLOCK_DOMAIN
+ is used to sepate the common blocks name namespace from regular
+ variable names. */
static void
read_common_block (struct die_info *die, struct dwarf2_cu *cu)
{
- struct die_info *child_die;
- struct attribute *attr;
- struct symbol *sym;
- CORE_ADDR base = (CORE_ADDR) 0;
-
- attr = dwarf2_attr (die, DW_AT_location, cu);
- if (attr)
- {
- /* Support the .debug_loc offsets. */
- if (attr_form_is_block (attr))
- {
- base = decode_locdesc (DW_BLOCK (attr), cu);
- }
- else if (attr_form_is_section_offset (attr))
- {
- dwarf2_complex_location_expr_complaint ();
- }
- else
- {
- dwarf2_invalid_attrib_class_complaint ("DW_AT_location",
- "common block member");
- }
- }
if (die->child != NULL)
{
- child_die = die->child;
- while (child_die && child_die->tag)
- {
- LONGEST offset;
+ struct objfile *objfile = cu->objfile;
+ struct die_info *child_die;
+ size_t n_entries = 0, size;
+ struct common_block *common_block;
+ struct symbol *sym;
+ for (child_die = die->child;
+ child_die && child_die->tag;
+ child_die = sibling_die (child_die))
+ ++n_entries;
+
+ size = (sizeof (struct common_block)
+ + (n_entries - 1) * sizeof (struct symbol *));
+ common_block = obstack_alloc (&objfile->objfile_obstack, size);
+ memset (common_block->contents, 0, n_entries * sizeof (struct symbol *));
+ common_block->n_entries = 0;
+
+ for (child_die = die->child;
+ child_die && child_die->tag;
+ child_die = sibling_die (child_die))
+ {
+ /* Create the symbol in the DW_TAG_common_block block in the current
+ symbol scope. */
sym = new_symbol (child_die, NULL, cu);
- if (sym != NULL
- && handle_data_member_location (child_die, cu, &offset))
- {
- SYMBOL_VALUE_ADDRESS (sym) = base + offset;
- add_symbol_to_list (sym, &global_symbols);
- }
- child_die = sibling_die (child_die);
+ if (sym)
+ common_block->contents[common_block->n_entries++] = sym;
}
+
+ sym = new_symbol (die, objfile_type (objfile)->builtin_void, cu);
+ SYMBOL_VALUE_COMMON_BLOCK (sym) = common_block;
}
}
@@ -14956,6 +14954,13 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
{
var_decode_location (attr, sym, cu);
attr2 = dwarf2_attr (die, DW_AT_external, cu);
+
+ /* Fortran explicitly imports any global symbols to the local
+ scope by DW_TAG_common_block. */
+ if (cu->language == language_fortran && die->parent
+ && die->parent->tag == DW_TAG_common_block)
+ attr2 = NULL;
+
if (SYMBOL_CLASS (sym) == LOC_STATIC
&& SYMBOL_VALUE_ADDRESS (sym) == 0
&& !dwarf2_per_objfile->has_section_at_zero)
@@ -15120,6 +15125,11 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
list_to_add = &global_symbols;
break;
+ case DW_TAG_common_block:
+ SYMBOL_CLASS (sym) = LOC_STATIC;
+ SYMBOL_DOMAIN (sym) = COMMON_BLOCK_DOMAIN;
+ add_symbol_to_list (sym, cu->list_in_scope);
+ break;
default:
/* Not a tag we recognize. Hopefully we aren't processing
trash data, but since we must specifically ignore things