Commit Graph

136 Commits

Author SHA1 Message Date
Zoltan Somogyi
823de2d37b Require warning/info messages to specify an option.
The objective of this step is two-fold:

- to fix --inhibit-warnings, making it shut up all warning
  and informational messages; and

- to ensure that it *stays* fixed, even when after new diagnostics
  are added.

As part of this fix, this diff adds a whole bunch of new warning
options, in order to control the warnings that previously were
not controlled by any option. (There was no need for new
informational options.)

As it happens, we have long used severity_informational for messages
that did not report any information about the code being compiled,
but to report actions that the compiler was taking. Create a new
option category, oc_report, for the new options that now control
those diagnostics.

---------------------

compiler/error_spec.m:
    Change severity_warning and severity_informational to take an option
    as as argument. The semantics is that the diagnostic in which
    the severity occurs is conditional on that option, meaning that
    it is printed only if that option is set to "yes".

    Delete the severity_conditional function symbol from the severity
    type, since the mechanism just above handles its only use case.

    Define subtypes to represent error_specs in a standard form.

compiler/error_sort.m:
    Provide operations to convert error specs into their standard form.

    Make the sorting operation itself operate on the standard form.

compiler/write_error_spec.m:
    Convert error_specs to standard form before writing them out,
    in order to avoid duplicating the code for their standardization.

    Change the code that writes out error_specs to operate on the
    standard form. Implement the test implicit in the warning and
    and informational severities in this code.

compiler/error_util.m:
compiler/compiler_util.m:
    Delete operations that do not make sense with the new severity type.

---------------------

compiler/options.m:
    Add new options to control all the previously-uncontrolled
    warning and informational messages.

NEWS.md:
    Announce the *public* new options.

compiler/option_categories.m:
compiler/print_help.m:
    Add the new option category, and fake-include it in the help text
    and the user guide. (The inclusion is fake because none of the
    options in the new category are user visible, meaning the section
    containing them is not visible either.)

---------------------

compiler/det_infer_goal.m:
    Start a severity warning diagnostic with "Warning:"
    instead of "Error:".

compiler/mark_trace_goals.m:
    Fix an incorrect error message.

compiler/purity.m:
    Replace a correct/incorrect color pair with two inconsistent colors,
    because there is a reasonable probability of each one being right.

---------------------

compiler/accumulator.m:
compiler/add_clause.m:
compiler/add_mode.m:
compiler/add_pragma.m:
compiler/add_pragma_tabling.m:
compiler/add_pred.m:
compiler/add_type.m:
compiler/check_module_interface.m:
compiler/check_type_inst_mode_defns.m:
compiler/check_typeclass.m:
compiler/color_schemes.m:
compiler/common.m:
compiler/convert_import_use.m:
compiler/convert_parse_tree.m:
compiler/dead_proc_elim.m:
compiler/det_check_proc.m:
compiler/det_check_switch.m:
compiler/det_infer_goal.m:
compiler/du_type_layout.m:
compiler/format_call_errors.m:
compiler/grab_modules.m:
compiler/hlds_call_tree.m:
compiler/inst_check.m:
compiler/introduce_parallelism.m:
compiler/make_hlds_error.m:
compiler/make_hlds_warn.m:
compiler/mark_tail_calls.m:
compiler/mark_trace_goals.m:
compiler/mercury_compile_main.m:
compiler/mercury_compile_make_hlds.m:
compiler/mode_errors.m:
compiler/modes.m:
compiler/module_qual.qual_errors.m:
compiler/opt_deps_spec.m:
compiler/options_file.m:
compiler/parse_goal.m:
compiler/post_term_analysis.m:
compiler/post_typecheck.m:
compiler/pre_typecheck.m:
compiler/purity.m:
compiler/read_modules.m:
compiler/recompilation.check.m:
compiler/simplify_goal.m:
compiler/simplify_goal_call.m:
compiler/simplify_goal_disj.m:
compiler/simplify_goal_ite.m:
compiler/split_parse_tree_src.m:
compiler/state_var.m:
compiler/stratify.m:
compiler/style_checks.m:
compiler/superhomogeneous.m:
compiler/table_gen.m:
compiler/term_constr_errors.m:
compiler/term_errors.m:
compiler/termination.m:
compiler/typecheck_clauses.m:
compiler/typecheck_error_overload.m:
compiler/typecheck_error_undef.m:
compiler/typecheck_errors.m:
compiler/typecheck_msgs.m:
compiler/unused_args.m:
compiler/unused_imports.m:
compiler/warn_unread_modules.m:
compiler/write_module_interface_files.m:
    Conform to the changes above, mostly by either

    - adding an option to all warning and informational messages,
      sometimes using existing warning options and sometimes new ones,
      or

    - turning already explicitly-conditional-on-an-option messages
      into implicitly-conditional-on-that-option messages.

---------------------

tests/invalid/one_member.m:
    Conform to the change in det_infer_goal.m.

tests/invalid/require_tailrec_1.err_exp:
tests/invalid/require_tailrec_2.err_exp:
    Actually obey the options for these modules in Mercury.options.

tests/invalid_purity/purity.err_exp:
tests/warnings/purity_warnings.err_exp:
    Conform to the change in purity.m.

tests/warnings/moved_trace_goal.err_exp:
    Conform to the change in mark_trace_goals.m.

tests/warnings/help_text.err_exp:
    Expect the documentation of all the new options.
2025-08-18 12:07:38 +02:00
Zoltan Somogyi
e40b90e5c6 Fix comment rot. 2024-12-31 15:21:58 +11:00
Zoltan Somogyi
79bfb1247f Carve prog_parse_tree.m out of prog_item.m.
compiler/prog_item.m:
compiler/prog_parse_tree.m:
    Split prog_item.m into two modules, with the new module prog_parse_tree.m
    containing the definitions of the file-kind-specific parse trees,
    and prog_item.m continuing to contain the definitions of the items
    that occur in those parse trees. Specialize the top-of-module comment
    to the current contents of each module.

compiler/parse_tree.m:
compiler/notes/compiler_design.html:
    Include and document the new module.

