summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2007-12-05 20:50:56 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2007-12-05 20:50:56 +0100
commit60332588d6194a8636748a484f102d8b36eef80d (patch)
treecab5c222f0441c84dd8b90bf0301cd07c43d705d
parentbce623434fce35c3d515224b70e08d03fabce691 (diff)
downloadgcc-60332588d6194a8636748a484f102d8b36eef80d.tar.gz
re PR debug/33739 (Failure of gfortran.dg/literal_character_constant_1_*.F with -m64 -g on Darwin)
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. From-SVN: r130629
-rw-r--r--gcc/fortran/ChangeLog17
-rw-r--r--gcc/fortran/error.c2
-rw-r--r--gcc/fortran/gfortran.h5
-rw-r--r--gcc/fortran/parse.c9
-rw-r--r--gcc/fortran/scanner.c103
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gfortran.dg/debug_2.f16
7 files changed, 125 insertions, 32 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 4752ae020ef..3b290ac590e 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,20 @@
+2007-12-05 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.
+
2007-12-05 Tobias Burnus <burnus@net-b.de>
PR fortran/34333
diff --git a/gcc/fortran/error.c b/gcc/fortran/error.c
index add23ce0fb3..e25a4286b24 100644
--- a/gcc/fortran/error.c
+++ b/gcc/fortran/error.c
@@ -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);
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 52ebe932f0e..9f83c795388 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -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 *);
diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c
index 3e20b78fba2..c941b4e5d29 100644
--- a/gcc/fortran/parse.c
+++ b/gcc/fortran/parse.c
@@ -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:
diff --git a/gcc/fortran/scanner.c b/gcc/fortran/scanner.c
index b9e71149110..1bea10f1dac 100644
--- a/gcc/fortran/scanner.c
+++ b/gcc/fortran/scanner.c
@@ -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_reason reason ATTRIBUTE_UNUSED)
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 initial)
/* 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;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 04c8ebf0bdd..0778f070073 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2007-12-05 Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/33739
+ * gfortran.dg/debug_2.f: New test.
+
2007-12-05 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/specs/elab1.ads: New test.
diff --git a/gcc/testsuite/gfortran.dg/debug_2.f b/gcc/testsuite/gfortran.dg/debug_2.f
new file mode 100644
index 00000000000..66bc5f6f6a0
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/debug_2.f
@@ -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