[PATCH] Ensure start_source_file and end_source_file debug hook calls in gfortran always match (PR debug/33739)

Jakub Jelinek jakub@redhat.com
Tue Dec 4 15:07:00 GMT 2007


Hi!

Below is a different approach at fixing PR33739.
Basically current_file is set at start of gfc_parse_file to the main source
file and then will do the same walk up and down through all the include
files as it did when we were actually loading the files resp. handling the
preprocessor lines, some changes are optionally done right at the start
(e.g. if the first real line already starts in some included file), then
whenever gfc_advance_line is called on a new line for the first time and
then at the end of the file.

In addition to this I have removed included_by field from gfc_file, because
it was always the same as the up field in the same structure, no need to
duplicate that.

Regtested on x86_64-linux, plus visual inspection of -gstabs -m32 output on
several testcases as well (to make sure the BINCL/EINCL stabs lines match).

Ok for trunk?

2007-12-04  Jakub Jelinek  <jakub@redhat.com>

	PR debug/33739
	* gfortran.h (gfc_file): Remove included_by field, add sibling and
	down.
	(gfc_start_source_files, gfc_end_source_files): New prototypes.
	* parse.c (gfc_parse_file): Call gfc_start_source_files and
	gfc_end_source_files instead of calling the debugging hooks directly.
	* error.c (show_locus): Use up field instead of included_by.
	* scanner.c (change_file, gfc_start_source_files,
	gfc_end_source_files): New functions.
	(gfc_advance_line): Call change_file instead of calling debug hooks
	directly.
	(get_file): Set up rather than included_by.  Initialize down and
	sibling.
	(preprocessor_line, load_file): Don't set up field here.

	* gfortran.dg/debug_2.f: New test.

--- gcc/fortran/parse.c.jj	2007-12-04 12:51:04.000000000 +0100
+++ gcc/fortran/parse.c	2007-12-04 12:54:06.000000000 +0100
@@ -3289,10 +3289,7 @@ gfc_parse_file (void)
   gfc_statement st;
   locus prog_locus;
 
-  /* If the debugger wants the name of the main source file,
-     we give it.  */
-  if (debug_hooks->start_end_main_source_file)
-    (*debug_hooks->start_source_file) (0, gfc_source_file);
+  gfc_start_source_files ();
 
   top.state = COMP_NONE;
   top.sym = NULL;
@@ -3404,9 +3401,7 @@ loop:
   goto loop;
 
 done:
-  if (debug_hooks->start_end_main_source_file)
-    (*debug_hooks->end_source_file) (0);
-
+  gfc_end_source_files ();
   return SUCCESS;
 
 duplicate_main:
--- gcc/fortran/error.c.jj	2007-08-20 09:49:07.000000000 +0200
+++ gcc/fortran/error.c	2007-12-04 12:56:56.000000000 +0100
@@ -207,7 +207,7 @@ show_locus (locus *loc, int c1, int c2)
     {
       i = f->inclusion_line;
 
-      f = f->included_by;
+      f = f->up;
       if (f == NULL) break;
 
       error_printf ("    Included at %s:%d:", f->filename, i);
--- gcc/fortran/gfortran.h.jj	2007-11-29 19:28:25.000000000 +0100
+++ gcc/fortran/gfortran.h	2007-12-04 14:39:06.000000000 +0100
@@ -706,7 +706,7 @@ symbol_attribute;
 
 typedef struct gfc_file
 {
-  struct gfc_file *included_by, *next, *up;
+  struct gfc_file *next, *up, *sibling, *down;
   int inclusion_line, line;
   char *filename;
 } gfc_file;
@@ -1938,6 +1938,9 @@ extern gfc_source_form gfc_current_form;
 extern const char *gfc_source_file;
 extern locus gfc_current_locus;
 
+void gfc_start_source_files (void);
+void gfc_end_source_files (void);
+
 /* misc.c */
 void *gfc_getmem (size_t) ATTRIBUTE_MALLOC;
 void gfc_free (void *);
--- gcc/fortran/scanner.c.jj	2007-12-04 12:51:04.000000000 +0100
+++ gcc/fortran/scanner.c	2007-12-04 14:53:29.000000000 +0100
@@ -299,6 +299,65 @@ gfc_at_eol (void)
   return (*gfc_current_locus.nextc == '\0');
 }
 