compiler/*.m:
    Conform to the changes above.
2024-12-19 01:27:00 +11:00
Zoltan Somogyi
3b3b543a84 Return both legacy and proposed file names.
compiler/file_names.m:
    Change the predicates that return file names to return as their result
    both the current, legacy filename, and the proposed filename.

    For ext_cur extensions, the legacy and the proposed filenames
    will always be identical. Add a predicate for these that returns
    just this one filename.

compiler/comp_unit_interface.m:
compiler/compile_target_code.m:
compiler/du_type_layout.m:
compiler/export.m:
compiler/fact_table.m:
compiler/generate_dep_d_files.m:
compiler/generate_mmakefile_fragments.m:
compiler/llds_out_file.m:
compiler/make.build.m:
compiler/make.check_up_to_date.m:
compiler/make.clean.m:
compiler/make.dependencies.m:
compiler/make.file_names.m:
compiler/make.get_module_dep_info.m:
compiler/make.library_install.m:
compiler/make.module_dep_file.m:
compiler/make.module_target.m:
compiler/make.program_target.m:
compiler/make.timestamp.m:
compiler/make.track_flags.m:
compiler/make.util.m:
compiler/make_module_file_names.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mercury_compile_main.m:
compiler/mercury_compile_make_hlds.m:
compiler/mercury_compile_middle_passes.m:
compiler/mercury_compile_mlds_back_end.m:
compiler/mlds_to_c_file.m:
compiler/mlds_to_cs_file.m:
compiler/mlds_to_java_file.m:
compiler/mmc_analysis.m:
compiler/mode_constraints.m:
compiler/module_cmds.m:
compiler/read_modules.m:
compiler/recompilation.used_file.m:
compiler/write_deps_file.m:
compiler/write_module_interface_files.m:
compiler/xml_documentation.m:
    Conform to the changes above. In most places, this means ignoring
    the proposed filename for now, but marking such places with "XXX LEGACY",
    to make them easier to find when we *do* start to make use of the proposed
    file names (first alongside the legacy names, and then without them).

    In some places, make variable names more descriptive.

library/set.m:
    Add utility predicate for use by a diff to one of the modules above.

NEWS.md:
    Announce the new library predicate.
2024-09-19 12:42:33 +02:00
Zoltan Somogyi
dc12878708 Shorten function symbols in error_specs.
compiler/error_spec.m:
    Replace simplest_spec with spec, and simplest_no_context_spec with
    no_ctxt_spec. These are now the most frequently used function symbols
    to create error specs, so their name should not make them out to be
    the exception.

    Replace simplest_msg with msg, and simplest_no_context_msg with
    no_ctxt_msg for the same reason.

    Abbreviate some of the long phase names.

compiler/*.m:
    Conform to the changes above. Most of these changes were done by a script,
    with minor manual tidying up, which consisted mostly of fitting code
    constructing error specs onto fewer lines than before.
2024-04-20 21:51:15 +10:00
Julien Fischer
b8bb4cdbb0 Update copyright notice.
compiler/write_module_interface_files.m:
    As above.
2024-02-13 16:06:43 +11:00
Zoltan Somogyi
6e2875842f Stop using .tmp files when generating .intN files.
compiler/write_module_interface_files.m:
    Instead of

        - writing out the new version of a .intN file to module.intN.tmp,
        - comparing that file with module.intN, and
        - renaming module.intN.tmp to module.intN if they differ,

    we now

        - read in the old .intN file to a string
        - convert the new parse tree for .intN to a string
        - write out the string form of the new parse tree to module.intN
          if they differ.

    The logic is bit more complex in the presence of smart recompilation
    (in both the old new algorithms) but not by much.

    The new algorithm requires significantly fewer system calls than the old.

compiler/comp_unit_interface.m:
    Don't create a name for .intN.tmp files, since they are not needed anymore.

compiler/module_cmds.m:
    Reorder the predicates that copy files putting the most basic predicate
    last, so that calls go from earlier predicates to later predicates.

compiler/parse_module.m:
    Delete unneeded IO state args from the parse_intN_file predicates.

compiler/parse_tree_out.m:
    Carve output_parse_tree_string out of the existing
    output_some_parse_tree predicate which also *constructed* that parse tree.
    This capability is needed by new code in write_module_interface_files.m,
    which wants to perform other operations on the string forms of parse trees
    before writing them out.
2024-02-13 10:46:48 +11:00
Zoltan Somogyi
a3ea222883 Fix more C# test case failures in tests/invalid*.
compiler/options.m:
doc/user_guide.texi:
    Add a new developer-only option, --std-int-file-not-written-msgs,
    which, if specified, calls for the "file not written" messages
    we generate when we want to write interface files but can't
    to be written out in a standard form that deletes the directory
    path component from the names of the files not written out.
    In the long term, it is less work to add this option once
    than to add a separate .err_exp file for each affected test case.

compiler/write_module_interface_files.m:
    Obey the new option.

tests/invalid/ee_invalid.m:
    Add C# and Java foreign_types next to the C foreign_type.

tests/invalid/erroneous_throw_promise.m:
    Add C# foreign_procs next to the C and Java foreign_procs.

tests/invalid/exist_foreign_error.m:
    Add C# and Java foreign_procs next to a C foreign_proc.
tests/invalid/exist_foreign_error.err_exp:
tests/invalid/exist_foreign_error.err_exp2:
tests/invalid/exist_foreign_error.err_exp3:
    Update the line number in the expected error output file for C,
    and add expected error output files for Java and C#.

tests/invalid_make_int/bug17.{m,int_err_exp}:
tests/invalid_make_int/builtin_int.{m,int_err_exp}:
    Move these test cases here from tests/invalid, since all the errors
    we test for are reported when making the .int file.

tests/invalid/Mmakefile:
    Delete the tests moved to tests/invalid_make_int.

tests/invalid_make_int/Mercury.options:
tests/invalid_make_int/Mmakefile:
    Add the tests moved from tests/invalid. Specify the new option
    for all the test cases.
2023-10-25 19:21:06 +11:00
Zoltan Somogyi
a3546b16c3 Move code to generate interface to comp_unit_interface.m.
compiler/write_module_interface_files.m:
compiler/comp_unit_interface.m:
    Move the predicates that generate the parse trees of interface files
    from write_module_interface_files.m to comp_unit_interface.m.
    Move the types they need with them, and document them.

    Rename the predicates involved to make clear whether they generate
    parse trees, write them out, or both.

    In comp_unit_interface.m keep private the previously exported predicates,
    because their only callers are the moved predicates, so all calls them
    are now local to the module.

compiler/make.get_module_dep_info.m:
compiler/mercury_compile_main.m:
    Conform to the changes above.
2023-10-25 12:35:57 +11:00
Zoltan Somogyi
3dabbd4edf Generate and write parse_tree_intNs in separate preds.
compiler/write_module_interface_files.m:
    Put the code that writes out parse_tree_intNs in separate predicates
    from the code that generates them.

    This separation is useful in situations in which

    - we need to generate several .intN files as fast as possible, and
    - later operations will need access to the contents of those files.

    With the current setup, we can call e.g. write_short_interface_file_int3
    on several parse_tree_module_srcs in parallel, but this comes at the cost
    of each worker process building up only its own have_parse_tree_maps
    "database" of parse trees. This means if worker process A generates
    an interface file, another worker process B will need to read that
    interface file to get access to its contents.

    With the setup created by this diff, we can generate all the parse trees
    for the interface files in the main process, keeping *all* their parse
    trees in its have_parse_tree_maps structure, and hand off each parse tree
    as it is constructed to a worker process for writing out.
2023-10-25 10:05:46 +11:00
Zoltan Somogyi
26f1e5bb53 Give an initial module_baggage to grab_modules.m.
compiler/grab_modules.m:
    grab_{qual,unqual}_imported_modules_*, the two main predicates
    of this module, have for a while now taken as input both a
    parse_tree_module_src, and several separate arguments each describing
    part of the origin of that parse_tree_module_src. They then created
    a new module_baggage structure, filling some of its fields using
    those arguments, but filling other fields with default values,
    which were no more than guesses at what the right value might be.

    This has obviously worked, but it could work only because
    the guessed-at fields are either not used or were guessed well.
    However, this may change in the future. After this diff, we now require
    the caller to pass to these predicates a fully-and-correctly-filled-in
    module_baggage structure instead, which guards against that
    possibility, and leads to cleaner and more understandable code
    to boot.

    We do throw away any errors in the initial module_baggage
    in order to prevent parts of the compiler that aren't set up
    to handle any errors there from causing additional test failures
    in C# (and probably Java) grades. This preserves old behavior,
    at least for now.

compiler/write_module_interface_files.m:
    Make the versions of write_private_interface_file_int0 and
    write_interface_file_int1_int2 that took a burdened_module
    as an argument the *only* versions of those operations,
    since the burdened_module contains the module_baggage structure
    we now want to pass to grab_modules.m.

    Replace the parse_tree_module_src argument of
    write_short_interface_file_int3 with a burdened_module.
    This is only for "cultural compatibility" with the neighboring
    predicates; unlike those two, this predicate does not need access
    to the module_baggage.

compiler/make.get_module_dep_info.m:
compiler/mercury_compile_main.m:
    Conform to the changes above.

compiler/module_baggage.m:
    Fix a misleading variable name.
2023-10-23 11:39:58 +11:00
Zoltan Somogyi
c0cfae0061 Update some variable names. 2023-10-22 11:29:59 +11:00
Zoltan Somogyi
d394cfc7a5 Rename have_read_module_maps to have_parse_tree_maps ...
... to account for the fact that they now contain constructed parse trees,
as well as read-in parse trees.

compiler/read_modules.m:
    Make the rename described above.

    Make it possible to differentiate between constructed and read-in
    parse trees, in case this becomes necessary in the future.

compiler/deps_map.m:
compiler/generate_dep_d_files.m:
compiler/grab_modules.m:
compiler/make.get_module_dep_info.m:
compiler/make.make_info.m:
compiler/mercury_compile_main.m:
compiler/mercury_compile_make_hlds.m:
compiler/recompilation.check.m:
compiler/write_module_interface_files.m:
    Conform to the changes above.

    In make.get_module_dep_info.m, add an XXX.
2023-10-22 08:39:27 +11:00
Zoltan Somogyi
4f3bb3394e Write "can't open file" messages to ProgressStream ...
... instead of ErrorStream.

compiler/parse_tree_out.m:
    As above.

compiler/make.get_module_dep_info.m:
compiler/mercury_compile_main.m:
compiler/write_module_interface_files.m:
    Don't pass ErrorStream to predicates that don't need it anymore.
2023-10-19 19:59:40 +11:00
Zoltan Somogyi
b21e9e459a Delete all calls to get_progress_output_stream ...
... and almost all calls to get_error_output_stream. Replace them
with ProgressStreams and ErrorStreams passed down from higher in the
call tree.

Use ProgressStreams, not ErrorStreams, to write out error messages about
any failures of filesystem operations. These are not appropriate to put
into a module's .err file, since they are not about an error in the
Mercury code of the module.

compiler/globals.m:
    Delete the predicates that return progress streams, and the mutable
    behind them.

compiler/passes_aux.m:
    Delete the predicates that return progress streams. Delete the
    versions of the progress-message-writing predicates that didn't get
    the progress stream from their caller.

compiler/*.m:
    Pass around ProgressStreams and/or ErrorStreams explicitly,
    as mentioned at the top of log message.

    In a few places, don't write out error_specs to ErrorStream,
    returning it to be printed by our caller, or its caller etc instead.
    In some of those places, this allowed the deletion an existing
    ErrorStream argument.

    Given that get_{progress,error}_output_stream took a ModuleName input,
    deleting some of the calls to those predicates left ModuleName unused.
    Delete such unused ModuleNames.

    In a few places, change argument orders to conform to our usual
    programming style.

    Fix too-long lines.
2023-10-17 20:41:33 +11:00
Zoltan Somogyi
191eb9eb64 Make --generate-dependencies-ints more practical.
scripts/Mmake.rules:
    Add a rule for the pattern target %.depend_ints which invokes mmc
    with --generate-dependencies-ints, just as %.depend invokes mmc
    with --generate-dependencies.

    Document the reason why this addition requires yet more code duplication.

scripts/Mmake.vars.in:
    Add the make variable definitions needed by the new code in Mmake.rules.

compiler/mercury_compile_main.m:
    Make it practical to use --generate-dependencies-ints in a multi-directory
    project like the Mercury implementation, in which some directories
    may use --generate-dependencies-ints as the target of "mmake depend",
    while other directories, which come earlier in the build process,
    still do "mmake depend" using just --generate-dependencies.
    In such cases, mmc --generate-dependencies-ints in the later directory
    may fail to generate .int0, .int or .int2 files simply because
    the .int3 file of a module they import (from an earlier directory
    in which "mmake depend" uses just --generate-dependencies) hasn't been
    made yet. (This is what would happen if someone executed "mmake depend"
    at the top level in a freshly checked out workspace.)

    The practical fix is to simply report this fix using an error message
    that still allows the compiler to exit with an exit status that
    indicates success.

    Most of the rest of this diff is there to make this possible.

compiler/error_spec.m:
    Add a new phase, phase_find_files, that specifically indicates
    that we couldn't read a file because we couldn't find it.
    Give it a string argument naming the file, to allow mercury_compile_main.m
    to replace several error_specs that each report not being able to find
    one file with a single error_spec that reports not being able to find
    many files.

    Add a utility function for use by mercury_compile_main.m to construct
    that error message.

    Add another new phase, phase_make_int, that indicates a problem
    we discovered in the code of a Mercury source file while trying
    to decide what should got into one of the that module's interface files.

compiler/parse_error.m:
    Here also use separate function symbols in the fatal_module_read_error
    type for the situations "couldn't find a file" and "couldn't read a file".

    Update the predicates constructing error_specs to handle this distinction
    (which the callers make using the new function symbol in the above type).

compiler/compile_target_code.m:
compiler/error_util.m:
compiler/grab_modules.m:
compiler/options_file.m:
compiler/parse_module.m:
compiler/read_modules.m:
compiler/recompilation.check.m:
compiler/write_module_interface_files.m:
    Conform to the changes above.

compiler/options.m:
    Add a way to detect the presence of this diff in an installed compiler.
2023-10-15 13:10:40 +11:00
Zoltan Somogyi
25f8a6cc99 Add new option --generate-dependencies-ints.
This new option extends --generate-dependencies to take advantage of the
opportunity afforded by the fact that "mmc --generate-dependencies prog.m"
reads in every Mercury source file in the current directory that is
part of "prog". It does this by

- generating the .int3 file of all local-directory modules of the program;
- generating the .int0 file for each these modules that has submodules;
- generating the .int and .int2 files of all local-directory modules
  of the program.

Normally, the process of creating .int0, .int and .int3 files would
need to read in .int0 and .int3 files, but in every one of these cases,
we have just written out those files, so simply holding onto their
parse trees, we can skip this step. On my laptop, on a directory
containing library/*.m, mdbcomp/*.m and compiler/*.m, generating
the dependencies and generating all the .int3/.int0/.int/.int2 files
takes just over 25 seconds. Using the new option, the same process
takes less than 10 seconds.

compiler/options.m:
    Add the new option.

compiler/op_mode.m:
    Add a new variant of the existing op_mode for --generate-dependencies,
    which we select in the presence of the new option.

compiler/mercury_compile_main.m:
    Implement the new op_mode.

    Fix an old issue, which is that "mmc --make-private-interface x.m"
    generated a .int0 file for *every* module in x.m, even the modules
    that don't have any submodules.

compiler/deps_map.m:
    The code implementing the new option needs to know which modules
    of the program are in the current directory. The deps_map structure
    built by the code shared with the implementation of --generate-dependencies
    has not needed that info until now, so add a new field to the deps
    structure of each module to provide this info.

compiler/generate_dep_d_files.m:
    Return the deps_map created by the code that implements both
    --generate-dependencies and the new option to mercury_compile_main.m.

compiler/write_module_interface_files.m:
    Add a flag to the predicates that first construct the parse trees of,
    and then write out, .int3/.int0/.int/.int2 files, that
    mercury_compile_main.m can use to tell them to record the parse trees
    in the have read module maps.

    Add new variants of two of those predicates that take some of their
    arguments from burdened_module structures, since that is the form
    in which mercury_compile_main.m has that info.

compiler/module_baggage.m:
    The predicates in write_module_interface_files.m that generate
    .int0/.int/.int2 files take an argument that should be the timestamp
    of the source file they are being derived from, if that timestamp
    is needed for smart recompilation. Until now, we only ever invoked
    those predicates when we have just read in the source file,
    and this timestamp was readily available. The code implementing
    the new option needs to store this info for a short time, and
    the module baggage is the obvious place to store it, so add this field
    to the baggage.

compiler/error_spec.m:
    An invocation of the compiler with new option may report errors that
    prevent the construction of interface files for several modules.
    The new code in mercury_compile.m prints the error_specs that have
    contexts in the order of those contexts, but we want to print
    the messages without contexts (which in this case report that
    certain files could not be written or copied) to have a useful
    order too. Make this possible by allowing the invisible pieces
    we use for ordering to specify that order via a string (in this case,
    the name of the file that e.g. could not be written), rather than
    the only previous option, an integer.

compiler/grab_modules.m:
compiler/make.get_module_dep_info.m:
compiler/make.module_dep_file.m:
    Fill in the new field in the module baggage.

compiler/check_module_interface.m:
compiler/handle_options.m:
compiler/make_hlds_error.m:
compiler/parse_module.m:
compiler/prog_foreign_enum.m:
compiler/typecheck_error_util.m:
compiler/typecheck_msgs.m:
compiler/write_deps_file.m:
compiler/write_error_spec.m:
    Conform to the changes above.
2023-10-12 06:50:07 +11:00
Zoltan Somogyi
68c3d4040b Let callers of write_*interface_file* print errors.
compiler/write_module_interface_files.m:
    When the process of generating the contents of an interface file
    finds some errors, don't print those errors immediately. Just return
    them instead, letting the caller decide what to do with them.

    Fix comment rot.

compiler/make.get_module_dep_info.m:
compiler/mercury_compile_main.m:
    Print the error specs returned by the updated predicates (for now,
    at least).

compiler/error_sort.m:
    Fix an issue exposed by the changes above. When comparing two error_specs
    to see which one should be printed first, don't take the lack of a content
    in an error_spec as a sign that it should be printed first. Instead,
    pay attention to the comparison of contexts *only* if both of the
    error_specs being compared actually *have* contexts.

tests/invalid/type_inf_loop.err_exp:
    Expect the contextless message about exceeding the type inference
    iteration limit to come after the other messages, due to the update
    to error_sort.m.

tests/invalid/type_inf_loop.err_exp2:
    Delete this file. It can't match the compiler's current output,
    or (it seems) the output of any compiler version since we switched
    to reporting type errors using error_specs.
2023-10-08 10:11:08 +11:00
Zoltan Somogyi
e1e5480f16 Eliminate calls to io.output_stream in read_modules.m.
compiler/read_modules.m:
    When invoked to read a file specified by file name (as opposed to
    by module name), the code of this module wrote out progress messages
    to the current output stream, as returned by io.output_stream.
    Fix this by consistently requiring the ancestors of the predicates involved
    to pass an explicit stream to write progress messages to.

    The interfaces of some of the exported predicates allowed their callers
    to either pass a progress stream or not; if they didn't, this prevented
    the generation of any progress messages with -v and the generation of
    any statistics with -S. Most callers did specify the progress stream;
    the main parts of the compiler that did not were

    - the code that read the old versions of interface files in order to see
      whether the new version was identical to it, or not, and
    - the intermodule analysis framework.

    This diff requires callers to always pass a progress stream, because
    we *always* want to write out any error messages about nonexistent
    or unreadable files, and we don't want to write these to an implicitly
    specified file. We *could* add a parameter to the affected predicates
    to shut up progress messages and statistics for use at the call sites
    that previously passed us "no" as the maybe progress stream argument,
    but I see no reason why one wouldn't want -v and -S to work as usual
    in these above circumstances. If anyone ever finds such a reason,
    there is a simpler fix anyway: turning off -v and -S in the globals
    passed along next to the progress stream.

compiler/module_cmds.m:
    Stop requiring an error stream and as well as a progress stream
    when touching files. If the two streams were ever different, the
    output would have looked strange, as the error message would NOT follow
    the progress message announcing the operation that failed.

compiler/analysis.m:
compiler/deps_map.m:
compiler/generate_dep_d_files.m:
compiler/make.module_dep_file.m:
compiler/make.module_target.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_main.m:
compiler/mercury_compile_middle_passes.m:
compiler/recompilation.check.m:
compiler/write_module_interface_files.m:
    Conform to the changes above, mostly by passing along
    an explicit progress stream.
2023-09-15 17:55:14 +10:00
Zoltan Somogyi
691e5ca0c5 Group extensions by their translation algorithms.
compiler/file_names.m:
    Replace the current groups of extensions, which are based on the
    shared purpose of the files with those extensions, with a smaller
    number of groups, which are based on the algorithm we use to decide
    in what (sub)directories we want to place files with those extensions.
    The old distinctions based on purpose still remain in the naming
    convention for the enum values within each of the new groups.

compiler/analysis.file.m:
compiler/analysis.m:
compiler/compile_target_code.m:
compiler/du_type_layout.m:
compiler/fact_table.m:
compiler/file_kind.m:
compiler/generate_dep_d_files.m:
compiler/llds_out_file.m:
compiler/make.file_names.m:
compiler/make.module_dep_file.m:
compiler/make.module_target.m:
compiler/make.program_target.m:
compiler/make.track_flags.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mercury_compile_main.m:
compiler/mercury_compile_make_hlds.m:
compiler/mercury_compile_middle_passes.m:
compiler/mlds_to_c_file.m:
compiler/mlds_to_cs_file.m:
compiler/mlds_to_java_file.m:
compiler/mode_constraints.m:
compiler/module_cmds.m:
compiler/prog_foreign.m:
compiler/recompilation.used_file.m:
compiler/write_deps_file.m:
compiler/write_module_interface_files.m:
compiler/xml_documentation.m:
    Conform to the changes above.
2023-08-10 02:47:01 +02:00
Zoltan Somogyi
d302a4e5ca Give some predicates/constructors more meaningful names.
compiler/module_cmds.m:
    Rename the update_interface_X predicates to copy_dot_tmp_to_base_file_X,
    because

    - this better describes what they do, and
    - some of the files they are invoked on are *not* interface files.

    Add an extra parameter to copy_dot_tmp_to_base_file_report_any_error
    that specifies what kind of file is being copied, and print *that*
    as part of any error message.

    Do a similar rename of update_interface_result type, and of its
    function symbols.

    Give more meaningful names to touch_interface_datestamp and
    touch_datestamp as well.

compiler/analysis.file.m:
compiler/analysis.m:
compiler/compile_target_code.m:
compiler/export.m:
compiler/intermod.m:
compiler/make.module_target.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_main.m:
compiler/mercury_compile_middle_passes.m:
compiler/mlds_to_c_file.m:
compiler/recompilation.check.m:
compiler/write_module_interface_files.m:
    Conform to the changes above.
2023-08-02 04:02:24 +02:00
Zoltan Somogyi
d5c54ce697 Take ext_src out of the ext type.
compiler/file_names.m:
    Take ext_src out of the ext type, because this allows us to delete
    the I/O state pair of arguments out of every file translation predicate
    other than module_name_to_source_file_name and the ones that create
    directories.

compiler/file_kind.m:
    Delete the ext output argument of file_kind_to_extension, because
    we can't return ext_src for fk_src anymore.

compiler/write_deps_file.m:
    Delete a test for ext_src which could never succeed, because the
    predicate in question is never called with ext_src.

    Undo an accidental change from the diff that introduced
    module_name_to_lib_file_name_create_dirs.

    Conform to the changes above.

compiler/compile_target_code.m:
compiler/fact_table.m:
compiler/make.module_dep_file.m:
compiler/make.module_target.m:
compiler/make.program_target.m:
compiler/make.util.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mercury_compile_main.m:
compiler/mercury_compile_make_hlds.m:
compiler/mlds_to_c_file.m:
compiler/mmc_analysis.m:
compiler/module_cmds.m:
compiler/read_modules.m:
compiler/recompilation.used_file.m:
compiler/write_module_interface_files.m:
    Conform to the changes above.
2023-07-06 16:14:35 +02:00
Zoltan Somogyi
89979d681a Replace Mkdir parameters with predicate versions.
compiler/file_names.m:
    Split module_name_to_file_name into three versions.

    - One corresponds to the old predicate's operation with do_not_create_dirs,
    - one corresponds to the old predicate's operation with do_create_dirs, and
    - one just returns the directory path, and lets the caller make those
      directories if it wants to, using procedures that we now export.

    Do the same for module_name_to_lib_file_name.

    Do not do the same for fact_table_file_name, which has too few callers
    to make it worthwhile.

    The point is that the versions that do not create any dirs should NOT
    need to take I/O state pairs as arguments, once we take ext_src
    out of the ext type.

compiler/compile_target_code.m:
compiler/du_type_layout.m:
compiler/export.m:
compiler/fact_table.m:
compiler/generate_dep_d_files.m:
compiler/llds_out_file.m:
compiler/make.build.m:
compiler/make.module_dep_file.m:
compiler/make.module_target.m:
compiler/make.program_target.m:
compiler/make.track_flags.m:
compiler/make.util.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mercury_compile_main.m:
compiler/mercury_compile_make_hlds.m:
compiler/mercury_compile_middle_passes.m:
compiler/mercury_compile_mlds_back_end.m:
compiler/mlds_to_c_file.m:
compiler/mlds_to_cs_file.m:
compiler/mlds_to_java_file.m:
compiler/mmc_analysis.m:
compiler/mode_constraints.m:
compiler/module_cmds.m:
compiler/read_modules.m:
compiler/recompilation.used_file.m:
compiler/write_deps_file.m:
compiler/write_module_interface_files.m:
compiler/xml_documentation.m:
    Update calls to the affected predicates.

    In some places, add XXXs about seemingly-strange choices about
    what calls create directories and which don't.
2023-07-06 12:36:14 +02:00
Zoltan Somogyi
6517982c87 s/newext/ext/g and s/NewExt/Ext/g. 2023-07-04 22:32:38 +02:00
Zoltan Somogyi
0b60f07c46 Cut over to the new code in file_names.m.
compiler/file_names.m:
    Delete the old code for doing filename translations, and use
    just the new code.

    Delete all the code that was needed only for comparing the old and
    new code.

    Delete the newext_other extension category, since it was also needed
    only for that purpose. Delete all the code that supported it.

    Switch the infrastructure for recording the demand for translations
    to work with the new code.

compiler/analysis.file.m:
    Delete functions that returned old-style extensions, which are
    not useful anymore. The new-style extensions, by identifying
    extensions via enums rather than strings, serve the purpose
    for which these functions were created.

compiler/mercury_compile_main.m:
    Move the code to call to write out the translation record
    from just after a call to real_main_after_expansion to the
    end of real_main_after_expansion. The reason is that the
    predicate being called now needs access to a globals structure,
    real_main_after_expansion has access to a globals structure,
    but its caller does not.

    Don't try to test the equivalence of the old and new algorithms
    for file name translation, since that test code has been deleted.

compiler/analysis.m:
compiler/compile_target_code.m:
compiler/du_type_layout.m:
compiler/export.m:
compiler/fact_table.m:
compiler/file_kind.m:
compiler/generate_dep_d_files.m:
compiler/grab_modules.m:
compiler/llds_out_file.m:
compiler/make.build.m:
compiler/make.module_dep_file.m:
compiler/make.module_target.m:
compiler/make.program_target.m:
compiler/make.track_flags.m:
compiler/make.util.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mercury_compile_make_hlds.m:
compiler/mercury_compile_middle_passes.m:
compiler/mercury_compile_mlds_back_end.m:
compiler/mlds_to_c_file.m:
compiler/mlds_to_cs_file.m:
compiler/mlds_to_java_file.m:
compiler/mmc_analysis.m:
compiler/mode_constraints.m:
compiler/module_cmds.m:
compiler/prog_foreign.m:
compiler/read_modules.m:
compiler/recompilation.used_file.m:
compiler/write_deps_file.m:
compiler/write_module_interface_files.m:
compiler/xml_documentation.m:
    Conform to the changes in file_names.m.
2023-07-04 18:22:42 +02:00
Zoltan Somogyi
edeb58bc16 Start using the new code in file_names.m.
compiler/file_names.m:
    Change the argument vectors of the predicates that compute filenames
    by taking *two* arguments to specify the extension: adding an argument
    value of the "newext" type right after the old "ext" type. To make this
    possible, export the newext type.

    By default, use the new argument to do every filename computation twice,
    with the old and new algorithms, throwing an exception if their results
    differ. (There is no easy way to test whether the "make-any-needed-dirs"
    part was done the same way, but this is reasonably easy to check
    visually in the code.)

    In case an exception does get thrown, this can be suppressed (hopefully
    after the exception being reported) by setting the environment variable
    "NO_EXT_CHECKS" to any value.

    Add representations of "get the value of this extension from this option"
    style extensions to the newext type, for each of the options that the
    compiler uses this way. The one exception is java_object_file_extension,
    which was used in this way, but which had no code handling it in
    file_names.m.

    Add a representation of ".$(EXT_FOR_PIC_OBJECTS)" as a value
    to the newext type.

    Shorten some function symbol names in the newext type and its components,
    to make them easier to fit without excessive line lengths in the modules
    listed below.

compiler/analysis.file.m:
compiler/analysis.m:
compiler/compile_target_code.m:
compiler/du_type_layout.m:
compiler/export.m:
compiler/fact_table.m:
compiler/file_kind.m:
compiler/generate_dep_d_files.m:
compiler/grab_modules.m:
compiler/llds_out_file.m:
compiler/make.build.m:
compiler/make.module_dep_file.m:
compiler/make.module_target.m:
compiler/make.track_flags.m:
compiler/make.util.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mercury_compile_main.m:
compiler/mercury_compile_make_hlds.m:
compiler/mercury_compile_middle_passes.m:
compiler/mercury_compile_mlds_back_end.m:
compiler/mlds_to_c_file.m:
compiler/mlds_to_cs_file.m:
compiler/mlds_to_java_file.m:
compiler/mmc_analysis.m:
compiler/mode_constraints.m:
compiler/module_cmds.m:
compiler/prog_foreign.m:
compiler/read_modules.m:
compiler/recompilation.used_file.m:
compiler/write_deps_file.m:
compiler/write_module_interface_files.m:
compiler/xml_documentation.m:
    Pass extensions as ext/newext pairs, not just as exts.

    To make this possible, change functions and predicates that returned
    just old-style extensions to return new-style extensions as well.

compiler/make.program_target.m:
    Pass extensions as ext/newext pairs, not just as exts.

    Add an XXX about java_object_file_extension for Julien, since he added
    this option (in 2001 :-().
2023-06-07 18:46:48 +02:00
Zoltan Somogyi
6bdd8b84ee Move maybe_changed to maybe_succeeded.m and rename it.
compiler/maybe_util.m:
    Move the maybe_changed type from several modules of the compiler
    to maybe_succeeded.m, and rename it to maybe_util.m.

compiler/libs.m:
compiler/notes/compiler_design.html:
    Implement and document the rename.

compiler/common.m:
compiler/compile_target_code.m:
compiler/decide_type_repn.m:
compiler/det_analysis.m:
compiler/det_util.m:
compiler/equiv_type.m:
compiler/equiv_type_hlds.m:
compiler/file_util.m:
compiler/llds_out_file.m:
compiler/make.build.m:
compiler/make.dependencies.m:
compiler/make.module_dep_file.m:
compiler/make.module_target.m:
compiler/make.program_target.m:
compiler/make.top_level.m:
compiler/make.track_flags.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mercury_compile_main.m:
compiler/mercury_compile_mlds_back_end.m:
compiler/mlds_to_c_file.m:
compiler/mlds_to_c_type.m:
compiler/mlds_to_cs_file.m:
compiler/mlds_to_java_file.m:
compiler/module_cmds.m:
compiler/parse_tree_out.m:
compiler/process_util.m:
compiler/recompilation.version.m:
compiler/write_module_interface_files.m:
    Conform to the changes above.
2023-04-21 17:24:30 +10:00
Zoltan Somogyi
6f82724091 Pass streams explicitly at the top levels.
compiler/mercury_compile_main.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mercury_compile_make_hlds.m:
compiler/mercury_compile_middle_passes.m:
compiler/mercury_compile_mlds_back_end.m:
    Pass progress and error streams explicitly in these top modules
    of the compiler. Use "XXX STREAM" to mark places where we could switch
    from using stderr for both the progress and error streams to using
    module-specific files as the progress and/or error streams.

compiler/passes_aux.m:
    Add a "maybe_" prefix to the names of the predicates that print progress
    messages at the appropriate verbosity levels, as their printing of those
    messages is conditional.

    Provide versions of those predicates that take explicitly specified
    streams to write to, and mark the versions that write to the current
    output stream as obsolete.

    The predicate that wrote progress messages for procedures
    used to have two versions, one taking a pred_proc_id, and one taking
    a pred_id/proc_id pair. Delete the latter, because the arity difference
    that differentiated the two versions is now needed for the difference
    between supplying and not supplying an explicit stream.

compiler/file_util.m:
compiler/hlds_error_util.m:
compiler/write_error_spec.m:
    Delete several predicates that wrote to the current output stream,
    since all their callers now use the versions that specify an explicit
    output stream.

compiler/check_promise.m:
compiler/check_typeclass.m:
compiler/closure_analysis.m:
compiler/complexity.m:
compiler/cse_detection.m:
compiler/deforest.m:
compiler/delay_construct.m:
compiler/delay_partial_inst.m:
compiler/deps_map.m:
compiler/direct_arg_in_out.m:
compiler/grab_modules.m:
compiler/handle_options.m:
compiler/hhf.m:
compiler/inlining.m:
compiler/make.module_dep_file.m:
compiler/ml_proc_gen.m:
compiler/ml_top_gen.m:
compiler/mode_constraints.m:
compiler/modes.m:
compiler/polymorphism.m:
compiler/purity.m:
compiler/read_modules.m:
compiler/recompilation.check.m:
compiler/saved_vars.m:
compiler/simplify_proc.m:
compiler/size_prof.m:
compiler/stack_opt.m:
compiler/switch_detection.m:
compiler/typecheck.m:
compiler/unique_modes.m:
compiler/unneeded_code.m:
compiler/write_module_interface_files.m:
    Get these modules to take an explicitly specified stream to which
    to write progress messages when they are invoked from mercury_compile_*.m.

    For predicates in these modules that can be invoked both directly
    by mercury_compile_*.m *and* by other modules, the latter effectively
    as a subcontractor, make them take a maybe(stream), with the intention
    being that all the other modules that use the predicate as a subcontractor
    would pass a "no". This avoids the need to pass progress streams
    down to the internals of other passes, and also avoids overwhelming
    the user invoking the compiler with unnecessary details.

    As above, and also delete a progress message that shouldn't be needed
    anymore.

    Move a test of option value compatibility from
    mercury_compile_middle_passes.m to handle_options.m, where it belongs.

compiler/float_regs.m:
    Write a debug message to the debug stream.

compiler/pd_info.m:
    Include the progress stream in the pd_info structure, because this is
    the simplest way to ensure that all parts of the partial deduction pass
    have access to it.

compiler/make.build.m:
compiler/make.program_target.m:
compiler/make.track_flags.m:
    Make the minimal changes needed to conform to the changes above.
    The rest can be done when the make package is converted to consistently
    use explicit streams.

compiler/bytecode_gen.m:
compiler/structure_reuse.direct.m:
compiler/structure_reuse.versions.m:
compiler/structure_sharing.analysis.m:
    Make the minimal changes needed to conform to the changes above.
    The rest can be done when these modules start being maintained again.

compiler/Mercury.options:
    Stop specifying --no-warn-implicit-stream-calls for mercury_compile_*.m,
    since this diff makes that unnecessary.

    Start specifying --no-warn-implicit-stream-calls for some modules that
    are not currently being actively maintained, because the addition of
    progress-reporting predicates that take explicitly specified streams
    would otherwise cause the generation of such warnings for them.
2022-11-01 11:33:41 +11:00
Zoltan Somogyi
307b1dc148 Split up error_util.m into five modules.
compiler/error_spec.m:
    This new module contains the part of the old error_util.m that defines
    the error_spec type, and some functions that can help construct pieces
    of error_specs. Most modules of the compiler that deal with errors
    will need to import only this part of the old error_util.m.

    This change also renames the format_component type to format_piece,
    which matches our long-standing naming convention for variables containing
    (lists of) values of this type.

compiler/write_error_spec.m:
    This new module contains the part of the old error_util.m that
    writes out error specs, and converts them to strings.

    This diff marks as obsolete the versions of predicates that
    write out error specs to the current output stream, without
    *explicitly* specifying the intended stream.

compiler/error_sort.m:
    This new module contains the part of the old error_util.m that
    sorts lists of error specs and error msgs.

compiler/error_type_util.m:
    This new module contains the part of the old error_util.m that
    convert types to format_pieces that generate readable output.

compiler/parse_tree.m:
compiler/notes/compiler_design.html:
    Include and document the new modules.

compiler/error_util.m:
    The code remaining in the original error_util.m consists of
    general utility predicates and functions that don't fit into
    any of the modules above.

    Delete an unneeded pair of I/O states from the argument list
    of a predicate.

compiler/file_util.m:
    Move the unable_to_open_file predicate here from error_util.m,
    since it belongs here. Mark another predicate that writes
    to the current output stream as obsolete.

compiler/hlds_error_util.m:
    Mark two predicates that wrote out error_spec to the current output
    stream as obsolete, and add versions that take an explicit output stream.

compiler/Mercury.options:
    Compile the modules that call the newly obsoleted predicates
    with --no-warn-obsolete, for the time being.

compiler/*.m:
    Conform to the changes above, mostly by updating import_module
    declarations, and renaming format_component to format_piece.
2022-10-12 20:50:16 +11:00
Zoltan Somogyi
07f877bc3f Carve term_context.m out of term.m.
library/term.m:
library/term_context.m:
    As above.

    Rename the term.context type as term_context.term_context, with
    term.context now being defined as an equivalence type.

    Replace the context_init function and predicate and the dummy_context_init
    function with just one function: dummy_context. This name includes
    the important part (the fact that it return a *dummy* context) and deletes
    the nonimportant part (dummy contexts are just about never updated,
    so the function does not really "initialize" them).

    Reduce function/predicate pairs that do the same thing to just a function.

library/MODULES_DOC:
library/library.m:
    Add the new module to the list of standard library modules.

NEWS:
    Mention the new module, and the obsoleting of the moved predicates
    and functions in term.m.

compiler/*.m:
library/*.m:
    Conform to the changes above.
2022-08-23 12:56:37 +10:00
Zoltan Somogyi
7b6bace9ec Don't return dummy parse_trees for missing files.
The predicates that read a Mercury source, interface or optimization file
used to return four things:

- the name of the file (for callers who specified only a module name),
- the timestamp, if requested and available,
- a parse tree, and
- a representation of any errors (sets of error categories, and error_specs).

However, these four things were not independent. Some combinations of their
values were not allowed, but (a) there was no documentation of what these
combinations were, and (b) code that processed these four things had to be
prepared to handle illegal as well as legal combinations.

This diff makes these predicates return only one result, which contains

- all four of the above things, when the file could be opened, but
- only the file name and a representation of the error if the file
  could not be opened,
- only the file name and a representation of *no* errors, if the caller
  asked the predicate to read the file only if its timestamp did not match
  a specified value, and it does match that value.

We use a somewhat modified version of an existing type, have_read_module,
for this. It is modified both by including information that its users
now need that they did not need before, and shortening the names of its
function symbols, which now occur in many more places than before.

compiler/read_modules.m:
    Make the change to the output arguments described above.

    Making this change requires having the affected predicates deal with
    the case where we either cannot find or cannot open the relevant file.
    (The two are effectively the same thing in this module, since we search
    by attempting to open.) Passing that task off to parse_modules.m
    was always inelegant.

    Simplify the have_read_module_map type by making the key always
    be a module_name. We deleted the only use of have_read_module_maps
    with another kind of key a while ago.

    Delete some no-longer-needed predicates.

compiler/parse_module.m:
    Delete the code dealing with the absence of a file stream to parse.

    Replace code that used to construct dummy parse trees with code
    that simply returns *no* parse tree if the file could be opened
    but could not be read, or if its timestamp indicated that reading it
    would have been redundant.

    Delete some utility predicates moved to parse_error.m, so that
    read_modules.m could also use them.

    Fix comment rot.

compiler/parse_error.m:
    Add some utility predicates for use by read_modules.m and parse_module.m.

compiler/deps_map.m:
    Conform to the changes above.

    Document the dubious effects of an old design decision.

    Fix a misleading predicate name.

    Fix comment rot.

compiler/grab_modules.m:
    Conform to the changes above.

    Some predicates used to return parse trees that could be dummies.
    Change them to return just the parts of the parse tree that the
    caller was interested in, which was usually a tiny part, and which
    can be constructed trivially even when we don't have a parse tree.

    Delete an unneeded type.

compiler/recompilation.check.m:
    Conform to the changes above.

    Represent the operations we need to test version numbers in interface files
    as a typeclass, and rewrite the checking operation in terms of that
    typeclass, with one instance for each kind of interface file.

    Move some repeated code into a predicate.

    Shorten some long names.

compiler/mercury_compile_main.m:
    Conform to the changes above.

    Break up a large predicate.

compiler/generate_dep_d_files.m:
compiler/make.module_dep_file.m:
compiler/write_module_interface_files.m:
    Conform to the changes above.

compiler/prog_item.m:
    Delete the parse_tree_some_int type. The change in recompilation.check.m,
    deleted its last few uses there, and allowed the deletion of the last
    uses in read_modules.m.

tests/recompilation/two_module_debug:
    Extend this script to help deal with problems in all stages of the
    execution of a test case, since that was required while debugging
    this diff.

    Document which parts of this script correspond to which parts of
    two_module_test.

tests/recompilation/test_functions:
tests/recompilation/two_module_test:
    Simplify the logic of the main test function, by testing a condition
    once instead of three times.

    Specify whether a recompilation test is expected to succeed or fail
    directly, using alternatives that model a bespoke type, instead
    of alternatives that mimic a boolean answer to a question, which
    does not help readers who don't remember the question.

    Always put shell variable names in braces.

    Note a problem that makes one of the shell functions ineffective.

tests/recompilation/Mmakefile:
    Tell two_module_test what to do using its updated interface.
2022-04-30 14:37:22 +10:00
Zoltan Somogyi
94affaec76 Separate fatal and nonfatal module reading errors, ...
... and bundle sets of error kinds and their associated lists of error_specs
into a single structure.

compiler/parse_error.m:
    Use separate types to represent fatal errors and nonfatal errors,
    because those two kinds of errors are often treated differently.

    Change the read_module_errors type, which used to be just a set of errors,
    to being a set of fatal errors, a set of nonfatal errors, the error
    message for each, and error messages for warnings. This preserves
    distinctions that we should be able to use in the future to improve
    error handling.

    Provide utility routines for operating on this now-structured type.

compiler/parse_types.m:
    Change the definition of the item_or_marker type slighly to preserve
    distinctions that the read_module_errors type now cares about.

compiler/parse_module.m:
    Thread the new read_module_errors structure through the predicates
    that parse source, interface and optimization files.

    Treat the failure of reading the contents of a file as a fatal error.
    Previously, we treated it as a nonfatal error.

    Delete some fields from types when those field were always set to the
    same value, and therefore contained no useful information.

compiler/module_baggage.m:
    Switch to using the new read_module_errors structure in module baggage.

compiler/grab_modules.m:
    Conform to the changes above.

    Use a bespoke type to represent the absence/presence of errors
    when reading in optimization files.

compiler/mercury_compile_make_hlds.m:
    Conform to the changes above.

    Delete a call to pre_hlds_write_out_errors that duplicates
    another call a few lines above.

compiler/deps_map.m:
compiler/generate_dep_d_files.m:
compiler/make.module_dep_file.m:
compiler/mercury_compile_main.m:
compiler/parse_item.m:
compiler/parse_pragma.m:
compiler/parse_type_defn.m:
compiler/read_modules.m:
compiler/recompilation.check.m:
compiler/write_deps_file.m:
compiler/write_module_interface_files.m:
    Conform to the changes above.
2022-04-23 20:56:12 +10:00
Zoltan Somogyi
ea4f95a7ed Use var_tables in lco.m, and when dumping goals.
Since this is the first converted module that dumps out goals when
debugging trace flags are enabled, this required generalizing the code
that does that, to take either varsets or var_tables as a means of
specifying the names of variables. We do this via a new type,
var_name_source, which contains either a varset or a var_table.

Almost all of this diff is there to implement this generalization.
A large part of it affects code in the parse_tree package that we use
to write out the parts of HLDS goals that are defined by types defined
in that package. Since we want to avoid making any part of the parse_tree
package dependent on the hlds package, this required defining the
var_name_source type in the parse_tree package, which in turn requires
var_table.m to be in that same package.

compiler/lco.m:
    Convert this module to use var_tables instead of varsets and vartypes.

compiler/var_table.m:
    Move this module from the hlds package to the parse_tree package.

    To make this, possible, move the parts that required access to the HLDS
    to hlds_pred.m, from where it was usually invoked.

    Export some utility predicates to allow the moved code to work
    in hlds_pred.m without access to the actual definition of the
    var_table type.

    Define the var_name_source type.

    Add some utility functions for use by code writing out variable names.

compiler/hlds_pred.m:
    Add the code moved from var_table.m.

compiler/vartypes.m:
    Move this module from the hlds package to the parse_tree package,
    for symmetry with var_table.m. It did not depend on being in hlds
    in any way.

compiler/hlds.m:
compiler/parse_tree.m:
    Move vartypes.m and var_table.m from the hlds package
    to the parse_tree package.

compiler/hlds_out_goal.m:
    Change all the predicates in this module to take a var_name_source
    instead of a prog_varset.

    Fix some comments.

compiler/hlds_out_util.m:
    Change some of the predicates in this module (those called from
    hlds_out_goal.m) to take a var_name_source instead of a prog_varset.

compiler/parse_tree_out_term.m:
    Provide variants of some existing predicates and functions that take
    var_name_sources instead of varsets. The code of the copies
    duplicates the logic of the originals, though I hope that this
    duplication can be done away with at the end of the transition.
    (The best solution would be to use a typeclass with methods
    that convert vars to their names, but we would want to ensure
    that the compiler can specialize all the affected predicates
    and functions to the two instances of this typeclass, which is
    something that we cannot do yet. In the meantime, the lack of
    any generalization in the old versions preserves their performance.)

tools/sort_imports:
tools/filter_sort_imports:
    A new tool that automatically sorts any occurrences of consecutive
    ":- import_module" declarations in the named files. The sorting is done
    in filter_sort_imports; sort_imports loops over the named files.

    After automatically replacing all occurrences of hlds.{vartypes,var_table}
    in import_module declarations with their parse_tree versions, the updated
    import_module declarations were usually out of order with respect to
    their neighbours. I used this script to fix that, and some earlier
    out-of-order imports.

compiler/accumulator.m:
compiler/add_class.m:
compiler/add_clause.m:
compiler/add_foreign_proc.m:
compiler/add_heap_ops.m:
compiler/add_pragma_type_spec.m:
compiler/add_pred.m:
compiler/add_trail_ops.m:
compiler/analysis.m:
compiler/arg_info.m:
compiler/build_mode_constraints.m:
compiler/bytecode_gen.m:
compiler/call_gen.m:
compiler/check_promise.m:
compiler/closure_analysis.m:
compiler/closure_gen.m:
compiler/code_info.m:
compiler/code_loc_dep.m:
compiler/common.m:
compiler/compile_target_code.m:
compiler/complexity.m:
compiler/const_prop.m:
compiler/constraint.m:
compiler/continuation_info.m:
compiler/convert_parse_tree.m:
compiler/coverage_profiling.m:
compiler/cse_detection.m:
compiler/ctgc.datastruct.m:
compiler/ctgc.util.m:
compiler/dead_proc_elim.m:
compiler/deep_profiling.m:
compiler/deforest.m:
compiler/delay_construct.m:
compiler/delay_partial_inst.m:
compiler/dep_par_conj.m:
compiler/det_analysis.m:
compiler/det_report.m:
compiler/det_util.m:
compiler/direct_arg_in_out.m:
compiler/disj_gen.m:
compiler/distance_granularity.m:
compiler/equiv_type_hlds.m:
compiler/exception_analysis.m:
compiler/file_names.m:
compiler/float_regs.m:
compiler/follow_vars.m:
compiler/format_call.m:
compiler/generate_dep_d_files.m:
compiler/get_dependencies.m:
compiler/goal_expr_to_goal.m:
compiler/goal_mode.m:
compiler/goal_path.m:
compiler/goal_store.m:
compiler/goal_util.m:
compiler/granularity.m:
compiler/hhf.m:
compiler/higher_order.m:
compiler/hlds_clauses.m:
compiler/hlds_code_util.m:
compiler/hlds_error_util.m:
compiler/hlds_goal.m:
compiler/hlds_llds.m:
compiler/hlds_out_pred.m:
compiler/hlds_rtti.m:
compiler/hlds_statistics.m:
compiler/inlining.m:
compiler/inst_check.m:
compiler/inst_test.m:
compiler/inst_user.m:
compiler/instance_method_clauses.m:
compiler/instmap.m:
compiler/intermod.m:
compiler/intermod_analysis.m:
compiler/interval.m:
compiler/introduce_exists_casts.m:
compiler/introduce_parallelism.m:
compiler/item_util.m:
compiler/lambda.m:
compiler/live_vars.m:
compiler/liveness.m:
compiler/llds.m:
compiler/llds_out_data.m:
compiler/llds_out_file.m:
compiler/llds_out_util.m:
compiler/lookup_switch.m:
compiler/loop_inv.m:
compiler/make.module_target.m:
compiler/make.util.m:
compiler/make_goal.m:
compiler/make_hlds_separate_items.m:
compiler/make_hlds_types.m:
compiler/mark_tail_calls.m:
compiler/mercury_compile_mlds_back_end.m:
compiler/middle_rec.m:
compiler/ml_accurate_gc.m:
compiler/ml_args_util.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/ml_code_gen.m:
compiler/ml_code_util.m:
compiler/ml_commit_gen.m:
compiler/ml_disj_gen.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_gen_info.m:
compiler/ml_lookup_switch.m:
compiler/ml_proc_gen.m:
compiler/ml_simplify_switch.m:
compiler/ml_switch_gen.m:
compiler/ml_tag_switch.m:
compiler/ml_unify_gen.m:
compiler/ml_unify_gen_construct.m:
compiler/ml_unify_gen_deconstruct.m:
compiler/ml_unify_gen_test.m:
compiler/ml_unify_gen_util.m:
compiler/mlds_to_c_data.m:
compiler/mlds_to_c_func.m:
compiler/mlds_to_c_global.m:
compiler/mlds_to_cs_class.m:
compiler/mlds_to_cs_file.m:
compiler/mlds_to_java_data.m:
compiler/mlds_to_java_file.m:
compiler/mlds_to_java_stmt.m:
compiler/mlds_to_java_type.m:
compiler/mmc_analysis.m:
compiler/mode_comparison.m:
compiler/mode_constraints.m:
compiler/mode_debug.m:
compiler/mode_errors.m:
compiler/mode_info.m:
compiler/mode_ordering.m:
compiler/modecheck_call.m:
compiler/modecheck_coerce.m:
compiler/modecheck_goal.m:
compiler/modecheck_unify.m:
compiler/modecheck_util.m:
compiler/modes.m:
compiler/module_cmds.m:
compiler/old_type_constraints.m:
compiler/opt_debug.m:
compiler/optimize.m:
compiler/options_file.m:
compiler/ordering_mode_constraints.m:
compiler/par_loop_control.m:
compiler/parse_item.m:
compiler/parse_string_format.m:
compiler/parse_tree_out_inst.m:
compiler/parse_tree_to_term.m:
compiler/parse_util.m:
compiler/pd_debug.m:
compiler/pd_info.m:
compiler/pd_util.m:
compiler/peephole.m:
compiler/polymorphism.m:
compiler/polymorphism_info.m:
compiler/polymorphism_lambda.m:
compiler/polymorphism_type_class_info.m:
compiler/polymorphism_type_info.m:
compiler/post_typecheck.m:
compiler/pragma_c_gen.m:
compiler/pred_name.m:
compiler/pred_table.m:
compiler/prog_item.m:
compiler/prog_rep.m:
compiler/prop_mode_constraints.m:
compiler/purity.m:
compiler/push_goals_together.m:
compiler/qual_info.m:
compiler/quantification.m:
compiler/rbmm.execution_path.m:
compiler/rbmm.m:
compiler/rbmm.points_to_analysis.m:
compiler/rbmm.points_to_graph.m:
compiler/rbmm.points_to_info.m:
compiler/rbmm.region_resurrection_renaming.m:
compiler/rbmm.region_transformation.m:
compiler/recompilation.used_file.m:
compiler/recompilation.version.m:
compiler/recompute_instmap_deltas.m:
compiler/resolve_unify_functor.m:
compiler/rtti.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
compiler/saved_vars.m:
compiler/set_of_var.m:
compiler/simplify_goal_call.m:
compiler/simplify_goal_conj.m:
compiler/simplify_goal_disj.m:
compiler/simplify_goal_ite.m:
compiler/simplify_goal_scope.m:
compiler/simplify_goal_switch.m:
compiler/simplify_goal_unify.m:
compiler/simplify_info.m:
compiler/simplify_proc.m:
compiler/size_prof.m:
compiler/smm_common.m:
compiler/ssdebug.m:
compiler/stack_alloc.m:
compiler/stack_layout.m:
compiler/stack_opt.m:
compiler/stm_expand.m:
compiler/store_alloc.m:
compiler/structure_reuse.analysis.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/structure_reuse.direct.detect_garbage.m:
compiler/structure_reuse.domain.m:
compiler/structure_reuse.indirect.m:
compiler/structure_reuse.lbu.m:
compiler/structure_reuse.lfu.m:
compiler/structure_sharing.analysis.m:
compiler/structure_sharing.domain.m:
compiler/superhomogeneous.m:
compiler/switch_detection.m:
compiler/switch_gen.m:
compiler/switch_util.m:
compiler/table_gen.m:
compiler/tabling_analysis.m:
compiler/term_constr_build.m:
compiler/term_constr_data.m:
compiler/term_constr_initial.m:
compiler/term_constr_main.m:
compiler/term_constr_main_types.m:
compiler/term_constr_util.m:
compiler/term_pass1.m:
compiler/term_traversal.m:
compiler/term_util.m:
compiler/trace_gen.m:
compiler/trailing_analysis.m:
compiler/transform_llds.m:
compiler/try_expand.m:
compiler/tupling.m:
compiler/type_assign.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
compiler/typecheck.m:
compiler/typecheck_debug.m:
compiler/typecheck_errors.m:
compiler/typecheck_info.m:
compiler/unify_gen_construct.m:
compiler/unify_gen_deconstruct.m:
compiler/unify_proc.m:
compiler/unique_modes.m:
compiler/unneeded_code.m:
compiler/untupling.m:
compiler/unused_args.m:
compiler/unused_imports.m:
compiler/var_locn.m:
compiler/write_deps_file.m:
compiler/write_module_interface_files.m:
    Conform to the changes above.
2022-04-18 02:00:38 +10:00
Zoltan Somogyi
3503128d9b Rename module_imports.m to module_baggage.m.
compiler/module_baggage.m:
    This reflects the changes to this module over the last year.

compiler/parse_tree.m:
    Change the module name in the include_module declaration.

compiler/deps_map.m:
compiler/generate_dep_d_files.m:
compiler/grab_modules.m:
compiler/make.dependencies.m:
compiler/make.module_dep_file.m:
compiler/make.module_target.m:
compiler/mercury_compile_main.m:
compiler/module_dep_info.m:
compiler/recompilation.check.m:
compiler/recompilation.usage.m:
compiler/recompilation.used_file.m:
compiler/write_deps_file.m:
compiler/write_module_interface_files.m:
    Change the module name in import_module declarations.

compiler/notes/compiler_design.html:
    Change the module name in the module description.
2022-04-15 12:41:32 +10:00
Zoltan Somogyi
25b4b67403 Carve io.file.m out of io.m.
library/io.file.m:
library/io.m:
    Move two sections of io.m, the "file handling predicates" section
    and the "handling temporary files" section to the new submodule io.file.m.

    Leave behind in io.m "forwarding predicates", predicates that do nothing
    except call the moved predicates in io.file.m, to provide backward
    compatibility. But do mark the forwarding predicates as obsolete,
    to tell people to update their (at their leisure, since the obsoleteness
    warning can be turned off).

    Also leave behind in io.m the definitions of the two types used
    by some parameters of some of the moved predicates. Document the reason
    why this is done.

library/MODULES_DOC:
    List the new module among the documented modules.

NEWS:
    Announce the changes.

browser/browse.m:
browser/interactive_query.m:
browser/listing.m:
compiler/analysis.file.m:
compiler/compile_target_code.m:
compiler/export.m:
compiler/fact_table.m:
compiler/file_util.m:
compiler/handle_options.m:
compiler/make.build.m:
compiler/make.module_dep_file.m:
compiler/make.module_target.m:
compiler/make.program_target.m:
compiler/make.util.m:
compiler/mercury_compile_main.m:
compiler/module_cmds.m:
compiler/parse_module.m:
compiler/passes_aux.m:
compiler/prog_event.m:
compiler/recompilation.check.m:
compiler/write_deps_file.m:
compiler/write_module_interface_files.m:
deep_profiler/conf.m:
deep_profiler/mdprof_cgi.m:
library/dir.m:
mdbcomp/program_representation.m:
ssdb/ssdb.m:
    Call the file operation predicates directly in io.file.m, not indirectly
    through io.m.

    In two modules, add a #include of fcntl.h in C code. These modules contain
    C code that needs this #include, but until now, they got it via a copy
    in an automatically generated C header file of a foreign_decl pragma
    in io.m that contained that #include. This diff moves that foreign_decl
    to io.file.m, removing that crutch.

tests/debugger/browser_test.m:
tests/hard_coded/bit_buffer_test.m:
tests/hard_coded/bitmap_test.m:
tests/hard_coded/construct_bug.m:
tests/hard_coded/dir_fold.m:
tests/hard_coded/dir_test.m:
tests/hard_coded/read_binary_int16.m:
tests/hard_coded/read_binary_int32.m:
tests/hard_coded/read_binary_int64.m:
tests/hard_coded/read_binary_uint16.m:
tests/hard_coded/read_binary_uint32.m:
tests/hard_coded/read_binary_uint64.m:
tests/hard_coded/read_bitmap_size.m:
tests/hard_coded/remove_file.m:
tests/hard_coded/write_binary.m:
tests/hard_coded/write_binary_int8.m:
tests/hard_coded/write_binary_multibyte_int.m:
tests/hard_coded/write_binary_uint8.m:
    Call the file operation predicates directly in io.file.m, not indirectly
    through io.m.
2022-03-08 06:01:21 +11:00
Zoltan Somogyi
b9908ddaf6 Standardize messages about reading files.
compiler/read_modules.m:
    When reading in Mercury source files, interface files or optimization
    files, we optionally generate progress messages of the form

        % Reading module xyz... done.

    But the form of these messages has not been consistent, so that
    when reading .opt files, we got messages of the form

        % Reading xyz.opt...
        % Done.

    And we sometimes got messages such as

        % Reading .int file for module xyz.int... done.

    This is mostly because responsibility for constructing these messages
    has been dispersed; different parts of it were generated in different
    places, and sometimes when one place switches to a new scheme, not all
    the corresponding places where updated accordingly.

    This diff changes that by constructing these messages in two predicates
    (output_read_msg and output_read_done_msg) in this module, leaving to
    callers only a choice between a set of four message forms.

    To make this possible, move the read_module_{plain,trans}_opt predicates
    here from grab_modules.m. Their equivalents for reading Mercury source
    files and interface files were here already, so here is where they belong.

    Add several "XXX CLEANUP" markers for future changes.

compiler/parse_module.m:
    Do not expect callers to compute the filenames containing .opt
    and .trans_opt files, since the code here already does that.

compiler/grab_modules.m:
    Delete the predicates moved to read_modules.m (under new names, to fit in
    with the predicates already there).

    Delete some obsolete comments.

    Fix some old variable names.

compiler/deps_map.m:
compiler/generate_dep_d_files.m:
compiler/make.module_dep_file.m:
compiler/mercury_compile_main.m:
compiler/recompilation.check.m:
compiler/write_module_interface_files.m:
    Conform to the changes above.
2022-01-21 18:00:22 +11:00
Zoltan Somogyi
243491523d Stop counting errors in module_infos.
Over time, we have almost completely switched over to using error_specs,
using their severity (if not yet printed out) and their effect on the
exit status (if already printed out) to represent the presence of errors,
leaving only a few places that either updated or paid attention to the
num_error field in the module_info. This diff completes that process.

compiler/hlds_module.m:
    Delete the num_errors field in the module_info, and the predicates
    that operate on it.

compiler/hlds_error_util.m:
    Delete module_info arguments whose only purpose was to update the
    now-delete field.

compiler/error_util.m:
    Delete the old write_error_spec predicates that updated a count of warnings
    and a count of errors.

    Rename the write_error_spec_ignore predicates, which ignored those counts,
    by deleting the "_ignore" from their names. This makes them take the
    place of the deleted predicates.

compiler/add_pragma_type_spec.m:
compiler/add_pred.m:
compiler/add_type.m:
compiler/compile_target_code.m:
compiler/cse_detection.m:
compiler/find_module.m:
compiler/generate_dep_d_files.m:
compiler/handle_options.m:
compiler/make.module_dep_file.m:
compiler/make.module_target.m:
compiler/make.program_target.m:
compiler/make.top_level.m:
compiler/make.track_flags.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mercury_compile_main.m:
compiler/mercury_compile_middle_passes.m:
compiler/mercury_compile_mlds_back_end.m:
compiler/mode_info.m:
compiler/modes.m:
compiler/pd_util.m:
compiler/pred_table.m:
compiler/recompilation.check.m:
compiler/typecheck.m:
compiler/write_module_interface_files.m:
    Conform to the changes above.
2022-01-15 16:33:38 +11:00
Zoltan Somogyi
1927c8ee21 Separate always_treat_as_first from treat_as_first.
compiler/error_util.m:
    The internal operation of formatting error messages requires knowing
    whether an error_msg should be treated as the first message, or not.
    (First messages get indented 1 space; other messages get indented by 3.)
    We use the treat_at_first type for this.

    In the past, we also used this type in error_msgs themselves, but there,
    one of the alternatives of the type, do_not_treat_as_first, is misleading.
    Such messages will in fact be treated as first if they are in fact
    the first error_msg in an error_spec, which happens quite frequently,
    since *most* error_specs contain only one error_msg.

    This diff therefore defines a new type, always_treat_as_first,
    whose two values have names that *accurately* reflect their meaning:
    always_treat_as_first, and treat_based_on_posn. Make all code outside
    error_util.m itself use this type; restrict the use of the treat_as_first
    type to just the code that does error message formatting.

compiler/add_class.m:
compiler/add_foreign_proc.m:
compiler/check_typeclass.m:
compiler/common.m:
compiler/compile_target_code.m:
compiler/compiler_util.m:
compiler/compute_grade.m:
compiler/fact_table.m:
compiler/find_module.m:
compiler/grab_modules.m:
compiler/handle_options.m:
compiler/make.top_level.m:
compiler/mercury_compile_main.m:
compiler/mercury_compile_mlds_back_end.m:
compiler/mode_errors.m:
compiler/modes.m:
compiler/options_file.m:
compiler/parse_module.m:
compiler/post_typecheck.m:
compiler/prog_event.m:
compiler/recompilation.check.m:
compiler/term_constr_errors.m:
compiler/term_errors.m:
compiler/typecheck_msgs.m:
compiler/write_module_interface_files.m:
    Conform to the change in error_util.m. In many cases where this is
    appropriate, use the recently introduced simplest_no_context_specs.
2022-01-12 18:03:17 +11:00
Zoltan Somogyi
8f50e16eb2 Fix a possible silent failure when making .int files.
When I split two files in a recent change, I ran into an annoying problem.
The problem was caused by unneeded imports in the interface of the new modules,
whose initial part I originally simply copied from the source module.
The problem was that when I attempted to compile new module A which imported
new module B, the compilation of module A would fail with a message about
not finding module B's .int file. It couldn't find B.int because the
compiler invocation that was supposed to create it failed, but it did not
print any error message about *why* it failed, and as a consequence,
it also did not set the exit status to nonzero to tell mmake that
the file was not actually built, so later build actions that need that file
should not be executed.

The cause of this problem was the following.

- The default value of the --warn-unused-imports is off, but COMP_FLAGS
  turns it on for modules in the compiler directory. This enables warnings
  generated by unused_imports.m.

- There is code that does a similar job in module_qual.qual_errors.m, but
  that one is limited to imports in interface sections. Due to the overlap
  between tasks, when this code finds an unused import_module declaration
  in an interface, it generates an error message that was conditional
  on --warn-unused-imports being off. When it was on, as it is with
  COMP_FLAGS, it generates an error_spec that, when given to write_error_specs,
  generates no output.

- Code in write_module_interface_files.m that decided whether the building
  of the .int file has failed, tested only whether the process of generating
  its contents has returned any error_specs, not whether it returned
  any error_specs that would actually be printed, and, by being printed
  with a sufficiently high severity, would set the exit status to signal
  failure.

compiler/error_util.m:
    The two changes to this file together fix the root cause of this problem.

    First, a new predicate checks whether an error_spec has any part
    whose printing is NOT disabled by being attached to an unmet condition.

    Second, the predicate through which we pass all error_specs created
    during the generation of the contents of the .int file filters out
    any error_specs that yield no output.

The later changes are not strictly part of the bugfix, they are there
simply to make the code simpler to understand, in the hope that this fact
will reduce the probability of similar problems in the future.

compiler/module_qual.qual_errors.m:
    Instead of generating error_specs that are conditional on
    --warn-unused-imports being OFF, generate them conditional on
    the new option --warn-unused-interface-imports being ON.
    Using --warn-unused-imports here was strange because that option controls
    whether the compiler invokes unused_imports.m. It was NOT specific
    to this piece of code, while the new option is.

compiler/options.m:
doc/user_guide.texi:
    Add the new option. Comment out its documentation, since I don't think
    I can describe the reason for its existence simply enough for users
    to understand.

compiler/handle_options.m:
    Turn off the new option --warn-unused-interface-imports if
    --warn-unused-imports is set. This duplicates the old behavior
    of module_qual.qual_errors.m.

    Turn off the new option --warn-unused-interface-imports if
    we are generating interface files. This is because the presence
    of unneeded imports in .m files does not prevent the creation
    of valid .int files, so having to fix such warnings at .int file
    creation time interferes with the programmer's ability to choose
    the order in which he/she works on getting modules to a compilable shape.

compiler/write_module_interface_files.m:
    Generate all output on error as part of an error_spec.

compiler/unused_imports.m:
    Fix indentation.

tests/valid_make_int/extra_interface_import.m:
    A new test case for this bug.

tests/valid_make_int/Mmakefile:
    Enable the new test case.
2021-12-17 12:55:29 +11:00
Zoltan Somogyi
1f9948215f Remove obsoleted interface files.
compiler/write_module_interface_files.m:
    When we get errors that prevent us from constructing a new valid version
    of an interface file, delete both

    - any existing copy of that interface file to prevent its now-outdated info
      from causing misleading error messages when compiling other modules, and

    - any existing copy of its timestamp file, to prevent the build system
      from executing any commands that need the now-deleted interface file.
2021-12-02 00:11:04 +11:00
Zoltan Somogyi
8827b6a466 Make --halt-at-invalid-interface the default.
NEWS:
    Mention this fact.

    Group related changes together.

    Fix some typos.

compiler/error_util.m:
    Let the halt_at_invalid_interface option govern whether we print error
    messages when we generate .int/.int2 files, rather than
    the print_errors_warnings_when_generating_interface option.
    This simplifies the use of that option.

compiler/options.m:
doc/user_guide.texi:
    Document the halt_at_invalid_interface option.

    Delete the print_errors_warnings_when_generating_interface option,
    since its functionality has been subsumed into halt_at_invalid_interface.

compiler/grab_modules.m:
    Check the accessibility of imported modules not just when generating target
    language code, but also when generating .int/.int2 files. Without this,
    the test_nested test case, which this diff moves from invalid to
    invalid_make_int, would miss out on some errors being reported
    in its new home.

    To make the above possible, refactor the code that does the check
    to let it work on aug_make_int_units as well as from aug_compilation_units.
    Make the wording of any error message depend on where the info came from,
    because unlike aug_comp_units, aug_make_int_units work with an
    known-incomplete picture of the relevant info.

    Update some obsolete comments.

compiler/write_module_interface_files.m:
    Add a comment about a design decision that affects this diff.

tests/invalid_make_int/Mercury.options:
tests/invalid_make_int/Mmakefile:
    Add to this directory's list the test cases that this diff moves
    to this directory from other test directories, because the errors
    that they test for are now reported at interface generation time.

    Fix the rule handling multimodule tests, now that we have some :-(

    Specify -j1 for this directory, since the two tests moved here
    from invalid_submodules include nested submodules.

tests/invalid_make_int/bad_type_class_constraint_intermodule.{m,int_err_exp}:
    Move this test case here from invalid, renaming files slightly,
    and update the expected output.

tests/invalid_make_int/bug499.{m,int_err_exp}:
    Move this test case here from invalid, and update the expected output.

tests/invalid_make_int/int_impl_imports.{m,int_err_exp}:
tests/invalid_make_int/int_impl_imports_2.m:
    Move this test case here from invalid, and update the expected output.

tests/invalid_make_int/missing_interface_import2.{m,int_err_exp}:
tests/invalid_make_int/missing_interface_import3.m:
    Move this test case here from invalid, and update the expected output.

tests/invalid_make_int/missing_parent_import.{m,int_err_exp}:
tests/invalid_make_int/children.m:
tests/invalid_make_int/children2.m:
    Move this test case here from invalid_submodules,
    and update the expected output.

tests/invalid_make_int/sub_c.{m,int_err_exp}:
tests/invalid_make_int/sub_a.m:
    Move this test case here from invalid_submodules,
    and update the expected output.

tests/invalid_make_int/test_nested.{m,int_err_exp}:
tests/invalid_make_int/parent.m:
tests/invalid_make_int/parent.private_child.m:
tests/invalid_make_int/parent.public_child.m:
tests/invalid_make_int/parent.undeclared_child.m:
tests/invalid_make_int/parent2.child.m:
tests/invalid_make_int/parent2.m:
    Move this test case here from invalid, and update the expected output.

tests/invalid_make_int/transitive_import.{m,int_err_exp}:
    Move this test case here from invalid, update it,
    and update the expected output.

tests/invalid/Mmakefile:
    Delete from the list of tests in this directory the tests
    moved to invalid_make_int, and test bug521.

tests/invalid/bug521.{m,err_exp}:
tests/invalid/bug521_sub.m:
    Delete this test. invalid_make_int already had a copy of the relevant
    part of this test.

tests/invalid_submodules/Mmakefile:
    Delete from the list of tests in this directory the two tests
    moved to invalid_make_int.

    Delete from the list of tests in this directory two other tests
    for which we now detect some or all of the errors tested for
    at interface generation time, but which are already covered
    by other tests.

tests/valid_make_int/Mmakefile:
    Delete from the list of tests in this directory the test
    moved to invalid_make_int. (We could successfully generate
    a .int file for that test case *only if* we did not check it
    for errors :-)

tests/valid_seq/intermod_nested_module_bug2.m:
tests/valid_seq/intermod_nested_module_bug2.sub.m:
    Move two module imports from the parent to the child module,
    because only the child needs them, and any compiler with this diff
    will now complain about them being unused in the parent
    at interface generation time. Delete a third import, which was
    not used anywhere.
2021-11-20 23:49:19 +11:00
Zoltan Somogyi
6622e5fbb9 Process parse_tree_int[012], not parse_tree_int.
compiler/recompilation.version.m:
    Compute version numbers for parse_tree_int[012], not parse_tree_int.

    Group gathered items and gathered instances into a single type.

    Change argument lists to consistently put old things (gathered items,
    gathered instances, version numbers) before new.

compiler/write_module_interface_files.m:
    Compare new version numbers vs old for parse_tree_int[012],
    not parse_tree_int.

compiler/prog_item.m:
    Move the parse_tree_int type to convert_parse_tree.m, since now
    it is used only by the parser, which them immediately converts
    the generic parse_tree_int to parse_tree_intN for the required N.

compiler/convert_parse_tree.m:
    Move the parse_tree_int type here.

    Delete the predicates that convert parse_tree_int[0123] to parse_tree_int,
    since they are not needed anymore.

compiler/parse_module.m:
compiler/read_modules.m:
    Delete the predicates that read in parse_tree_int,
    since they are not needed anymore.
2021-08-25 15:44:07 +10:00
Zoltan Somogyi
703f52fd7a Stop using exit status to report success/failure.
compiler/make.module_dep_file.m:
    Judge whether calls to write_short_interface_file_int3 succeeded
    by an explicit maybe_succeeded value they now return, instead of
    checking the exit status in the I/O state.

compiler/module_cmds.m:
compiler/parse_tree_out.m:
compiler/write_module_interface_files.m:
    Make operations on files return a maybe_succeeded argument to indicate
    success vs failure.

compiler/make.module_target.m:
compiler/mlds_to_c_file.m:
    Take the new maybe_succeeded arguments in calls into account
    when computing whether an action succeeded.

compiler/analysis.m:
compiler/export.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_main.m:
compiler/mercury_compile_middle_passes.m:
compiler/recompilation.check.m:
    Ignore the maybe_succeeded results returned by calls, for now.

    In export.m, switch from /* */ to // syntax for the C comments we write.
2021-08-23 22:07:14 +10:00
Zoltan Somogyi
567b7c421b Use explicit streams when writing .int* files.
compiler/parse_tree_out.m:
compiler/write_module_interface_files.m:
    Write any progress messages and error messages to explicitly
    provided streams.

compiler/make.module_dep_file.m:
compiler/mercury_compile_main.m:
    Explicitly pass progress and error streams.
2021-08-19 19:10:35 +10:00
Zoltan Somogyi
428aa400eb Introduce aug_make_int_unit.
compiler/prog_item.m:
    Split aug_compilation_unit into two types. One, aug_make_int_unit,
    is a new type, and it is a version of the old aug_compilation_unit
    that contains only what is needed when making .int{,0,2} files.
    The other, the new aug_compilation_unit, contains what is needed
    when generating target language code. Both encode in their argument types
    stronger invariants that the old aug_compilation_unit type did.

compiler/comp_unit_interface.m:
compiler/decide_type_repn.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/grab_modules.m:
compiler/make_hlds_separate_items.m:
compiler/module_qual.collect_mq_info.m:
compiler/module_qual.m:
compiler/parse_tree_out.m:
compiler/write_deps_file.m:
compiler/write_module_interface_files.m:
    Conform to the change above.

    In some cases, this means passing around aug_make_int_units instead of
    aug_compilation_units.

    In a few cases, it means creating two copies of a predicate,
    one for aug_compilation_units and one for aug_make_int_units.
    In such cases, factor out any commonalities between the copies.

    In many cases, it means updates to account for the specialized types
    of the fields of aug_compilation_unit or aug_make_int_unit.

    In some cases, it means deleting code that was always unreachable,
    but the not-tight-enough types did not make this fact visible.
    (Due to this effect, this diff removes more lines than it adds.)
