Makefile.in (dwarf2out.o): Add dependendcy on hashtab.h.

* Makefile.in (dwarf2out.o): Add dependendcy on hashtab.h.
	* dwarf2out.c: Include hashtab.h.
	(is_main_source): New static variable.
	(attr_checksum, die_checksum): Modified to handle die references.
	(same_loc_p, same_dw_val_p, same_attr_p, same_die_p, same_die_p_wrap,
	unmark_all_dies, htab_cu_hash, htab_cu_eq, htab_cu_del, check_duplicate_cu,
	record_comdat_symbol_number): New static functions.
	(output_comp_unit, compute_section_prefix, is_type_die, break_out_includes,
	mark_dies, unmark_dies, dwarf2out_start_source_file): Modified.
	* toplev.c (rest_of_decl_compilation): Call of dwarf2out_decl for type
	declarations added.

From-SVN: r58578
This commit is contained in:
Zdenek Dvorak 2002-10-27 10:14:04 +01:00 committed by Zdenek Dvorak
parent 085825b83b
commit cc0017a983
4 changed files with 402 additions and 26 deletions

View File

@ -1,3 +1,17 @@
2002-10-27 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
* Makefile.in (dwarf2out.o): Add dependendcy on hashtab.h.
* dwarf2out.c: Include hashtab.h.
(is_main_source): New static variable.
(attr_checksum, die_checksum): Modified to handle die references.
(same_loc_p, same_dw_val_p, same_attr_p, same_die_p, same_die_p_wrap,
unmark_all_dies, htab_cu_hash, htab_cu_eq, htab_cu_del, check_duplicate_cu,
record_comdat_symbol_number): New static functions.
(output_comp_unit, compute_section_prefix, is_type_die, break_out_includes,
mark_dies, unmark_dies, dwarf2out_start_source_file): Modified.
* toplev.c (rest_of_decl_compilation): Call of dwarf2out_decl for type
declarations added.
2002-10-26 Kazu Hirata <kazu@cs.umass.edu>
* config/h8300/h8300.c (initial_offset): Change to

View File

@ -1455,7 +1455,7 @@ dwarfout.o : dwarfout.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) dwarf.h \
dwarf2out.o : dwarf2out.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) dwarf2.h \
debug.h flags.h insn-config.h reload.h output.h diagnostic.h real.h \
hard-reg-set.h $(REGS_H) $(EXPR_H) libfuncs.h toplev.h dwarf2out.h varray.h \
$(GGC_H) except.h dwarf2asm.h $(TM_P_H) langhooks.h gt-dwarf2out.h
$(GGC_H) except.h dwarf2asm.h $(TM_P_H) langhooks.h $(HASHTAB_H) gt-dwarf2out.h
dwarf2asm.o : dwarf2asm.c $(CONFIG_H) $(SYSTEM_H) flags.h $(RTL_H) $(TREE_H) \
output.h dwarf2asm.h $(TM_P_H) $(GGC_H)
vmsdbgout.o : vmsdbgout.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) flags.h \

View File