+static void
+change_file (gfc_file *to)
+{
+  if (current_file == NULL)
+    return;
+
+  while (current_file != to)
+    if (current_file->down)
+      {
+	gfc_file *f = current_file->down;
+	/* Ensure we don't enter it ever again.  */
+	current_file->down = NULL;
+	current_file = f;
+	(*debug_hooks->start_source_file) (current_file->inclusion_line,
+					   current_file->filename);
+      }
+    else if (current_file->sibling)
+      current_file = current_file->sibling;
+    else
+      {
+	gcc_assert (current_file->up);
+	(*debug_hooks->end_source_file) (current_file->inclusion_line + 1);
+	current_file = current_file->up;
+      }
+}
+
+void
+gfc_start_source_files (void)
+{
+  /* If the debugger wants the name of the main source file,
+     we give it.  */
+  if (debug_hooks->start_end_main_source_file)
+    (*debug_hooks->start_source_file) (0, gfc_source_file);
+
+  if (gfc_current_locus.lb && gfc_current_locus.lb->file)
+    {
+      current_file = gfc_current_locus.lb->file;
+      while (current_file->up)
+	current_file = current_file->up;
+      change_file (gfc_current_locus.lb->file);
+    }
+  else
+    current_file = NULL;
+}
+
+void
+gfc_end_source_files (void)
+{
+  if (current_file != NULL)
+    {
+      gfc_file *to = current_file;
+      while (to->up)
+	to = to->up;
+      change_file (to);
+    }
+
+  if (debug_hooks->start_end_main_source_file)
+    (*debug_hooks->end_source_file) (0);
+}
 
 /* Advance the current line pointer to the next line.  */
 
@@ -315,26 +374,11 @@ gfc_advance_line (void)
     } 
 
   if (gfc_current_locus.lb->next
-      && gfc_current_locus.lb->next->file != gfc_current_locus.lb->file)
+      && gfc_current_locus.lb->next->file != gfc_current_locus.lb->file
+      && !gfc_current_locus.lb->next->dbg_emitted)
     {
-      if (gfc_current_locus.lb->next->file
-	  && !gfc_current_locus.lb->next->dbg_emitted
-	  && gfc_current_locus.lb->file->up == gfc_current_locus.lb->next->file)
-	{
-	  /* We exit from an included file. */
-	  (*debug_hooks->end_source_file)
-		(gfc_linebuf_linenum (gfc_current_locus.lb->next));
-	  gfc_current_locus.lb->next->dbg_emitted = true;
-	}
-      else if (gfc_current_locus.lb->next->file != gfc_current_locus.lb->file
-	       && !gfc_current_locus.lb->next->dbg_emitted)
-	{
-	  /* We enter into a new file.  */
-	  (*debug_hooks->start_source_file)
-		(gfc_linebuf_linenum (gfc_current_locus.lb),
-		 gfc_current_locus.lb->next->file->filename);
-	  gfc_current_locus.lb->next->dbg_emitted = true;
-	}
+      change_file (gfc_current_locus.lb->next->file);
+      gfc_current_locus.lb->next->dbg_emitted = true;
     }
 
   gfc_current_locus.lb = gfc_current_locus.lb->next;
@@ -1219,9 +1263,24 @@ get_file (const char *name, enum lc_reas
   f->next = file_head;
   file_head = f;
 
-  f->included_by = current_file;
+  f->up = current_file;
+  /* Already cleared by gfc_getmem.
+     f->down = NULL;
+     f->sibling = NULL;  */
   if (current_file != NULL)
-    f->inclusion_line = current_file->line;
+    {
+      f->inclusion_line = current_file->line;
+      if (current_file->down == NULL)
+	current_file->down = f;
+      else
+	{
+	  gfc_file *s;
+
+	  for (s = current_file->down; s->sibling; s = s->sibling)
+	    ;
+	  s->sibling = f;
+	}
+    }
 
 #ifdef USE_MAPPED_LOCATION
   linemap_add (line_table, reason, false, f->filename, 1);
@@ -1331,7 +1390,6 @@ preprocessor_line (char *c)
   if (flag[1]) /* Starting new file.  */
     {
       f = get_file (filename, LC_RENAME);
-      f->up = current_file;
       current_file = f;
     }
 
@@ -1499,7 +1557,6 @@ load_file (const char *filename, bool in
   /* Load the file.  */
 
   f = get_file (filename, initial ? LC_RENAME : LC_ENTER);
-  f->up = current_file;
   current_file = f;
   current_file->line = 1;
   line = NULL;
--- gcc/testsuite/gfortran.dg/debug_2.f.jj	2007-12-04 15:17:51.000000000 +0100
+++ gcc/testsuite/gfortran.dg/debug_2.f	2007-12-04 15:18:41.000000000 +0100
@@ -0,0 +1,16 @@
+# 1 "debug_2.F"
+# 1 "<built-in>"
+# 1 "<command line>"
+# 1 "debug_2.F"
+# 3 "debug_2.inc1" 1
+# 4 "debug_2.inc2" 1
+! The above lines must be present as is.
+! PR fortran/34084
+! { dg-do compile }
+! { dg-options "-g" }
+      subroutine foo
+      end subroutine foo
+# 4 "debug_2.inc1" 2
+# 2 "debug_2.F" 2
+      program bar
+      end program bar

	Jakub



More information about the Gcc-patches mailing list