2021-08-17 19:23:55 +10:00
Zoltan Somogyi
5c3d4fe4f0 Replace module_and_imports with aug_compilation_unit.
compiler/module_imports.m:
    Delete the module_and_imports type, and replace its uses with
    aug_compilation_units.

    The structure of module_and_imports used to be private, but the
    structure of aug_compilation_units is public. Delete the getter/setter
    predicates on module_and_imports structures that can now be done
    using field names on aug_compilation_units. Delete, along with this,
    the infrastructure for keeping track of which module_and_imports fields
    are ever accessed. It has served its purpose, but it won't be needed
    anymore.

    Change types that used to include module_and_imports to include
    aug_compilation_units instead.

    Rename any types, predicates and functions that used to contain
    the "module_and_imports" string in their name.

compiler/prog_item.m:
    Move the version number map to be the last field of aug_compilation_units,
    as it used to be in module_and_imports structures, since this fits better.

compiler/get_dependencies.m:
    Make the name of a predicate more reflective of the type it returns.

compiler/comp_unit_interface.m:
compiler/deps_map.m:
compiler/equiv_type.m:
compiler/generate_dep_d_files.m:
compiler/grab_modules.m:
compiler/make.m:
compiler/make.module_dep_file.m:
compiler/make_hlds_separate_items.m:
compiler/mercury_compile_main.m:
compiler/module_qual.m:
compiler/write_deps_file.m:
compiler/write_module_interface_files.m:
    Conform to the changes above.
