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.
This commit is contained in:
Tom Tromey
2012-09-26 19:38:32 +00:00
parent 965f07a88d
commit 4357ac6c6f
10 changed files with 327 additions and 175 deletions

View File

@@ -34,10 +34,12 @@
#include "gdbcore.h"
#include "command.h"
#include "block.h"
#include "dictionary.h"
#include "gdb_assert.h"
#include "exceptions.h"
extern void _initialize_f_valprint (void);
static void info_common_command (char *, int);
static void list_all_visible_commons (const char *);
static void f77_create_arrayprint_offset_tbl (struct type *,
struct ui_file *);
static void f77_get_dynamic_length_of_aggregate (struct type *);
@@ -410,21 +412,57 @@ f_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
}
static void
list_all_visible_commons (const char *funname)
info_common_command_for_block (struct block *block, const char *comname,
int *any_printed)
{
SAVED_F77_COMMON_PTR tmp;
struct block_iterator iter;
struct symbol *sym;
const char *name;
struct value_print_options opts;
tmp = head_common_list;
get_user_print_options (&opts);
printf_filtered (_("All COMMON blocks visible at this level:\n\n"));
ALL_BLOCK_SYMBOLS (block, iter, sym)
if (SYMBOL_DOMAIN (sym) == COMMON_BLOCK_DOMAIN)
{
struct common_block *common = SYMBOL_VALUE_COMMON_BLOCK (sym);
size_t index;
while (tmp != NULL)
{
if (strcmp (tmp->owning_function, funname) == 0)
printf_filtered ("%s\n", tmp->name);
gdb_assert (SYMBOL_CLASS (sym) == LOC_STATIC);
tmp = tmp->next;
}
if (comname && (!SYMBOL_LINKAGE_NAME (sym)
|| strcmp (comname, SYMBOL_LINKAGE_NAME (sym)) != 0))
continue;
if (*any_printed)
putchar_filtered ('\n');
else
*any_printed = 1;
if (SYMBOL_PRINT_NAME (sym))
printf_filtered (_("Contents of F77 COMMON block '%s':\n"),
SYMBOL_PRINT_NAME (sym));
else
printf_filtered (_("Contents of blank COMMON block:\n"));
for (index = 0; index < common->n_entries; index++)
{
struct value *val = NULL;
volatile struct gdb_exception except;
printf_filtered ("%s = ",
SYMBOL_PRINT_NAME (common->contents[index]));
TRY_CATCH (except, RETURN_MASK_ERROR)
{
val = value_of_variable (common->contents[index], block);
value_print (val, gdb_stdout, &opts);
}
if (except.reason < 0)
printf_filtered ("<error reading variable: %s>", except.message);
putchar_filtered ('\n');
}
}
}
/* This function is used to print out the values in a given COMMON
@@ -434,11 +472,9 @@ list_all_visible_commons (const char *funname)
static void
info_common_command (char *comname, int from_tty)
{
SAVED_F77_COMMON_PTR the_common;
COMMON_ENTRY_PTR entry;
struct frame_info *fi;
const char *funname = 0;
struct symbol *func;
struct block *block;
int values_printed = 0;
/* We have been told to display the contents of F77 COMMON
block supposedly visible in this function. Let us
@@ -450,87 +486,30 @@ info_common_command (char *comname, int from_tty)
/* The following is generally ripped off from stack.c's routine
print_frame_info(). */
func = find_pc_function (get_frame_pc (fi));
if (func)
block = get_frame_block (fi, 0);
if (block == NULL)
{
/* In certain pathological cases, the symtabs give the wrong
function (when we are in the first function in a file which
is compiled without debugging symbols, the previous function
is compiled with debugging symbols, and the "foo.o" symbol
that is supposed to tell us where the file with debugging symbols
ends has been truncated by ar because it is longer than 15
characters).
So look in the minimal symbol tables as well, and if it comes
up with a larger address for the function use that instead.
I don't think this can ever cause any problems; there shouldn't
be any minimal symbols in the middle of a function.
FIXME: (Not necessarily true. What about text labels?) */
struct minimal_symbol *msymbol =
lookup_minimal_symbol_by_pc (get_frame_pc (fi));
if (msymbol != NULL
&& (SYMBOL_VALUE_ADDRESS (msymbol)
> BLOCK_START (SYMBOL_BLOCK_VALUE (func))))
funname = SYMBOL_LINKAGE_NAME (msymbol);
else
funname = SYMBOL_LINKAGE_NAME (func);
}
else
{
struct minimal_symbol *msymbol =
lookup_minimal_symbol_by_pc (get_frame_pc (fi));
if (msymbol != NULL)
funname = SYMBOL_LINKAGE_NAME (msymbol);
else /* Got no 'funname', code below will fail. */
error (_("No function found for frame."));
}
/* If comname is NULL, we assume the user wishes to see the
which COMMON blocks are visible here and then return. */
if (comname == 0)
{
list_all_visible_commons (funname);
printf_filtered (_("No symbol table info available.\n"));
return;
}
the_common = find_common_for_function (comname, funname);
if (the_common)
while (block)
{
struct frame_id frame_id = get_frame_id (fi);
if (strcmp (comname, BLANK_COMMON_NAME_LOCAL) == 0)
printf_filtered (_("Contents of blank COMMON block:\n"));
else
printf_filtered (_("Contents of F77 COMMON block '%s':\n"), comname);
printf_filtered ("\n");
entry = the_common->entries;
while (entry != NULL)
{
fi = frame_find_by_id (frame_id);
if (fi == NULL)
{
warning (_("Unable to restore previously selected frame."));
break;
}
print_variable_and_value (NULL, entry->symbol, fi, gdb_stdout, 0);
/* print_variable_and_value invalidates FI. */
fi = NULL;
entry = entry->next;
}
info_common_command_for_block (block, comname, &values_printed);
/* After handling the function's top-level block, stop. Don't
continue to its superblock, the block of per-file symbols. */
if (BLOCK_FUNCTION (block))
break;
block = BLOCK_SUPERBLOCK (block);
}
if (!values_printed)
{
if (comname)
printf_filtered (_("No common block '%s'.\n"), comname);
else
printf_filtered (_("No common blocks.\n"));
}
else
printf_filtered (_("Cannot locate the common block %s in function '%s'\n"),
comname, funname);
}
void