This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[pch] fix dwarf2 output
- From: Richard Henderson <rth at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 16 Jan 2003 18:44:01 -0800
- Subject: [pch] fix dwarf2 output
Two problems fixed here.
(1) We recorded the main input filename very early. This name
got saved to the .pch file, and restored with it as well.
This meant that the main input filename in the debug info
was _always_ that of the precompiled .h file.
Fixed by not recording the main input filename until
dwarf2out_finish.
(2) We didn't save and restore the file table. This created
genuinely incorrect dwarf2 output, since we would reuse
file indicies.
I tried the minimal fix of allocating the file_table
memory via the garbage collector, and marking the structure
appropriately. I'm not sure what I did wrong, but the
parser wasn't happy with
char ** GTY ((length "%h.allocated_size")) table;
In any case, fixed by switching to use a varray, which
already works, and eliminates all the resizing code as well.
With this, plus a testsuite patch to be posted shortly, I
get only one pch failure on i686-linux:
FAIL: gcc.dg/pch/inline-1.c (test for excess errors)
which is the gen_subprogram_die abort already reported.
r~
* dwarf2out.c (struct file_table): Remove.
(FILE_TABLE_INCREMENT): Remove.
(file_table): Make a varray; mark for GC. Update all users.
(file_table_last_lookup_index): Extract from struct file_table.
(output_file_names): Fix unsigned compare warnings.
(add_name_attribute): Remove inline marker.
(add_comp_dir_attribute): Split out from gen_compile_unit_die.
(lookup_filename): Don't manage size of file_table.
(init_file_table): Allocate file_table with GC.
(dwarf2out_init): Don't record main_input_filename here.
(dwarf2out_finish): Do it here instead.
Index: dwarf2out.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/dwarf2out.c,v
retrieving revision 1.393
diff -c -p -d -r1.393 dwarf2out.c
*** dwarf2out.c 16 Jan 2003 15:37:53 -0000 1.393
--- dwarf2out.c 17 Jan 2003 02:28:23 -0000
*************** static int is_main_source;
*** 3458,3480 ****
/* A list of DIEs with a NULL parent waiting to be relocated. */
static GTY(()) limbo_die_node *limbo_die_list;
- /* Structure used by lookup_filename to manage sets of filenames. */
- struct file_table
- {
- char **table;
- unsigned allocated;
- unsigned in_use;
- unsigned last_lookup_index;
- };
-
- /* Size (in elements) of increments by which we may expand the filename
- table. */
- #define FILE_TABLE_INCREMENT 64
-
- #ifdef DWARF2_DEBUGGING_INFO
/* Filenames referenced by this compilation unit. */
! static struct file_table file_table;
! #endif
/* A pointer to the base of a table of references to DIE's that describe
declarations. The table is indexed by DECL_UID() which is a unique
--- 3458,3466 ----
/* A list of DIEs with a NULL parent waiting to be relocated. */
static GTY(()) limbo_die_node *limbo_die_list;
/* Filenames referenced by this compilation unit. */
! static GTY(()) varray_type file_table;
! static GTY(()) size_t file_table_last_lookup_index;
/* A pointer to the base of a table of references to DIE's that describe
declarations. The table is indexed by DECL_UID() which is a unique
*************** static rtx rtl_for_decl_location PARAMS
*** 3789,3794 ****
--- 3775,3781 ----
static void add_location_or_const_value_attribute PARAMS ((dw_die_ref, tree));
static void tree_add_const_value_attribute PARAMS ((dw_die_ref, tree));
static void add_name_attribute PARAMS ((dw_die_ref, const char *));
+ static void add_comp_dir_attribute PARAMS ((dw_die_ref));
static void add_bound_info PARAMS ((dw_die_ref,
enum dwarf_attribute, tree));
static void add_subscript_info PARAMS ((dw_die_ref, tree));
*************** print_dwarf_line_table (outfile)
*** 5452,5458 ****
{
line_info = &line_info_table[i];
fprintf (outfile, "%5d: ", i);
! fprintf (outfile, "%-20s", file_table.table[line_info->dw_file_num]);
fprintf (outfile, "%6ld", line_info->dw_line_num);
fprintf (outfile, "\n");
}
--- 5439,5446 ----
{
line_info = &line_info_table[i];
fprintf (outfile, "%5d: ", i);
! fprintf (outfile, "%-20s",
! VARRAY_CHAR_PTR (file_table, line_info->dw_file_num));
fprintf (outfile, "%6ld", line_info->dw_line_num);
fprintf (outfile, "\n");
}
*************** output_file_names ()
*** 7298,7321 ****
int *saved;
int *savehere;
int *backmap;
! int ndirs;
int idx_offset;
! int i;
int idx;
/* Allocate the various arrays we need. */
! files = (struct file_info *) alloca (file_table.in_use
* sizeof (struct file_info));
! dirs = (struct dir_info *) alloca (file_table.in_use
* sizeof (struct dir_info));
/* Sort the file names. */
! for (i = 1; i < (int) file_table.in_use; i++)
{
char *f;
/* Skip all leading "./". */
! f = file_table.table[i];
while (f[0] == '.' && f[1] == '/')
f += 2;
--- 7286,7309 ----
int *saved;
int *savehere;
int *backmap;
! size_t ndirs;
int idx_offset;
! size_t i;
int idx;
/* Allocate the various arrays we need. */
! files = (struct file_info *) alloca (VARRAY_ACTIVE_SIZE (file_table)
* sizeof (struct file_info));
! dirs = (struct dir_info *) alloca (VARRAY_ACTIVE_SIZE (file_table)
* sizeof (struct dir_info));
/* Sort the file names. */
! for (i = 1; i < VARRAY_ACTIVE_SIZE (file_table); i++)
{
char *f;
/* Skip all leading "./". */
! f = VARRAY_CHAR_PTR (file_table, i);
while (f[0] == '.' && f[1] == '/')
f += 2;
*************** output_file_names ()
*** 7329,7335 ****
files[i].fname = f == NULL ? files[i].path : f + 1;
}
! qsort (files + 1, file_table.in_use - 1, sizeof (files[0]), file_info_cmp);
/* Find all the different directories used. */
dirs[0].path = files[1].path;
--- 7317,7324 ----
files[i].fname = f == NULL ? files[i].path : f + 1;
}
! qsort (files + 1, VARRAY_ACTIVE_SIZE (file_table) - 1,
! sizeof (files[0]), file_info_cmp);
/* Find all the different directories used. */
dirs[0].path = files[1].path;
*************** output_file_names ()
*** 7341,7347 ****
files[1].dir_idx = 0;
ndirs = 1;
! for (i = 2; i < (int) file_table.in_use; i++)
if (files[i].fname - files[i].path == dirs[ndirs - 1].length
&& memcmp (dirs[ndirs - 1].path, files[i].path,
dirs[ndirs - 1].length) == 0)
--- 7330,7336 ----
files[1].dir_idx = 0;
ndirs = 1;
! for (i = 2; i < VARRAY_ACTIVE_SIZE (file_table); i++)
if (files[i].fname - files[i].path == dirs[ndirs - 1].length
&& memcmp (dirs[ndirs - 1].path, files[i].path,
dirs[ndirs - 1].length) == 0)
*************** output_file_names ()
*** 7352,7358 ****
}
else
{
! int j;
/* This is a new directory. */
dirs[ndirs].path = files[i].path;
--- 7341,7347 ----
}
else
{
! size_t j;
/* This is a new directory. */
dirs[ndirs].path = files[i].path;
*************** output_file_names ()
*** 7387,7393 ****
memset (saved, '\0', ndirs * sizeof (saved[0]));
for (i = 0; i < ndirs; i++)
{
! int j;
int total;
/* We can always save some space for the current directory. But this
--- 7376,7382 ----
memset (saved, '\0', ndirs * sizeof (saved[0]));
for (i = 0; i < ndirs; i++)
{
! size_t j;
int total;
/* We can always save some space for the current directory. But this
*************** output_file_names ()
*** 7405,7414 ****
int k;
k = dirs[j].prefix;
! while (k != -1 && k != i)
k = dirs[k].prefix;
! if (k == i)
{
/* Yes it is. We can possibly safe some memory but
writing the filenames in dirs[j] relative to
--- 7394,7403 ----
int k;
k = dirs[j].prefix;
! while (k != -1 && k != (int) i)
k = dirs[k].prefix;
! if (k == (int) i)
{
/* Yes it is. We can possibly safe some memory but
writing the filenames in dirs[j] relative to
*************** output_file_names ()
*** 7439,7446 ****
/* We have to emit them in the order they appear in the file_table array
since the index is used in the debug info generation. To do this
efficiently we generate a back-mapping of the indices first. */
! backmap = (int *) alloca (file_table.in_use * sizeof (int));
! for (i = 1; i < (int) file_table.in_use; i++)
{
backmap[files[i].file_idx] = i;
--- 7428,7435 ----
/* We have to emit them in the order they appear in the file_table array
since the index is used in the debug info generation. To do this
efficiently we generate a back-mapping of the indices first. */
! backmap = (int *) alloca (VARRAY_ACTIVE_SIZE (file_table) * sizeof (int));
! for (i = 1; i < VARRAY_ACTIVE_SIZE (file_table); i++)
{
backmap[files[i].file_idx] = i;
*************** output_file_names ()
*** 7471,7477 ****
dirs[0].used = 0;
/* Now write all the file names. */
! for (i = 1; i < (int) file_table.in_use; i++)
{
int file_idx = backmap[i];
int dir_idx = dirs[files[file_idx].dir_idx].dir_idx;
--- 7460,7466 ----
dirs[0].used = 0;
/* Now write all the file names. */
! for (i = 1; i < VARRAY_ACTIVE_SIZE (file_table); i++)
{
int file_idx = backmap[i];
int dir_idx = dirs[files[file_idx].dir_idx].dir_idx;
*************** output_line_info ()
*** 7630,7636 ****
current_file = line_info->dw_file_num;
dw2_asm_output_data (1, DW_LNS_set_file, "DW_LNS_set_file");
dw2_asm_output_data_uleb128 (current_file, "(\"%s\")",
! file_table.table[current_file]);
}
/* Emit debug info for the current line number, choosing the encoding
--- 7619,7626 ----
current_file = line_info->dw_file_num;
dw2_asm_output_data (1, DW_LNS_set_file, "DW_LNS_set_file");
dw2_asm_output_data_uleb128 (current_file, "(\"%s\")",
! VARRAY_CHAR_PTR (file_table,
! current_file));
}
/* Emit debug info for the current line number, choosing the encoding
*************** output_line_info ()
*** 7738,7744 ****
current_file = line_info->dw_file_num;
dw2_asm_output_data (1, DW_LNS_set_file, "DW_LNS_set_file");
dw2_asm_output_data_uleb128 (current_file, "(\"%s\")",
! file_table.table[current_file]);
}
/* Emit debug info for the current line number, choosing the encoding
--- 7728,7735 ----
current_file = line_info->dw_file_num;
dw2_asm_output_data (1, DW_LNS_set_file, "DW_LNS_set_file");
dw2_asm_output_data_uleb128 (current_file, "(\"%s\")",
! VARRAY_CHAR_PTR (file_table,
! current_file));
}
/* Emit debug info for the current line number, choosing the encoding
*************** tree_add_const_value_attribute (var_die,
*** 9602,9608 ****
/* Generate an DW_AT_name attribute given some string value to be included as
the value of the attribute. */
! static inline void
add_name_attribute (die, name_string)
dw_die_ref die;
const char *name_string;
--- 9593,9599 ----
/* Generate an DW_AT_name attribute given some string value to be included as
the value of the attribute. */
! static void
add_name_attribute (die, name_string)
dw_die_ref die;
const char *name_string;
*************** add_name_attribute (die, name_string)
*** 9616,9621 ****
--- 9607,9623 ----
}
}
+ /* Generate an DW_AT_comp_dir attribute for DIE. */
+
+ static void
+ add_comp_dir_attribute (die)
+ dw_die_ref die;
+ {
+ const char *wd = getpwd ();
+ if (wd != NULL)
+ add_AT_string (die, DW_AT_comp_dir, wd);
+ }
+
/* Given a tree node describing an array bound (either lower or upper) output
a representation for that bound. */
*************** gen_compile_unit_die (filename)
*** 11294,11308 ****
{
dw_die_ref die;
char producer[250];
- const char *wd = getpwd ();
const char *language_string = lang_hooks.name;
int language;
die = new_die (DW_TAG_compile_unit, NULL, NULL);
- add_name_attribute (die, filename);
! if (wd != NULL && filename[0] != DIR_SEPARATOR)
! add_AT_string (die, DW_AT_comp_dir, wd);
sprintf (producer, "%s %s", language_string, version_string);
--- 11296,11312 ----
{
dw_die_ref die;
char producer[250];
const char *language_string = lang_hooks.name;
int language;
die = new_die (DW_TAG_compile_unit, NULL, NULL);
! if (filename)
! {
! add_name_attribute (die, filename);
! if (filename[0] != DIR_SEPARATOR)
! add_comp_dir_attribute (die);
! }
sprintf (producer, "%s %s", language_string, version_string);
*************** static unsigned
*** 12310,12316 ****
lookup_filename (file_name)
const char *file_name;
{
! unsigned i;
/* ??? Why isn't DECL_SOURCE_FILE left null instead. */
if (strcmp (file_name, "<internal>") == 0
--- 12314,12321 ----
lookup_filename (file_name)
const char *file_name;
{
! size_t i, n;
! char *save_file_name;
/* ??? Why isn't DECL_SOURCE_FILE left null instead. */
if (strcmp (file_name, "<internal>") == 0
*************** lookup_filename (file_name)
*** 12319,12352 ****
/* Check to see if the file name that was searched on the previous
call matches this file name. If so, return the index. */
! if (file_table.last_lookup_index != 0)
! if (0 == strcmp (file_name,
! file_table.table[file_table.last_lookup_index]))
! return file_table.last_lookup_index;
/* Didn't match the previous lookup, search the table */
! for (i = 1; i < file_table.in_use; i++)
! if (strcmp (file_name, file_table.table[i]) == 0)
{
! file_table.last_lookup_index = i;
return i;
}
- /* Prepare to add a new table entry by making sure there is enough space in
- the table to do so. If not, expand the current table. */
- if (i == file_table.allocated)
- {
- file_table.allocated = i + FILE_TABLE_INCREMENT;
- file_table.table = (char **)
- xrealloc (file_table.table, file_table.allocated * sizeof (char *));
- memset (file_table.table + i, 0,
- FILE_TABLE_INCREMENT * sizeof (char *));
- }
-
/* Add the new entry to the end of the filename table. */
! file_table.table[i] = xstrdup (file_name);
! file_table.in_use = i + 1;
! file_table.last_lookup_index = i;
if (DWARF2_ASM_LINE_DEBUG_INFO)
{
--- 12324,12350 ----
/* Check to see if the file name that was searched on the previous
call matches this file name. If so, return the index. */
! if (file_table_last_lookup_index != 0)
! {
! const char *last
! = VARRAY_CHAR_PTR (file_table, file_table_last_lookup_index);
! if (strcmp (file_name, last) == 0)
! return file_table_last_lookup_index;
! }
/* Didn't match the previous lookup, search the table */
! n = VARRAY_ACTIVE_SIZE (file_table);
! for (i = 1; i < n; i++)
! if (strcmp (file_name, VARRAY_CHAR_PTR (file_table, i)) == 0)
{
! file_table_last_lookup_index = i;
return i;
}
/* Add the new entry to the end of the filename table. */
! file_table_last_lookup_index = n;
! save_file_name = (char *) ggc_strdup (file_name);
! VARRAY_PUSH_CHAR_PTR (file_table, save_file_name);
if (DWARF2_ASM_LINE_DEBUG_INFO)
{
*************** static void
*** 12362,12373 ****
init_file_table ()
{
/* Allocate the initial hunk of the file_table. */
! file_table.table = (char **) xcalloc (FILE_TABLE_INCREMENT, sizeof (char *));
! file_table.allocated = FILE_TABLE_INCREMENT;
/* Skip the first entry - file numbers begin at 1. */
! file_table.in_use = 1;
! file_table.last_lookup_index = 0;
}
/* Output a label to mark the beginning of a source code line entry
--- 12360,12370 ----
init_file_table ()
{
/* Allocate the initial hunk of the file_table. */
! VARRAY_CHAR_PTR_INIT (file_table, 64, "file_table");
/* Skip the first entry - file numbers begin at 1. */
! VARRAY_PUSH_CHAR_PTR (file_table, NULL);
! file_table_last_lookup_index = 0;
}
/* Output a label to mark the beginning of a source code line entry
*************** dwarf2out_undef (lineno, buffer)
*** 12544,12559 ****
/* Set up for Dwarf output at the start of compilation. */
static void
! dwarf2out_init (main_input_filename)
! const char *main_input_filename;
{
init_file_table ();
- /* Add the name of the primary input file to the file table first,
- under the assumption that we'll be emitting line number data for
- it first, which avoids having to add an initial DW_LNS_set_file. */
- lookup_filename (main_input_filename);
-
/* Allocate the initial hunk of the decl_die_table. */
decl_die_table = ggc_alloc_cleared (DECL_DIE_TABLE_INCREMENT
* sizeof (dw_die_ref));
--- 12541,12551 ----
/* Set up for Dwarf output at the start of compilation. */
static void
! dwarf2out_init (input_filename)
! const char *input_filename ATTRIBUTE_UNUSED;
{
init_file_table ();
/* Allocate the initial hunk of the decl_die_table. */
decl_die_table = ggc_alloc_cleared (DECL_DIE_TABLE_INCREMENT
* sizeof (dw_die_ref));
*************** dwarf2out_init (main_input_filename)
*** 12582,12589 ****
value given in the DW_AT_name attribute of the DW_TAG_compile_unit DIE
will (typically) be a relative pathname and that this pathname should be
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");
--- 12574,12582 ----
value given in the DW_AT_name attribute of the DW_TAG_compile_unit DIE
will (typically) be a relative pathname and that this pathname should be
taken as being relative to the directory from which the compiler was
! invoked when the given (base) source file was compiled. We will fill
! in this value in dwarf2out_finish. */
! comp_unit_die = gen_compile_unit_die (NULL);
is_main_source = 1;
VARRAY_TREE_INIT (incomplete_types, 64, "incomplete_types");
*************** output_indirect_string (h, v)
*** 12651,12660 ****
static void
dwarf2out_finish (input_filename)
! const char *input_filename ATTRIBUTE_UNUSED;
{
limbo_die_node *node, *next_node;
dw_die_ref die = 0;
/* Traverse the limbo die list, and add parent/child links. The only
dies without parents that should be here are concrete instances of
--- 12644,12659 ----
static void
dwarf2out_finish (input_filename)
! const char *input_filename;
{
limbo_die_node *node, *next_node;
dw_die_ref die = 0;
+
+ /* Add the name for the main input file now. We delayed this from
+ dwarf2out_init to avoid complications with PCH. */
+ add_name_attribute (comp_unit_die, input_filename);
+ if (input_filename[0] != DIR_SEPARATOR)
+ add_comp_dir_attribute (comp_unit_die);
/* Traverse the limbo die list, and add parent/child links. The only
dies without parents that should be here are concrete instances of