2021-08-17 09:11:53 +10:00
Zoltan Somogyi
b7fb46c073 Introduce and use module_baggage.
compiler/module_imports.m:
    Keep in the module_and_imports structure only the fields that used to
    construct aug_compilation_units, to prepare for the replacement
    of module_and_imports by aug_compilation_unit. Move the remaining fields
    into a new structure, the module_baggage, and introduce a new type,
    module_imports_and_baggage, that contains module_and_imports (for now)
    and module_baggage.

    The point of this is to allow the splitting of aug_compilation_unit
    into types:

    - one (aug_compilation_unit itself) for use when generating
      target language code, and
    - one (maybe named aug_make_int_unit) for use when generating
      .int/.int2 files.

    These two use cases fill some of the fields, such as direct and indirect
    imports, with different kinds of parse trees. Until now, we handled this
    using types such as direct_int_spec, which could contain either kind
    of parse tree, but having separate aug_compilation_unit/aug_make_int_unit
    types would allow the compiler to enforce the different invariants
    of the two use cases.

    This split requires factoring out the common parts of module_and_imports
    structure. The module_baggage type contains these common parts.

    Simplify some operations as permitted by the above change.

    Rename others to reflect the new names of the types they operate on.

    Don't return an output argument that is contained in another output
    argument.

    Delete operations on deleted fields.

    Delete a predicate that has become identical to another.