@ -62,6 +62,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "target.h"
#include "langhooks.h"
#include "hashtable.h"
#include "hashtab.h"
#ifdef DWARF2_DEBUGGING_INFO
static void dwarf2out_source_line PARAMS ((unsigned int, const char *));
@ -3333,6 +3334,10 @@ static unsigned long next_die_offset;
/* Record the root of the DIE's built for the current compilation unit. */
static dw_die_ref comp_unit_die;
/* We need special handling in dwarf2out_start_source_file if it is
first one. */
static int is_main_source;
/* A list of DIEs with a NULL parent waiting to be relocated. */
static limbo_die_node *limbo_die_list = 0;
@ -3569,15 +3574,29 @@ static dw_die_ref pop_compile_unit PARAMS ((dw_die_ref));
static void loc_checksum PARAMS ((dw_loc_descr_ref,
struct md5_ctx *));
static void attr_checksum PARAMS ((dw_attr_ref,
struct md5_ctx *));
struct md5_ctx *,
int *));
static void die_checksum PARAMS ((dw_die_ref,
struct md5_ctx *));
struct md5_ctx *,
int *));
static int same_loc_p PARAMS ((dw_loc_descr_ref,
dw_loc_descr_ref, int *));
static int same_dw_val_p PARAMS ((dw_val_node *, dw_val_node *,
int *));
static int same_attr_p PARAMS ((dw_attr_ref, dw_attr_ref, int *));
static int same_die_p PARAMS ((dw_die_ref, dw_die_ref, int *));
static int same_die_p_wrap PARAMS ((dw_die_ref, dw_die_ref));
static void compute_section_prefix PARAMS ((dw_die_ref));
static int is_type_die PARAMS ((dw_die_ref));
static int is_comdat_die PARAMS ((dw_die_ref));
static int is_symbol_die PARAMS ((dw_die_ref));
static void assign_symbol_names PARAMS ((dw_die_ref));
static void break_out_includes PARAMS ((dw_die_ref));
static hashval_t htab_cu_hash PARAMS ((const void *));
static int htab_cu_eq PARAMS ((const void *, const void *));
static void htab_cu_del PARAMS ((void *));
static int check_duplicate_cu PARAMS ((dw_die_ref, htab_t, unsigned *));
static void record_comdat_symbol_number PARAMS ((dw_die_ref, htab_t, unsigned));
static void add_sibling_attributes PARAMS ((dw_die_ref));
static void build_abbrev_table PARAMS ((dw_die_ref));
static void output_location_lists PARAMS ((dw_die_ref));
@ -3586,6 +3605,7 @@ static unsigned long size_of_die PARAMS ((dw_die_ref));
static void calc_die_sizes PARAMS ((dw_die_ref));
static void mark_dies PARAMS ((dw_die_ref));
static void unmark_dies PARAMS ((dw_die_ref));
static void unmark_all_dies PARAMS ((dw_die_ref));
static unsigned long size_of_pubnames PARAMS ((void));
static unsigned long size_of_aranges PARAMS ((void));
static enum dwarf_form value_format PARAMS ((dw_attr_ref));
@ -3594,7 +3614,7 @@ static void output_abbrev_section PARAMS ((void));
static void output_die_symbol PARAMS ((dw_die_ref));
static void output_die PARAMS ((dw_die_ref));
static void output_compilation_unit_header PARAMS ((void));
static void output_comp_unit PARAMS ((dw_die_ref));
static void output_comp_unit PARAMS ((dw_die_ref, int));
static const char *dwarf2_name PARAMS ((tree, int));
static void add_pubname PARAMS ((tree, dw_die_ref));
static void output_pubnames PARAMS ((void));
@ -5420,9 +5440,10 @@ loc_checksum (loc, ctx)
/* Calculate the checksum of an attribute. */
static void
attr_checksum (at, ctx)
attr_checksum (at, ctx, mark)
dw_attr_ref at;
struct md5_ctx *ctx;
int *mark;
{
dw_loc_descr_ref loc;
rtx r;
@ -5480,9 +5501,8 @@ attr_checksum (at, ctx)
break;
case dw_val_class_die_ref:
if (AT_ref (at)->die_offset)
CHECKSUM (AT_ref (at)->die_offset);
/* FIXME else use target die name or something. */
die_checksum (AT_ref (at), ctx, mark);
break;
case dw_val_class_fde_ref:
case dw_val_class_lbl_id:
@ -5497,25 +5517,195 @@ attr_checksum (at, ctx)
/* Calculate the checksum of a DIE. */
static void
die_checksum (die, ctx)
die_checksum (die, ctx, mark)
dw_die_ref die;
struct md5_ctx *ctx;
int *mark;
{
dw_die_ref c;
dw_attr_ref a;
/* To avoid infinite recursion. */
if (die->die_mark)
{
CHECKSUM (die->die_mark);
return;
}
die->die_mark = ++(*mark);
CHECKSUM (die->die_tag);
for (a = die->die_attr; a; a = a->dw_attr_next)
attr_checksum (a, ctx);
attr_checksum (a, ctx, mark);
for (c = die->die_child; c; c = c->die_sib)
die_checksum (c, ctx);
die_checksum (c, ctx, mark);
}
#undef CHECKSUM
#undef CHECKSUM_STRING
/* Do the location expressions look same? */
static inline int
same_loc_p (loc1, loc2, mark)
dw_loc_descr_ref loc1;
dw_loc_descr_ref loc2;
int *mark;
{
return loc1->dw_loc_opc == loc2->dw_loc_opc
&& same_dw_val_p (&loc1->dw_loc_oprnd1, &loc2->dw_loc_oprnd1, mark)
&& same_dw_val_p (&loc1->dw_loc_oprnd2, &loc2->dw_loc_oprnd2, mark);
}
/* Do the values look the same? */
static int
same_dw_val_p (v1, v2, mark)
dw_val_node *v1;
dw_val_node *v2;
int *mark;
{
dw_loc_descr_ref loc1, loc2;
rtx r1, r2;
unsigned i;
if (v1->val_class != v2->val_class)
return 0;
switch (v1->val_class)
{
case dw_val_class_const:
return v1->v.val_int == v2->v.val_int;
case dw_val_class_unsigned_const:
return v1->v.val_unsigned == v2->v.val_unsigned;
case dw_val_class_long_long:
return v1->v.val_long_long.hi == v2->v.val_long_long.hi
&& v1->v.val_long_long.low == v2->v.val_long_long.low;
case dw_val_class_float:
if (v1->v.val_float.length != v2->v.val_float.length)
return 0;
for (i = 0; i < v1->v.val_float.length; i++)
if (v1->v.val_float.array[i] != v2->v.val_float.array[i])
return 0;
return 1;
case dw_val_class_flag:
return v1->v.val_flag == v2->v.val_flag;
case dw_val_class_str:
return !strcmp((const char *) HT_STR (&v1->v.val_str->id),
(const char *) HT_STR (&v2->v.val_str->id));
case dw_val_class_addr:
r1 = v1->v.val_addr;
r2 = v2->v.val_addr;
if (GET_CODE (r1) != GET_CODE (r2))
return 0;
switch (GET_CODE (r1))
{
case SYMBOL_REF:
return !strcmp (XSTR (r1, 0), XSTR (r2, 0));
default:
abort ();
}
case dw_val_class_offset:
return v1->v.val_offset == v2->v.val_offset;
case dw_val_class_loc:
for (loc1 = v1->v.val_loc, loc2 = v2->v.val_loc;
loc1 && loc2;
loc1 = loc1->dw_loc_next, loc2 = loc2->dw_loc_next)
if (!same_loc_p (loc1, loc2, mark))
return 0;
return !loc1 && !loc2;
case dw_val_class_die_ref:
return same_die_p (v1->v.val_die_ref.die, v2->v.val_die_ref.die, mark);
case dw_val_class_fde_ref:
case dw_val_class_lbl_id:
case dw_val_class_lbl_offset:
return 1;
default:
return 1;
}
}
/* Do the attributes look the same? */
static int
same_attr_p (at1, at2, mark)
dw_attr_ref at1;
dw_attr_ref at2;
int *mark;
{
if (at1->dw_attr != at2->dw_attr)
return 0;
/* We don't care about differences in file numbering. */
if (at1->dw_attr == DW_AT_decl_file
/* Or that this was compiled with a different compiler snapshot; if
the output is the same, that's what matters. */
|| at1->dw_attr == DW_AT_producer)
return 1;
return same_dw_val_p (&at1->dw_attr_val, &at2->dw_attr_val, mark);
}
/* Do the dies look the same? */
static int
same_die_p (die1, die2, mark)
dw_die_ref die1;
dw_die_ref die2;
int *mark;
{
dw_die_ref c1, c2;
dw_attr_ref a1, a2;
/* To avoid infinite recursion. */
if (die1->die_mark)
return die1->die_mark == die2->die_mark;
die1->die_mark = die2->die_mark = ++(*mark);
if (die1->die_tag != die2->die_tag)
return 0;
for (a1 = die1->die_attr, a2 = die2->die_attr;
a1 && a2;
a1 = a1->dw_attr_next, a2 = a2->dw_attr_next)
if (!same_attr_p (a1, a2, mark))
return 0;
if (a1 || a2)
return 0;
for (c1 = die1->die_child, c2 = die2->die_child;
c1 && c2;
c1 = c1->die_sib, c2 = c2->die_sib)
if (!same_die_p (c1, c2, mark))
return 0;
if (c1 || c2)
return 0;
return 1;
}
/* Do the dies look the same? Wrapper around same_die_p. */
static int
same_die_p_wrap (die1, die2)
dw_die_ref die1;
dw_die_ref die2;
{
int mark = 0;
int ret = same_die_p (die1, die2, &mark);
unmark_all_dies (die1);
unmark_all_dies (die2);
return ret;
}
/* The prefix to attach to symbols on DIEs in the current comdat debug
info section. */
static char *comdat_symbol_id;
@ -5530,10 +5720,11 @@ static void
compute_section_prefix (unit_die)
dw_die_ref unit_die;
{
const char *base = lbasename (get_AT_string (unit_die, DW_AT_name));
const char *die_name = get_AT_string (unit_die, DW_AT_name);
const char *base = die_name ? lbasename (die_name) : "anonymous";
char *name = (char *) alloca (strlen (base) + 64);
char *p;
int i;
int i, mark;
unsigned char checksum[16];
struct md5_ctx ctx;
@ -5541,7 +5732,9 @@ compute_section_prefix (unit_die)
the name filename of the unit. */
md5_init_ctx (&ctx);
die_checksum (unit_die, &ctx);
mark = 0;
die_checksum (unit_die, &ctx, &mark);
unmark_all_dies (unit_die);
md5_finish_ctx (&ctx, checksum);
sprintf (name, "%s.", base);
@ -5583,6 +5776,7 @@ is_type_die (die)
case DW_TAG_file_type:
case DW_TAG_packed_type:
case DW_TAG_volatile_type:
case DW_TAG_typedef:
return 1;
default:
return 0;
@ -5668,6 +5862,104 @@ assign_symbol_names (die)
assign_symbol_names (c);
}
struct cu_hash_table_entry
{
dw_die_ref cu;
unsigned min_comdat_num, max_comdat_num;
struct cu_hash_table_entry *next;
};
/* Routines to manipulate hash table of CUs. */
static hashval_t
htab_cu_hash (of)
const void *of;
{
const struct cu_hash_table_entry *entry = of;
return htab_hash_string (entry->cu->die_symbol);
}
static int
htab_cu_eq (of1, of2)
const void *of1;
const void *of2;
{
const struct cu_hash_table_entry *entry1 = of1;
const struct die_struct *entry2 = of2;
return !strcmp (entry1->cu->die_symbol, entry2->die_symbol);
}
static void
htab_cu_del (what)
void *what;
{
struct cu_hash_table_entry *next, *entry = what;
while (entry)
{
next = entry->next;
free (entry);
entry = next;
}
}
/* Check whether we have already seen this CU and set up SYM_NUM
accordingly. */
static int
check_duplicate_cu (cu, htable, sym_num)
dw_die_ref cu;
htab_t htable;
unsigned *sym_num;
{
struct cu_hash_table_entry dummy;
struct cu_hash_table_entry **slot, *entry, *last = &dummy;
dummy.max_comdat_num = 0;
slot = (struct cu_hash_table_entry **)
htab_find_slot_with_hash (htable, cu, htab_hash_string (cu->die_symbol),
INSERT);
entry = *slot;
for (; entry; last = entry, entry = entry->next)
{
if (same_die_p_wrap (cu, entry->cu))
break;
}
if (entry)
{
*sym_num = entry->min_comdat_num;
return 1;
}
entry = xcalloc (1, sizeof (struct cu_hash_table_entry));
entry->cu = cu;
entry->min_comdat_num = *sym_num = last->max_comdat_num;
entry->next = *slot;
*slot = entry;
return 0;
}
/* Record SYM_NUM to record of CU in HTABLE. */
static void
record_comdat_symbol_number (cu, htable, sym_num)
dw_die_ref cu;
htab_t htable;
unsigned sym_num;
{
struct cu_hash_table_entry **slot, *entry;
slot = (struct cu_hash_table_entry **)
htab_find_slot_with_hash (htable, cu, htab_hash_string (cu->die_symbol),
NO_INSERT);
entry = *slot;
entry->max_comdat_num = sym_num;
}
/* Traverse the DIE (which is always comp_unit_die), and set up
additional compilation units for each of the include files we see
bracketed by BINCL/EINCL. */
@ -5678,7 +5970,8 @@ break_out_includes (die)
{
dw_die_ref *ptr;
dw_die_ref unit = NULL;
limbo_die_node *node;
limbo_die_node *node, **pnode;
htab_t cu_hash_table;
for (ptr = &(die->die_child); *ptr;)
{
@ -5719,11 +6012,27 @@ break_out_includes (die)
#endif
assign_symbol_names (die);
for (node = limbo_die_list; node; node = node->next)
cu_hash_table = htab_create (10, htab_cu_hash, htab_cu_eq, htab_cu_del);
for (node = limbo_die_list, pnode = &limbo_die_list;
node;
node = node->next)
{
int is_dupl;
compute_section_prefix (node->die);
is_dupl = check_duplicate_cu (node->die, cu_hash_table,
&comdat_symbol_number);
assign_symbol_names (node->die);
if (is_dupl)
*pnode = node->next;
else
{
pnode = &node->next;
record_comdat_symbol_number (node->die, cu_hash_table,
comdat_symbol_number);
}
}
htab_delete (cu_hash_table);
}
/* Traverse the DIE and add a sibling attribute if it may have the
@ -5968,6 +6277,9 @@ mark_dies (die)
{
dw_die_ref c;
if (die->die_mark)
abort ();
die->die_mark = 1;
for (c = die->die_child; c; c = c->die_sib)
mark_dies (c);
@ -5981,11 +6293,35 @@ unmark_dies (die)
{
dw_die_ref c;
if (!die->die_mark)
abort ();
die->die_mark = 0;
for (c = die->die_child; c; c = c->die_sib)
unmark_dies (c);
}
/* Clear the marks for a die, its children and referred dies. */
static void
unmark_all_dies (die)
dw_die_ref die;
{
dw_die_ref c;
dw_attr_ref a;
if (!die->die_mark)
return;
die->die_mark = 0;
for (c = die->die_child; c; c = c->die_sib)
unmark_all_dies (c);
for (a = die->die_attr; a; a = a->dw_attr_next)
if (AT_class (a) == dw_val_class_die_ref)
unmark_all_dies (AT_ref (a));
}
/* Return the size of the .debug_pubnames table generated for the
compilation unit. */
@ -6455,10 +6791,16 @@ output_compilation_unit_header ()
/* Output the compilation unit DIE and its children. */
static void
output_comp_unit (die)
output_comp_unit (die, output_if_empty)
dw_die_ref die;
int output_if_empty;
{
const char *secname;
char *oldsym, *tmp;
/* Unless we are outputting main CU, we may throw away empty ones. */
if (!output_if_empty && die->die_child == NULL)
return;
/* Even if there are no children of this DIE, we must output the information
about the compilation unit. Otherwise, on an empty translation unit, we
@ -6473,11 +6815,12 @@ output_comp_unit (die)
next_die_offset = DWARF_COMPILE_UNIT_HEADER_SIZE;
calc_die_sizes (die);
if (die->die_symbol)
oldsym = die->die_symbol;
if (oldsym)
{
char *tmp = (char *) alloca (strlen (die->die_symbol) + 24);
tmp = (char *) alloca (strlen (oldsym) + 24);
sprintf (tmp, ".gnu.linkonce.wi.%s", die->die_symbol);
sprintf (tmp, ".gnu.linkonce.wi.%s", oldsym);
secname = tmp;
die->die_symbol = NULL;
}
@ -6491,8 +6834,11 @@ output_comp_unit (die)
/* Leave the marks on the main CU, so we can check them in
output_pubnames. */
if (die->die_symbol)
unmark_dies (die);
if (oldsym)
{
unmark_dies (die);
die->die_symbol = oldsym;
}
}
/* The DWARF2 pubname for a nested thingy looks like "A::f". The
@ -11981,13 +12327,17 @@ dwarf2out_start_source_file (lineno, filename)
unsigned int lineno;
const char *filename;
{
if (flag_eliminate_dwarf2_dups)
if (flag_eliminate_dwarf2_dups && !is_main_source)
{
/* Record the beginning of the file for break_out_includes. */
dw_die_ref bincl_die = new_die (DW_TAG_GNU_BINCL, comp_unit_die, NULL);
dw_die_ref bincl_die;
bincl_die = new_die (DW_TAG_GNU_BINCL, comp_unit_die, NULL);
add_AT_string (bincl_die, DW_AT_name, filename);
}
is_main_source = 0;
if (debug_info_level >= DINFO_LEVEL_VERBOSE)
{
named_section_flags (DEBUG_MACINFO_SECTION, SECTION_DEBUG);
@ -12100,6 +12450,7 @@ dwarf2out_init (main_input_filename)
taken as being relative to the directory from which the compiler was
invoked when the given (base) source file was compiled. */
comp_unit_die = gen_compile_unit_die (main_input_filename);
is_main_source = 1;
VARRAY_TREE_INIT (incomplete_types, 64, "incomplete_types");
@ -12317,9 +12668,9 @@ dwarf2out_finish (input_filename)
/* Output all of the compilation units. We put the main one last so that
the offsets are available to output_pubnames. */
for (node = limbo_die_list; node; node = node->next)
output_comp_unit (node->die);
output_comp_unit (node->die, 0);
output_comp_unit (comp_unit_die);
output_comp_unit (comp_unit_die, 0);
/* Output the abbreviation table. */
named_section_flags (DEBUG_ABBREV_SECTION, SECTION_DEBUG);

View File

@ -2316,6 +2316,17 @@ rest_of_decl_compilation (decl, asmspec, top_level, at_end)
timevar_pop (TV_SYMOUT);
}
#endif
#ifdef DWARF2_DEBUGGING_INFO
else if ((write_symbols == DWARF2_DEBUG
|| write_symbols == VMS_AND_DWARF2_DEBUG)
&& top_level
&& TREE_CODE (decl) == TYPE_DECL)
{
timevar_push (TV_SYMOUT);
dwarf2out_decl (decl);
timevar_pop (TV_SYMOUT);
}
#endif
}
/* Called after finishing a record, union or enumeral type. */