diff --git a/compiler/check_module_interface.m b/compiler/check_module_interface.m index 4703f0faa..e85cd8974 100644 --- a/compiler/check_module_interface.m +++ b/compiler/check_module_interface.m @@ -30,8 +30,7 @@ % report a warning. % :- pred check_module_interface_for_no_exports(globals::in, - parse_tree_module_src::in, - list(error_spec)::in, list(error_spec)::out) is det. + parse_tree_module_src::in, list(error_spec)::out) is det. %---------------------------------------------------------------------------% %---------------------------------------------------------------------------% @@ -52,10 +51,11 @@ %---------------------------------------------------------------------------% %---------------------------------------------------------------------------% -check_module_interface_for_no_exports(Globals, ParseTreeModuleSrc, !Specs) :- +check_module_interface_for_no_exports(Globals, ParseTreeModuleSrc, Specs) :- globals.lookup_bool_option(Globals, warn_nothing_exported, ExportWarning), ( - ExportWarning = no + ExportWarning = no, + Specs = [] ; ExportWarning = yes, ParseTreeModuleSrc = parse_tree_module_src(ModuleName, @@ -152,9 +152,10 @@ check_module_interface_for_no_exports(Globals, ParseTreeModuleSrc, !Specs) :- IntPromises = [] then generate_no_exports_warning(ModuleName, ModuleNameContext, - NumIntIncls, !Specs) + NumIntIncls, Spec), + Specs = [Spec] else - true + Specs = [] ) ). @@ -163,10 +164,9 @@ check_module_interface_for_no_exports(Globals, ParseTreeModuleSrc, !Specs) :- ; 1. :- pred generate_no_exports_warning(module_name::in, prog_context::in, - int::in(num_int_incls), - list(error_spec)::in, list(error_spec)::out) is det. + int::in(num_int_incls), error_spec::out) is det. -generate_no_exports_warning(ModuleName, Context, NumIntIncls, !Specs) :- +generate_no_exports_warning(ModuleName, Context, NumIntIncls, Spec) :- AlwaysPieces = [invis_order_default_start(2, ""), words("Warning: the interface of module")] ++ @@ -202,8 +202,7 @@ generate_no_exports_warning(ModuleName, Context, NumIntIncls, !Specs) :- [always(AlwaysPieces), verbose_only(verbose_always, VerbosePieces)]), Spec = error_spec($pred, severity_warning(warn_nothing_exported), - phase_t2pt, [Msg]), - !:Specs = [Spec | !.Specs]. + phase_t2pt, [Msg]). %---------------------------------------------------------------------------% :- end_module parse_tree.check_module_interface. diff --git a/compiler/link_target_code_c.m b/compiler/link_target_code_c.m index 058c0a807..8ddfb2aa1 100644 --- a/compiler/link_target_code_c.m +++ b/compiler/link_target_code_c.m @@ -72,9 +72,9 @@ % % Section three: link flags. % - % Output the list of flags required to link against the selected set - % of Mercury libraries (the standard libraries, plus any other specified - % via the --ml option) in the current grade. + % Return a string containing the list of flags required to link + % against the selected set of Mercury libraries (the standard libraries, + % plus any other specified via the --ml option) in the current grade. % This predicate is used to implement the `--output-library-link-flags' % option. % @@ -82,8 +82,8 @@ % but it does do a search in the filesystem for libraries that are % named in the values of options, and those searches can fail. % -:- pred output_library_link_flags_for_c(globals::in, io.text_output_stream::in, - list(error_spec)::out, io::di, io::uo) is det. +:- pred get_library_link_flags_for_c(globals::in, list(error_spec)::out, + string::out, io::di, io::uo) is det. %---------------------------------------------------------------------------% % @@ -788,18 +788,13 @@ create_static_lib_for_c(ProgressStream, Globals, FullLibFileName, Quote, cmd_verbose_commands, RanLibCmd, Succeeded, !IO) ). -%---------------------------------------------------------------------------% -% -% Utility predicates needed for creating more than one kind of linked target. -% - %---------------------------------------------------------------------------% %---------------------------------------------------------------------------% % -% Library link flags. +% Section three. % -output_library_link_flags_for_c(Globals, Stream, Specs, !IO) :- +get_library_link_flags_for_c(Globals, Specs, LinkFlagsStr, !IO) :- % We output the library link flags as they are for when we are linking % an executable. LinkedTargetType = executable, @@ -825,9 +820,9 @@ output_library_link_flags_for_c(Globals, Stream, Specs, !IO) :- % Find the Mercury standard libraries. get_mercury_std_libs_for_c(Globals, LinkedTargetType, MercuryStdLibs), get_system_libs_for_c(Globals, LinkedTargetType, SystemLibs), - io.format(Stream, "%s %s %s %s %s\n", + string.format("%s %s %s %s %s\n", [s(LinkLibraryDirectories), s(RpathOpts), s(LinkLibraries), - s(MercuryStdLibs), s(SystemLibs)], !IO). + s(MercuryStdLibs), s(SystemLibs)], LinkFlagsStr). :- pred get_system_libs_for_c(globals::in, linked_target_type::in(c_exe_or_shared_lib), string::out) is det. diff --git a/compiler/mercury_compile_augment.m b/compiler/mercury_compile_augment.m index bc5ee6655..0138a7833 100644 --- a/compiler/mercury_compile_augment.m +++ b/compiler/mercury_compile_augment.m @@ -27,7 +27,7 @@ :- import_module mdbcomp. :- import_module mdbcomp.sym_name. :- import_module parse_tree. -:- import_module parse_tree.error_spec. +:- import_module parse_tree.error_util. :- import_module parse_tree.parse_error. :- import_module parse_tree.prog_parse_tree. :- import_module parse_tree.read_modules. @@ -43,9 +43,9 @@ op_mode_invoked_by_mmc_make::in, file_name::in, maybe(timestamp)::in, read_module_errors::in, parse_tree_src::in, file_components_to_recompile::in, - list(module_name)::out, list(string)::out, list(error_spec)::out, + list(module_name)::out, list(string)::out, have_parse_tree_maps::in, have_parse_tree_maps::out, - io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. %---------------------------------------------------------------------------% %---------------------------------------------------------------------------% @@ -70,7 +70,7 @@ :- import_module libs.options. :- import_module mdbcomp.builtin_modules. :- import_module parse_tree.check_module_interface. -:- import_module parse_tree.error_util. +:- import_module parse_tree.error_spec. :- import_module parse_tree.file_names. :- import_module parse_tree.grab_modules. :- import_module parse_tree.module_baggage. @@ -96,11 +96,13 @@ augment_and_process_source_file(ProgressStream, ErrorStream, Globals, OpModeAugment, InvokedByMmcMake, SourceFileName, MaybeTimestamp, ReadModuleErrors, ParseTreeSrc, MaybeModulesToRecompile, - ModulesToLink, ExtraObjFiles, !:Specs, !HaveParseTreeMaps, !IO) :- + ModulesToLink, ExtraObjFiles, + !HaveParseTreeMaps, !MaybeWrittenSpecs, !IO) :- ModuleName = ParseTreeSrc ^ pts_module_name, parse_tree_src_to_burdened_module_list(Globals, SourceFileName, ReadModuleErrors, MaybeTimestamp, ParseTreeSrc, - !:Specs, BurdenedModules0), + SplitSpecs, BurdenedModules0), + add_to_be_written_specs(SplitSpecs, !MaybeWrittenSpecs), ( MaybeModulesToRecompile = some_file_components(ModulesToRecompile), ToRecompile = @@ -136,7 +138,7 @@ augment_and_process_source_file(ProgressStream, ErrorStream, Globals, augment_and_process_all_submodules(ProgressStream, ErrorStream, GlobalsToUse, OpModeAugment, InvokedByMmcMake, MaybeTimestamp, BurdenedModulesToRecompile, ModulesToLink, ExtraObjFiles, - !Specs, !HaveParseTreeMaps, !IO). + !HaveParseTreeMaps, !MaybeWrittenSpecs, !IO). %---------------------------------------------------------------------------% @@ -147,19 +149,18 @@ augment_and_process_source_file(ProgressStream, ErrorStream, Globals, io.text_output_stream::in, globals::in, op_mode_augment::in, op_mode_invoked_by_mmc_make::in, maybe(timestamp)::in, list(burdened_module)::in, list(module_name)::out, list(string)::out, - list(error_spec)::in, list(error_spec)::out, have_parse_tree_maps::in, have_parse_tree_maps::out, - io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. augment_and_process_all_submodules(ProgressStream, ErrorStream, Globals, OpModeAugment, InvokedByMmcMake, MaybeTimestamp, BurdenedModules, ModulesToLink, ExtraObjFiles, - !Specs, !HaveParseTreeMaps, !IO) :- + !HaveParseTreeMaps, !MaybeWrittenSpecs, !IO) :- list.map_foldl3( augment_and_process_module(ProgressStream, ErrorStream, Globals, OpModeAugment, InvokedByMmcMake, MaybeTimestamp), BurdenedModules, ExtraObjFileLists, - !Specs, !HaveParseTreeMaps, !IO), + !HaveParseTreeMaps, !MaybeWrittenSpecs, !IO), list.map(burdened_module_to_module_name, BurdenedModules, ModulesToLink), list.condense(ExtraObjFileLists, ExtraObjFiles). @@ -189,27 +190,30 @@ burdened_module_to_module_name(BurdenedModule, ModuleName) :- io.text_output_stream::in, globals::in, op_mode_augment::in, op_mode_invoked_by_mmc_make::in, maybe(timestamp)::in, burdened_module::in, list(string)::out, - list(error_spec)::in, list(error_spec)::out, have_parse_tree_maps::in, have_parse_tree_maps::out, - io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. augment_and_process_module(ProgressStream, ErrorStream, Globals, OpModeAugment, InvokedByMmcMake, MaybeTimestamp, - BurdenedModule, ExtraObjFiles, !Specs, !HaveParseTreeMaps, !IO) :- + BurdenedModule, ExtraObjFiles, + !HaveParseTreeMaps, !MaybeWrittenSpecs, !IO) :- BurdenedModule = burdened_module(Baggage0, ParseTreeModuleSrc), - check_module_interface_for_no_exports(Globals, ParseTreeModuleSrc, !Specs), + check_module_interface_for_no_exports(Globals, ParseTreeModuleSrc, + NoExportSpecs), + add_to_be_written_specs(NoExportSpecs, !MaybeWrittenSpecs), % XXX STREAM We could switch from a general progress stream % to a module-specific progress stream. grab_qual_imported_modules_augment(ProgressStream, Globals, MaybeTimestamp, ParseTreeModuleSrc, AugCompUnit, Baggage0, Baggage, !HaveParseTreeMaps, !IO), - Errors = Baggage ^ mb_errors, - !:Specs = get_read_module_specs(Errors) ++ !.Specs, - ( if set.is_empty(Errors ^ rm_fatal_errors) then + BaggageErrors = Baggage ^ mb_errors, + BaggageSpecs = get_read_module_specs(BaggageErrors), + add_to_be_written_specs(BaggageSpecs, !MaybeWrittenSpecs), + ( if set.is_empty(BaggageErrors ^ rm_fatal_errors) then process_augmented_module(ProgressStream, ErrorStream, Globals, OpModeAugment, InvokedByMmcMake, Baggage, AugCompUnit, ExtraObjFiles, no_prev_dump, _, - !Specs, !HaveParseTreeMaps, !IO) + !HaveParseTreeMaps, !MaybeWrittenSpecs, !IO) else ExtraObjFiles = [] ). @@ -219,25 +223,25 @@ augment_and_process_module(ProgressStream, ErrorStream, Globals, op_mode_augment::in, op_mode_invoked_by_mmc_make::in, module_baggage::in, aug_compilation_unit::in, list(string)::out, dump_info::in, dump_info::out, - list(error_spec)::in, list(error_spec)::out, have_parse_tree_maps::in, have_parse_tree_maps::out, - io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. process_augmented_module(ProgressStream, ErrorStream, Globals, OpModeAugment, InvokedByMmcMake, Baggage, AugCompUnit, ExtraObjFiles, - !DumpInfo, !Specs, !HaveParseTreeMaps, !IO) :- + !DumpInfo, !HaveParseTreeMaps, !MaybeWrittenSpecs, !IO) :- make_hlds_pass(ProgressStream, ErrorStream, Globals, OpModeAugment, InvokedByMmcMake, Baggage, AugCompUnit, HLDS1, QualInfo, MaybeTimestampMap, UndefTypes, UndefModes, - PreHLDSErrors, !DumpInfo, !Specs, !HaveParseTreeMaps, !IO), + PreHLDSErrors, !DumpInfo, !HaveParseTreeMaps, !MaybeWrittenSpecs, !IO), frontend_pass(ProgressStream, ErrorStream, OpModeAugment, QualInfo, UndefTypes, UndefModes, PreHLDSErrors, FrontEndErrors, - HLDS1, HLDS20, !DumpInfo, !Specs, !IO), + HLDS1, HLDS20, !DumpInfo, !MaybeWrittenSpecs, !IO), io.get_exit_status(ExitStatus, !IO), ( if PreHLDSErrors = no, FrontEndErrors = no, - contains_errors(Globals, !.Specs) = no, + SpecsSofar = maybe_written_specs_to_specs(!.MaybeWrittenSpecs), + contains_errors(Globals, SpecsSofar) = no, ExitStatus = 0 then globals.lookup_bool_option(Globals, verbose, Verbose), @@ -253,8 +257,8 @@ process_augmented_module(ProgressStream, ErrorStream, Globals, ExtraObjFiles = [] ; OpModeAugment = opmau_make_trans_opt, - output_trans_opt_file(ProgressStream, HLDS21, !Specs, - !DumpInfo, !IO), + output_trans_opt_file(ProgressStream, HLDS21, !DumpInfo, + !MaybeWrittenSpecs, !IO), ExtraObjFiles = [] ; OpModeAugment = opmau_make_analysis_registry, @@ -262,11 +266,11 @@ process_augmented_module(ProgressStream, ErrorStream, Globals, Verbose, Stats, AnalysisSpecs, HLDS21, HLDS22, !IO), ( AnalysisSpecs = [], - output_analysis_file(ProgressStream, HLDS22, !Specs, - !DumpInfo, !IO) + output_analysis_file(ProgressStream, HLDS22, + !DumpInfo, !MaybeWrittenSpecs, !IO) ; AnalysisSpecs = [_ | _], - !:Specs = AnalysisSpecs ++ !.Specs + add_to_be_written_specs(AnalysisSpecs, !MaybeWrittenSpecs) ), ExtraObjFiles = [] ; @@ -282,10 +286,10 @@ process_augmented_module(ProgressStream, ErrorStream, Globals, MaybeTopModule = Baggage ^ mb_maybe_top_module, after_front_end_passes(ProgressStream, ErrorStream, Globals, OpModeFrontAndMiddle, MaybeTopModule, MaybeTimestampMap, - HLDS22, ExtraObjFiles, !Specs, !DumpInfo, !IO) + HLDS22, ExtraObjFiles, !DumpInfo, !MaybeWrittenSpecs, !IO) ; AnalysisSpecs = [_ | _], - !:Specs = AnalysisSpecs ++ !.Specs, + add_to_be_written_specs(AnalysisSpecs, !MaybeWrittenSpecs), ExtraObjFiles = [] ) ) @@ -371,16 +375,16 @@ prepare_for_intermodule_analysis(ProgressStream, Globals, io.text_output_stream::in, globals::in, op_mode_front_and_middle::in, maybe_top_module::in, maybe(module_timestamp_map)::in, module_info::in, - list(string)::out, list(error_spec)::in, list(error_spec)::out, - dump_info::in, dump_info::out, io::di, io::uo) is det. + list(string)::out, dump_info::in, dump_info::out, + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. after_front_end_passes(ProgressStream, ErrorStream, Globals, OpModeFrontAndMiddle, MaybeTopModule, MaybeTimestampMap, !.HLDS, - ExtraObjFiles, !Specs, !DumpInfo, !IO) :- + ExtraObjFiles, !DumpInfo, !MaybeWrittenSpecs, !IO) :- globals.lookup_bool_option(Globals, statistics, Stats), maybe_output_prof_call_graph(ProgressStream, Stats, !HLDS, !IO), middle_pass(ProgressStream, ErrorStream, OpModeFrontAndMiddle, - !HLDS, !DumpInfo, !Specs, !IO), + !HLDS, !DumpInfo, !MaybeWrittenSpecs, !IO), % Remove any existing `.used' file before writing the output file. % This avoids leaving the old `used' file lying around if compilation @@ -393,8 +397,9 @@ after_front_end_passes(ProgressStream, ErrorStream, Globals, UsageFileName, _UsageFileNameProposed), io.file.remove_file(UsageFileName, _, !IO), + FrontEndSpecs = maybe_written_specs_to_specs(!.MaybeWrittenSpecs), FrontEndErrors = - contains_errors_or_warnings_treated_as_errors(Globals, !.Specs), + contains_errors_or_warnings_treated_as_errors(Globals, FrontEndSpecs), io.get_exit_status(ExitStatus, !IO), ( if FrontEndErrors = no, @@ -412,7 +417,7 @@ after_front_end_passes(ProgressStream, ErrorStream, Globals, choose_and_execute_backend_passes(ProgressStream, ErrorStream, Globals, OpModeCodeGen, ModuleName, MaybeTopModule, MaybeTimestampMap, !.HLDS, ExtraObjFiles, - !Specs, !DumpInfo, !IO) + !DumpInfo, !MaybeWrittenSpecs, !IO) ) else % Make sure that the compiler exits with a non-zero exit status. @@ -428,22 +433,24 @@ after_front_end_passes(ProgressStream, ErrorStream, Globals, io.text_output_stream::in, globals::in, op_mode_codegen::in, module_name::in, maybe_top_module::in, maybe(module_timestamp_map)::in, module_info::in, - list(string)::out, list(error_spec)::in, list(error_spec)::out, - dump_info::in, dump_info::out, io::di, io::uo) is det. + list(string)::out, dump_info::in, dump_info::out, + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. choose_and_execute_backend_passes(ProgressStream, ErrorStream, Globals, OpModeCodeGen, ModuleName, MaybeTopModule, MaybeTimestampMap, !.HLDS, - ExtraObjFiles, !Specs, !DumpInfo, !IO) :- + ExtraObjFiles, !DumpInfo, !MaybeWrittenSpecs, !IO) :- globals.get_target(Globals, Target), ( Target = target_csharp, - hlds_to_mlds(ProgressStream, !.HLDS, MLDS, !Specs, !DumpInfo, !IO), + hlds_to_mlds(ProgressStream, !.HLDS, MLDS, + !DumpInfo, !MaybeWrittenSpecs, !IO), % mlds_to_csharp never goes beyond generating C# code. mlds_to_csharp(ProgressStream, !.HLDS, MLDS, Succeeded, !IO), ExtraObjFiles = [] ; Target = target_java, - hlds_to_mlds(ProgressStream, !.HLDS, MLDS, !Specs, !DumpInfo, !IO), + hlds_to_mlds(ProgressStream, !.HLDS, MLDS, + !DumpInfo, !MaybeWrittenSpecs, !IO), mlds_to_java(ProgressStream, !.HLDS, MLDS, TargetCodeSucceeded, !IO), ( OpModeCodeGen = opfam_target_code_only, @@ -476,7 +483,8 @@ choose_and_execute_backend_passes(ProgressStream, ErrorStream, Globals, globals.lookup_bool_option(Globals, highlevel_code, HighLevelCode), ( HighLevelCode = yes, - hlds_to_mlds(ProgressStream, !.HLDS, MLDS, !Specs, !DumpInfo, !IO), + hlds_to_mlds(ProgressStream, !.HLDS, MLDS, + !DumpInfo, !MaybeWrittenSpecs, !IO), mlds_to_high_level_c(ProgressStream, Globals, MLDS, TargetCodeSucceeded, !IO), ( @@ -512,7 +520,7 @@ choose_and_execute_backend_passes(ProgressStream, ErrorStream, Globals, ; HighLevelCode = no, hlds_to_llds(ProgressStream, ErrorStream, !HLDS, - GlobalData, LLDS, !DumpInfo, !IO), + GlobalData, LLDS, !DumpInfo, !MaybeWrittenSpecs, !IO), llds_to_c(ProgressStream, !.HLDS, GlobalData, LLDS, TargetCodeSucceeded, !IO), ( diff --git a/compiler/mercury_compile_front_end.m b/compiler/mercury_compile_front_end.m index da2519817..b96ffba0a 100644 --- a/compiler/mercury_compile_front_end.m +++ b/compiler/mercury_compile_front_end.m @@ -29,20 +29,19 @@ :- import_module libs. :- import_module libs.op_mode. :- import_module parse_tree. -:- import_module parse_tree.error_spec. +:- import_module parse_tree.error_util. :- import_module bool. :- import_module io. -:- import_module list. :- import_module maybe. %---------------------------------------------------------------------------% :- pred frontend_pass(io.text_output_stream::in, io.text_output_stream::in, op_mode_augment::in, qual_info::in, bool::in, bool::in, - bool::in, bool::out, module_info::in, module_info::out, dump_info::in, - dump_info::out, list(error_spec)::in, list(error_spec)::out, - io::di, io::uo) is det. + bool::in, bool::out, module_info::in, module_info::out, + dump_info::in, dump_info::out, + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. %---------------------------------------------------------------------------% @@ -89,7 +88,7 @@ :- pred maybe_simplify(io.text_output_stream::in, maybe(io.text_output_stream)::in, bool::in, simplify_pass::in, bool::in, bool::in, module_info::in, module_info::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. %---------------------------------------------------------------------------% %---------------------------------------------------------------------------% @@ -140,7 +139,7 @@ :- import_module libs.options. :- import_module mdbcomp. :- import_module mdbcomp.sym_name. -:- import_module parse_tree.error_util. +:- import_module parse_tree.error_spec. :- import_module parse_tree.file_names. :- import_module parse_tree.find_module. :- import_module parse_tree.maybe_error. @@ -158,6 +157,7 @@ :- import_module benchmarking. :- import_module int. +:- import_module list. :- import_module map. :- import_module pair. :- import_module require. @@ -170,7 +170,7 @@ frontend_pass(ProgressStream, ErrorStream, OpModeAugment, QualInfo0, FoundUndefTypeError, FoundUndefModeError, !FoundError, - !HLDS, !DumpInfo, !Specs, !IO) :- + !HLDS, !DumpInfo, !MaybeWrittenSpecs, !IO) :- % We can't continue after an undefined type error, since typecheck % would get internal errors. module_info_get_globals(!.HLDS, Globals), @@ -180,13 +180,15 @@ frontend_pass(ProgressStream, ErrorStream, OpModeAugment, QualInfo0, % We can't continue after an undefined type error, because if we did, % typecheck could get internal errors. !:FoundError = yes, - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), maybe_write_string(ProgressStream, Verbose, "% Program contains undefined type error(s).\n", !IO), io.set_exit_status(1, !IO) ; FoundUndefTypeError = no, - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), % It would be nice to move the decide_type_repns pass later, % possibly all the way to the end of the semantic analysis passes, @@ -197,7 +199,7 @@ frontend_pass(ProgressStream, ErrorStream, OpModeAugment, QualInfo0, % for reasons that are documented at the top of du_type_layout.m. globals.lookup_bool_option(Globals, statistics, Stats), decide_type_repns_pass(ProgressStream, ErrorStream, Verbose, Stats, - !HLDS, !Specs, !IO), + !HLDS, !MaybeWrittenSpecs, !IO), maybe_dump_hlds(ProgressStream, !.HLDS, 3, "decide_type_repns", !DumpInfo, !IO), @@ -206,7 +208,7 @@ frontend_pass(ProgressStream, ErrorStream, OpModeAugment, QualInfo0, check_typeclasses(ProgressStream, !HLDS, QualInfo0, QualInfo, TypeClassSpecs), TypeClassErrors = contains_errors(Globals, TypeClassSpecs), - !:Specs = TypeClassSpecs ++ !.Specs, + add_to_be_written_specs(TypeClassSpecs, !MaybeWrittenSpecs), maybe_dump_hlds(ProgressStream, !.HLDS, 5, "typeclass", !DumpInfo, !IO), set_module_recompilation_info(QualInfo, !HLDS), @@ -219,7 +221,7 @@ frontend_pass(ProgressStream, ErrorStream, OpModeAugment, QualInfo0, TypeClassErrors = no, frontend_pass_after_typeclass_check(ProgressStream, ErrorStream, OpModeAugment, FoundUndefModeError, !FoundError, - !HLDS, !DumpInfo, !Specs, !IO) + !HLDS, !DumpInfo, !MaybeWrittenSpecs, !IO) ) ). @@ -227,21 +229,22 @@ frontend_pass(ProgressStream, ErrorStream, OpModeAugment, QualInfo0, io.text_output_stream::in, op_mode_augment::in, bool::in, bool::in, bool::out, module_info::in, module_info::out, dump_info::in, dump_info::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. frontend_pass_after_typeclass_check(ProgressStream, ErrorStream, OpModeAugment, - FoundUndefModeError, !FoundError, !HLDS, !DumpInfo, !Specs, !IO) :- + FoundUndefModeError, !FoundError, !HLDS, !DumpInfo, + !MaybeWrittenSpecs, !IO) :- module_info_get_globals(!.HLDS, Globals), globals.lookup_bool_option(Globals, verbose, Verbose), globals.lookup_bool_option(Globals, statistics, Stats), maybe_eliminate_dead_preds(ProgressStream, ErrorStream, OpModeAugment, - Verbose, Stats, Globals, !HLDS, !DumpInfo, !Specs, !IO), + Verbose, Stats, Globals, !HLDS, !DumpInfo, !MaybeWrittenSpecs, !IO), check_insts_for_matching_types(ProgressStream, ErrorStream, Verbose, Stats, - Globals, !HLDS, !DumpInfo, !Specs, !IO), + Globals, !HLDS, !DumpInfo, !MaybeWrittenSpecs, !IO), do_typecheck(ProgressStream, ErrorStream, Verbose, Stats, Globals, FoundSyntaxError, FoundTypeError, DidWeExceedIterationLimit, - !HLDS, !DumpInfo, !Specs, !IO), + !HLDS, !DumpInfo, !MaybeWrittenSpecs, !IO), % We can't continue after an undefined inst/mode error, since % propagate_types_into_proc_modes (in post_typecheck.m -- called by @@ -265,7 +268,7 @@ frontend_pass_after_typeclass_check(ProgressStream, ErrorStream, OpModeAugment, io.set_exit_status(1, !IO) else check_for_missing_type_defns(!.HLDS, MissingTypeDefnSpecs), - !:Specs = !.Specs ++ MissingTypeDefnSpecs, + add_to_be_written_specs(MissingTypeDefnSpecs, !MaybeWrittenSpecs), SomeMissingTypeDefns = contains_errors(Globals, MissingTypeDefnSpecs), pretest_user_inst_table(!HLDS), @@ -273,7 +276,8 @@ frontend_pass_after_typeclass_check(ProgressStream, ErrorStream, OpModeAugment, PostTypeCheckAlwaysSpecs, PostTypeCheckNoTypeErrorSpecs), io.get_exit_status(ExitStatus, !IO), - MaybeWorstSeverity = worst_severity_in_specs(Globals, !.Specs), + SpecsSoFar = maybe_written_specs_to_specs(!.MaybeWrittenSpecs), + MaybeWorstSeverity = worst_severity_in_specs(Globals, SpecsSoFar), ( if ( ExitStatus \= 0 ; MaybeWorstSeverity = yes(actual_severity_error) @@ -304,7 +308,8 @@ frontend_pass_after_typeclass_check(ProgressStream, ErrorStream, OpModeAugment, % invoke it during *this* compiler invocation. true else - warn_about_unused_types(!.HLDS, !Specs) + warn_about_unused_types(!.HLDS, [], UnusedTypeSpecs), + add_to_be_written_specs(UnusedTypeSpecs, !MaybeWrittenSpecs) ), maybe_dump_hlds(ProgressStream, !.HLDS, 19, "post_typecheck", !DumpInfo, !IO), @@ -313,10 +318,11 @@ frontend_pass_after_typeclass_check(ProgressStream, ErrorStream, OpModeAugment, % messages. We get post_typecheck to put all such messages into % PostTypeCheckNoTypeErrorSpecs, and we report them only if % we did not find any errors during typecheck. - !:Specs = !.Specs ++ PostTypeCheckAlwaysSpecs, + add_to_be_written_specs(PostTypeCheckAlwaysSpecs, !MaybeWrittenSpecs), ( FoundTypeError = no, - !:Specs = !.Specs ++ PostTypeCheckNoTypeErrorSpecs + add_to_be_written_specs(PostTypeCheckNoTypeErrorSpecs, + !MaybeWrittenSpecs) ; FoundTypeError = yes ), @@ -337,7 +343,7 @@ frontend_pass_after_typeclass_check(ProgressStream, ErrorStream, OpModeAugment, else frontend_pass_after_typecheck(ProgressStream, ErrorStream, OpModeAugment, Verbose, Stats, Globals, FoundUndefModeError, - !FoundError, !HLDS, !DumpInfo, !Specs, !IO) + !FoundError, !HLDS, !DumpInfo, !MaybeWrittenSpecs, !IO) ) ). @@ -345,10 +351,10 @@ frontend_pass_after_typeclass_check(ProgressStream, ErrorStream, OpModeAugment, io.text_output_stream::in, op_mode_augment::in, bool::in, bool::in, globals::in, module_info::in, module_info::out, dump_info::in, dump_info::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. maybe_eliminate_dead_preds(ProgressStream, ErrorStream, OpModeAugment, - Verbose, Stats, Globals, !HLDS, !DumpInfo, !Specs, !IO) :- + Verbose, Stats, Globals, !HLDS, !DumpInfo, !MaybeWrittenSpecs, !IO) :- globals.lookup_bool_option(Globals, intermodule_optimization, IntermodOpt), globals.lookup_bool_option(Globals, intermodule_analysis, IntermodAnalysis), @@ -364,11 +370,13 @@ maybe_eliminate_dead_preds(ProgressStream, ErrorStream, OpModeAugment, % to speed up compilation. This must be done after % typeclass instances have been checked, since that % fills in which pred_ids are needed by instance decls. - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), maybe_write_string(ProgressStream, Verbose, "% Eliminating dead predicates... ", !IO), dead_pred_elim(!HLDS), - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), maybe_write_string(ProgressStream, Verbose, "done.\n", !IO), maybe_report_stats(ProgressStream, Stats, !IO), maybe_dump_hlds(ProgressStream, !.HLDS, 10, "dead_pred_elim", @@ -380,18 +388,21 @@ maybe_eliminate_dead_preds(ProgressStream, ErrorStream, OpModeAugment, :- pred check_insts_for_matching_types(io.text_output_stream::in, io.text_output_stream::in, bool::in, bool::in, globals::in, module_info::in, module_info::out, dump_info::in, dump_info::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. check_insts_for_matching_types(ProgressStream, ErrorStream, Verbose, Stats, - Globals, !HLDS, !DumpInfo, !Specs, !IO) :- - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + Globals, !HLDS, !DumpInfo, !MaybeWrittenSpecs, !IO) :- + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), maybe_write_string(ProgressStream, Verbose, "% Checking that insts have matching types... ", !IO), globals.lookup_bool_option(Globals, warn_insts_without_matching_type, WarnInstsWithNoMatchingType), check_insts_have_matching_types(WarnInstsWithNoMatchingType, - !HLDS, !Specs), - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + !HLDS, [], MatchSpecs), + add_to_be_written_specs(MatchSpecs, !MaybeWrittenSpecs), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), maybe_write_string(ProgressStream, Verbose, "done.\n", !IO), maybe_report_stats(ProgressStream, Stats, !IO), maybe_dump_hlds(ProgressStream, !.HLDS, 12, @@ -401,13 +412,14 @@ check_insts_for_matching_types(ProgressStream, ErrorStream, Verbose, Stats, bool::in, bool::in, globals::in, maybe_clause_syntax_errors::out, bool::out, number_of_iterations::out, module_info::in, module_info::out, dump_info::in, dump_info::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. do_typecheck(ProgressStream, ErrorStream, Verbose, Stats, Globals, FoundSyntaxError, FoundTypeError, DidWeExceedIterationLimit, - !HLDS, !DumpInfo, !Specs, !IO) :- + !HLDS, !DumpInfo, !MaybeWrittenSpecs, !IO) :- % Next typecheck the clauses. - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), maybe_write_string(ProgressStream, Verbose, "% Type-checking...\n", !IO), maybe_write_string(ProgressStream, Verbose, @@ -427,7 +439,8 @@ do_typecheck(ProgressStream, ErrorStream, Verbose, Stats, Globals, DidWeExceedIterationLimit = within_iteration_limit ; TypeCheckUsingConstraints = no, - prepare_for_typecheck_module(!HLDS, !Specs), + prepare_for_typecheck_module(!HLDS, [], PrepareSpecs), + add_to_be_written_specs(PrepareSpecs, !MaybeWrittenSpecs), % This dump opportunity is here mostly to allow observation of % the effects of the transformation for regularizing headvar names. maybe_dump_hlds(ProgressStream, !.HLDS, 14, "pre_typecheck", @@ -435,8 +448,9 @@ do_typecheck(ProgressStream, ErrorStream, Verbose, Stats, Globals, typecheck_module(ProgressStream, !HLDS, TypeCheckSpecs, FoundSyntaxError, DidWeExceedIterationLimit) ), - !:Specs = TypeCheckSpecs ++ !.Specs, - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + add_to_be_written_specs(TypeCheckSpecs, !MaybeWrittenSpecs), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), FoundTypeError = contains_errors(Globals, TypeCheckSpecs), ( FoundTypeError = yes, @@ -454,11 +468,11 @@ do_typecheck(ProgressStream, ErrorStream, Verbose, Stats, Globals, io.text_output_stream::in, op_mode_augment::in, bool::in, bool::in, globals::in, bool::in, bool::in, bool::out, module_info::in, module_info::out, dump_info::in, dump_info::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. frontend_pass_after_typecheck(ProgressStream, ErrorStream, OpModeAugment, Verbose, Stats, Globals, FoundUndefModeError, - !FoundError, !HLDS, !DumpInfo, !Specs, !IO) :- + !FoundError, !HLDS, !DumpInfo, !MaybeWrittenSpecs, !IO) :- % We invoke purity check even if --typecheck-only was specified, % because the resolution of predicate and function overloading % is done during the purity pass, and errors in the resolution @@ -468,11 +482,11 @@ frontend_pass_after_typecheck(ProgressStream, ErrorStream, OpModeAugment, % (See Mantis bug 113.) puritycheck(ProgressStream, ErrorStream, Verbose, Stats, - !HLDS, !Specs, !IO), + !HLDS, !MaybeWrittenSpecs, !IO), maybe_dump_hlds(ProgressStream, !.HLDS, 20, "puritycheck", !DumpInfo, !IO), check_promises(ProgressStream, ErrorStream, Verbose, Stats, - !HLDS, !Specs, !IO), + !HLDS, !MaybeWrittenSpecs, !IO), maybe_dump_hlds(ProgressStream, !.HLDS, 22, "check_promises", !DumpInfo, !IO), @@ -504,7 +518,7 @@ frontend_pass_after_typecheck(ProgressStream, ErrorStream, OpModeAugment, % Substitute implementation-defined literals before % clauses are written out to `.opt' files. subst_implementation_defined_literals(ProgressStream, ErrorStream, - Verbose, Stats, !HLDS, !Specs, !IO), + Verbose, Stats, !HLDS, !MaybeWrittenSpecs, !IO), maybe_dump_hlds(ProgressStream, !.HLDS, 25, "implementation_defined_literals", !DumpInfo, !IO), @@ -538,7 +552,8 @@ frontend_pass_after_typecheck(ProgressStream, ErrorStream, OpModeAugment, % This will invoke frontend_pass_by_phases *if and only if* % some of the enabled optimizations need it. create_and_write_opt_file(ProgressStream, ErrorStream, - IntermodAnalysis, Globals, !HLDS, !DumpInfo, !Specs, !IO) + IntermodAnalysis, Globals, !HLDS, !DumpInfo, + !MaybeWrittenSpecs, !IO) ) % If our job was to write out the `.opt' file, then we are done. ; @@ -552,7 +567,8 @@ frontend_pass_after_typecheck(ProgressStream, ErrorStream, OpModeAugment, ), % Now go ahead and do the rest of the front end passes. frontend_pass_by_phases(ProgressStream, ErrorStream, - !HLDS, FoundModeOrDetError, !DumpInfo, !Specs, !IO), + !HLDS, FoundModeOrDetError, !DumpInfo, + !MaybeWrittenSpecs, !IO), bool.or(FoundModeOrDetError, !FoundError) ) ). @@ -562,10 +578,10 @@ frontend_pass_after_typecheck(ProgressStream, ErrorStream, OpModeAugment, :- pred create_and_write_opt_file(io.text_output_stream::in, io.text_output_stream::in, bool::in, globals::in, module_info::in, module_info::out, dump_info::in, dump_info::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. create_and_write_opt_file(ProgressStream, ErrorStream, IntermodAnalysis, - Globals, !HLDS, !DumpInfo, !Specs, !IO) :- + Globals, !HLDS, !DumpInfo, !MaybeWrittenSpecs, !IO) :- module_info_get_name(!.HLDS, ModuleName), % XXX LEGACY OptExt = ext_cur_ngs_gs_max_ngs(ext_cur_ngs_gs_max_ngs_legacy_opt_plain), @@ -593,11 +609,11 @@ create_and_write_opt_file(ProgressStream, ErrorStream, IntermodAnalysis, NeedMiddlePassForOptFile = yes then frontend_pass_by_phases(ProgressStream, ErrorStream, !HLDS, - FoundFrontEndError, !DumpInfo, !Specs, !IO), + FoundFrontEndError, !DumpInfo, !MaybeWrittenSpecs, !IO), ( FoundFrontEndError = no, middle_pass_for_opt_file(ProgressStream, !HLDS, UnusedArgsInfos, - !Specs, !IO), + !MaybeWrittenSpecs, !IO), append_analysis_pragmas_to_opt_file(!.HLDS, UnusedArgsInfos, ParseTreePlainOpt0, ParseTreePlainOpt, OptState1, OptState) ; @@ -773,16 +789,16 @@ need_middle_pass_for_opt_file(Globals, NeedMiddlePassForOptFile) :- :- pred frontend_pass_by_phases(io.text_output_stream::in, io.text_output_stream::in, module_info::in, module_info::out, bool::out, dump_info::in, dump_info::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. frontend_pass_by_phases(ProgressStream, ErrorStream, !HLDS, FoundError, - !DumpInfo, !Specs, !IO) :- + !DumpInfo, !MaybeWrittenSpecs, !IO) :- module_info_get_globals(!.HLDS, Globals), globals.lookup_bool_option(Globals, verbose, Verbose), globals.lookup_bool_option(Globals, statistics, Stats), main_polymorphism_pass(ProgressStream, ErrorStream, Verbose, Stats, - ExistsCastPredIds, PolySafeToContinue, !HLDS, !Specs, !IO), + ExistsCastPredIds, PolySafeToContinue, !HLDS, !MaybeWrittenSpecs, !IO), maybe_dump_hlds(ProgressStream, !.HLDS, 30, "polymorphism", !DumpInfo, !IO), @@ -793,17 +809,17 @@ frontend_pass_by_phases(ProgressStream, ErrorStream, !HLDS, FoundError, PolySafeToContinue = safe_to_continue, clause_to_proc(ProgressStream, ErrorStream, Verbose, Stats, - !HLDS, !Specs, !IO), + !HLDS, !MaybeWrittenSpecs, !IO), maybe_dump_hlds(ProgressStream, !.HLDS, 31, "clause_to_proc", !DumpInfo, !IO), post_copy_polymorphism_pass(ProgressStream, ErrorStream, - Verbose, Stats, ExistsCastPredIds, !HLDS, !Specs, !IO), + Verbose, Stats, ExistsCastPredIds, !HLDS, !MaybeWrittenSpecs, !IO), maybe_dump_hlds(ProgressStream, !.HLDS, 32, "post_copy_polymorphism", !DumpInfo, !IO), maybe_warn_about_unused_imports(ProgressStream, ErrorStream, - Verbose, Stats, !.HLDS, !Specs, !IO), + Verbose, Stats, !.HLDS, !MaybeWrittenSpecs, !IO), maybe_dump_hlds(ProgressStream, !.HLDS, 33, "unused_imports", !DumpInfo, !IO), @@ -813,12 +829,12 @@ frontend_pass_by_phases(ProgressStream, ErrorStream, !HLDS, FoundError, !DumpInfo, !IO), modecheck(ProgressStream, ErrorStream, Verbose, Stats, !HLDS, - FoundModeError, ModesSafeToContinue, !Specs, !IO), + FoundModeError, ModesSafeToContinue, !MaybeWrittenSpecs, !IO), maybe_dump_hlds(ProgressStream, !.HLDS, 35, "modecheck", !DumpInfo, !IO), maybe_compute_goal_modes(ProgressStream, ErrorStream, Verbose, Stats, - !HLDS, !Specs, !IO), + !HLDS, !MaybeWrittenSpecs, !IO), maybe_dump_hlds(ProgressStream, !.HLDS, 36, "goal_modes", !DumpInfo, !IO), @@ -836,39 +852,40 @@ frontend_pass_by_phases(ProgressStream, ErrorStream, !HLDS, FoundError, maybe_dump_hlds(ProgressStream, !.HLDS, 45, "cse", !DumpInfo, !IO), check_determinism(ProgressStream, ErrorStream, Verbose, Stats, - !HLDS, !Specs, !IO), + !HLDS, !MaybeWrittenSpecs, !IO), maybe_dump_hlds(ProgressStream, !.HLDS, 50, "determinism", !DumpInfo, !IO), check_unique_modes(ProgressStream, ErrorStream, Verbose, Stats, - !HLDS, FoundUniqError, !Specs, !IO), + !HLDS, FoundUniqError, !MaybeWrittenSpecs, !IO), maybe_dump_hlds(ProgressStream, !.HLDS, 55, "unique_modes", !DumpInfo, !IO), maybe_write_call_tree(ProgressStream, Verbose, Stats, - !.HLDS, !Specs, !IO), + !.HLDS, !MaybeWrittenSpecs, !IO), check_stratification(ProgressStream, ErrorStream, Verbose, Stats, - !HLDS, FoundStratError, !Specs, !IO), + !HLDS, FoundStratError, !MaybeWrittenSpecs, !IO), maybe_dump_hlds(ProgressStream, !.HLDS, 60, "stratification", !DumpInfo, !IO), check_oisu_pragmas(ProgressStream, ErrorStream, Verbose, Stats, - !HLDS, FoundOISUError, !Specs, !IO), + !HLDS, FoundOISUError, !MaybeWrittenSpecs, !IO), maybe_dump_hlds(ProgressStream, !.HLDS, 61, "oisu", !DumpInfo, !IO), process_try_goals(ProgressStream, ErrorStream, Verbose, Stats, - !HLDS, FoundTryError, !Specs, !IO), + !HLDS, FoundTryError, !MaybeWrittenSpecs, !IO), maybe_dump_hlds(ProgressStream, !.HLDS, 62, "try", !DumpInfo, !IO), check_pragma_format_call(ProgressStream, ErrorStream, - Verbose, Stats, !HLDS, !Specs, !IO), + Verbose, Stats, !HLDS, !MaybeWrittenSpecs, !IO), maybe_dump_hlds(ProgressStream, !.HLDS, 63, "format_call", !DumpInfo, !IO), maybe_simplify(ProgressStream, yes(ErrorStream), yes, - simplify_pass_frontend, Verbose, Stats, !HLDS, !Specs, !IO), + simplify_pass_frontend, Verbose, Stats, + !HLDS, !MaybeWrittenSpecs, !IO), maybe_dump_hlds(ProgressStream, !.HLDS, 65, "frontend_simplify", !DumpInfo, !IO), @@ -878,16 +895,17 @@ frontend_pass_by_phases(ProgressStream, ErrorStream, !HLDS, FoundError, % by adding messages about style, which, in that case, would be % just clutter. maybe_generate_style_warnings(ProgressStream, ErrorStream, - Verbose, Stats, !.HLDS, !Specs, !IO), + Verbose, Stats, !.HLDS, !MaybeWrittenSpecs, !IO), - maybe_proc_statistics(ProgressStream, ErrorStream, - Verbose, Stats, "AfterFrontEnd", !.HLDS, !Specs, !IO), - maybe_inst_statistics(ProgressStream, ErrorStream, - Verbose, Stats, !.HLDS, !Specs, !IO), + maybe_proc_statistics(ProgressStream, ErrorStream, Verbose, Stats, + "AfterFrontEnd", !.HLDS, !MaybeWrittenSpecs, !IO), + maybe_inst_statistics(ProgressStream, ErrorStream, Verbose, Stats, + !.HLDS, !MaybeWrittenSpecs, !IO), % Work out whether we encountered any errors. + SpecsSoFar = maybe_written_specs_to_specs(!.MaybeWrittenSpecs), MaybeWorstSpecsSeverity = - worst_severity_in_specs(Globals, !.Specs), + worst_severity_in_specs(Globals, SpecsSoFar), io.get_exit_status(ExitStatus, !IO), ( if FoundModeError = no, @@ -921,15 +939,17 @@ frontend_pass_by_phases(ProgressStream, ErrorStream, !HLDS, FoundError, :- pred decide_type_repns_pass(io.text_output_stream::in, io.text_output_stream::in, bool::in, bool::in, module_info::in, module_info::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. decide_type_repns_pass(ProgressStream, ErrorStream, Verbose, Stats, - !HLDS, !Specs, !IO) :- + !HLDS, !MaybeWrittenSpecs, !IO) :- module_info_get_globals(!.HLDS, Globals), - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), maybe_write_string(ProgressStream, Verbose, "% Deciding type representations...\n", !IO), - decide_type_repns(!HLDS, !Specs, !IO), + decide_type_repns(!HLDS, [], RepnSpecs, !IO), + add_to_be_written_specs(RepnSpecs, !MaybeWrittenSpecs), maybe_write_string(ProgressStream, Verbose, "% done.\n", !IO), maybe_report_stats(ProgressStream, Stats, !IO). @@ -937,16 +957,18 @@ decide_type_repns_pass(ProgressStream, ErrorStream, Verbose, Stats, :- pred puritycheck(io.text_output_stream::in, io.text_output_stream::in, bool::in, bool::in, module_info::in, module_info::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. -puritycheck(ProgressStream, ErrorStream, Verbose, Stats, !HLDS, !Specs, !IO) :- +puritycheck(ProgressStream, ErrorStream, Verbose, Stats, !HLDS, + !MaybeWrittenSpecs, !IO) :- maybe_write_string(ProgressStream, Verbose, "% Purity-checking clauses...\n", !IO), puritycheck_module(ProgressStream, !HLDS, [], PuritySpecs), - !:Specs = PuritySpecs ++ !.Specs, + add_to_be_written_specs(PuritySpecs, !MaybeWrittenSpecs), module_info_get_globals(!.HLDS, Globals), PurityErrors = contains_errors(Globals, PuritySpecs), - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), ( PurityErrors = yes, maybe_write_string(ProgressStream, Verbose, @@ -962,17 +984,18 @@ puritycheck(ProgressStream, ErrorStream, Verbose, Stats, !HLDS, !Specs, !IO) :- :- pred check_promises(io.text_output_stream::in, io.text_output_stream::in, bool::in, bool::in, module_info::in, module_info::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. check_promises(ProgressStream, ErrorStream, Verbose, Stats, - !HLDS, !Specs, !IO) :- + !HLDS, !MaybeWrittenSpecs, !IO) :- maybe_write_string(ProgressStream, Verbose, "% Checking any promises...\n", !IO), check_promises_in_module(ProgressStream, !HLDS, [], PromiseSpecs), - !:Specs = PromiseSpecs ++ !.Specs, + add_to_be_written_specs(PromiseSpecs, !MaybeWrittenSpecs), module_info_get_globals(!.HLDS, Globals), PromiseErrors = contains_errors(Globals, PromiseSpecs), - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), ( PromiseErrors = yes, maybe_write_string(ProgressStream, Verbose, @@ -989,12 +1012,13 @@ check_promises(ProgressStream, ErrorStream, Verbose, Stats, :- pred subst_implementation_defined_literals(io.text_output_stream::in, io.text_output_stream::in, bool::in, bool::in, module_info::in, module_info::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. subst_implementation_defined_literals(ProgressStream, ErrorStream, - Verbose, Stats, !HLDS, !Specs, !IO) :- + Verbose, Stats, !HLDS, !MaybeWrittenSpecs, !IO) :- module_info_get_globals(!.HLDS, Globals), - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), maybe_write_string(ProgressStream, Verbose, "% Substituting implementation-defined literals...\n", !IO), maybe_flush_output(ProgressStream, Verbose, !IO), @@ -1008,12 +1032,13 @@ subst_implementation_defined_literals(ProgressStream, ErrorStream, io.text_output_stream::in, bool::in, bool::in, list(pred_id)::out, maybe_safe_to_continue::out, module_info::in, module_info::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. main_polymorphism_pass(ProgressStream, ErrorStream, Verbose, Stats, - ExistsCastPredIds, SafeToContinue, !HLDS, !Specs, !IO) :- + ExistsCastPredIds, SafeToContinue, !HLDS, !MaybeWrittenSpecs, !IO) :- module_info_get_globals(!.HLDS, Globals), - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), globals.lookup_bool_option(Globals, very_verbose, VeryVerbose), ( @@ -1028,7 +1053,7 @@ main_polymorphism_pass(ProgressStream, ErrorStream, Verbose, Stats, maybe_flush_output(ProgressStream, Verbose, !IO), polymorphism_process_module(ProgressStream, !HLDS, ExistsCastPredIds, SafeToContinue, PolySpecs), - !:Specs = PolySpecs ++ !.Specs, + add_to_be_written_specs(PolySpecs, !MaybeWrittenSpecs), ( VeryVerbose = no, maybe_write_string(ProgressStream, Verbose, " done.\n", !IO) @@ -1036,19 +1061,21 @@ main_polymorphism_pass(ProgressStream, ErrorStream, Verbose, Stats, VeryVerbose = yes, maybe_write_string(ProgressStream, Verbose, "% done.\n", !IO) ), - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), maybe_report_stats(ProgressStream, Stats, !IO). %---------------------------------------------------------------------------% :- pred clause_to_proc(io.text_output_stream::in, io.text_output_stream::in, bool::in, bool::in, module_info::in, module_info::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. clause_to_proc(ProgressStream, ErrorStream, Verbose, Stats, - !HLDS, !Specs, !IO) :- + !HLDS, !MaybeWrittenSpecs, !IO) :- module_info_get_globals(!.HLDS, Globals), - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), maybe_write_string(ProgressStream, Verbose, "% Copying clauses to procedures...", !IO), copy_clauses_to_proc_for_all_valid_procs(!HLDS), @@ -1060,12 +1087,13 @@ clause_to_proc(ProgressStream, ErrorStream, Verbose, Stats, :- pred post_copy_polymorphism_pass(io.text_output_stream::in, io.text_output_stream::in, bool::in, bool::in, list(pred_id)::in, module_info::in, module_info::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. post_copy_polymorphism_pass(ProgressStream, ErrorStream, Verbose, Stats, - ExistsCastPredIds, !HLDS, !Specs, !IO) :- + ExistsCastPredIds, !HLDS, !MaybeWrittenSpecs, !IO) :- module_info_get_globals(!.HLDS, Globals), - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), maybe_write_string(ProgressStream, Verbose, "% Post copy polymorphism...", !IO), post_copy_polymorphism(ExistsCastPredIds, !HLDS), @@ -1076,21 +1104,23 @@ post_copy_polymorphism_pass(ProgressStream, ErrorStream, Verbose, Stats, :- pred maybe_warn_about_unused_imports(io.text_output_stream::in, io.text_output_stream::in, bool::in, bool::in, module_info::in, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. maybe_warn_about_unused_imports(ProgressStream, ErrorStream, Verbose, Stats, - HLDS, !Specs, !IO) :- + HLDS, !MaybeWrittenSpecs, !IO) :- module_info_get_globals(HLDS, Globals), globals.lookup_bool_option(Globals, warn_unused_imports, WarnUnusedImports), ( WarnUnusedImports = yes, - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), maybe_write_string(ProgressStream, Verbose, "% Checking for unused imports...", !IO), warn_about_unused_imports(ProgressStream, HLDS, UnusedImportSpecs), - !:Specs = UnusedImportSpecs ++ !.Specs, - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + add_to_be_written_specs(UnusedImportSpecs, !MaybeWrittenSpecs), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), maybe_write_string(ProgressStream, Verbose, " done.\n", !IO), maybe_report_stats(ProgressStream, Stats, !IO) ; @@ -1121,12 +1151,13 @@ maybe_mode_constraints(ProgressStream, Verbose, Stats, !HLDS, !IO) :- :- pred modecheck(io.text_output_stream::in, io.text_output_stream::in, bool::in, bool::in, module_info::in, module_info::out, bool::out, maybe_safe_to_continue::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. modecheck(ProgressStream, ErrorStream, Verbose, Stats, !HLDS, - FoundModeError, SafeToContinue, !Specs, !IO) :- + FoundModeError, SafeToContinue, !MaybeWrittenSpecs, !IO) :- module_info_get_globals(!.HLDS, Globals), - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), maybe_write_string(ProgressStream, Verbose, "% Mode-checking clauses...\n", !IO), globals.lookup_bool_option(Globals, benchmark_modes, BenchmarkModes), @@ -1149,16 +1180,18 @@ modecheck(ProgressStream, ErrorStream, Verbose, Stats, !HLDS, BenchmarkModes = no, modecheck_module(ProgressStream, !HLDS, SafeToContinue, ModeSpecs) ), - !:Specs = ModeSpecs ++ !.Specs, + add_to_be_written_specs(ModeSpecs, !MaybeWrittenSpecs), FoundModeError = contains_errors(Globals, ModeSpecs), ( FoundModeError = no, - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), maybe_write_string(ProgressStream, Verbose, "% Program is mode-correct.\n", !IO) ; FoundModeError = yes, - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), maybe_write_string(ProgressStream, Verbose, "% Program contains mode error(s).\n", !IO) ), @@ -1195,17 +1228,18 @@ do_io_benchmark(Pred, Repeats, A0, A - Time, !IO) :- :- pred maybe_compute_goal_modes(io.text_output_stream::in, io.text_output_stream::in, bool::in, bool::in, module_info::in, module_info::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. maybe_compute_goal_modes(ProgressStream, ErrorStream, Verbose, Stats, - !HLDS, !Specs, !IO) :- + !HLDS, !MaybeWrittenSpecs, !IO) :- module_info_get_globals(!.HLDS, Globals), globals.lookup_bool_option(Globals, compute_goal_modes, ComputeGoalModes), ( ComputeGoalModes = no ; ComputeGoalModes = yes, - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), maybe_write_string(ProgressStream, Verbose, "% Computing goal modes... ", !IO), compute_goal_modes_in_module(!HLDS), @@ -1242,15 +1276,16 @@ detect_cse(ProgressStream, Verbose, Stats, !HLDS, !IO) :- :- pred check_determinism(io.text_output_stream::in, io.text_output_stream::in, bool::in, bool::in, module_info::in, module_info::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. check_determinism(ProgressStream, ErrorStream, Verbose, Stats, - !HLDS, !Specs, !IO) :- + !HLDS, !MaybeWrittenSpecs, !IO) :- determinism_pass(ProgressStream, DetismSpecs, !HLDS), - !:Specs = DetismSpecs ++ !.Specs, + add_to_be_written_specs(DetismSpecs, !MaybeWrittenSpecs), module_info_get_globals(!.HLDS, Globals), FoundError = contains_errors(Globals, DetismSpecs), - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), ( FoundError = yes, maybe_write_string(ProgressStream, Verbose, @@ -1267,18 +1302,20 @@ check_determinism(ProgressStream, ErrorStream, Verbose, Stats, :- pred check_unique_modes(io.text_output_stream::in, io.text_output_stream::in, bool::in, bool::in, module_info::in, module_info::out, bool::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. check_unique_modes(ProgressStream, ErrorStream, Verbose, Stats, - !HLDS, FoundError, !Specs, !IO) :- + !HLDS, FoundError, !MaybeWrittenSpecs, !IO) :- module_info_get_globals(!.HLDS, Globals), - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), maybe_write_string(ProgressStream, Verbose, "% Checking for backtracking over unique modes...\n", !IO), unique_modes_check_module(ProgressStream, !HLDS, UniqueSpecs), - !:Specs = UniqueSpecs ++ !.Specs, + add_to_be_written_specs(UniqueSpecs, !MaybeWrittenSpecs), FoundError = contains_errors(Globals, UniqueSpecs), - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), ( FoundError = yes, maybe_write_string(ProgressStream, Verbose, @@ -1294,9 +1331,10 @@ check_unique_modes(ProgressStream, ErrorStream, Verbose, Stats, :- pred maybe_write_call_tree(io.text_output_stream::in, bool::in, bool::in, module_info::in, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. -maybe_write_call_tree(ProgressStream, Verbose, Stats, HLDS, !Specs, !IO) :- +maybe_write_call_tree(ProgressStream, Verbose, Stats, HLDS, + !MaybeWrittenSpecs, !IO) :- module_info_get_globals(HLDS, Globals), globals.lookup_bool_option(Globals, show_local_call_tree, ShowCallTree), globals.lookup_accumulating_option(Globals, show_pred_movability, @@ -1367,7 +1405,7 @@ maybe_write_call_tree(ProgressStream, Verbose, Stats, HLDS, !Specs, !IO) :- ShowMovability = [_ | _], hlds.hlds_call_tree.generate_movability_report(HLDS, CallTreeInfo, ShowMovability, MovabilitySpecs), - !:Specs = MovabilitySpecs ++ !.Specs + add_to_be_written_specs(MovabilitySpecs, !MaybeWrittenSpecs) ; ShowMovability = [] ), @@ -1381,10 +1419,10 @@ maybe_write_call_tree(ProgressStream, Verbose, Stats, HLDS, !Specs, !IO) :- :- pred check_stratification(io.text_output_stream::in, io.text_output_stream::in, bool::in, bool::in, module_info::in, module_info::out, bool::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. check_stratification(ProgressStream, ErrorStream, Verbose, Stats, - !HLDS, FoundError, !Specs, !IO) :- + !HLDS, FoundError, !MaybeWrittenSpecs, !IO) :- module_info_get_must_be_stratified_preds(!.HLDS, MustBeStratifiedPreds), module_info_get_globals(!.HLDS, Globals), globals.lookup_bool_option(Globals, warn_non_stratification, Warn), @@ -1393,13 +1431,15 @@ check_stratification(ProgressStream, ErrorStream, Verbose, Stats, ; Warn = yes ) then - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), maybe_write_string(ProgressStream, Verbose, "% Checking stratification...\n", !IO), check_module_for_stratification(!HLDS, StratifySpecs), - !:Specs = StratifySpecs ++ !.Specs, + add_to_be_written_specs(StratifySpecs, !MaybeWrittenSpecs), FoundError = contains_errors(Globals, StratifySpecs), - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), ( FoundError = yes, maybe_write_string(ProgressStream, Verbose, @@ -1418,10 +1458,10 @@ check_stratification(ProgressStream, ErrorStream, Verbose, Stats, :- pred check_oisu_pragmas(io.text_output_stream::in, io.text_output_stream::in, bool::in, bool::in, module_info::in, module_info::out, bool::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. check_oisu_pragmas(ProgressStream, ErrorStream, Verbose, Stats, - !HLDS, FoundError, !Specs, !IO) :- + !HLDS, FoundError, !MaybeWrittenSpecs, !IO) :- module_info_get_oisu_map(!.HLDS, OISUMap), map.to_assoc_list(OISUMap, OISUPairs), module_info_get_name(!.HLDS, ModuleName), @@ -1430,13 +1470,15 @@ check_oisu_pragmas(ProgressStream, ErrorStream, Verbose, Stats, ( ModuleOISUPairs = [_ | _], module_info_get_globals(!.HLDS, Globals), - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), maybe_write_string(ProgressStream, Verbose, "% Checking oisu pragmas...\n", !IO), check_oisu_pragmas_for_module(ModuleOISUPairs, !HLDS, OISUSpecs), - !:Specs = OISUSpecs ++ !.Specs, + add_to_be_written_specs(OISUSpecs, !MaybeWrittenSpecs), FoundError = contains_errors(Globals, OISUSpecs), - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), ( FoundError = yes, maybe_write_string(ProgressStream, Verbose, @@ -1463,18 +1505,20 @@ type_ctor_is_defined_in_this_module(ModuleName, TypeCtor - _) :- :- pred process_try_goals(io.text_output_stream::in, io.text_output_stream::in, bool::in, bool::in, module_info::in, module_info::out, bool::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. process_try_goals(ProgressStream, ErrorStream, Verbose, Stats, - !HLDS, FoundError, !Specs, !IO) :- + !HLDS, FoundError, !MaybeWrittenSpecs, !IO) :- module_info_get_globals(!.HLDS, Globals), - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), maybe_write_string(ProgressStream, Verbose, "% Transforming try goals...\n", !IO), expand_try_goals_in_module(ProgressStream, !HLDS, [], TryExpandSpecs), - !:Specs = TryExpandSpecs ++ !.Specs, + add_to_be_written_specs(TryExpandSpecs, !MaybeWrittenSpecs), FoundError = contains_errors(Globals, TryExpandSpecs), - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), ( FoundError = yes, maybe_write_string(ProgressStream, Verbose, @@ -1490,22 +1534,24 @@ process_try_goals(ProgressStream, ErrorStream, Verbose, Stats, :- pred check_pragma_format_call(io.text_output_stream::in, io.text_output_stream::in,bool::in, bool::in, module_info::in, module_info::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. check_pragma_format_call(ProgressStream, ErrorStream, Verbose, Stats, - !HLDS, !Specs, !IO) :- + !HLDS, !MaybeWrittenSpecs, !IO) :- module_info_get_format_call_pragma_preds(!.HLDS, FormatCallPredIds), ( if set.is_empty(FormatCallPredIds) then true else module_info_get_globals(!.HLDS, Globals), - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), maybe_write_string(ProgressStream, Verbose, "% Checking format_call pragmas...\n", !IO), check_pragma_format_call_preds(FormatCallPredIds, !HLDS, [], CheckSpecs), - !:Specs = CheckSpecs ++ !.Specs, - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + add_to_be_written_specs(CheckSpecs, !MaybeWrittenSpecs), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), maybe_write_string(ProgressStream, Verbose, "% done.\n", !IO), maybe_report_stats(ProgressStream, Stats, !IO) ). @@ -1513,7 +1559,7 @@ check_pragma_format_call(ProgressStream, ErrorStream, Verbose, Stats, %---------------------------------------------------------------------------% maybe_simplify(ProgressStream, MaybeErrorStream, Warn, SimplifyPass, - Verbose, Stats, !HLDS, !Specs, !IO) :- + Verbose, Stats, !HLDS, !MaybeWrittenSpecs, !IO) :- module_info_get_globals(!.HLDS, Globals), some [!SimpList] ( ( Warn = no, WarnGen = do_not_generate_warnings @@ -1595,7 +1641,8 @@ maybe_simplify(ProgressStream, MaybeErrorStream, Warn, SimplifyPass, SimpList = [_ | _], ( MaybeErrorStream = yes(ErrorStreamA), - maybe_write_out_errors(ErrorStreamA, Verbose, Globals, !Specs, !IO) + maybe_write_not_yet_written_specs(ErrorStreamA, Globals, Verbose, + !MaybeWrittenSpecs, !IO) ; MaybeErrorStream = no ), @@ -1610,9 +1657,9 @@ maybe_simplify(ProgressStream, MaybeErrorStream, Warn, SimplifyPass, SimplifyPass = simplify_pass_frontend, ( MaybeErrorStream = yes(ErrorStreamB), - !:Specs = SimplifySpecs ++ !.Specs, - maybe_write_out_errors(ErrorStreamB, Verbose, Globals, - !Specs, !IO) + add_to_be_written_specs(SimplifySpecs, !MaybeWrittenSpecs), + maybe_write_not_yet_written_specs(ErrorStreamB, + Globals, Verbose, !MaybeWrittenSpecs, !IO) ; MaybeErrorStream = no, expect(unify(SimplifySpecs, []), $pred, "SimplifySpecs != []") @@ -1650,12 +1697,12 @@ simplify_pred(ProgressStream, SimplifyTasks0, PredId, else SimplifyTasks = SimplifyTasks0 ), - ErrorSpecs0 = init_error_spec_accumulator, + PredSpecsAcc0 = init_error_spec_accumulator, simplify_pred_procs(ProgressStream, SimplifyTasks, PredId, ProcIds, - !PredInfo, !ModuleInfo, ErrorSpecs0, ErrorSpecs), + !PredInfo, !ModuleInfo, PredSpecsAcc0, PredSpecsAcc), + PredSpecs = error_spec_accumulator_to_list(PredSpecsAcc), + !:Specs = PredSpecs ++ !.Specs, module_info_get_globals(!.ModuleInfo, Globals), - SpecsList = error_spec_accumulator_to_list(ErrorSpecs), - !:Specs = SpecsList ++ !.Specs, globals.lookup_bool_option(Globals, detailed_statistics, Statistics), trace [io(!IO)] ( maybe_report_stats(ProgressStream, Statistics, !IO) @@ -1665,15 +1712,16 @@ simplify_pred(ProgressStream, SimplifyTasks0, PredId, :- pred maybe_generate_style_warnings(io.text_output_stream::in, io.text_output_stream::in, bool::in, bool::in, module_info::in, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. maybe_generate_style_warnings(ProgressStream, ErrorStream, Verbose, Stats, - HLDS, !Specs, !IO) :- + HLDS, !MaybeWrittenSpecs, !IO) :- module_info_get_globals(HLDS, Globals), - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), do_we_want_style_warnings(HLDS, DoWeWantStyleWarnings, OptSpecs), - !:Specs = OptSpecs ++ !.Specs, + add_to_be_written_specs(OptSpecs, !MaybeWrittenSpecs), ( DoWeWantStyleWarnings = do_not_want_style_warnings ; @@ -1681,7 +1729,7 @@ maybe_generate_style_warnings(ProgressStream, ErrorStream, Verbose, Stats, maybe_write_string(ProgressStream, Verbose, "% Generating style warnings...\n", !IO), generate_any_style_warnings(HLDS, WarningsWeWant, StyleSpecs), - !:Specs = StyleSpecs ++ !.Specs, + add_to_be_written_specs(StyleSpecs, !MaybeWrittenSpecs), maybe_write_string(ProgressStream, Verbose, "% done.\n", !IO), maybe_report_stats(ProgressStream, Stats, !IO) ). @@ -1690,12 +1738,13 @@ maybe_generate_style_warnings(ProgressStream, ErrorStream, Verbose, Stats, :- pred maybe_proc_statistics(io.text_output_stream::in, io.text_output_stream::in, bool::in, bool::in, string::in, module_info::in, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. maybe_proc_statistics(ProgressStream, ErrorStream, Verbose, Stats, Msg, - HLDS, !Specs, !IO) :- + HLDS, !MaybeWrittenSpecs, !IO) :- module_info_get_globals(HLDS, Globals), - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), globals.lookup_string_option(Globals, proc_size_statistics, StatsFileName), ( if StatsFileName = "" then @@ -1724,12 +1773,13 @@ maybe_proc_statistics(ProgressStream, ErrorStream, Verbose, Stats, Msg, :- pred maybe_inst_statistics(io.text_output_stream::in, io.text_output_stream::in, bool::in, bool::in, module_info::in, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. maybe_inst_statistics(ProgressStream, ErrorStream, Verbose, Stats, - HLDS, !Specs, !IO) :- + HLDS, !MaybeWrittenSpecs, !IO) :- module_info_get_globals(HLDS, Globals), - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), globals.lookup_string_option(Globals, inst_statistics, StatsFileName), ( if StatsFileName = "" then diff --git a/compiler/mercury_compile_llds_back_end.m b/compiler/mercury_compile_llds_back_end.m index 5b5a63ba5..1898f5413 100644 --- a/compiler/mercury_compile_llds_back_end.m +++ b/compiler/mercury_compile_llds_back_end.m @@ -28,6 +28,8 @@ :- import_module ll_backend.llds. :- import_module mdbcomp. :- import_module mdbcomp.sym_name. +:- import_module parse_tree. +:- import_module parse_tree.error_util. :- import_module bool. :- import_module io. @@ -36,7 +38,7 @@ :- pred hlds_to_llds(io.text_output_stream::in, io.text_output_stream::in, module_info::in, module_info::out, global_data::out, list(c_procedure)::out, dump_info::in, dump_info::out, - io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. :- pred map_args_to_regs(io.text_output_stream::in, bool::in, bool::in, module_info::in, module_info::out, io::di, io::uo) is det. @@ -98,9 +100,7 @@ :- import_module ll_backend.unify_gen_construct. :- import_module mdbcomp.prim_data. :- import_module mdbcomp.program_representation. -:- import_module parse_tree. :- import_module parse_tree.error_spec. -:- import_module parse_tree.error_util. :- import_module parse_tree.file_names. :- import_module parse_tree.prog_data. :- import_module parse_tree.prog_data_foreign. @@ -122,7 +122,7 @@ %---------------------------------------------------------------------------% hlds_to_llds(ProgressStream, ErrorStream, !HLDS, !:GlobalData, LLDS, - !DumpInfo, !IO) :- + !DumpInfo, !MaybeWrittenSpecs,!IO) :- module_info_get_name(!.HLDS, ModuleName), module_info_get_globals(!.HLDS, Globals), globals.lookup_bool_option(Globals, unboxed_float, OptUnboxFloat), @@ -164,24 +164,23 @@ hlds_to_llds(ProgressStream, ErrorStream, !HLDS, !:GlobalData, LLDS, ( TradPasses = no, llds_backend_pass_by_phases(ProgressStream, !HLDS, LLDS, !GlobalData, - [], Specs, !DumpInfo, !IO) + !DumpInfo, !MaybeWrittenSpecs, !IO) ; TradPasses = yes, llds_backend_pass_by_preds(ProgressStream, !HLDS, LLDS, !GlobalData, - [], Specs) + !MaybeWrittenSpecs) ), - write_error_specs(ErrorStream, Globals, Specs, !IO). + write_not_yet_written_specs(ErrorStream, Globals, !MaybeWrittenSpecs, !IO). %---------------------------------------------------------------------------% :- pred llds_backend_pass_by_phases(io.text_output_stream::in, module_info::in, module_info::out, list(c_procedure)::out, - global_data::in, global_data::out, - list(error_spec)::in, list(error_spec)::out, - dump_info::in, dump_info::out, io::di, io::uo) is det. + global_data::in, global_data::out, dump_info::in, dump_info::out, + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. -llds_backend_pass_by_phases(ProgressStream, !HLDS, !:LLDS, !GlobalData, !Specs, - !DumpInfo, !IO) :- +llds_backend_pass_by_phases(ProgressStream, !HLDS, !:LLDS, !GlobalData, + !DumpInfo, !MaybeWrittenSpecs, !IO) :- module_info_get_globals(!.HLDS, Globals), globals.lookup_bool_option(Globals, verbose, Verbose), globals.lookup_bool_option(Globals, statistics, Stats), @@ -198,7 +197,8 @@ llds_backend_pass_by_phases(ProgressStream, !HLDS, !:LLDS, !GlobalData, !Specs, maybe_dump_hlds(ProgressStream, !.HLDS, 320, "followcode", !DumpInfo, !IO), maybe_simplify(ProgressStream, maybe.no, bool.no, simplify_pass_ll_backend, - Verbose, Stats, !HLDS, [], SimplifySpecs, !IO), + Verbose, Stats, !HLDS, init_maybe_written_specs, SimplifyMWS, !IO), + SimplifySpecs = maybe_written_specs_to_specs(SimplifyMWS), expect(unify(contains_errors(Globals, SimplifySpecs), no), $pred, "simplify has errors"), maybe_dump_hlds(ProgressStream, !.HLDS, 325, "ll_backend_simplify", @@ -207,7 +207,8 @@ llds_backend_pass_by_phases(ProgressStream, !HLDS, !:LLDS, !GlobalData, !Specs, compute_liveness(ProgressStream, Verbose, Stats, !HLDS, !IO), maybe_dump_hlds(ProgressStream, !.HLDS, 330, "liveness", !DumpInfo, !IO), - mark_tail_rec_calls(ProgressStream, Verbose, Stats, !HLDS, !Specs, !IO), + mark_tail_rec_calls(ProgressStream, Verbose, Stats, !HLDS, + !MaybeWrittenSpecs, !IO), maybe_dump_hlds(ProgressStream, !.HLDS, 332, "mark_debug_tailrec_calls", !DumpInfo, !IO), @@ -230,7 +231,7 @@ llds_backend_pass_by_phases(ProgressStream, !HLDS, !:LLDS, !GlobalData, !Specs, :- pred llds_backend_pass_by_preds(io.text_output_stream::in, module_info::in, module_info::out, list(c_procedure)::out, global_data::in, global_data::out, - list(error_spec)::in, list(error_spec)::out) is det. + maybe_written_specs::in, maybe_written_specs::out) is det. llds_backend_pass_by_preds(ProgressStream, !HLDS, LLDS, !GlobalData, !Specs) :- module_info_get_valid_pred_ids(!.HLDS, PredIds), @@ -270,7 +271,7 @@ llds_backend_pass_by_preds(ProgressStream, !HLDS, LLDS, !GlobalData, !Specs) :- maybe(dup_proc_label_map)::in, cord(c_procedure)::in, cord(c_procedure)::out, global_data::in, global_data::out, - list(error_spec)::in, list(error_spec)::out) is det. + maybe_written_specs::in, maybe_written_specs::out) is det. llds_backend_pass_by_preds_loop_over_preds(_, !HLDS, _, _, [], _, !CProcsCord, !GlobalData, !Specs). @@ -290,7 +291,7 @@ llds_backend_pass_by_preds_loop_over_preds(ProgressStream, !HLDS, maybe(dup_proc_label_map)::in, maybe(dup_proc_label_map)::out, cord(c_procedure)::in, cord(c_procedure)::out, global_data::in, global_data::out, - list(error_spec)::in, list(error_spec)::out) is det. + maybe_written_specs::in, maybe_written_specs::out) is det. llds_backend_pass_by_preds_do_one_pred(ProgressStream, !HLDS, ConstStructMap, SCCMap, PredId, !MaybeDupProcMap, !CProcsCord, !GlobalData, !Specs) :- @@ -360,7 +361,7 @@ llds_backend_pass_by_preds_do_one_pred(ProgressStream, !HLDS, ConstStructMap, pred_info::in, list(proc_id)::in, assoc_list(mdbcomp.prim_data.proc_label, c_procedure)::out, global_data::in, global_data::out, module_info::in, module_info::out, - list(error_spec)::in, list(error_spec)::out) is det. + maybe_written_specs::in, maybe_written_specs::out) is det. llds_backend_pass_for_pred(_, _, _, _, _, [], [], !GlobalData, !HLDS, !Specs). llds_backend_pass_for_pred(ProgressStream, ConstStructMap, SCCMap, @@ -378,11 +379,11 @@ llds_backend_pass_for_pred(ProgressStream, ConstStructMap, SCCMap, const_struct_map::in, scc_map(pred_proc_id)::in, pred_id::in, proc_id::in, pred_info::in, proc_info::in, c_procedure::out, global_data::in, global_data::out, module_info::in, module_info::out, - list(error_spec)::in, list(error_spec)::out) is det. + maybe_written_specs::in, maybe_written_specs::out) is det. llds_backend_pass_for_proc(ProgressStream, ConstStructMap, SCCMap, PredId, ProcId, PredInfo, !.ProcInfo, CProc, - !GlobalData, !HLDS, !Specs) :- + !GlobalData, !HLDS, !MaybeWrittenSpecs) :- module_info_get_globals(!.HLDS, Globals), globals.get_opt_tuple(Globals, OptTuple), SavedVarsConst = OptTuple ^ ot_opt_saved_vars_const, @@ -449,7 +450,8 @@ llds_backend_pass_for_proc(ProgressStream, ConstStructMap, SCCMap, "Marking directly tail recursive calls in", PredProcId, !IO) ), mark_tail_rec_calls_in_proc_for_llds_code_gen(!.HLDS, PredId, ProcId, - PredInfo, SCCMap, !ProcInfo, !Specs), + PredInfo, SCCMap, !ProcInfo, [], TailSpecs), + add_to_be_written_specs(TailSpecs, !MaybeWrittenSpecs), trace [io(!IO)] ( maybe_write_proc_progress_message(ProgressStream, !.HLDS, @@ -581,9 +583,10 @@ compute_liveness(ProgressStream, Verbose, Stats, !HLDS, !IO) :- :- pred mark_tail_rec_calls(io.text_output_stream::in, bool::in, bool::in, module_info::in, module_info::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. -mark_tail_rec_calls(ProgressStream, Verbose, Stats, !HLDS, !Specs, !IO) :- +mark_tail_rec_calls(ProgressStream, Verbose, Stats, + !HLDS, !MaybeWrittenSpecs, !IO) :- maybe_write_string(ProgressStream, Verbose, "% Marking directly tail recursive calls...", !IO), maybe_flush_output(ProgressStream, Verbose, !IO), @@ -592,7 +595,8 @@ mark_tail_rec_calls(ProgressStream, Verbose, Stats, !HLDS, !Specs, !IO) :- process_valid_nonimported_preds_errors( update_pred_error( mark_tail_rec_calls_in_pred_for_llds_code_gen(SCCMap)), - !HLDS, !Specs), + !HLDS, [], TailSpecs), + add_to_be_written_specs(TailSpecs, !MaybeWrittenSpecs), maybe_write_string(ProgressStream, Verbose, " done.\n", !IO), maybe_report_stats(ProgressStream, Stats, !IO). diff --git a/compiler/mercury_compile_main.m b/compiler/mercury_compile_main.m index 0b3c8510c..3865d54a7 100644 --- a/compiler/mercury_compile_main.m +++ b/compiler/mercury_compile_main.m @@ -200,10 +200,11 @@ main_after_setup(ProgressStream, ErrorStream, Globals, ArgPack, !IO) :- else globals.get_op_mode(Globals, OpMode), HaveParseTreeMaps0 = init_have_parse_tree_maps, - Specs0 = [], do_op_mode(ProgressStream, ErrorStream, Globals, OpMode, ArgPack, - HaveParseTreeMaps0, _HaveParseTreeMaps, Specs0, Specs, !IO), - write_error_specs(ErrorStream, Globals, Specs, !IO) + HaveParseTreeMaps0, _HaveParseTreeMaps, + init_maybe_written_specs, MaybeWrittenSpecs, !IO), + write_not_yet_written_specs(ErrorStream, Globals, + MaybeWrittenSpecs, _, !IO) ). %---------------------------------------------------------------------------% @@ -211,10 +212,10 @@ main_after_setup(ProgressStream, ErrorStream, Globals, ArgPack, !IO) :- :- pred do_op_mode(io.text_output_stream::in, io.text_output_stream::in, globals::in, op_mode::in, compiler_arg_pack::in, have_parse_tree_maps::in, have_parse_tree_maps::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. do_op_mode(ProgressStream, ErrorStream, Globals, OpMode, ArgPack, - !HaveParseTreeMaps, !Specs, !IO) :- + !HaveParseTreeMaps, !MaybeWrittenSpecs, !IO) :- ( OpMode = opm_top_make, % make_process_compiler_args itself does not pay attention to the @@ -233,7 +234,7 @@ do_op_mode(ProgressStream, ErrorStream, Globals, OpMode, ArgPack, StandaloneIntBasename, !IO) ; OpMode = opm_top_query(OpModeQuery), - do_op_mode_query(ErrorStream, Globals, OpModeQuery, !IO) + do_op_mode_query(Globals, OpModeQuery, !MaybeWrittenSpecs, !IO) ; OpMode = opm_top_args(OpModeArgs, InvokedByMmcMake), globals.lookup_bool_option(Globals, filenames_from_stdin, @@ -248,7 +249,7 @@ do_op_mode(ProgressStream, ErrorStream, Globals, OpMode, ArgPack, else do_op_mode_args(ProgressStream, ErrorStream, Globals, OpModeArgs, InvokedByMmcMake, FileNamesFromStdin, ArgPack, - !HaveParseTreeMaps, !Specs, !IO) + !HaveParseTreeMaps, !MaybeWrittenSpecs, !IO) ) ). @@ -279,10 +280,10 @@ do_op_mode_standalone_interface(ProgressStream, ErrorStream, Globals, %---------------------------------------------------------------------------% -:- pred do_op_mode_query(io.text_output_stream::in, globals::in, - op_mode_query::in, io::di, io::uo) is det. +:- pred do_op_mode_query(globals::in, op_mode_query::in, + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. -do_op_mode_query(ErrorStream, Globals, OpModeQuery, !IO) :- +do_op_mode_query(Globals, OpModeQuery, !MaybeWrittenSpecs, !IO) :- io.stdout_stream(StdOutStream, !IO), ( OpModeQuery = opmq_output_cc, @@ -331,8 +332,9 @@ do_op_mode_query(ErrorStream, Globals, OpModeQuery, !IO) :- io.print_line(StdOutStream, LinkCommand, !IO) ; OpModeQuery = opmq_output_library_link_flags, - output_library_link_flags_for_c(Globals, StdOutStream, Specs, !IO), - write_error_specs(ErrorStream, Globals, Specs, !IO) + get_library_link_flags_for_c(Globals, Specs, LinkFlags, !IO), + io.write_string(StdOutStream, LinkFlags, !IO), + add_to_be_written_specs(Specs, !MaybeWrittenSpecs) ; OpModeQuery = opmq_output_grade_string, % When Mmake asks for the grade, it really wants the directory @@ -394,11 +396,11 @@ do_op_mode_query(ErrorStream, Globals, OpModeQuery, !IO) :- globals::in, op_mode_args::in, op_mode_invoked_by_mmc_make::in, bool::in, compiler_arg_pack::in, have_parse_tree_maps::in, have_parse_tree_maps::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. do_op_mode_args(ProgressStream, ErrorStream, Globals, OpModeArgs, InvokedByMmcMake, FileNamesFromStdin, ArgPack, - !HaveParseTreeMaps, !Specs, !IO) :- + !HaveParseTreeMaps, !MaybeWrittenSpecs, !IO) :- ArgPack = compiler_arg_pack(EnvOptFileVariables, EnvVarArgs, OptionArgs, Args), Params = compiler_params(EnvOptFileVariables, EnvVarArgs, @@ -416,7 +418,7 @@ do_op_mode_args(ProgressStream, ErrorStream, Globals, OpModeArgs, setup_and_process_compiler_stdin_args(ProgressStream, ErrorStream, StdIn, Globals, OpModeArgs, InvokedByMmcMake, Params, cord.empty, ModulesToLinkCord, cord.empty, ExtraObjFilesCord, - !HaveParseTreeMaps, !Specs, !IO) + !HaveParseTreeMaps, !MaybeWrittenSpecs, !IO) ; FileNamesFromStdin = no, ( @@ -424,20 +426,23 @@ do_op_mode_args(ProgressStream, ErrorStream, Globals, OpModeArgs, setup_and_process_compiler_cmd_line_args(ProgressStream, ErrorStream, Globals, OpModeArgs, InvokedByMmcMake, Params, Args, cord.empty, ModulesToLinkCord, - cord.empty, ExtraObjFilesCord, !HaveParseTreeMaps, !IO) + cord.empty, ExtraObjFilesCord, + !HaveParseTreeMaps, !MaybeWrittenSpecs, !IO) ; InvokedByMmcMake = op_mode_invoked_by_mmc_make, % `mmc --make' has already set up the options. do_process_compiler_cmd_line_args(ProgressStream, ErrorStream, Globals, OpModeArgs, InvokedByMmcMake, OptionArgs, Args, cord.empty, ModulesToLinkCord, - cord.empty, ExtraObjFilesCord, !HaveParseTreeMaps, !IO) + cord.empty, ExtraObjFilesCord, + !HaveParseTreeMaps, !MaybeWrittenSpecs, !IO) ) ), % Print all remaining module-specific error_specs, % as well as the ones generated just above. - write_error_specs(ErrorStream, Globals, !.Specs, !IO), + write_not_yet_written_specs(ErrorStream, Globals, + !MaybeWrittenSpecs, !IO), io.get_exit_status(ExitStatus, !IO), ( if OpModeArgs = opma_augment(opmau_front_and_middle( @@ -454,19 +459,18 @@ do_op_mode_args(ProgressStream, ErrorStream, Globals, OpModeArgs, FirstModule, ModulesToLink, ExtraObjFiles, !IO) else if all_args_end_in_dot_m(Args) = yes, - % XXX We should test not only !.Specs, but ALL the - % error_specs we have already printed *before* the call - % to write_error_specs above. - could_not_read_some_int_file(!.Specs) = yes + AllSpecsSoFar = + maybe_written_specs_to_specs(!.MaybeWrittenSpecs), + could_not_read_some_int_file(AllSpecsSoFar) = yes then % Should we add the condition that all words in Args % end with ".m"? Pieces = [words("You can invoke the Mercury compiler"), words("with a list of Mercury source files to compile")] ++ - color_as_incorrect([words("only")]) ++ - [words("if you have previously built"), - words("all the interface files they need, and,"), - words("if intermodule is enabled,"), + [words("only if you have")] ++ + color_as_incorrect([words("previously built"), + words("all the interface files they need,")]) ++ + [words("and, if intermodule optimization is enabled,"), words("all the optimization interface files they need."), words("Since arranging all this by hand is tedious,"), words("you should consider using either"), @@ -477,7 +481,7 @@ do_op_mode_args(ProgressStream, ErrorStream, Globals, OpModeArgs, % (b) we do not need them. Severity = severity_informational(warn_dodgy_simple_code), Spec = no_ctxt_spec($pred, Severity, phase_style, Pieces), - !:Specs = [Spec | !.Specs] + add_to_be_written_specs([Spec], !MaybeWrittenSpecs) else true ) @@ -488,12 +492,15 @@ do_op_mode_args(ProgressStream, ErrorStream, Globals, OpModeArgs, ; LibgradeCheckSpecs = [_ | _], % Print all remaining module-specific error_specs. - write_error_specs(ErrorStream, Globals, !.Specs, !IO), + write_not_yet_written_specs(ErrorStream, Globals, + !MaybeWrittenSpecs, !IO), maybe_print_delayed_error_messages(ErrorStream, Globals, !IO), % Print the error_specs from the library check, which are % not specific to any module. - write_error_specs(StdErr, Globals, LibgradeCheckSpecs, !IO) + add_to_be_written_specs(LibgradeCheckSpecs, !MaybeWrittenSpecs), + write_not_yet_written_specs(StdErr, Globals, + !MaybeWrittenSpecs, !IO) ), globals.lookup_bool_option(Globals, statistics, Statistics), @@ -610,11 +617,12 @@ generate_executable(ProgressStream, ErrorStream, Globals, InvokedByMmcMake, cord(module_name)::in, cord(module_name)::out, cord(string)::in, cord(string)::out, have_parse_tree_maps::in, have_parse_tree_maps::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. setup_and_process_compiler_stdin_args(ProgressStream, ErrorStream, StdIn, Globals, OpModeArgs, InvokedByMmcMake, Params, - !Modules, !ExtraObjFiles, !HaveParseTreeMaps, !Specs, !IO) :- + !Modules, !ExtraObjFiles, !HaveParseTreeMaps, + !MaybeWrittenSpecs, !IO) :- ( if cord.is_empty(!.Modules) then true else @@ -626,12 +634,14 @@ setup_and_process_compiler_stdin_args(ProgressStream, ErrorStream, StdIn, Arg = string.rstrip(Line), setup_and_process_compiler_arg(ProgressStream, ErrorStream, Globals, OpModeArgs, InvokedByMmcMake, Params, Arg, - ArgModules, ArgExtraObjFiles, !HaveParseTreeMaps, !IO), + ArgModules, ArgExtraObjFiles, !HaveParseTreeMaps, + !MaybeWrittenSpecs, !IO), cord.snoc_list(ArgModules, !Modules), cord.snoc_list(ArgExtraObjFiles, !ExtraObjFiles), setup_and_process_compiler_stdin_args(ProgressStream, ErrorStream, StdIn, Globals, OpModeArgs, InvokedByMmcMake, Params, - !Modules, !ExtraObjFiles, !HaveParseTreeMaps, !Specs, !IO) + !Modules, !ExtraObjFiles, !HaveParseTreeMaps, + !MaybeWrittenSpecs, !IO) ; LineResult = eof ; @@ -640,7 +650,7 @@ setup_and_process_compiler_stdin_args(ProgressStream, ErrorStream, StdIn, Pieces = [words("Error reading module name from standard input:"), words(Msg), suffix("."), nl], Spec = no_ctxt_spec($pred, severity_error, phase_read_files, Pieces), - !:Specs = [Spec | !.Specs] + add_to_be_written_specs([Spec], !MaybeWrittenSpecs) ). %---------------------% @@ -652,16 +662,19 @@ setup_and_process_compiler_stdin_args(ProgressStream, ErrorStream, StdIn, cord(module_name)::in, cord(module_name)::out, cord(string)::in, cord(string)::out, have_parse_tree_maps::in, have_parse_tree_maps::out, - io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. setup_and_process_compiler_cmd_line_args(_, _, _, _, _, _, [], - !Modules, !ExtraObjFiles, !HaveParseTreeMaps, !IO). + !Modules, !ExtraObjFiles, + !HaveParseTreeMaps, !MaybeWrittenSpecs, !IO). setup_and_process_compiler_cmd_line_args(ProgressStream, ErrorStream, Globals, OpModeArgs, InvokedByMmcMake, Params, [Arg | Args], - !Modules, !ExtraObjFiles, !HaveParseTreeMaps, !IO) :- + !Modules, !ExtraObjFiles, + !HaveParseTreeMaps, !MaybeWrittenSpecs, !IO) :- setup_and_process_compiler_arg(ProgressStream, ErrorStream, Globals, OpModeArgs, InvokedByMmcMake, Params, Arg, - ArgModules, ArgExtraObjFiles, !HaveParseTreeMaps, !IO), + ArgModules, ArgExtraObjFiles, !HaveParseTreeMaps, + !MaybeWrittenSpecs, !IO), ( Args = [] ; @@ -672,7 +685,8 @@ setup_and_process_compiler_cmd_line_args(ProgressStream, ErrorStream, cord.snoc_list(ArgExtraObjFiles, !ExtraObjFiles), setup_and_process_compiler_cmd_line_args(ProgressStream, ErrorStream, Globals, OpModeArgs, InvokedByMmcMake, Params, Args, - !Modules, !ExtraObjFiles, !HaveParseTreeMaps, !IO). + !Modules, !ExtraObjFiles, + !HaveParseTreeMaps, !MaybeWrittenSpecs, !IO). :- pred do_process_compiler_cmd_line_args(io.text_output_stream::in, io.text_output_stream::in, globals::in, op_mode_args::in, @@ -680,18 +694,21 @@ setup_and_process_compiler_cmd_line_args(ProgressStream, ErrorStream, cord(module_name)::in, cord(module_name)::out, cord(string)::in, cord(string)::out, have_parse_tree_maps::in, have_parse_tree_maps::out, - io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. do_process_compiler_cmd_line_args(_, _, _, _, _, _, [], - !ModulesToLink, !ExtraObjFiles, !HaveParseTreeMaps, !IO). + !ModulesToLink, !ExtraObjFiles, + !HaveParseTreeMaps, !MaybeWrittenSpecs, !IO). do_process_compiler_cmd_line_args(ProgressStream, ErrorStream, Globals, OpModeArgs, InvokedByMmcMake, OptionArgs, [Arg | Args], - !ModulesToLink, !ExtraObjFiles, !HaveParseTreeMaps, !IO) :- + !ModulesToLink, !ExtraObjFiles, + !HaveParseTreeMaps, !MaybeWrittenSpecs, !IO) :- % `mmc --make' has already set up the options. FileOrModule = string_to_file_or_module(Arg), do_process_compiler_arg(ProgressStream, ErrorStream, Globals, OpModeArgs, InvokedByMmcMake, OptionArgs, FileOrModule, - ArgModules, ArgExtraObjFiles, !HaveParseTreeMaps, !IO), + ArgModules, ArgExtraObjFiles, + !HaveParseTreeMaps, !MaybeWrittenSpecs, !IO), ( Args = [] ; @@ -702,7 +719,8 @@ do_process_compiler_cmd_line_args(ProgressStream, ErrorStream, Globals, cord.snoc_list(ArgExtraObjFiles, !ExtraObjFiles), do_process_compiler_cmd_line_args(ProgressStream, ErrorStream, Globals, OpModeArgs, InvokedByMmcMake, OptionArgs, Args, - !ModulesToLink, !ExtraObjFiles, !HaveParseTreeMaps, !IO). + !ModulesToLink, !ExtraObjFiles, + !HaveParseTreeMaps, !MaybeWrittenSpecs, !IO). %---------------------% @@ -724,11 +742,12 @@ do_process_compiler_cmd_line_args(ProgressStream, ErrorStream, Globals, compiler_params::in, string::in, list(module_name)::out, list(string)::out, have_parse_tree_maps::in, have_parse_tree_maps::out, - io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. setup_and_process_compiler_arg(ProgressStream, ErrorStream, Globals, OpModeArgs, InvokedByMmcMake, Params, Arg, - ModulesToLink, ExtraObjFiles, !HaveParseTreeMaps, !IO) :- + ModulesToLink, ExtraObjFiles, + !HaveParseTreeMaps, !MaybeWrittenSpecs, !IO) :- get_default_options(Globals, DefaultOptionTable), FileOrModule = string_to_file_or_module(Arg), ModuleName = file_or_module_to_module_name(FileOrModule), @@ -749,7 +768,8 @@ setup_and_process_compiler_arg(ProgressStream, ErrorStream, Globals, Params = compiler_params(_EnvOptFileVars, _EnvVarArgs, OptionArgs), do_process_compiler_arg(ProgressStream, ErrorStream, BuildGlobals, OpModeArgs, InvokedByMmcMake, OptionArgs, FileOrModule, - ModulesToLink, ExtraObjFiles, !HaveParseTreeMaps, !IO) + ModulesToLink, ExtraObjFiles, + !HaveParseTreeMaps, !MaybeWrittenSpecs, !IO) ). %---------------------% @@ -759,11 +779,12 @@ setup_and_process_compiler_arg(ProgressStream, ErrorStream, Globals, op_mode_args::in, op_mode_invoked_by_mmc_make::in, list(string)::in, file_or_module::in, list(module_name)::out, list(string)::out, have_parse_tree_maps::in, have_parse_tree_maps::out, - io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. do_process_compiler_arg(ProgressStream, ErrorStream, Globals0, OpModeArgs, InvokedByMmcMake, OptionArgs, FileOrModule, - ModulesToLink, ExtraObjFiles, !HaveParseTreeMaps, !IO) :- + ModulesToLink, ExtraObjFiles, + !HaveParseTreeMaps, !MaybeWrittenSpecs, !IO) :- % XXX ITEM_LIST There is an inconsistency between the various OpModeArgs % that construct a module_and_imports structure in how they do it. % @@ -793,6 +814,9 @@ do_process_compiler_arg(ProgressStream, ErrorStream, Globals0, % % XXX The predicates named in the above comment have been deleted, though % I (zs) think that the problem it describes probably still remains. + % + % For example, old module_and_import structures have been replaced + % by aug_compilation_units, which are quite different. % XXX Another, different problem is that % @@ -808,23 +832,23 @@ do_process_compiler_arg(ProgressStream, ErrorStream, Globals0, OpModeArgs = opma_generate_dependencies(MaybeMakeInts), generate_and_write_dep_file_gendep(ProgressStream, Globals0, FileOrModule, DepsMap, DepSpecs, !IO), + add_to_be_written_specs(DepSpecs, !MaybeWrittenSpecs), ( if MaybeMakeInts = do_make_ints, contains_errors(Globals0, DepSpecs) = no then deps_make_ints(ProgressStream, Globals0, DepsMap, - DepSpecs, Specs, !HaveParseTreeMaps, !IO) + !HaveParseTreeMaps, !MaybeWrittenSpecs, !IO) else - Specs = DepSpecs + true ), - SpecsList = [Specs], ModulesToLink = [], ExtraObjFiles = [] ; OpModeArgs = opma_generate_dependency_file, generate_and_write_d_file_gendep(ProgressStream, Globals0, FileOrModule, _DepsMap, DepSpecs, !IO), - SpecsList = [DepSpecs], + add_to_be_written_specs(DepSpecs, !MaybeWrittenSpecs), ModulesToLink = [], ExtraObjFiles = [] ; @@ -848,13 +872,14 @@ do_process_compiler_arg(ProgressStream, ErrorStream, Globals0, ) ), Specs = get_read_module_specs(Errors), - SpecsList = [Specs], + add_to_be_written_specs(Specs, !MaybeWrittenSpecs), ModulesToLink = [], ExtraObjFiles = [] ; OpModeArgs = opma_make_interface(InterfaceFile), do_process_compiler_arg_make_interface(ProgressStream, Globals0, - InterfaceFile, FileOrModule, SpecsList, !HaveParseTreeMaps, !IO), + InterfaceFile, FileOrModule, + !HaveParseTreeMaps, !MaybeWrittenSpecs, !IO), ModulesToLink = [], ExtraObjFiles = [] ; @@ -867,29 +892,43 @@ do_process_compiler_arg(ProgressStream, ErrorStream, Globals0, % all the necessary intermediate files are present and up-to-date. % % XXX What does the above comment have to do with the code here? - SpecsList = [], ModulesToLink = [], ExtraObjFiles = [] else read_augment_and_process_module(ProgressStream, ErrorStream, Globals, OpModeAugment, InvokedByMmcMake, OptionArgs, FileOrModule, WhatToRecompile, ModulesToLink, ExtraObjFiles, - Specs, !HaveParseTreeMaps, !IO), - SpecsList = [Specs] + ModuleMaybeWrittenSpecs0, !HaveParseTreeMaps, !IO), + write_not_yet_written_specs(ErrorStream, Globals, + ModuleMaybeWrittenSpecs0, ModuleMaybeWrittenSpecs, !IO), + union_maybe_written_specs(ModuleMaybeWrittenSpecs, + !MaybeWrittenSpecs) ) ), - list.foldl(write_error_specs(ErrorStream, Globals0), SpecsList, !IO), + write_not_yet_written_specs(ErrorStream, Globals0, + !MaybeWrittenSpecs, !IO), maybe_print_delayed_error_messages(ErrorStream, Globals0, !IO). +:- pred union_maybe_written_specs( + maybe_written_specs::in, maybe_written_specs::in, + maybe_written_specs::out) is det. + +union_maybe_written_specs(MaybeWrittenSpecsA, MaybeWrittenSpecsB, + MaybeWrittenSpecs) :- + MaybeWrittenSpecsA = maybe_written_specs(ToBeWrittenA, AlreadyWrittenA), + MaybeWrittenSpecsB = maybe_written_specs(ToBeWrittenB, AlreadyWrittenB), + ToBeWritten = ToBeWrittenA ++ ToBeWrittenB, + AlreadyWritten = AlreadyWrittenA ++ AlreadyWrittenB, + MaybeWrittenSpecs = maybe_written_specs(ToBeWritten, AlreadyWritten). + %---------------------% :- pred deps_make_ints(io.text_output_stream::in, globals::in, deps_map::in, - list(error_spec)::in, list(error_spec)::out, have_parse_tree_maps::in, have_parse_tree_maps::out, - io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. deps_make_ints(ProgressStream, Globals, DepsMap, - !Specs, !HaveParseTreeMaps, !IO) :- + !HaveParseTreeMaps, !MaybeWrittenSpecs, !IO) :- map.values(DepsMap, DepsList), list.map_foldl(gather_local_burdened_modules, DepsList, BurdenedModules, [], Ancestors), @@ -909,7 +948,7 @@ deps_make_ints(ProgressStream, Globals, DepsMap, BurdenedModules, _Succeededs3, SpecsList3, !HaveParseTreeMaps, !IO), list.condense(SpecsList3, Specs3), - !:Specs = Specs3 ++ !.Specs, + add_to_be_written_specs(Specs3, !MaybeWrittenSpecs), Errors3 = contains_errors(Globals, Specs3), ( Errors3 = yes @@ -953,7 +992,7 @@ deps_make_ints(ProgressStream, Globals, DepsMap, % with a successful exit status. list.condense(RawSpecsList0, RawSpecs0), handle_not_found_files(RawSpecs0, Specs0, Continue0), - !:Specs = Specs0 ++ !.Specs, + add_to_be_written_specs(Specs0, !MaybeWrittenSpecs), Errors0 = contains_errors(Globals, Specs0), ( if Errors0 = no, @@ -981,7 +1020,7 @@ deps_make_ints(ProgressStream, Globals, DepsMap, !HaveParseTreeMaps, !IO), list.condense(RawSpecsList12, RawSpecs12), handle_not_found_files(RawSpecs12, Specs12, _Continue12), - !:Specs = Specs12 ++ !.Specs + add_to_be_written_specs(Specs12, !MaybeWrittenSpecs) else true ) @@ -1053,12 +1092,12 @@ acc_not_found_files(Spec, !NotFoundFiles, !OtherSpecs) :- :- pred do_process_compiler_arg_make_interface(io.text_output_stream::in, globals::in, op_mode_interface_file::in, file_or_module::in, - list(list(error_spec))::out, have_parse_tree_maps::in, have_parse_tree_maps::out, - io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. do_process_compiler_arg_make_interface(ProgressStream, Globals0, - InterfaceFile, FileOrModule, SpecLists, !HaveParseTreeMaps, !IO) :- + InterfaceFile, FileOrModule, + !HaveParseTreeMaps, !MaybeWrittenSpecs, !IO) :- ( InterfaceFile = omif_int3, ReturnTimestamp = do_not_return_timestamp @@ -1080,23 +1119,25 @@ do_process_compiler_arg_make_interface(ProgressStream, Globals0, ( HaveReadSrc = have_not_read_module(_FileName, ReadErrors), ReadSpecs = get_read_module_specs(ReadErrors), - SpecLists = [ReadSpecs] + add_to_be_written_specs(ReadSpecs, !MaybeWrittenSpecs) ; HaveReadSrc = have_module(FileName, ParseTreeSrc, Source), have_parse_tree_source_get_maybe_timestamp_errors(Source, MaybeTimestamp, ReadErrors), ReadSpecs = get_read_module_specs(ReadErrors), ( if halt_at_module_error(Globals, ReadErrors) then - SpecLists = [ReadSpecs] + add_to_be_written_specs(ReadSpecs, !MaybeWrittenSpecs) else parse_tree_src_to_burdened_module_list(Globals, FileName, ReadErrors, MaybeTimestamp, ParseTreeSrc, SplitSpecs, BurdenedModules), % parse_tree_src_to_burdened_module_list includes in SplitSpecs % the errors it gets from ReadErrors. + % ZZZ ReadSplitSpecs0 = SplitSpecs, filter_interface_generation_specs(Globals, ReadSplitSpecs0, ReadSplitSpecs), + add_to_be_written_specs(ReadSplitSpecs, !MaybeWrittenSpecs), ( InterfaceFile = omif_int0, IsAncestor = @@ -1127,7 +1168,8 @@ do_process_compiler_arg_make_interface(ProgressStream, Globals0, BurdenedModules, _Succeededs, WriteSpecsList, !HaveParseTreeMaps, !IO) ), - SpecLists = [ReadSplitSpecs | WriteSpecsList] + list.foldl(add_to_be_written_specs, WriteSpecsList, + !MaybeWrittenSpecs) ) ). @@ -1190,14 +1232,15 @@ find_file_components_to_recompile(ProgressStream, Globals0, Globals, io.text_output_stream::in, globals::in, op_mode_augment::in, op_mode_invoked_by_mmc_make::in, list(string)::in, file_or_module::in, file_components_to_recompile::in, - list(module_name)::out, list(string)::out, list(error_spec)::out, + list(module_name)::out, list(string)::out, maybe_written_specs::out, have_parse_tree_maps::in, have_parse_tree_maps::out, io::di, io::uo) is det. read_augment_and_process_module(ProgressStream, ErrorStream, Globals0, OpModeAugment, InvokedByMmcMake, OptionArgs, FileOrModule, - MaybeWhatToRecompile, ModulesToLink, ExtraObjFiles, Specs, - !HaveParseTreeMaps, !IO) :- + MaybeWhatToRecompile, ModulesToLink, ExtraObjFiles, + !:MaybeWrittenSpecs, !HaveParseTreeMaps, !IO) :- + !:MaybeWrittenSpecs = init_maybe_written_specs, ( ( OpModeAugment = opmau_make_plain_opt ; OpModeAugment = opmau_make_trans_opt @@ -1219,6 +1262,7 @@ read_augment_and_process_module(ProgressStream, ErrorStream, Globals0, ( HaveReadSrc = have_not_read_module(_, Errors), Specs = get_read_module_specs(Errors), + add_to_be_written_specs(Specs, !MaybeWrittenSpecs), ModulesToLink = [], ExtraObjFiles = [] ; @@ -1227,6 +1271,7 @@ read_augment_and_process_module(ProgressStream, ErrorStream, Globals0, MaybeTimestamp, ReadModuleErrors), ( if halt_at_module_error(Globals, ReadModuleErrors) then Specs = get_read_module_specs(ReadModuleErrors), + add_to_be_written_specs(Specs, !MaybeWrittenSpecs), ModulesToLink = [], ExtraObjFiles = [] else @@ -1237,7 +1282,7 @@ read_augment_and_process_module(ProgressStream, ErrorStream, Globals0, Globals, OpModeAugment, InvokedByMmcMake, SourceFileName, MaybeTimestamp, ReadModuleErrors, ParseTreeSrc, MaybeWhatToRecompile, ModulesToLink, ExtraObjFiles, - Specs, !HaveParseTreeMaps, !IO) + !HaveParseTreeMaps, !MaybeWrittenSpecs, !IO) ) ). diff --git a/compiler/mercury_compile_make_hlds.m b/compiler/mercury_compile_make_hlds.m index 15a03a431..2984a8996 100644 --- a/compiler/mercury_compile_make_hlds.m +++ b/compiler/mercury_compile_make_hlds.m @@ -16,25 +16,22 @@ :- module top_level.mercury_compile_make_hlds. :- interface. -:- import_module libs. -:- import_module libs.globals. - :- import_module hlds. :- import_module hlds.hlds_module. :- import_module hlds.make_hlds. - :- import_module hlds.make_hlds.qual_info. :- import_module hlds.passes_aux. +:- import_module libs. +:- import_module libs.globals. :- import_module libs.op_mode. :- import_module parse_tree. -:- import_module parse_tree.error_spec. +:- import_module parse_tree.error_util. :- import_module parse_tree.module_baggage. :- import_module parse_tree.prog_parse_tree. :- import_module parse_tree.read_modules. :- import_module bool. :- import_module io. -:- import_module list. :- import_module maybe. :- pred make_hlds_pass(io.text_output_stream::in, io.text_output_stream::in, @@ -42,9 +39,9 @@ module_baggage::in, aug_compilation_unit::in, module_info::out, qual_info::out, maybe(module_timestamp_map)::out, bool::out, bool::out, bool::out, - dump_info::in, dump_info::out, list(error_spec)::in, list(error_spec)::out, + dump_info::in, dump_info::out, have_parse_tree_maps::in, have_parse_tree_maps::out, - io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. %---------------------------------------------------------------------------% %---------------------------------------------------------------------------% @@ -62,7 +59,7 @@ :- import_module mdbcomp.sym_name. :- import_module parse_tree.build_eqv_maps. :- import_module parse_tree.equiv_type_parse_tree. -:- import_module parse_tree.error_util. +:- import_module parse_tree.error_spec. :- import_module parse_tree.file_names. :- import_module parse_tree.generate_mmakefile_fragments. :- import_module parse_tree.grab_modules. @@ -80,6 +77,7 @@ :- import_module char. :- import_module library. +:- import_module list. :- import_module map. :- import_module set. :- import_module set_tree234. @@ -96,11 +94,13 @@ make_hlds_pass(ProgressStream, ErrorStream, Globals, OpModeAugment, InvokedByMMCMake, Baggage0, AugCompUnit0, HLDS0, QualInfo, MaybeTimestampMap, UndefTypes, UndefModes, - PreHLDSErrors, !DumpInfo, !Specs, !HaveReadModuleMaps, !IO) :- + PreHLDSErrors, !DumpInfo, + !HaveReadModuleMaps, !MaybeWrittenSpecs, !IO) :- globals.lookup_bool_option(Globals, statistics, Stats), globals.lookup_bool_option(Globals, verbose, Verbose), ParseTreeModuleSrc = AugCompUnit0 ^ acu_module_src, - maybe_warn_about_stdlib_shadowing(Globals, ParseTreeModuleSrc, !Specs), + maybe_warn_about_stdlib_shadowing(Globals, ParseTreeModuleSrc, + !MaybeWrittenSpecs), ModuleName = ParseTreeModuleSrc ^ ptms_module_name, ( @@ -162,19 +162,21 @@ make_hlds_pass(ProgressStream, ErrorStream, Globals, IntermodError = no ; OptBlockingSpecs = [_ | _], - !:Specs = OptBlockingSpecs ++ !.Specs, + add_to_be_written_specs(OptBlockingSpecs, !MaybeWrittenSpecs), IntermodError = yes ), MaybeTimestampMap = Baggage1 ^ mb_maybe_timestamp_map, - !:Specs = get_read_module_specs(Baggage1 ^ mb_errors) ++ !.Specs, + BaggageSpecs = get_read_module_specs(Baggage1 ^ mb_errors), + add_to_be_written_specs(BaggageSpecs, !MaybeWrittenSpecs), globals.lookup_string_option(Globals, event_set_file_name, EventSetFileName), maybe_read_event_set(Globals, EventSetFileName, EventSetName, - EventSpecMap0, EventSetErrors, !Specs, !IO), + EventSpecMap0, EventSetErrors, !MaybeWrittenSpecs, !IO), - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), maybe_write_string(ProgressStream, Verbose, "% Module qualifying items...\n", !IO), maybe_flush_output(ProgressStream, Verbose, !IO), @@ -182,8 +184,9 @@ make_hlds_pass(ProgressStream, ErrorStream, Globals, EventSpecMap0, EventSpecMap1, EventSetFileName, MQInfo0, UnusedImports, MQUndefTypes, MQUndefInsts, MQUndefModes, MQUndefTypeClasses, [], QualifySpecs), - !:Specs = QualifySpecs ++ !.Specs, - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + add_to_be_written_specs(QualifySpecs, !MaybeWrittenSpecs), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), maybe_write_string(ProgressStream, Verbose, "% done.\n", !IO), maybe_report_stats(ProgressStream, Stats, !IO), @@ -195,8 +198,9 @@ make_hlds_pass(ProgressStream, ErrorStream, Globals, EventSpecMap1, EventSpecMap, TypeEqvMap, UsedEqvModules, RecompInfo0, RecompInfo, ExpandSpecs), ExpandErrors = contains_errors(Globals, ExpandSpecs), - !:Specs = ExpandSpecs ++ !.Specs, - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + add_to_be_written_specs(ExpandSpecs, !MaybeWrittenSpecs), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), maybe_write_string(ProgressStream, Verbose, "% done.\n", !IO), maybe_report_stats(ProgressStream, Stats, !IO), mq_info_set_recompilation_info(RecompInfo, MQInfo0, MQInfo), @@ -206,7 +210,7 @@ make_hlds_pass(ProgressStream, ErrorStream, Globals, MQInfo, TypeEqvMap, UsedEqvModules, UnusedImports, Verbose, Stats, HLDS0, QualInfo, MakeHLDSFoundInvalidType, MakeHLDSFoundInvalidInstOrMode, - FoundSemanticError, !Specs, !IO), + FoundSemanticError, !MaybeWrittenSpecs, !IO), bool.or(FoundSemanticError, IntermodError, PreHLDSErrors), maybe_write_definitions(ProgressStream, Verbose, Stats, HLDS0, !IO), @@ -273,9 +277,10 @@ make_hlds_pass(ProgressStream, ErrorStream, Globals, :- pred maybe_warn_about_stdlib_shadowing(globals::in, parse_tree_module_src::in, - list(error_spec)::in, list(error_spec)::out) is det. + maybe_written_specs::in, maybe_written_specs::out) is det. -maybe_warn_about_stdlib_shadowing(Globals, ParseTreeModuleSrc, !Specs) :- +maybe_warn_about_stdlib_shadowing(Globals, ParseTreeModuleSrc, + !MaybeWrittenSpecs) :- globals.lookup_bool_option(Globals, warn_stdlib_shadowing, WarnShadowing), ( WarnShadowing = no @@ -298,7 +303,7 @@ maybe_warn_about_stdlib_shadowing(Globals, ParseTreeModuleSrc, !Specs) :- Context = ParseTreeModuleSrc ^ ptms_module_name_context, Severity = severity_warning(warn_stdlib_shadowing), Spec = spec($pred, Severity, phase_read_files, Context, Pieces), - !:Specs = [Spec | !.Specs] + add_to_be_written_specs([Spec], !MaybeWrittenSpecs) else if GetStdlibModules = ( pred(LibModuleName::out) is multi :- @@ -336,7 +341,7 @@ maybe_warn_about_stdlib_shadowing(Globals, ParseTreeModuleSrc, !Specs) :- Context = ParseTreeModuleSrc ^ ptms_module_name_context, Severity = severity_warning(warn_stdlib_shadowing), Spec = spec($pred, Severity, phase_read_files, Context, Pieces), - !:Specs = [Spec | !.Specs] + add_to_be_written_specs([Spec], !MaybeWrittenSpecs) else true ) @@ -361,10 +366,10 @@ maybe_mention_undoc(DocUndoc, Pieces0, Pieces) :- :- pred maybe_read_event_set(globals::in, string::in, string::out, event_spec_map::out, bool::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. maybe_read_event_set(Globals, EventSetFileName, EventSetName, EventSpecMap, - Errors, !Specs, !IO) :- + Errors, !MaybeWrittenSpecs, !IO) :- ( if EventSetFileName = "" then EventSetName = "", EventSpecMap = map.init, @@ -372,7 +377,7 @@ maybe_read_event_set(Globals, EventSetFileName, EventSetName, EventSpecMap, else read_event_set(EventSetFileName, EventSetName0, EventSpecMap0, EventSetSpecs, !IO), - !:Specs = EventSetSpecs ++ !.Specs, + add_to_be_written_specs(EventSetSpecs, !MaybeWrittenSpecs), Errors = contains_errors(Globals, EventSetSpecs), ( Errors = no, @@ -616,13 +621,14 @@ maybe_grab_plain_and_trans_opt_files(ProgressStream, ErrorStream, Globals, type_eqv_map::in, used_eqv_modules::in, set_tree234(module_name)::in, bool::in, bool::in, module_info::out, qual_info::out, found_invalid_type::out, found_invalid_inst_or_mode::out, bool::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. make_hlds(ProgressStream, ErrorStream, Globals, AugCompUnit, EventSet, MQInfo, TypeEqvMap, UsedEqvModules, UnusedImports, Verbose, Stats, !:HLDS, QualInfo, FoundInvalidType, FoundInvalidInstOrMode, - FoundSemanticError, !Specs, !IO) :- - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + FoundSemanticError, !MaybeWrittenSpecs, !IO) :- + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), maybe_write_string(ProgressStream, Verbose, "% Converting parse tree to hlds...\n", !IO), ParseTreeModuleSrc = AugCompUnit ^ acu_module_src, @@ -632,10 +638,11 @@ make_hlds(ProgressStream, ErrorStream, Globals, AugCompUnit, EventSet, MQInfo, parse_tree_to_hlds(ProgressStream, AugCompUnit, Globals, DumpBaseFileName, MQInfo, TypeEqvMap, UsedEqvModules, UnusedImports, QualInfo, FoundInvalidType, FoundInvalidInstOrMode, !:HLDS, MakeSpecs), - !:Specs = MakeSpecs ++ !.Specs, + add_to_be_written_specs(MakeSpecs, !MaybeWrittenSpecs), module_info_set_event_set(EventSet, !HLDS), io.get_exit_status(Status, !IO), - SpecsErrors = contains_errors(Globals, !.Specs), + SpecsSoFar = maybe_written_specs_to_specs(!.MaybeWrittenSpecs), + SpecsErrors = contains_errors(Globals, SpecsSoFar), ( if ( Status \= 0 ; SpecsErrors = yes @@ -646,7 +653,8 @@ make_hlds(ProgressStream, ErrorStream, Globals, AugCompUnit, EventSet, MQInfo, else FoundSemanticError = no ), - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), maybe_write_string(ProgressStream, Verbose, "% done.\n", !IO), maybe_report_stats(ProgressStream, Stats, !IO). diff --git a/compiler/mercury_compile_middle_passes.m b/compiler/mercury_compile_middle_passes.m index fc7340563..c1674dd39 100644 --- a/compiler/mercury_compile_middle_passes.m +++ b/compiler/mercury_compile_middle_passes.m @@ -22,29 +22,28 @@ :- import_module libs. :- import_module libs.op_mode. :- import_module parse_tree. -:- import_module parse_tree.error_spec. +:- import_module parse_tree.error_util. :- import_module parse_tree.prog_item. :- import_module io. -:- import_module list. :- import_module set. :- pred middle_pass(io.text_output_stream::in, io.text_output_stream::in, op_mode_front_and_middle::in, module_info::in, module_info::out, dump_info::in, dump_info::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. :- pred middle_pass_for_opt_file(io.text_output_stream::in, module_info::in, module_info::out, set(gen_pragma_unused_args_info)::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. :- pred output_trans_opt_file(io.text_output_stream::in, module_info::in, - list(error_spec)::in, list(error_spec)::out, - dump_info::in, dump_info::out, io::di, io::uo) is det. + dump_info::in, dump_info::out, + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. :- pred output_analysis_file(io.text_output_stream::in, module_info::in, - list(error_spec)::in, list(error_spec)::out, - dump_info::in, dump_info::out, io::di, io::uo) is det. + dump_info::in, dump_info::out, + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. %---------------------------------------------------------------------------% %---------------------------------------------------------------------------% @@ -63,6 +62,7 @@ :- import_module libs.options. :- import_module ll_backend. :- import_module ll_backend.deep_profiling. +:- import_module parse_tree.error_spec. :- import_module parse_tree.file_names. :- import_module parse_tree.module_cmds. :- import_module parse_tree.parse_tree_out. @@ -119,6 +119,7 @@ :- import_module bool. :- import_module int. +:- import_module list. :- import_module map. :- import_module maybe. :- import_module pair. @@ -262,7 +263,7 @@ middle_pass(ProgressStream, ErrorStream, OpModeFrontAndMiddle, maybe_simplify(ProgressStream, maybe.no, bool.no, simplify_pass_pre_implicit_parallelism, Verbose, Stats, - !HLDS, [], _SimplifySpecsPreImpPar, !IO), + !HLDS, init_maybe_written_specs, _SimplifySpecsPreImpPar, !IO), maybe_dump_hlds(ProgressStream, !.HLDS, 172, "pre_implicit_parallelism_simplify", !DumpInfo, !IO), @@ -334,7 +335,7 @@ middle_pass(ProgressStream, ErrorStream, OpModeFrontAndMiddle, % have been applied. maybe_simplify(ProgressStream, maybe.no, bool.no, simplify_pass_pre_prof_transforms, Verbose, Stats, !HLDS, - [], _SimplifySpecsPreProf, !IO), + init_maybe_written_specs, _SimplifySpecsPreProf, !IO), maybe_dump_hlds(ProgressStream, !.HLDS, 215, "pre_prof_transforms_simplify", !DumpInfo, !IO), @@ -376,7 +377,7 @@ middle_pass(ProgressStream, ErrorStream, OpModeFrontAndMiddle, %---------------------------------------------------------------------------% middle_pass_for_opt_file(ProgressStream, !HLDS, PragmaUnusedArgsInfos, - !Specs, !IO) :- + !MaybeWrittenSpecs, !IO) :- % NOTE If you add any passes here, you will probably need to change the % code in mercury_compile_front_end.m that decides whether to call % this predicate. @@ -405,9 +406,11 @@ middle_pass_for_opt_file(ProgressStream, !HLDS, PragmaUnusedArgsInfos, maybe_exception_analysis(ProgressStream, Verbose, Stats, !HLDS, !IO), maybe_unused_args(ProgressStream, Verbose, Stats, do_gather_pragma_unused_args, do_not_record_analysis_unused_args, - PragmaUnusedArgsInfos, !HLDS, !Specs, !IO), - maybe_termination(ProgressStream, Verbose, Stats, !HLDS, !Specs, !IO), - maybe_termination2(ProgressStream, Verbose, Stats, !HLDS, !Specs, !IO), + PragmaUnusedArgsInfos, !HLDS, !MaybeWrittenSpecs, !IO), + maybe_termination(ProgressStream, Verbose, Stats, + !HLDS, !MaybeWrittenSpecs, !IO), + maybe_termination2(ProgressStream, Verbose, Stats, + !HLDS, !MaybeWrittenSpecs, !IO), maybe_structure_sharing_analysis(ProgressStream, Verbose, Stats, !HLDS, !IO), maybe_structure_reuse_analysis(ProgressStream, Verbose, Stats, !HLDS, !IO), @@ -416,7 +419,8 @@ middle_pass_for_opt_file(ProgressStream, !HLDS, PragmaUnusedArgsInfos, %---------------------------------------------------------------------------% -output_trans_opt_file(ProgressStream, !.HLDS, !Specs, !DumpInfo, !IO) :- +output_trans_opt_file(ProgressStream, !.HLDS, !DumpInfo, + !MaybeWrittenSpecs, !IO) :- module_info_get_globals(!.HLDS, Globals), globals.lookup_bool_option(Globals, verbose, Verbose), globals.lookup_bool_option(Globals, statistics, Stats), @@ -442,10 +446,12 @@ output_trans_opt_file(ProgressStream, !.HLDS, !Specs, !DumpInfo, !IO) :- maybe_exception_analysis(ProgressStream, Verbose, Stats, !HLDS, !IO), maybe_dump_hlds(ProgressStream, !.HLDS, 118, "exception_analysis", !DumpInfo, !IO), - maybe_termination(ProgressStream, Verbose, Stats, !HLDS, !Specs, !IO), + maybe_termination(ProgressStream, Verbose, Stats, + !HLDS, !MaybeWrittenSpecs, !IO), maybe_dump_hlds(ProgressStream, !.HLDS, 120, "termination", !DumpInfo, !IO), - maybe_termination2(ProgressStream, Verbose, Stats, !HLDS, !Specs, !IO), + maybe_termination2(ProgressStream, Verbose, Stats, + !HLDS, !MaybeWrittenSpecs, !IO), maybe_dump_hlds(ProgressStream, !.HLDS, 121, "termination_2", !DumpInfo, !IO), ( @@ -564,7 +570,8 @@ output_trans_opt_file(ProgressStream, !.HLDS, !Specs, !DumpInfo, !IO) :- %---------------------------------------------------------------------------% -output_analysis_file(ProgressStream, !.HLDS, !Specs, !DumpInfo, !IO) :- +output_analysis_file(ProgressStream, !.HLDS, !DumpInfo, + !MaybeWrittenSpecs, !IO) :- module_info_get_globals(!.HLDS, Globals), globals.lookup_bool_option(Globals, verbose, Verbose), globals.lookup_bool_option(Globals, statistics, Stats), @@ -590,10 +597,12 @@ output_analysis_file(ProgressStream, !.HLDS, !Specs, !DumpInfo, !IO) :- maybe_exception_analysis(ProgressStream, Verbose, Stats, !HLDS, !IO), maybe_dump_hlds(ProgressStream, !.HLDS, 118, "exception_analysis", !DumpInfo, !IO), - maybe_termination(ProgressStream, Verbose, Stats, !HLDS, !Specs, !IO), + maybe_termination(ProgressStream, Verbose, Stats, + !HLDS, !MaybeWrittenSpecs, !IO), maybe_dump_hlds(ProgressStream, !.HLDS, 120, "termination", !DumpInfo, !IO), - maybe_termination2(ProgressStream, Verbose, Stats, !HLDS, !Specs, !IO), + maybe_termination2(ProgressStream, Verbose, Stats, + !HLDS, !MaybeWrittenSpecs, !IO), maybe_dump_hlds(ProgressStream, !.HLDS, 121, "termination_2", !DumpInfo, !IO), ( @@ -625,7 +634,7 @@ output_analysis_file(ProgressStream, !.HLDS, !Specs, !DumpInfo, !IO) :- !DumpInfo, !IO), maybe_unused_args(ProgressStream, Verbose, Stats, do_not_gather_pragma_unused_args, do_record_analysis_unused_args, - _PragmaUnusedArgsInfos, !HLDS, !Specs, !IO), + _PragmaUnusedArgsInfos, !HLDS, !MaybeWrittenSpecs, !IO), maybe_dump_hlds(ProgressStream, !.HLDS, 165, "unused_args", !DumpInfo, !IO), maybe_analyse_trail_usage(ProgressStream, Verbose, Stats, !HLDS, !IO), @@ -640,7 +649,7 @@ output_analysis_file(ProgressStream, !.HLDS, !Specs, !DumpInfo, !IO) :- % XXX Is AllAvailModules the right set of modules to pass here? analysis.operations.write_analysis_files(ProgressStream, mmc, !.HLDS, AllAvailModules, AnalysisInfo, AnalysisSpecs, !IO), - !:Specs = AnalysisSpecs ++ !.Specs. + add_to_be_written_specs(AnalysisSpecs, !MaybeWrittenSpecs). %---------------------------------------------------------------------------% %---------------------------------------------------------------------------% @@ -690,13 +699,14 @@ maybe_read_experimental_complexity_file(ErrorStream, !HLDS, !IO) :- :- pred tabling(io.text_output_stream::in, bool::in, bool::in, module_info::in, module_info::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. -tabling(ProgressStream, Verbose, Stats, !HLDS, !Specs, !IO) :- +tabling(ProgressStream, Verbose, Stats, !HLDS, !MaybeWrittenSpecs, !IO) :- maybe_write_string(ProgressStream, Verbose, "% Transforming tabled predicates...", !IO), maybe_flush_output(ProgressStream, Verbose, !IO), - table_gen_process_module(!HLDS, !Specs), + table_gen_process_module(!HLDS, [], TableSpecs), + add_to_be_written_specs(TableSpecs, !MaybeWrittenSpecs), maybe_write_string(ProgressStream, Verbose, " done.\n", !IO), maybe_report_stats(ProgressStream, Stats, !IO). @@ -717,10 +727,10 @@ expand_lambdas(ProgressStream, Verbose, Stats, !HLDS, !IO) :- :- pred maybe_do_direct_arg_in_out_transform(io.text_output_stream::in, bool::in, bool::in, module_info::in, module_info::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. maybe_do_direct_arg_in_out_transform(ProgressStream, Verbose, Stats, - !HLDS, !Specs, !IO) :- + !HLDS, !MaybeWrittenSpecs, !IO) :- module_info_get_direct_arg_proc_map(!.HLDS, DirectArgProcMap), ( if map.is_empty(DirectArgProcMap) then true @@ -729,7 +739,7 @@ maybe_do_direct_arg_in_out_transform(ProgressStream, Verbose, Stats, "% Transforming direct arg in out procedures...\n", !IO), do_direct_arg_in_out_transform_in_module(ProgressStream, DirectArgProcMap, !HLDS, DirectArgSpecs), - !:Specs = DirectArgSpecs ++ !.Specs, + add_to_be_written_specs(DirectArgSpecs, !MaybeWrittenSpecs), maybe_write_string(ProgressStream, Verbose, "% done.\n", !IO), maybe_report_stats(ProgressStream, Stats, !IO) ). @@ -802,9 +812,10 @@ maybe_exception_analysis(ProgressStream, Verbose, Stats, !HLDS, !IO) :- :- pred maybe_termination(io.text_output_stream::in, bool::in, bool::in, module_info::in, module_info::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. -maybe_termination(ProgressStream, Verbose, Stats, !HLDS, !Specs, !IO) :- +maybe_termination(ProgressStream, Verbose, Stats, !HLDS, + !MaybeWrittenSpecs, !IO) :- module_info_get_globals(!.HLDS, Globals), globals.lookup_bool_option(Globals, termination_enable, Termination), ( @@ -812,7 +823,7 @@ maybe_termination(ProgressStream, Verbose, Stats, !HLDS, !Specs, !IO) :- maybe_write_string(ProgressStream, Verbose, "% Detecting termination...\n", !IO), analyse_termination_in_module(!HLDS, TermSpecs), - !:Specs = TermSpecs ++ !.Specs, + add_to_be_written_specs(TermSpecs, !MaybeWrittenSpecs), maybe_write_string(ProgressStream, Verbose, "% Termination checking done.\n", !IO), maybe_report_stats(ProgressStream, Stats, !IO) @@ -824,9 +835,10 @@ maybe_termination(ProgressStream, Verbose, Stats, !HLDS, !Specs, !IO) :- :- pred maybe_termination2(io.text_output_stream::in, bool::in, bool::in, module_info::in, module_info::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. -maybe_termination2(ProgressStream, Verbose, Stats, !HLDS, !Specs, !IO) :- +maybe_termination2(ProgressStream, Verbose, Stats, !HLDS, + !MaybeWrittenSpecs, !IO) :- module_info_get_globals(!.HLDS, Globals), globals.lookup_bool_option(Globals, termination2_enable, Termination2), ( @@ -834,7 +846,7 @@ maybe_termination2(ProgressStream, Verbose, Stats, !HLDS, !Specs, !IO) :- maybe_write_string(ProgressStream, Verbose, "% Detecting termination 2...\n", !IO), term2_analyse_module(!HLDS, TermSpecs), - !:Specs = TermSpecs ++ !.Specs, + add_to_be_written_specs(TermSpecs, !MaybeWrittenSpecs), maybe_write_string(ProgressStream, Verbose, "% Termination 2 checking done.\n", !IO), maybe_report_stats(ProgressStream, Stats, !IO) @@ -865,10 +877,11 @@ maybe_type_ctor_infos(ProgressStream, Verbose, Stats, !HLDS, !IO) :- %---------------------------------------------------------------------------% :- pred maybe_warn_dead_procs(io.text_output_stream::in, bool::in, bool::in, - module_info::in, list(error_spec)::in, list(error_spec)::out, + module_info::in, maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. -maybe_warn_dead_procs(ProgressStream, Verbose, Stats, HLDS, !Specs, !IO) :- +maybe_warn_dead_procs(ProgressStream, Verbose, Stats, HLDS, + !MaybeWrittenSpecs, !IO) :- module_info_get_globals(HLDS, Globals), globals.lookup_bool_option(Globals, warn_dead_procs, WarnDeadProcs), globals.lookup_bool_option(Globals, warn_dead_preds, WarnDeadPreds), @@ -888,7 +901,7 @@ maybe_warn_dead_procs(ProgressStream, Verbose, Stats, HLDS, !Specs, !IO) :- ), maybe_flush_output(ProgressStream, Verbose, !IO), dead_proc_warn(HLDS, DeadSpecs), - !:Specs = DeadSpecs ++ !.Specs, + add_to_be_written_specs(DeadSpecs, !MaybeWrittenSpecs), maybe_write_string(ProgressStream, Verbose, "% done.\n", !IO), maybe_report_stats(ProgressStream, Stats, !IO) else @@ -912,7 +925,7 @@ maybe_untuple_arguments(ProgressStream, Verbose, Stats, !HLDS, !IO) :- maybe_write_string(ProgressStream, Verbose, "% done.\n", !IO), maybe_simplify(ProgressStream, maybe.no, bool.no, simplify_pass_post_untuple, Verbose, Stats, !HLDS, - [], _SimplifySpecs, !IO), + init_maybe_written_specs, _SimplifyMaybeWrittenSpecs, !IO), maybe_report_stats(ProgressStream, Stats, !IO) ; Untuple = do_not_untuple @@ -922,9 +935,10 @@ maybe_untuple_arguments(ProgressStream, Verbose, Stats, !HLDS, !IO) :- :- pred maybe_tuple_arguments(io.text_output_stream::in, bool::in, bool::in, module_info::in, module_info::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. -maybe_tuple_arguments(ProgressStream, Verbose, Stats, !HLDS, !Specs, !IO) :- +maybe_tuple_arguments(ProgressStream, Verbose, Stats, !HLDS, + !MaybeWrittenSpecs, !IO) :- module_info_get_globals(!.HLDS, Globals), globals.get_opt_tuple(Globals, OptTuple), Tuple = OptTuple ^ ot_tuple, @@ -933,7 +947,7 @@ maybe_tuple_arguments(ProgressStream, Verbose, Stats, !HLDS, !Specs, !IO) :- maybe_write_string(ProgressStream, Verbose, "% Tupling...\n", !IO), maybe_flush_output(ProgressStream, Verbose, !IO), tuple_arguments(ProgressStream, TupleSpecs, !HLDS, !IO), - !:Specs = TupleSpecs ++ !.Specs, + add_to_be_written_specs(TupleSpecs, !MaybeWrittenSpecs), maybe_write_string(ProgressStream, Verbose, "% done.\n", !IO), maybe_report_stats(ProgressStream, Stats, !IO) ; @@ -1011,10 +1025,10 @@ maybe_source_to_source_debug(ProgressStream, Verbose, Stats, !HLDS, !IO) :- :- pred maybe_implicit_parallelism(io.text_output_stream::in, io.text_output_stream::in, bool::in, bool::in, module_info::in, module_info::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. maybe_implicit_parallelism(ProgressStream, ErrorStream, Verbose, Stats, - !HLDS, !Specs, !IO) :- + !HLDS, !MaybeWrittenSpecs, !IO) :- module_info_get_globals(!.HLDS, Globals), globals.lookup_bool_option(Globals, implicit_parallelism, ImplicitParallelism), @@ -1026,8 +1040,9 @@ maybe_implicit_parallelism(ProgressStream, ErrorStream, Verbose, Stats, apply_implicit_parallelism_transformation(ParSpecs, !HLDS), maybe_write_string(ProgressStream, Verbose, "% done.\n", !IO), % XXX This is a bit late for printing errors. - !:Specs = ParSpecs ++ !.Specs, - maybe_write_out_errors(ErrorStream, Verbose, Globals, !Specs, !IO), + add_to_be_written_specs(ParSpecs, !MaybeWrittenSpecs), + maybe_write_not_yet_written_specs(ErrorStream, Globals, Verbose, + !MaybeWrittenSpecs, !IO), maybe_report_stats(ProgressStream, Stats, !IO) ; % The user hasn't asked for implicit parallelism. @@ -1038,10 +1053,10 @@ maybe_implicit_parallelism(ProgressStream, ErrorStream, Verbose, Stats, :- pred maybe_introduce_accumulators(io.text_output_stream::in, bool::in, bool::in, module_info::in, module_info::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. maybe_introduce_accumulators(ProgressStream, Verbose, Stats, - !HLDS, !Specs, !IO) :- + !HLDS, !MaybeWrittenSpecs, !IO) :- module_info_get_globals(!.HLDS, Globals), globals.get_opt_tuple(Globals, OptTuple), IntroduceAccumulators = OptTuple ^ ot_introduce_accumulators, @@ -1058,7 +1073,7 @@ maybe_introduce_accumulators(ProgressStream, Verbose, Stats, Task = update_module_pred_cookie(_, Cookie), univ_to_type(Cookie, AccSpecs) then - !:Specs = AccSpecs ++ !.Specs + add_to_be_written_specs(AccSpecs, !MaybeWrittenSpecs) else unexpected($pred, "bad task") ), @@ -1233,11 +1248,11 @@ maybe_structure_reuse_analysis(ProgressStream, Verbose, Stats, !HLDS, !IO) :- :- pred maybe_unused_args(io.text_output_stream::in, bool::in, bool::in, maybe_gather_pragma_unused_args::in, maybe_record_analysis_unused_args::in, set(gen_pragma_unused_args_info)::out, module_info::in, module_info::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. maybe_unused_args(ProgressStream, Verbose, Stats, GatherPragmas, RecordAnalysis, PragmaUnusedArgsInfos, - !HLDS, !Specs, !IO) :- + !HLDS, !MaybeWrittenSpecs, !IO) :- module_info_get_globals(!.HLDS, Globals), globals.get_opt_tuple(Globals, OptTuple), OptUnusedArgs = OptTuple ^ ot_opt_unused_args, @@ -1254,7 +1269,7 @@ maybe_unused_args(ProgressStream, Verbose, Stats, maybe_flush_output(ProgressStream, Verbose, !IO), unused_args_process_module(GatherPragmas, RecordAnalysis, UnusedSpecs, PragmaUnusedArgsInfos, !HLDS), - !:Specs = UnusedSpecs ++ !.Specs, + add_to_be_written_specs(UnusedSpecs, !MaybeWrittenSpecs), maybe_write_string(ProgressStream, Verbose, "% done.\n", !IO), maybe_report_stats(ProgressStream, Stats, !IO) else @@ -1488,9 +1503,10 @@ maybe_par_loop_control(ProgressStream, Verbose, Stats, !HLDS, !IO) :- :- pred maybe_float_reg_wrapper(io.text_output_stream::in, bool::in, bool::in, module_info::in, module_info::out, - list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det. + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. -maybe_float_reg_wrapper(ProgressStream, Verbose, Stats, !HLDS, !Specs, !IO) :- +maybe_float_reg_wrapper(ProgressStream, Verbose, Stats, !HLDS, + !MaybeWrittenSpecs, !IO) :- module_info_get_globals(!.HLDS, Globals), globals.lookup_bool_option(Globals, use_float_registers, UseFloatRegs), ( @@ -1499,7 +1515,7 @@ maybe_float_reg_wrapper(ProgressStream, Verbose, Stats, !HLDS, !Specs, !IO) :- "% Inserting float register wrappers...", !IO), maybe_flush_output(ProgressStream, Verbose, !IO), float_regs.insert_reg_wrappers(!HLDS, RegSpecs), - !:Specs = RegSpecs ++ !.Specs, + add_to_be_written_specs(RegSpecs, !MaybeWrittenSpecs), maybe_write_string(ProgressStream, Verbose, " done.\n", !IO), maybe_report_stats(ProgressStream, Stats, !IO) ; diff --git a/compiler/mercury_compile_mlds_back_end.m b/compiler/mercury_compile_mlds_back_end.m index 176ad1b6a..9f8cfbda3 100644 --- a/compiler/mercury_compile_mlds_back_end.m +++ b/compiler/mercury_compile_mlds_back_end.m @@ -25,14 +25,13 @@ :- import_module ml_backend. :- import_module ml_backend.mlds. :- import_module parse_tree. -:- import_module parse_tree.error_spec. +:- import_module parse_tree.error_util. :- import_module io. -:- import_module list. :- pred hlds_to_mlds(io.text_output_stream::in, module_info::in, mlds::out, - list(error_spec)::in, list(error_spec)::out, - dump_info::in, dump_info::out, io::di, io::uo) is det. + dump_info::in, dump_info::out, + maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. :- pred mlds_to_high_level_c(io.text_output_stream::in, globals::in, mlds::in, maybe_succeeded::out, io::di, io::uo) is det. @@ -68,24 +67,27 @@ :- import_module ml_backend.mlds_to_cs_file. % MLDS -> C# :- import_module ml_backend.mlds_to_java_file. % MLDS -> Java :- import_module ml_backend.rtti_to_mlds. % HLDS/RTTI -> MLDS +:- import_module parse_tree.error_spec. :- import_module parse_tree.file_names. :- import_module top_level.mercury_compile_front_end. :- import_module top_level.mercury_compile_llds_back_end. :- import_module bool. +:- import_module list. :- import_module maybe. :- import_module pprint. :- import_module string. %---------------------------------------------------------------------------% -hlds_to_mlds(ProgressStream, !.HLDS, !:MLDS, !Specs, !DumpInfo, !IO) :- +hlds_to_mlds(ProgressStream, !.HLDS, !:MLDS, + !DumpInfo, !MaybeWrittenSpecs, !IO) :- module_info_get_globals(!.HLDS, Globals), globals.lookup_bool_option(Globals, verbose, Verbose), globals.lookup_bool_option(Globals, statistics, Stats), maybe_simplify(ProgressStream, maybe.no, bool.no, simplify_pass_ml_backend, - Verbose, Stats, !HLDS, [], _SimplifySpecs, !IO), + Verbose, Stats, !HLDS, init_maybe_written_specs, _SimplifySpecs, !IO), maybe_dump_hlds(ProgressStream, !.HLDS, 405, "ml_backend_simplify", !DumpInfo, !IO), @@ -113,7 +115,8 @@ hlds_to_mlds(ProgressStream, !.HLDS, !:MLDS, !Specs, !DumpInfo, !IO) :- !DumpInfo, !IO), mark_tail_rec_calls_hlds(ProgressStream, Verbose, Stats, - !HLDS, !Specs, !IO), + !HLDS, [], TailSpecs, !IO), + add_to_be_written_specs(TailSpecs, !MaybeWrittenSpecs), maybe_dump_hlds(ProgressStream, !.HLDS, 430, "mark_tail_calls", !DumpInfo, !IO), @@ -130,7 +133,8 @@ hlds_to_mlds(ProgressStream, !.HLDS, !:MLDS, !Specs, !DumpInfo, !IO) :- ), maybe_write_string(ProgressStream, Verbose, "% Converting HLDS to MLDS...\n", !IO), - ml_code_gen(ProgressStream, MLDS_Target, !:MLDS, !HLDS, !Specs), + ml_code_gen(ProgressStream, MLDS_Target, !:MLDS, !HLDS, [], CodeGenSpecs), + add_to_be_written_specs(CodeGenSpecs, !MaybeWrittenSpecs), maybe_write_string(ProgressStream, Verbose, "% done.\n", !IO), maybe_report_stats(ProgressStream, Stats, !IO), maybe_dump_hlds(ProgressStream, !.HLDS, 499, "final", !DumpInfo, !IO), diff --git a/compiler/write_error_spec.m b/compiler/write_error_spec.m index 09c4e93f1..de53ccecb 100644 --- a/compiler/write_error_spec.m +++ b/compiler/write_error_spec.m @@ -46,7 +46,8 @@ %---------------------------------------------------------------------------% - % maybe_write_out_errors(Stream, Verbose, Globals, !Specs, !IO): + % maybe_write_not_yet_written_specs(Stream, Globals, Verbose, + % !MaybeWrittenSpecs, !IO): % % Every possible path of execution in mercury_compile.m should call % write_error_specs on the accumulated but not-yet-printed error_specs @@ -62,30 +63,32 @@ % If Verbose = yes, then keeping all the error messages until the end would % be confusing, since we would be reporting that e.g. the program had type % errors *before* printing the type error messages. In that case, - % we want to print (using maybe_write_out_errors) all the accumulated + % we want to print (using maybe_write_not_yet_written_specs) + % all the accumulated % errors before each message to the user. % % This applies to *all* messages. % - % - The calls to maybe_write_out_errors before a message that announces - % the completion (and success or failure) of a phase should obviously - % report the errors (if any) discovered by the phase. + % - The calls to maybe_write_not_yet_written_specs before a message + % that announces the completion (and success or failure) of a phase + % should obviously report the errors (if any) discovered by the phase. % - % - The calls to maybe_write_out_errors before a message that announces - % the phase the compiler is about to enter serve to write out any - % messages from previous phases that have not yet been written out. + % - The calls to maybe_write_not_yet_written_specs before a message + % that announces the phase the compiler is about to enter serve + % to write out any messages from previous phases that have not yet + % been written out. % % We could require each phase to write out the errors it discovers % when it finishes (if Verbose = yes, that is), but that would eliminate % any opportunity to group and sort together the error messages % of two or more adjacent phases that are *not* separated by a message % to the user even with Verbose = yes. Since the cost of calling - % maybe_write_out_errors when there is nothing to print is so low - % (a few dozen instructions), we can easily afford to incur it - % unnecessarily once per compiler phase. + % maybe_write_not_yet_written_specs when there is nothing to print + % is so low (a few dozen instructions), we can easily afford + % to incur it unnecessarily once per compiler phase. % -:- pred maybe_write_out_errors(io.text_output_stream::in, bool::in, - globals::in, list(error_spec)::in, list(error_spec)::out, +:- pred maybe_write_not_yet_written_specs(io.text_output_stream::in, + globals::in, bool::in, maybe_written_specs::in, maybe_written_specs::out, io::di, io::uo) is det. %---------------------------------------------------------------------------% @@ -257,13 +260,13 @@ %---------------------------------------------------------------------------% %---------------------------------------------------------------------------% -maybe_write_out_errors(Stream, Verbose, Globals, !Specs, !IO) :- +maybe_write_not_yet_written_specs(Stream, Globals, Verbose, + !MaybeWrittenSpecs, !IO) :- ( Verbose = no ; Verbose = yes, - write_error_specs(Stream, Globals, !.Specs, !IO), - !:Specs = [] + write_not_yet_written_specs(Stream, Globals, !MaybeWrittenSpecs, !IO) ). %---------------------------------------------------------------------------%