compiler/grab_modules.m:
    Add operations on module_baggage (that previously were operations on
    module_and_imports) that are needed only in this module.

    Conform to the changes above.

compiler/deps_map.m:
compiler/generate_dep_d_files.m:
compiler/make.m:
compiler/make.module_dep_file.m:
compiler/mercury_compile_main.m:
compiler/write_deps_file.m:
compiler/write_module_interface_files.m:
    Conform to the changes above.
2021-08-14 08:15:09 +10:00
Zoltan Somogyi
f1927afe0b Break a source file info parse_tree_module_srcs ...
... instead of into raw_compilation_units. Besides being more convenient to
work on, a parse_tree_module_src encodes in its type a significant number
of invariants that a raw_compilation unit does not.

compiler/split_parse_tree_src.m:
    Immediately after creating a raw_compilation_unit for one of the modules
    in a potentially multi-module source file, convert it to a
    parse_tree_module_src.

    Fix an old problem that can come up in contrived erroneous code.
    Specifically, when a submodule is both nested inside its parent module,
    *and* it also has an explicit include_module declaration, we used to
    record the contexts of both "inclusions", after generating an error
    message. The more rigorous checking that later code now does on the
    resulting inclusion map would look at this "duplicate inclusion"
    and generate *another* error message. To avoid this redundant message,
    do not record the contexts of erroneous inclusions for which a message
    has already been generated.

