diff options
author | Paul Thomas <pault@gcc.gnu.org> | 2009-08-01 13:45:12 +0000 |
---|---|---|
committer | Paul Thomas <pault@gcc.gnu.org> | 2009-08-01 13:45:12 +0000 |
commit | 3af8d8cb86aeb7582f5c5e6ffc5c24f782d072f7 (patch) | |
tree | 0d387c47cf00a2962560d0777fe3a4edba3543d1 /gcc/fortran/parse.c | |
parent | 4fcf08308d076999d6d95f70c0e71de4a34be002 (diff) | |
download | gcc-3af8d8cb86aeb7582f5c5e6ffc5c24f782d072f7.zip gcc-3af8d8cb86aeb7582f5c5e6ffc5c24f782d072f7.tar.gz gcc-3af8d8cb86aeb7582f5c5e6ffc5c24f782d072f7.tar.bz2 |
re PR fortran/40011 (Problems with -fwhole-file)
2009-08-01 Paul Thomas <pault@gcc.gnu.org>
PR fortran/40011
* error.c : Add static flag 'warnings_not_errors'.
(gfc_error): If 'warnings_not_errors' is set, branch to code
from gfc_warning.
(gfc_clear_error): Reset 'warnings_not_errors'.
(gfc_errors_to_warnings): New function.
* options.c (gfc_post_options): If pedantic and flag_whole_file
change the latter to a value of 2.
* parse.c (parse_module): Add module namespace to gsymbol.
(resolve_all_program_units): New function.
(clean_up_modules): New function.
(translate_all_program_units): New function.
(gfc_parse_file): If whole_file, do not clean up module right
away and add derived types to namespace derived types. In
addition, call the three new functions above.
* resolve.c (not_in_recursive): New function.
(not_entry_self_reference): New function.
(resolve_global_procedure): Symbol must not be IFSRC_UNKNOWN,
procedure must not be in the course of being resolved and
must return false for the two new functions. Pack away the
current derived type list before calling gfc_resolve for the
gsymbol namespace. It is unconditionally an error if the ranks
of the reference and ther procedure do not match. Convert
errors to warnings during call to gfc_procedure_use if not
pedantic or legacy.
(gfc_resolve): Set namespace resolved flag to -1 during
resolution and store current cs_base.
* trans-decl.c (gfc_get_symbol_decl): If whole_file compilation
substitute a use associated variable, if it is available in a
gsymbolnamespace.
(gfc_get_extern_function_decl): If the procedure is use assoc,
do not attempt to find it in a gsymbol because it could be an
interface. If the symbol exists in a module namespace, return
its backend_decl.
* trans-expr.c (gfc_trans_scalar_assign): If a derived type
assignment, set the rhs TYPE_MAIN_VARIANT to that of the rhs.
* trans-types.c (copy_dt_decls_ifequal): Add 'from_gsym' as a
boolean argument. Copy component backend_decls directly if the
components are derived types and from_gsym is true.
(gfc_get_derived_type): If whole_file copy the derived type from
the module if it is use associated, otherwise, if can be found
in another gsymbol namespace, use the existing derived type as
the TYPE_CANONICAL and build normally.
* gfortran.h : Add derived_types and resolved fields to
gfc_namespace. Include prototype for gfc_errors_to_warnings.
2009-08-01 Paul Thomas <pault@gcc.gnu.org>
PR fortran/40011
* gfortran.dg/whole_file_7.f90: New test.
* gfortran.dg/whole_file_8.f90: New test.
* gfortran.dg/whole_file_9.f90: New test.
* gfortran.dg/whole_file_10.f90: New test.
* gfortran.dg/whole_file_11.f90: New test.
* gfortran.dg/whole_file_12.f90: New test.
* gfortran.dg/whole_file_13.f90: New test.
* gfortran.dg/whole_file_14.f90: New test.
From-SVN: r150333
Diffstat (limited to 'gcc/fortran/parse.c')
-rw-r--r-- | gcc/fortran/parse.c | 113 |
1 files changed, 91 insertions, 22 deletions
diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c index da16c2b..e4463bd 100644 --- a/gcc/fortran/parse.c +++ b/gcc/fortran/parse.c @@ -3760,6 +3760,8 @@ loop: st = next_statement (); goto loop; } + + s->ns = gfc_current_ns; } @@ -3809,6 +3811,76 @@ add_global_program (void) } +/* Resolve all the program units when whole file scope option + is active. */ +static void +resolve_all_program_units (gfc_namespace *gfc_global_ns_list) +{ + gfc_free_dt_list (); + gfc_current_ns = gfc_global_ns_list; + for (; gfc_current_ns; gfc_current_ns = gfc_current_ns->sibling) + { + gfc_current_locus = gfc_current_ns->proc_name->declared_at; + gfc_resolve (gfc_current_ns); + gfc_current_ns->derived_types = gfc_derived_types; + gfc_derived_types = NULL; + } +} + + +static void +clean_up_modules (gfc_gsymbol *gsym) +{ + if (gsym == NULL) + return; + + clean_up_modules (gsym->left); + clean_up_modules (gsym->right); + + if (gsym->type != GSYM_MODULE || !gsym->ns) + return; + + gfc_current_ns = gsym->ns; + gfc_derived_types = gfc_current_ns->derived_types; + gfc_done_2 (); + gsym->ns = NULL; + return; +} + + +/* Translate all the program units when whole file scope option + is active. This could be in a different order to resolution if + there are forward references in the file. */ +static void +translate_all_program_units (gfc_namespace *gfc_global_ns_list) +{ + int errors; + + gfc_current_ns = gfc_global_ns_list; + gfc_get_errors (NULL, &errors); + + for (; !errors && gfc_current_ns; gfc_current_ns = gfc_current_ns->sibling) + { + gfc_current_locus = gfc_current_ns->proc_name->declared_at; + gfc_derived_types = gfc_current_ns->derived_types; + gfc_generate_code (gfc_current_ns); + gfc_current_ns->translated = 1; + } + + /* Clean up all the namespaces after translation. */ + gfc_current_ns = gfc_global_ns_list; + for (;gfc_current_ns;) + { + gfc_namespace *ns = gfc_current_ns->sibling; + gfc_derived_types = gfc_current_ns->derived_types; + gfc_done_2 (); + gfc_current_ns = ns; + } + + clean_up_modules (gfc_gsym_root); +} + + /* Top level parser. */ gfc_try @@ -3933,15 +4005,24 @@ loop: gfc_dump_module (s.sym->name, errors_before == errors); if (errors == 0) gfc_generate_module_code (gfc_current_ns); + pop_state (); + if (!gfc_option.flag_whole_file) + gfc_done_2 (); + else + { + gfc_current_ns->derived_types = gfc_derived_types; + gfc_derived_types = NULL; + gfc_current_ns = NULL; + } } else { if (errors == 0) gfc_generate_code (gfc_current_ns); + pop_state (); + gfc_done_2 (); } - pop_state (); - gfc_done_2 (); goto loop; prog_units: @@ -3964,35 +4045,23 @@ prog_units: if (!gfc_option.flag_whole_file) goto termination; - /* Do the resolution. */ - gfc_current_ns = gfc_global_ns_list; - for (; gfc_current_ns; gfc_current_ns = gfc_current_ns->sibling) - { - gfc_current_locus = gfc_current_ns->proc_name->declared_at; - gfc_resolve (gfc_current_ns); - } + /* Do the resolution. */ + resolve_all_program_units (gfc_global_ns_list); /* Do the parse tree dump. */ - gfc_current_ns = gfc_option.dump_parse_tree ? gfc_global_ns_list : NULL; + gfc_current_ns + = gfc_option.dump_parse_tree ? gfc_global_ns_list : NULL; + for (; gfc_current_ns; gfc_current_ns = gfc_current_ns->sibling) { gfc_dump_parse_tree (gfc_current_ns, stdout); - fputs ("-----------------------------------------\n\n", stdout); + fputs ("------------------------------------------\n\n", stdout); } - gfc_current_ns = gfc_global_ns_list; - gfc_get_errors (NULL, &errors); - - /* Do the translation. This could be in a different order to - resolution if there are forward references in the file. */ - for (; !errors && gfc_current_ns; gfc_current_ns = gfc_current_ns->sibling) - { - gfc_current_locus = gfc_current_ns->proc_name->declared_at; - gfc_generate_code (gfc_current_ns); - } + /* Do the translation. */ + translate_all_program_units (gfc_global_ns_list); termination: - gfc_free_dt_list (); gfc_end_source_files (); return SUCCESS; |