Commit cc0017a9 by Zdenek Dvorak Committed by Zdenek Dvorak

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
parent 085825b8
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> 2002-10-26 Kazu Hirata <kazu@cs.umass.edu>
* config/h8300/h8300.c (initial_offset): Change to * config/h8300/h8300.c (initial_offset): Change to
......
...@@ -1455,7 +1455,7 @@ dwarfout.o : dwarfout.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) dwarf.h \ ...@@ -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 \ 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 \ 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 \ 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) \ dwarf2asm.o : dwarf2asm.c $(CONFIG_H) $(SYSTEM_H) flags.h $(RTL_H) $(TREE_H) \
output.h dwarf2asm.h $(TM_P_H) $(GGC_H) output.h dwarf2asm.h $(TM_P_H) $(GGC_H)
vmsdbgout.o : vmsdbgout.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) flags.h \ vmsdbgout.o : vmsdbgout.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) flags.h \
......
...@@ -62,6 +62,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA ...@@ -62,6 +62,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "target.h" #include "target.h"
#include "langhooks.h" #include "langhooks.h"
#include "hashtable.h" #include "hashtable.h"
#include "hashtab.h"
#ifdef DWARF2_DEBUGGING_INFO #ifdef DWARF2_DEBUGGING_INFO
static void dwarf2out_source_line PARAMS ((unsigned int, const char *)); static void dwarf2out_source_line PARAMS ((unsigned int, const char *));
...@@ -3333,6 +3334,10 @@ static unsigned long next_die_offset; ...@@ -3333,6 +3334,10 @@ static unsigned long next_die_offset;
/* Record the root of the DIE's built for the current compilation unit. */ /* Record the root of the DIE's built for the current compilation unit. */
static dw_die_ref comp_unit_die; 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. */ /* A list of DIEs with a NULL parent waiting to be relocated. */
static limbo_die_node *limbo_die_list = 0; static limbo_die_node *limbo_die_list = 0;
...@@ -3569,15 +3574,29 @@ static dw_die_ref pop_compile_unit PARAMS ((dw_die_ref)); ...@@ -3569,15 +3574,29 @@ static dw_die_ref pop_compile_unit PARAMS ((dw_die_ref));
static void loc_checksum PARAMS ((dw_loc_descr_ref, static void loc_checksum PARAMS ((dw_loc_descr_ref,
struct md5_ctx *)); struct md5_ctx *));
static void attr_checksum PARAMS ((dw_attr_ref, static void attr_checksum PARAMS ((dw_attr_ref,
struct md5_ctx *)); struct md5_ctx *,
int *));
static void die_checksum PARAMS ((dw_die_ref, 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 void compute_section_prefix PARAMS ((dw_die_ref));
static int is_type_die 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_comdat_die PARAMS ((dw_die_ref));
static int is_symbol_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 assign_symbol_names PARAMS ((dw_die_ref));
static void break_out_includes 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 add_sibling_attributes PARAMS ((dw_die_ref));
static void build_abbrev_table PARAMS ((dw_die_ref)); static void build_abbrev_table PARAMS ((dw_die_ref));
static void output_location_lists 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)); ...@@ -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 calc_die_sizes PARAMS ((dw_die_ref));
static void mark_dies PARAMS ((dw_die_ref)); static void mark_dies PARAMS ((dw_die_ref));
static void unmark_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_pubnames PARAMS ((void));
static unsigned long size_of_aranges PARAMS ((void)); static unsigned long size_of_aranges PARAMS ((void));
static enum dwarf_form value_format PARAMS ((dw_attr_ref)); static enum dwarf_form value_format PARAMS ((dw_attr_ref));
...@@ -3594,7 +3614,7 @@ static void output_abbrev_section PARAMS ((void)); ...@@ -3594,7 +3614,7 @@ static void output_abbrev_section PARAMS ((void));
static void output_die_symbol PARAMS ((dw_die_ref)); static void output_die_symbol PARAMS ((dw_die_ref));
static void output_die PARAMS ((dw_die_ref)); static void output_die PARAMS ((dw_die_ref));
static void output_compilation_unit_header PARAMS ((void)); 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 const char *dwarf2_name PARAMS ((tree, int));
static void add_pubname PARAMS ((tree, dw_die_ref)); static void add_pubname PARAMS ((tree, dw_die_ref));
static void output_pubnames PARAMS ((void)); static void output_pubnames PARAMS ((void));
...@@ -5420,9 +5440,10 @@ loc_checksum (loc, ctx) ...@@ -5420,9 +5440,10 @@ loc_checksum (loc, ctx)
/* Calculate the checksum of an attribute. */ /* Calculate the checksum of an attribute. */
static void static void
attr_checksum (at, ctx) attr_checksum (at, ctx, mark)
dw_attr_ref at; dw_attr_ref at;
struct md5_ctx *ctx; struct md5_ctx *ctx;
int *mark;
{ {
dw_loc_descr_ref loc; dw_loc_descr_ref loc;
rtx r; rtx r;
...@@ -5480,9 +5501,8 @@ attr_checksum (at, ctx) ...@@ -5480,9 +5501,8 @@ attr_checksum (at, ctx)
break; break;
case dw_val_class_die_ref: case dw_val_class_die_ref:
if (AT_ref (at)->die_offset) die_checksum (AT_ref (at), ctx, mark);
CHECKSUM (AT_ref (at)->die_offset); break;
/* FIXME else use target die name or something. */
case dw_val_class_fde_ref: case dw_val_class_fde_ref:
case dw_val_class_lbl_id: case dw_val_class_lbl_id:
...@@ -5497,25 +5517,195 @@ attr_checksum (at, ctx) ...@@ -5497,25 +5517,195 @@ attr_checksum (at, ctx)
/* Calculate the checksum of a DIE. */ /* Calculate the checksum of a DIE. */
static void static void
die_checksum (die, ctx) die_checksum (die, ctx, mark)
dw_die_ref die; dw_die_ref die;
struct md5_ctx *ctx; struct md5_ctx *ctx;
int *mark;
{ {
dw_die_ref c; dw_die_ref c;
dw_attr_ref a; 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); CHECKSUM (die->die_tag);
for (a = die->die_attr; a; a = a->dw_attr_next) 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) for (c = die->die_child; c; c = c->die_sib)
die_checksum (c, ctx); die_checksum (c, ctx, mark);
} }
#undef CHECKSUM #undef CHECKSUM
#undef CHECKSUM_STRING #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 /* The prefix to attach to symbols on DIEs in the current comdat debug
info section. */ info section. */
static char *comdat_symbol_id; static char *comdat_symbol_id;
...@@ -5530,10 +5720,11 @@ static void ...@@ -5530,10 +5720,11 @@ static void
compute_section_prefix (unit_die) compute_section_prefix (unit_die)
dw_die_ref 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 *name = (char *) alloca (strlen (base) + 64);
char *p; char *p;
int i; int i, mark;
unsigned char checksum[16]; unsigned char checksum[16];
struct md5_ctx ctx; struct md5_ctx ctx;
...@@ -5541,7 +5732,9 @@ compute_section_prefix (unit_die) ...@@ -5541,7 +5732,9 @@ compute_section_prefix (unit_die)
the name filename of the unit. */ the name filename of the unit. */
md5_init_ctx (&ctx); 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); md5_finish_ctx (&ctx, checksum);
sprintf (name, "%s.", base); sprintf (name, "%s.", base);
...@@ -5583,6 +5776,7 @@ is_type_die (die) ...@@ -5583,6 +5776,7 @@ is_type_die (die)
case DW_TAG_file_type: case DW_TAG_file_type:
case DW_TAG_packed_type: case DW_TAG_packed_type:
case DW_TAG_volatile_type: case DW_TAG_volatile_type:
case DW_TAG_typedef:
return 1; return 1;
default: default:
return 0; return 0;
...@@ -5668,6 +5862,104 @@ assign_symbol_names (die) ...@@ -5668,6 +5862,104 @@ assign_symbol_names (die)
assign_symbol_names (c); 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 /* Traverse the DIE (which is always comp_unit_die), and set up
additional compilation units for each of the include files we see additional compilation units for each of the include files we see
bracketed by BINCL/EINCL. */ bracketed by BINCL/EINCL. */
...@@ -5678,7 +5970,8 @@ break_out_includes (die) ...@@ -5678,7 +5970,8 @@ break_out_includes (die)
{ {
dw_die_ref *ptr; dw_die_ref *ptr;
dw_die_ref unit = NULL; 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;) for (ptr = &(die->die_child); *ptr;)
{ {
...@@ -5719,11 +6012,27 @@ break_out_includes (die) ...@@ -5719,11 +6012,27 @@ break_out_includes (die)
#endif #endif
assign_symbol_names (die); 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); compute_section_prefix (node->die);
is_dupl = check_duplicate_cu (node->die, cu_hash_table,
&comdat_symbol_number);
assign_symbol_names (node->die); 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 /* Traverse the DIE and add a sibling attribute if it may have the
...@@ -5968,6 +6277,9 @@ mark_dies (die) ...@@ -5968,6 +6277,9 @@ mark_dies (die)
{ {
dw_die_ref c; dw_die_ref c;
if (die->die_mark)
abort ();
die->die_mark = 1; die->die_mark = 1;
for (c = die->die_child; c; c = c->die_sib) for (c = die->die_child; c; c = c->die_sib)
mark_dies (c); mark_dies (c);
...@@ -5981,11 +6293,35 @@ unmark_dies (die) ...@@ -5981,11 +6293,35 @@ unmark_dies (die)
{ {
dw_die_ref c; dw_die_ref c;
if (!die->die_mark)
abort ();
die->die_mark = 0; die->die_mark = 0;
for (c = die->die_child; c; c = c->die_sib) for (c = die->die_child; c; c = c->die_sib)
unmark_dies (c); 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 /* Return the size of the .debug_pubnames table generated for the
compilation unit. */ compilation unit. */
...@@ -6455,10 +6791,16 @@ output_compilation_unit_header () ...@@ -6455,10 +6791,16 @@ output_compilation_unit_header ()
/* Output the compilation unit DIE and its children. */ /* Output the compilation unit DIE and its children. */
static void static void
output_comp_unit (die) output_comp_unit (die, output_if_empty)
dw_die_ref die; dw_die_ref die;
int output_if_empty;
{ {
const char *secname; 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 /* 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 about the compilation unit. Otherwise, on an empty translation unit, we
...@@ -6473,11 +6815,12 @@ output_comp_unit (die) ...@@ -6473,11 +6815,12 @@ output_comp_unit (die)
next_die_offset = DWARF_COMPILE_UNIT_HEADER_SIZE; next_die_offset = DWARF_COMPILE_UNIT_HEADER_SIZE;
calc_die_sizes (die); 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; secname = tmp;
die->die_symbol = NULL; die->die_symbol = NULL;
} }
...@@ -6491,8 +6834,11 @@ output_comp_unit (die) ...@@ -6491,8 +6834,11 @@ output_comp_unit (die)
/* Leave the marks on the main CU, so we can check them in /* Leave the marks on the main CU, so we can check them in
output_pubnames. */ output_pubnames. */
if (die->die_symbol) if (oldsym)
unmark_dies (die); {
unmark_dies (die);
die->die_symbol = oldsym;
}
} }
/* The DWARF2 pubname for a nested thingy looks like "A::f". The /* The DWARF2 pubname for a nested thingy looks like "A::f". The
...@@ -11981,13 +12327,17 @@ dwarf2out_start_source_file (lineno, filename) ...@@ -11981,13 +12327,17 @@ dwarf2out_start_source_file (lineno, filename)
unsigned int lineno; unsigned int lineno;
const char *filename; 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. */ /* 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); add_AT_string (bincl_die, DW_AT_name, filename);
} }
is_main_source = 0;
if (debug_info_level >= DINFO_LEVEL_VERBOSE) if (debug_info_level >= DINFO_LEVEL_VERBOSE)
{ {
named_section_flags (DEBUG_MACINFO_SECTION, SECTION_DEBUG); named_section_flags (DEBUG_MACINFO_SECTION, SECTION_DEBUG);
...@@ -12100,6 +12450,7 @@ dwarf2out_init (main_input_filename) ...@@ -12100,6 +12450,7 @@ dwarf2out_init (main_input_filename)
taken as being relative to the directory from which the compiler was taken as being relative to the directory from which the compiler was
invoked when the given (base) source file was compiled. */ invoked when the given (base) source file was compiled. */
comp_unit_die = gen_compile_unit_die (main_input_filename); comp_unit_die = gen_compile_unit_die (main_input_filename);
is_main_source = 1;
VARRAY_TREE_INIT (incomplete_types, 64, "incomplete_types"); VARRAY_TREE_INIT (incomplete_types, 64, "incomplete_types");
...@@ -12317,9 +12668,9 @@ dwarf2out_finish (input_filename) ...@@ -12317,9 +12668,9 @@ dwarf2out_finish (input_filename)
/* Output all of the compilation units. We put the main one last so that /* Output all of the compilation units. We put the main one last so that
the offsets are available to output_pubnames. */ the offsets are available to output_pubnames. */
for (node = limbo_die_list; node; node = node->next) 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. */ /* Output the abbreviation table. */
named_section_flags (DEBUG_ABBREV_SECTION, SECTION_DEBUG); named_section_flags (DEBUG_ABBREV_SECTION, SECTION_DEBUG);
......
...@@ -2316,6 +2316,17 @@ rest_of_decl_compilation (decl, asmspec, top_level, at_end) ...@@ -2316,6 +2316,17 @@ rest_of_decl_compilation (decl, asmspec, top_level, at_end)
timevar_pop (TV_SYMOUT); timevar_pop (TV_SYMOUT);
} }
#endif #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. */ /* Called after finishing a record, union or enumeral type. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment