aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/parse.c
diff options
context:
space:
mode:
authorTobias Burnus <burnus@net-b.de>2012-01-09 14:11:05 +0100
committerTobias Burnus <burnus@gcc.gnu.org>2012-01-09 14:11:05 +0100
commite9078ebb19f0b5513786d0c43aa177f3916a11b2 (patch)
treee43530d529621d853c055badf47004cac50a6bf9 /gcc/fortran/parse.c
parentd18a0a84f639bf5c30d0044f2d6941fa2d0e1392 (diff)
downloadgcc-e9078ebb19f0b5513786d0c43aa177f3916a11b2.zip
gcc-e9078ebb19f0b5513786d0c43aa177f3916a11b2.tar.gz
gcc-e9078ebb19f0b5513786d0c43aa177f3916a11b2.tar.bz2
re PR fortran/51578 (Import of same symbol via different modules and renaming)
2012-01-09 Tobias Burnus <burnus@net-b.de> PR fortran/51578 * gfortran.h (gfc_use_list): * match.h (gfc_use_module): Rename to ... (gfc_use_modules): ... this. * module.c (use_locus, specified_nonint, specified_int): Remove global variable. (module_name): Change type to const char*, used with gfc_get_string. (module_list): New global variable. (free_rename): Free argument not global var. (gfc_match_use): Save match to module_list. (load_generic_interfaces, read_module): Don't free symtree. (write_dt_extensions, gfc_dump_module): Fix module-name I/O due to the type change of module_name. (write_symbol0, write_generic): Optimize due to the type change. (import_iso_c_binding_module, use_iso_fortran_env_module): Use locus of rename->where. (gfc_use_module): Take module_list as argument. (gfc_use_modules): New function. (gfc_module_init_2, gfc_module_done_2): Init module_list, rename_list. * parse.c (last_was_use_stmt): New global variable. (use_modules): New function. (decode_specification_statement, decode_statement): Move USE match up and call use_modules. (next_free, next_fixed): Call use_modules. (accept_statement): Don't call gfc_module_use. 2012-01-09 Tobias Burnus <burnus@net-b.de> PR fortran/51578 * gfortran.dg/use_17.f90: New. From-SVN: r183010
Diffstat (limited to 'gcc/fortran/parse.c')
-rw-r--r--gcc/fortran/parse.c64
1 files changed, 54 insertions, 10 deletions
diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c
index ea1d773..317fb84 100644
--- a/gcc/fortran/parse.c
+++ b/gcc/fortran/parse.c
@@ -1,6 +1,6 @@
/* Main parser.
Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
- 2009, 2010, 2011
+ 2009, 2010, 2011, 2012
Free Software Foundation, Inc.
Contributed by Andy Vaught
@@ -37,6 +37,7 @@ static locus label_locus;
static jmp_buf eof_buf;
gfc_state_data *gfc_state_stack;
+static bool last_was_use_stmt = false;
/* TODO: Re-order functions to kill these forward decls. */
static void check_statement_label (gfc_statement);
@@ -74,6 +75,26 @@ match_word (const char *str, match (*subr) (void), locus *old_locus)
}
+/* Load symbols from all USE statements encounted in this scoping unit. */
+
+static void
+use_modules (void)
+{
+ gfc_error_buf old_error;
+
+ gfc_push_error (&old_error);
+ gfc_buffer_error (0);
+ gfc_use_modules ();
+ gfc_buffer_error (1);
+ gfc_pop_error (&old_error);
+ gfc_commit_symbols ();
+ gfc_warning_check ();
+ gfc_current_ns->old_cl_list = gfc_current_ns->cl_list;
+ gfc_current_ns->old_equiv = gfc_current_ns->equiv;
+ last_was_use_stmt = false;
+}
+
+
/* Figure out what the next statement is, (mostly) regardless of
proper ordering. The do...while(0) is there to prevent if/else
ambiguity. */
@@ -108,8 +129,19 @@ decode_specification_statement (void)
old_locus = gfc_current_locus;
+ if (match_word ("use", gfc_match_use, &old_locus) == MATCH_YES)
+ {
+ last_was_use_stmt = true;
+ return ST_USE;
+ }
+ else
+ {
+ undo_new_statement ();
+ if (last_was_use_stmt)
+ use_modules ();
+ }
+
match ("import", gfc_match_import, ST_IMPORT);
- match ("use", gfc_match_use, ST_USE);
if (gfc_current_block ()->result->ts.type != BT_DERIVED)
goto end_of_block;
@@ -252,6 +284,22 @@ decode_statement (void)
old_locus = gfc_current_locus;
+ c = gfc_peek_ascii_char ();
+
+ if (c == 'u')
+ {
+ if (match_word ("use", gfc_match_use, &old_locus) == MATCH_YES)
+ {
+ last_was_use_stmt = true;
+ return ST_USE;
+ }
+ else
+ undo_new_statement ();
+ }
+
+ if (last_was_use_stmt)
+ use_modules ();
+
/* Try matching a data declaration or function declaration. The
input "REALFUNCTIONA(N)" can mean several things in different
contexts, so it (and its relatives) get special treatment. */
@@ -322,8 +370,6 @@ decode_statement (void)
statement, we eliminate most possibilities by peeking at the
first character. */
- c = gfc_peek_ascii_char ();
-
switch (c)
{
case 'a':
@@ -454,7 +500,6 @@ decode_statement (void)
case 'u':
match ("unlock", gfc_match_unlock, ST_UNLOCK);
- match ("use", gfc_match_use, ST_USE);
break;
case 'v':
@@ -713,6 +758,8 @@ next_free (void)
gcc_assert (c == ' ' || c == '\t');
gfc_gobble_whitespace ();
+ if (last_was_use_stmt)
+ use_modules ();
return decode_omp_directive ();
}
@@ -801,7 +848,8 @@ next_fixed (void)
gfc_error ("Bad continuation line at %C");
return ST_NONE;
}
-
+ if (last_was_use_stmt)
+ use_modules ();
return decode_omp_directive ();
}
/* FALLTHROUGH */
@@ -1595,10 +1643,6 @@ accept_statement (gfc_statement st)
{
switch (st)
{
- case ST_USE:
- gfc_use_module ();
- break;
-
case ST_IMPLICIT_NONE:
gfc_set_implicit_none ();
break;