compiler/grab_modules.m:
    Operate on parse_tree_module_srcs instead of raw_compilation_units.
    This allows us to avoid having code for doing what converting the
    raw_compilation_unit to a parse_tree_module_src has already done.
    In fact, that conversion code does a better job. The old code assumed
    that all implicitly available modules are used in the interface,
    whereas in fact only some should be used in the interface, with
    the rest being used in the implementation section.

compiler/module_imports.m:
    Make the predicates that create module_and_imports structures
    take a parse_tree_module_src instead of a raw_compilation_unit
    as input. For now, we convert the parse_tree_module_src back to
    a raw_compilation_unit for further processing, but I intend
    a later diff to change this. Nevertheless, one immediate change
    is that init_module_and_imports now stores the *actual*
    parse_tree_module_src in the module_and_imports structure,
    not a dummy.

compiler/prog_item.m:
    Do not include a list of foreign_enum items in the interface section
    of a parse_tree_module_src, since such items are not allowed to occur
    in interface sections.

    For the same reason, delete the field for foreign_enums in the interface
    sections of .int0 and .int files.

compiler/check_raw_comp_unit.m:
    Operate on parse_tree_module_srcs instead of raw_compilation_units.

compiler/comp_unit_interface.m:
    Operate on parse_tree_module_srcs instead of raw_compilation_units.

    Do not expect any foreign_enum items in interface sections, since
    they are not allowed there.

