This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]