compiler/read_modules.m:
    Provide a mechanism to remember having read a parse_tree_module_src.

compiler/write_module_interface_files.m:
    Operate on parse_tree_module_srcs instead of raw_compilation_units.

compiler/get_dependencies.m:
    Add a new version of an existing utility predicate. The old one operated
    on raw item lists, the new one operates on parse_tree_module_srcs.
    To make this possible, factor out the code pieces that operate on
    each non-ignored kind of item.

compiler/item_util.m:
    Add some new utility predicates/functions.

compiler/convert_parse_tree.m:
    Conform to the change in prog_item.m. (We already generated an error
    message for a foreign_enum item in the interface, but still passed around
    a list of foreign_enum items that was guaranteed to be stay empty.)

compiler/make.module_dep_file.m:
    Conform to the changes above.

    Use explicit streams in one place.

    Do not pass an unneeded argument.

compiler/check_parse_tree_type_defns.m:
compiler/equiv_type.m:
compiler/make_hlds_separate_items.m:
    Conform to the change in prog_item.m.

compiler/mercury_compile_main.m:
compiler/module_qual.collect_mq_info.m:
compiler/module_qual.qualify_items.m:
compiler/parse_tree_out.m:
    Conform to the changes above.

library/map.m:
library/tree234.m:
    Add foldl6, foldl6_values and foldr6 predicates. An earlier version
    of this diff needed foldl6, and I added the others for symmetry.

NEWS:
    Announce the new library predicates.

tests/invalid/bad_mutable.m:
    Export something, to avoid a warning about not exporting anything.

tests/invalid_submodules/duplicate_module.m:
tests/invalid_submodules/duplicate_module_test.m:
    Update programming style.
2021-07-19 13:23:28 +10:00
Zoltan Somogyi
93c306916a Specify streams explicitly in more modules.
compiler/module_cmds.m:
    Require all callers to specify output streams explicitly.

compiler/compile_target_code.m:
    Require callers to specify output streams explicitly in most cases.

    In the remaining cases, add "XXX STREAM" comments to request that
    the explicit streams be passed later.

    Add XXXs where preserving old behavior results in wrong-looking code.

    Modify the signature of compile_java_files to encode the invariant that
    the list of Java files given to it may not be empty.

compiler/error_util.m:
    Provide a version of an error predicate that takes explicit streams.

compiler/make.build.m:
    Mark predicates that help redirect implicit streams as predicates
    that should not be used.

compiler/make.module_target.m:
compiler/make.program_target.m:
    Add "XXX STREAM" comments to request that the explicit streams
    be passed later.

compiler/module_qual.m:
    Provide a means to construct the debug output stream.

compiler/module_qual.collect_mq_info.m:
    Use the debug output stream where relevant.

compiler/analysis.m:
compiler/export.m:
compiler/recompilation.check.m:
compiler/source_file_map.m:
compiler/write_module_interface_files.m:
compiler/xml_documentation.m:
    Conform to the changes above, mostly by passing explicit streams.

compiler/Mercury.options:
    Stop specifying --no-warn-implicit-stream-calls for the above modules
    (those that had it specified in the first place).

    Delete a long-unneeded workaround.

compiler/mercury_compile_front_end.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mercury_compile_main.m:
compiler/mercury_compile_middle_passes.m:
    Specify progress and output streams explicitly when calling the modules
    above (not in other places, just yet).
2021-05-17 22:55:06 +10:00
Zoltan Somogyi
4455f0450e Specify output streams in some places.
Besides this main purpose, this diff also replaces code that calls
io.write_string several times in a row with code that prints the
thing to be printed in one go with io.format. In a couple of places,
this has caught (and fixed) bugs where we wanted to put `' quotes
around a filename, but printed only one of the two quotes.

compiler/file_util.m:
    Provide alternatives to the existing maybe_report_stats,
    maybe_write_string and maybe_flush_output predicates that explicitly
    specify the output stream.

    Rename report_error_to_stream as report_error, to allow
    --warn-implicit-stream-calls to report calls to the existing report_error
    predicate, which does not take an explicit output stream.

    Add a module_name argument to the output_to_file_stream predicate,
    to allow its code to figure out where to print both progress and
    error messages.

compiler/module_cmds.m:
    Add a module_name argument to the predicates that update interface,
    to allow their code to figure out where to print both progress and
    error messages.

    For now, leave the predicates that issue commands that are not
    clearly linked to a single module using implicit streams.

compiler/pd_debug.m:
compiler/analysis.file.m:
    Specify output streams in some places.

    In other places, doing so would require redoing the whole debug
    infrastructure, since the current one is based on higher order predicates
    that always write to the non-explicitly-specified *current* output stream.

compiler/passes_aux.m:
    Provide predicates that get progress, debug and error streams
    given a module_info, by extracting the globals and the module name
    from the module_info, and then calling the predicates in globals.m
    to get those streams. Doing this sequence of actions here factors out
    what would otherwise be repeated code in many other parts of the compiler.

    Delete two predicates that were not used anywhere in the compiler.

compiler/deforest.m:
compiler/export.m:
compiler/intermod.m:
compiler/llds_out_file.m:
compiler/mlds_to_c_file.m:
compiler/mlds_to_cs_file.m:
compiler/mlds_to_java_file.m:
compiler/recompilation.usage.m:
compiler/simplify_goal_conj.m:
compiler/type_assign.m:
compiler/typecheck.m:
compiler/write_deps_file.m:
compiler/write_module_interface_files.m:
    Use explicit streams everywhere where --warn-implicit-stream-calls
    says this is possible.

compiler/Mercury.options:
    Specify --warn-implicit-stream-calls for the modules above
    with the listed exceptions, and with the exception of the modules
    for which it was already specified.

compiler/compile_target_code.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_middle_passes.m:
    Conform to the changes above.
2021-03-21 23:07:59 +11:00