Commit Graph

68 Commits

Author SHA1 Message Date
Zoltan Somogyi
f355497087 Delete include context maps from parse_tree_int[012].
compiler/prog_item.m:
    We used to record information about include declarations
    in parse_tree_int[012] in two forms:

    - as a pair of maps from module names to contexts (one each for
      includes in the interface and implementation sections), and
    - as a single map from module names to an include_module_info, which
      recorded the section of its appearance along with its context.

    The second of these data structures is derived from the first,
    in a process that can result in the generation of diagnostic messages.
    In the absence of any issues reported by these diagnostics, the two forms
    contain the same information.

    Avoid this redundancy by keeping only the second form in the parse trees
    of .int0, .int and .int2 files. (.int3 files cannot contain include_module
    declarations.)

    Since .int2 files may contain include_module declarations only in
    the interface section, change the representation of the second form
    to a type that expresses this invariant: int_include_module_map,
    which is a subtype of the existing type include_module_map.

compiler/comp_unit_interface.m:
compiler/convert_parse_tree.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/parse_tree_out.m:
compiler/recompilation.check.m:
compiler/recompilation.version.m:
    Conform to the change above.

compiler/item_util.m:
    Add a utility predicate for use by new code above.
2023-01-22 19:01:42 +11:00
Zoltan Somogyi
5ae7d25740 Delete import/use context maps from parse_tree_int[012].
compiler/prog_item.m:
    We used to record information about import and use declarations
    in parse_tree_int[012] in two forms:

    - as a quartet of maps from module names to contexts (one each for
      int imports, int uses, imp imports and imp uses), and
    - as a single map from module names to a section_import_and_or_use,
      which recorded the section and kind (import or use) of its appearance
      along with its one context, except for the case of modules that have
      an use_module declaration in the interface section and an import_module
      declaration in the implementation section.

    The second of these data structures is derived from the first,
    in a process that can result in the generation of diagnostic messages.
    In the absence of any issues reported by these diagnostics, the two forms
    contain the same information.

    Avoid this redundancy by keeping only the second form in the parse trees
    of .int0, .int and .int2 files. (For .int3 files, which can contain
    only import_modules, and only in the interface section, this redundancy
    has not been present even before now.)

    Since .int and .int2 files may contain only use_module declarations
    and not import_module declarations, change the representation of the
    second form to a type that expresses this invariant: the new type
    section_use_map, which is a subtype of the existing type
    section_import_and_or_use_map.

    For .int2 files, we could use an even tighter type right now, but
    a fix for Mantis bug #563 would have to undo such a change, so
    don't bother.

compiler/comp_unit_interface.m:
    Delete the code that used to construct the first form above
    for these interface file kinds. Conform to the changes above.

compiler/convert_parse_tree.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/parse_tree_out.m:
compiler/recompilation.check.m:
compiler/recompilation.version.m:
    Conform to the changes above.

compiler/item_util.m:
    Add new, specialized versions of existing utility predicates
    to make that conformance possible.
2023-01-21 21:31:00 +11:00
Zoltan Somogyi
faf9ebf5e3 Don't provide for implicit imports in .intN parse trees.
compiler/prog_item.m:
    The ptiN_import_use_map fields in the representations of .int0, .int
    and .int2 files had the same type as the ptms_import_use_map field
    in the parse trees of .m files, which is where they were derived from.
    However, while the ptms_import_use_map field needs to be able to represent
    implicit imports, the parse trees of .int0, .int and .int2 files
    should never include any implicit imports, and in fact any implicit
    imports in these fields were already ignored.

    Encode the invariant that interface files never include implicit imports
    in the types of these fields.

compiler/comp_unit_interface.m:
    Discard the implicit part of the source file's import_and_or_use_map
    when computing the contents of .int0, .int and .int2 files.

compiler/item_util.m:
    Provide the facilities used by the updated code in the modules above.

compiler/convert_parse_tree.m:
compiler/grab_modules.m:
compiler/make_hlds_separate_items.m:
    Conform to the changes above.
2023-01-21 06:38:17 +11: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
30cb4f0ba3 Tighten representation of include/import/use decls.
compiler/prog_item.m:
    Change the representation of include, import and use declarations
    in the data structures of .int0 and .int3 files.

    For both .int0 and .int3 files, switch from data structures that can
    associate one or more contexts with each such declaration with
    data structures that can associate just one. Any duplicates would be
    errors, and we don't want to allow the representation of errors in
    compiler-generated interface files. (Similar updates to .int/.int2
    files are coming soon.)

    For .int3 files, delete two fields that hold information about include
    declarations and import/use declarations respectively in a fully checked
    form. They are not needed, because with invariants that .int3 files
    are subject to (no uses, no implementation section, no implicit imports),
    they contain just the same info as the new data structures mentioned
    in the paragraph above.

compiler/comp_unit_interface.m:
    Update the code that computes the contents of .int0/.int3 files.

    Fix some out-of-sequence variable names.

compiler/convert_parse_tree.m:
    Update the code that converts the generic parsed representation of
    interface files to the specific representations of .int0/.int3 files.

compiler/item_util.m:
    Update the utility predicates that comp_unit_interface.m and
    convert_parse_tree.m use to do their jobs. Add new variants
    of some existing predicates.

compiler/grab_modules.m:
compiler/module_qual.collect_mq_info.m:
compiler/module_qual.qualify_items.m:
compiler/parse_tree_out.m:
compiler/recompilation.check.m:
2022-09-03 11:01:08 +10:00
Zoltan Somogyi
913d068b3a Update a comment. 2022-08-31 22:25:49 +10: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
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
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
48e0a04e6b Fix some comments. 2022-01-15 13:47:01 +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
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
d64961d79d Use checked types/insts/modes in parse_tree_module_src.
This means that we can do the exact same checks (and, if needed, generate
the exact same error messages) when generating interface files as when
generating target language code.

This should also allow us to simplify the process of adding type, inst
and mode definitions to the HLDS.

compiler/prog_item.m:
    As above.

    Delete unused function.

compiler/error_util.m:
    Add mechanisms that allow us to distinguish (a) error specs that represent
    a type, inst or mode name definition being invalid, from (b) other error
    specs.

compiler/check_type_inst_mode_defns.m:
    Improve the error messages we generate, in several ways.

    First, for each message, specify a real severity. When the messages
    could be seen only when generating interface files, making them all
    warnings was fine and preserved old behavior, but since soon these
    will be the only place for these checks, we need to call errors errors.

    Second, specify, in the phase, which errors represent a invalid type,
    inst or mode definition, and which don't.

    Third, improve the wording of messages. In some places, do this by
    being clearer about the distinction between declarations and definitions.
    In others, do it by including more information in the message. In yet
    others, do it by recovering some kinds of mistakes (mostly items being
    in the wrong section) enough to avoid avalanche errors.

    Fourth, fix a bug. If a type ctor has an exported *declaration*,
    then it is ok for any foreign type definitions for that type_ctor
    being in the implementation section, but if the type_ctor has an
    exported Mercury *definition*, then any foreign_type definitions
    must be in the interface section as well. The code that handled
    both these situations did not enforce that.

    Fifth, fix another bug: do not include foreign type definitions
    in the source definitions of a type_ctor twice, once as a "du" (sic)
    definition, and once as itself.

compiler/convert_parse_tree.m:
    Check type, inst and mode definitions in raw_compilation_units
    when creating parse_tree_module_srcs.

compiler/comp_unit_interface.m:
    Make the code constructing interface files work from the checked maps
    in parse_tree_module_srcs.

compiler/make_hlds_passes.m:
    Set the flags that say we have found invalid type, inst or mode definitions
    from the error specs constructed during the creation of the checked
    type, inst and mode maps.

compiler/add_type.m:
    Comment out an error message for a condition that will be detected and
    reported by check_type_inst_mode_defns.m.

compiler/make_hlds_separate_items.m:
    For now, turn checked maps of type, inst and mode definitions
    back to item lists for addition to the HLDS. Adding whole checked
    definitions to the HLDS will be done by a future change.

compiler/make_hlds_error.m:
    Fix misleading indentation in an error message.

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

    Generate output whose indentation does not depend on tab settings.

compiler/check_raw_comp_unit.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/grab_modules.m:
compiler/module_qual.collect_mq_info.m:
compiler/module_qual.qualify_items.m:
    Conform to the changes above.

compiler/parse_type_defn.m:
    Fix misleading error message for ":- type <name> = <type>".

tests/debugger/foreign_type.{m,exp}:
    Delete a redundant type declaration to avoid a warning, and update
    the .exp file to expect the new line numbers.

tests/invalid/any_mode.err_exp:
tests/invalid/bug436.err_exp:
tests/invalid/bug476.err_exp:
tests/invalid/exported_foreign_enum.err_exp:
tests/invalid/fe_unmapped_nonverbose.err_exp:
tests/invalid/fe_unmapped_verbose.err_exp:
tests/invalid/foreign_enum_invalid.err_exp:
tests/invalid/foreign_solver_type.err_exp:
tests/invalid/foreign_type_visibility.err_exp:
tests/invalid/pragma_qual_error.err_exp:
tests/invalid/repeated_field_name.err_exp:
tests/invalid/subtype_foreign.err_exp:
tests/invalid/type_with_no_defn.err_exp:
tests/invalid/types2.err_exp:
tests/invalid/user_field_access_decl_conflict.err_exp:
tests/invalid_nodepend/bad_foreign_type.err_exp:
tests/invalid_nodepend/bigtest.err_exp:
tests/invalid_nodepend/invalid_typeclass.err_exp:
tests/invalid_nodepend/types.err_exp:
tests/invalid_nodepend/uu_type.err_exp:
tests/invalid_nodepend/where_abstract_enum.err_exp:
    Expect the new error messages.

tests/invalid/abstract_solver_type.{m,err_exp}:
tests/warnings/abstract_solver_type.{m,exp}:
    Move the abstract_solver_type test case from invalid to warnings, because
    this diff changes its only error to be only a warning.

tests/invalid/Mmakefile
2021-10-16 17:37:36 +11:00
Zoltan Somogyi
4548706b85 Switch to checked type/inst/mode maps for .int0.
compiler/prog_item.m:
    As above.

compiler/comp_unit_interface.m:
compiler/convert_parse_tree.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/parse_tree_out.m:
compiler/recompilation.check.m:
compiler/recompilation.version.m:
    Conform to the change above.
2021-10-03 06:21:44 +11:00
Zoltan Somogyi
12605f8c10 Use checked type/inst/modes in parse_tree_int[123]s.
With this change, we guarantee that if any type, inst or mode
has inconsistent definitions in its defining module, those inconsistencies
will not make it into the the module's .int/.int2/.int3 files, where
they would confuse any compiler invocation that reads them in.

compiler/prog_item.m:
    Replace {type,inst,mode}_ctor_defn_maps, which are unchecked,
    with {type,inst,mode}_ctor_checked_maps in parse_tree_int[123]s.

    To make this possible,

    - generalize the items containing inst and mode definitions the way that
      items containing type definitions have been generalized previously,
      to allow them to store particular *kinds* of inst or mode definitions;

    - move the definitions of type_ctor_checked_map and its components
      here from check_type_inst_mode_defns.m; and

    - add similar, but simpler, definitions for {inst,mode}_ctor_checked_map.

compiler/check_type_inst_mode_defns.m:
    Delete the type definitions moved to prog_item.m.

    Modify the checking process slightly to allow it to check properly
    the definitions we now put into .int, .int2 and .int3 files.

    Add code to check inst and mode definitions as well as type definitions.
    Since insts and modes have only one non-abstract kind of definition,
    these codes are much simpler than the code for checking types.

compiler/comp_unit_interface.m:
    Construct checked type, inst and mode definitions to put into
    .int, .int2 and .int3 files. The .int2 and .int3 parts were
    reasonably simple, but the .int part requires some detailed
    case-by-case analysis.

compiler/convert_parse_tree.m:
    Check the type, inst and mode definitions read in from .int/.int2/.int3
    files when creating their parse trees. If those files were generated
    by a compiler that has this diff, then this checking process should
    not find any problems.

compiler/equiv_type.m:
    Operate on checked type, inst and mode definitions instead of their
    unchecked versions.

    Delete an unneeded field from a structure.

compiler/error_util.m:
    Add {qual,unqual}_{inst,mode}_ctor as format components, so that
    any error messages about inst and mode definitions do not have to convert
    inst_ctors and mode_ctors to symname/arity pairs.

compiler/item_util.m:
    Add some utility predicates and functions needed by the changes above.

compiler/module_qual.collect_mq_info.m:
    Since checked type, inst and mode definitions can contain info that is
    derived from both the interface and implementation sections of a module,
    add the capability to get only the *publicly* declared types, insts and
    modes from their respective kinds of checked definitions.

compiler/module_qual.qualify_items.m:
    Module qualify checked type, inst and mode definitions.

compiler/module_qual.qual_errors.m:
    Treat references to inst_ctors and mode_ctors in qualification error
    messages the same way as we treat type_ctors.

    Also replace mq_ids that are intended to represent classes with class_ids,
    to represent the intent better.

compiler/parse_tree_out.m:
    Output the updated parse_trees of .int/.int2/.int3 files.

compiler/prog_data.m:
    Add an XXX about a future change.

compiler/decide_type_repn.m:
compiler/get_dependencies.m:
compiler/grab_modules.m:
compiler/make_hlds_separate_items.m:
compiler/pred_table.m:
compiler/recompilation.check.m:
compiler/recompilation.version.m:
    Conform to the changes above.

library/maybe.m:
    Add utility predicates needed by the code above.

NEWS:
    Announce the new predicates in maybe.m.

tools/intdiffall:
    A script that shows differences between the automatically generated
    interface files between stage 1 and stage 2, which helped debug this diff.
2021-10-01 17:57:15 +10:00
Zoltan Somogyi
7194baab3c Rename version_numbers to module_item_version_numbers.
Also, turn some semidet functions into predicates, and given them
more meaningful names.

compiler/recompilation.m:
compiler/timestamp.m:
    As above.

compiler/comp_unit_interface.m:
compiler/grab_modules.m:
compiler/make_hlds_passes.m:
compiler/parse_item.m:
compiler/parse_module.m:
compiler/parse_tree_out.m:
compiler/parse_types.m:
compiler/prog_item.m:
compiler/recompilation.check.m:
compiler/recompilation.m:
compiler/recompilation.usage.m:
compiler/recompilation.version.m:
    Conform to the changes above.
2021-08-28 00:05:34 +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
b3748a367b Separate self-FIM languages by module section.
compiler/prog_item.m:
    Split the parse_tree_module_src that holds the languages for which
    the module needs a self-foreign-import into two, depending on the
    section (interface or implementation) into which the self-FIM should go.

compiler/convert_parse_tree.m:
    When computing the self-FIM languages, put each one into its section.

compiler/comp_unit_interface.m:
    Don't compute the interface self-FIMs, since they are now available
    in the parse_tree_module_src.

    Document why we *do* compute the implementation self-FIMs
    for the interface file we are constructing.

compiler/check_raw_comp_unit.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.qualify_items.m:
compiler/parse_tree_out.m:
    Conform to the changes above.
2021-08-17 12:01:52 +10:00
Zoltan Somogyi
071cf6a841 Move aug_comp_unit_add_* to grab_modules.m, ...
... since they are called *only* from there.
2021-08-17 09:41:17 +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
e2abe444f4 Always compute the self-import FIMs.
compiler/convert_parse_tree.m:
    Always compute the set of foreign languages for which
    the current module needs a self-import FIM. Use the algorithm
    that grab_unqual_imported_modules_make_int used to use to fill in
    that slot in the parse_tree_module_src.

    Stop computing some values whose only user was a sanity check.
    If it hasn't triggered by now, it won't.

    Delete an unused predicate that won't be needed.

compiler/prog_item.m:
    Since that field in the parse_tree_module_src is now always filled in
    when the parse_tree_module_src is created, delete the maybe wrapper
    around it.

compiler/grab_modules.m:
    Don't fill in the already-filled-in field.

compiler/comp_unit_interface.m:
    Conform to the changes above, and add an XXX.

compiler/parse_tree_out.m:
    Conform to the changes above.
2021-08-14 14:45:10 +10:00
Zoltan Somogyi
229137126f Document the source file dir field.
compiler/module_imports.m:
    As above.

compiler/grab_modules.m:
    Delete the XXXs about that field.
2021-08-14 12:58:29 +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
813f26d8b7 Unify {init,make}_module_and_imports.
compiler/module_imports.m:
    Originally, we had three different ways to initialize module_and_imports
    structures. In the last few weeks, I replaced one of them with code
    that creates a module_dep_summary instead, which left two:
    init_module_and_imports and make_module_and_imports. These differed
    in how (and, more to the point, whether) they initialized the fields
    of the module_and_imports structure that semantically were properties
    that were computable from the other fields, the fields that would
    eventually be put into the augmented compilation unit. Changes in the
    last few weeks have deleted all these "computable from elsewhere" fields,
    leaving only a trivial difference between init_module_and_imports
    and make_module_and_imports.

    This diff makes the last step, and replaces both those predicates
    with a single predicate, which is also called init_module_and_imports,
    whose argument list is the union of the argument lists of its two
    progenitors.

compiler/grab_modules.m:
    Conform to the change above.
2021-08-12 09:35:47 +10:00
Zoltan Somogyi
8b8619c26d Delete the indirect_deps field of module_imports.
compiler/module_imports.m:
    As above.

compiler/grab_modules.m:
    Add indirectly imported module names only to indirect_int_specs field,
    and not redundantly to the now-deleted field.

compiler/write_deps_file.m:
    Get the same info from the indirect_int_specs field.
2021-08-12 08:26:54 +10:00
Zoltan Somogyi
7a67b0c494 Delete module_and_imports' {int,imp}_deps fields.
compiler/module_imports.m:
    Delete module_and_imports' {int,imp}_deps fields, as their contents
    are computable from the field containing the parse_tree_module_src.

    Add a utility predicate that returns the int and imp dependencies
    separately. Clients for whom the int/imp distinction is not relevant
    can get the union of those sets more simply by just taking the
    key set of the parse_tree_module_src's import_and_or_use_map.

    Delete now unneeded arguments.

    Make some minor rearrangements to minimize the remaining differences
    between the two methods of initializing module_and_imports structures,
    init_module_and_imports and make_module_and_imports.

compiler/grab_modules.m:
compiler/make.module_dep_file.m:
compiler/mercury_compile_main.m:
compiler/write_deps_file.m:
    Conform to the change above.
2021-08-11 15:41:17 +10:00
Zoltan Somogyi
01c5365642 Delete module_and_imports' contains_foreign_* fields.
compiler/module_imports.m:
    As above. The new approach has a much simpler correctness argument,
    especially since some of the methods for initializing module_and_imports
    structures didn't actually fill in one of the fields with meaningful
    information.

    Don't ask callers for arguments that are not used.

compiler/get_dependencies.m:
    Add utility predicates for computing the information that those fields
    used to contain on demand.

    Simplify the interface to some similar recently-added utility predicates.

compiler/make.module_dep_file.m:
    Call those utility predicates when needed.

compiler/item_util.m:
    Delete the utility predicates that module_imports.m *used* to use
    to fill in those fields, which is no longer needed.

compiler/grab_modules.m:
compiler/write_deps_file.m:
    Conform to the changes above.
2021-08-06 13:16:23 +10:00
Zoltan Somogyi
e8cc825684 With experiment3, read in ancestors' .int files. 2021-08-01 01:18:14 +10:00
Zoltan Somogyi
cbb7aba336 Delete foreign includes field of module_and_imports.
compiler/module_imports.m:
    Delete the field containing foreign_include_file_infos from
    the module_and_imports structure, because it is redundant;
    the same info is implicit in the parse_tree_module_src field.

compiler/grab_modules.m:
    Don't pass the set of foreign_file_include_infos to module_imports.m,
    since it does not need it anymore.

compiler/get_dependencies.m:
    Provide a predicate to get the set of foreign_file_include_infos
    on demand. Provide this info in the form of a set, not a cord,
    since duplicates don't count.

compiler/make.module_dep_file.m:
compiler/write_deps_file.m:
    Get the set of foreign_file_include_infos when needed.

compiler/prog_data_foreign.m:
    Delete a type synonym that is not needed anymore.
2021-07-30 23:21:13 +10:00
Zoltan Somogyi
fb6bced9a9 Don't store fact table info in module_and_imports.
compiler/module_imports.m:
    Delete the redundant fact table field from module_and_imports.
    Get that info when needed from the parse_tree_module_src stored
    in the module_and_imports structure.

compiler/get_dependencies.m:
    Add a predicate to get this info on demand.

compiler/grab_modules.m:
    Don't precompute the set of fact tables. (Actually, for now we do
    precompute it but ignore it, but the precomputation should be gone soon.)

compiler/make.module_dep_file.m:
    Conform to the changes above, and give a predicate a better name.

compiler/write_deps_file.m:
    Conform to the changes above.
2021-07-30 18:33:13 +10:00
Zoltan Somogyi
01591bbce7 Put all the top level predicates at the front. 2021-07-29 01:10:41 +10:00
Zoltan Somogyi
3f217b533e Read in a module's own .int only with experiment3.
compiler/grab_modules.m
    The recent failures in tests/invalid on testing.mercurylang.org
    occurred with intermodule optimization being enabled, and were due to
    not being able to find the .int file of the module being compiled.

    The bug occurred only with intermodule optimization because the call
    to read in the problematic .int file was in the predicate that grabbed
    .opt files, .trans_opt files and the .int* files they needed, NOT
    in its proper place, which is in the predicate that grabs all the files
    needed to create an augmented compilation unit to be compiled.
    Fix this my moving the call.

    Bootchecks with --intermod-opt in Mmake.stage.params were not affected
    because by default, tools/bootcheck does NOT execute the test cases
    with the flags in Mmake.stage.params. We should maybe change that
    default.

    With the moved call, all compilations will try to read in the module's
    own .int file. This is what we ordinarily want. However, it is not what
    we want in tests/invalid, because

    - in multi-module programs, for which we make dependencies, and for which
      we should build those .int files, it can change the symptoms of errors,
      and

    - in single-module programs, for which we do not (now) make dependencies,
      we totally replace all error with the error that the .int file cannot
      be read. For many single-module programs, making dependencies would
      not be a cure either, because the bugs we deliberately put into their
      source code would cause the process of making dependencies itself fail.

    Likewise, the tests in tests/recompilation fail with this change,
    because the test scripts have not yet been updated to generate the
    .int file.

    For these reasons, the code to read in the module's own .int file
    is now guarded by an option, experiment3, which defaults to off.
    I intend that this guard be removed once the problems listed above
    have been fixed. The code inside the guard also describes some
    required future work.

    The movement of the call exposed two other bugs, which this diff
    also fixes.

    The first bug is that for modules that have submodules, such as
    string.m in the library dir, it was the presence of the call
    in its old position that prevented the following code from
    trying to read in the module's own .int0 file. Reading in that file
    leads to a duplicate definition error for everything defined in the
    module, with one definition in the .m file, and another in the .int0
    file derived from it. This is clearly bad, but the fix is simple:
    exclude the module being compiled from having its .int0 file
    being read in. (Its ancestors were already excluded.)

    The second bug is that the kinds of errors that we do not report
    while *constructing* the .int file (which is all of them for now,
    since we suppress error message generation at that time by default)
    but which we do report when *reading* the .int file, the inclusion
    of those error reports causes mismatches against the expected error
    output files in tests/invalid. This diff thus does not add the error specs
    from reading in .int files to the module_and_imports structure
    (which effectively means forgetting about them altogether) if the reason
    for reading the .int file was getting type representation information.
2021-07-25 00:32:23 +10:00
Zoltan Somogyi
d84571c0c2 Delete redundant fields in aug_compilation_units.
compiler/prog_item.m:
    Delete the module name and module name context fields from
    aug_compilation_units, since the same info is available from
    the parse_tree_module_src field.

compiler/comp_unit_interface.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/grab_modules.m:
compiler/item_util.m:
compiler/make_hlds_passes.m:
compiler/make_hlds_separate_items.m:
compiler/mercury_compile_main.m:
compiler/module_imports.m:
compiler/module_qual.m:
compiler/prog_item_stats.m:
compiler/write_deps_file.m:
    Conform to the change above.
2021-07-20 06:13:55 +10:00
Zoltan Somogyi
97fcb29811 Don't record anccestors in module_and_imports.
compiler/module_imports.m:
    As above; delete the ancestors field, since users can compute its value
    by calling get_ancestors_set on the module name.

    On some initialization paths, the ancestors field used to be filled
    with a dummy empty set, so this change should improve robustness.

compiler/deps_map.m:
compiler/grab_modules.m:
compiler/make.dependencies.m:
compiler/make.module_dep_file.m:
compiler/mercury_compile_main.m:
compiler/module_deps_graph.m:
compiler/write_deps_file.m:
    Conform to the changes in module_imports.m.
2021-07-19 23:12:33 +10:00
Zoltan Somogyi
a2f9f9d705 Get children info from parse_tree_module_src, ...
... not from separate fields in the module_and_imports_structure.

compiler/module_imports.m:
    As above. This is a step towards using the parse_tree_module_src
    as the single source of truth about the properties of the module
    being compiled.

compiler/deps_map.m:
compiler/grab_modules.m:
compiler/write_deps_file.m:
    Conform to the changes in module_imports.m.
2021-07-19 22:21:19 +10:00
Zoltan Somogyi
52208fc8bf Use the new type maybe_top_module.
compiler/module_imports.m:
    The module_and_imports structure used to have a field, mf_nested_children,
    which stored a set of module names, but which had confusing semantics:
    it had two different meanings in two different circumstances.
    Replace that field with a value of a new type, maybe_top_module, which
    has two separate function symbols for those two circumstances:
    when a module is the top module in its source file, and when it is not.

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

    Put related arguments next to each other.

compiler/grab_modules.m:
compiler/make.dependencies.m:
compiler/make.module_dep_file.m:
compiler/make.module_target.m:
compiler/recompilation.check.m:
compiler/write_deps_file.m:
    Conform to the change above.

tests/recompilation/test_functions:
    Impose a limit of 10 minutes of CPU time on each process. This should
    help catch infinite loops, such as happened during the development
    of this diff.

    Fix indentation, and clarify some comments.

tests/recompilation/README:
    Fix stray blank line.
2021-07-19 20:48:12 +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
e627efcf50 A start on getting type_repn info from .int files.
compiler/du_type_layout.m:
    Add a first draft of the code that will eventually get type representation
    information from .int files. Invoke the new code only if undocumented,
    developer-only experiment flags are set, and when invoked, compare
    its output with the output of the old algorithm it is intended to
    eventually replace.

    The new code is not yet complete, and thus has not yet been tested.

compiler/prog_item.m:
    Add a new field to the augmented compilation unit data type
    that is intended to hold the .int file of the main module, the module
    that the augmented compilation unit is for. For every module imported
    by the main module, we read its .int or .int2 file and get the
    representation information for the types they define from those files,
    but we need this info for the main module's own types as well.

    Add "need type representation information" as reason for reading
    a .int file.

    Break some types down into smaller types, to allow their components
    to be manipulated individually by du_type_layout.m.

    Start using uint8, not uint, in situations where we want to store
    values that select bits in words, which fit into 6 bits.

    Add XXXs where we could, and maybe should switch to uint8s.

    Add extra documentation.

compiler/grab_modules.m:
    Read in the main module's own .int file.

    Replace a bool with a bespoke type.

compiler/module_imports.m:
    Provide a slot for the main module's own interface file,
    which will be used to set the new slot in augmented compilation units.

compiler/comp_unit_interface.m:
    Put the exact same type_ctor_repn_map into .int2 files as .int files.
    This should prevent the scenario where a compilation reads
    e.g. mod_x.int2, gains access to the definitions of the exported types
    of module mod_x,  but then needs to read mod_x.int as well to find out
    how those types are represented. Since neither type checking nor any
    other semantic analysis pass pays any attention to type_repn items,
    the additional type_repn items in mod_x.int2 cannot turn an otherwise
    illegal program into a legal one.

compiler/hlds_data.m:
    Clarify a comment.

compiler/maybe_error.m:
    Provide a utility predicate.

compiler/prog_data.m:
    Add XXXs about possible future improvements.

compiler/decide_type_repn.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/make_hlds_passes.m:
compiler/make_hlds_separate_items.m:
compiler/module_qual.collect_mq_info.m:
compiler/module_qual.m:
compiler/parse_tree_out.m:
compiler/parse_tree_out_type_repn.m:
compiler/parse_type_repn.m:
compiler/prog_item_stats.m:
compiler/write_deps_file.m:
    Conform to the changes above.
2021-07-01 06:12:21 +10:00
Zoltan Somogyi
0d7c8a7654 Specify pred or func for all pragmas.
*/*.m:
    As above.

configure.ac:
    Require the installed compiler to support this capability.
2021-06-16 15:23:58 +10:00
Zoltan Somogyi
b0d147b057 Don't compute has_main/no_main.
That info hasn't been used in a long time (since we deleted the IL backend,
according to an old comment).

compiler/module_imports.m:
    Delete the has_main field from the module_and_imports structure.

compiler/convert_parse_tree.m:
compiler/get_dependencies.m:
    Don't look for main/2.

compiler/make.module_dep_file.m:
    When reading in module_dep structures, ignore the contents of the
    no_main/has_main field. The value in that field used to be stored
    elsewhere, but it was never used.

    When writing out module_dep structures, always put "no_main"
    into the no_main/has_main field.

    Add comments describing possible changes to the on-disk module_dep
    structure.

compiler/grab_modules.m:
    Conform to the changes above.
2020-11-07 14:14:07 +11:00
Zoltan Somogyi
181ada0dbf Avoid -O<n> resetting previously set options.
This implements Mantis feature request #495.

NEWS:
    Announce the change.

compiler/optimization_options.m:
    A new module for managing optimization options.

    It defines a separate bespoke type for every boolean optimization option
    to make it harder to confuse them. It defines a tuple type (opt_tuple)
    for accessing optimization options quickly. It implements the turning on
    (but NOT turning off) of optimizations when a given optimization level
    is selected.

tools/make_optimization_options_middle:
tools/make_optimization_options_db:
    The script that generates the meat of optimization_options.m,
    and the database of option names, kinds and initial values
    that it uses as its input. The script also generates some code
    for the special_handler predicate in compiler/options.m.

tools/make_optimization_options_start:
tools/make_optimization_options_end:
    The handwritten initial and final parts of optimization_options.m.

tools/make_optimization_options:
    The script that pulls these parts together to form optimization_options.m.

compiler/options.m:
    Make every optimization option a special option, to be handled by
    the special_handler predicate. That handling consists of simply
    adding a representation of the option to the end of a cord of
    optimization options, to be processed later by optimization_options.m.
    That processing will record the values of these options in the opt_tuple,
    which is where every other part of the compiler should get them from.

    Change the interface of special_handler to make the above possible.

    Add an "optopt_" (optimization option) prefix to the name of
    every optimization option, to make them inaccessible to the rest
    of the compiler under their old name, and thus help enforce the switch
    to using the opt_tuple. Any access to these options to look up
    their values would fail anyway, since the option data would no longer be
    e.g. bool(yes), but bool_special, but the name change makes this failure
    happen at compile time, not runtime.

    Reclassify a few options to make the above make sense. Some options
    (unneeded_code_debug, unneeded_code_debug_pred_name, and
    common_struct_preds) were classified as oc_opt even though they
    control only the *debugging* of optimizations, while some options
    (c_optimize and inline_alloc) were not classified as oc_opt
    even though we do set them automatically at some optimization levels.

    Delete the opt_level_number option, since it was not used anywhere.

    Delete the code for handling -ON and --opt-space, since that is now
    done in optimization_options.m.

    Add some XXXs.

compiler/handle_options.m:
    Switch to using getopt_io.process_options_userdata_se, as required
    by the new interface of the special_handler in options.m.
    In the absence of errors, invoke optimization_options.m to initialize
    the opt_tuple. Then update the opt_tuple incrementally when processing
    option implications that affect optimization options.

compiler/globals.m:
    Put the opt_tuple into a new field of the globals structure.

compiler/accumulator.m:
compiler/add_pragma_type_spec.m:
compiler/add_trail_ops.m:
compiler/code_info.m:
compiler/code_loc_dep.m:
compiler/compile_target_code.m:
compiler/const_struct.m:
compiler/deforest.m:
compiler/dep_par_conj.m:
compiler/disj_gen.m:
compiler/erl_code_gen.m:
compiler/format_call.m:
compiler/global_data.m:
compiler/grab_modules.m:
compiler/higher_order.m:
compiler/hlds_pred.m:
compiler/inlining.m:
compiler/intermod.m:
compiler/ite_gen.m:
compiler/jumpopt.m:
compiler/libs.m:
compiler/llds_out_code_addr.m:
compiler/llds_out_data.m:
compiler/llds_out_file.m:
compiler/llds_out_instr.m:
compiler/llds_out_util.m:
compiler/matching.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/ml_disj_gen.m:
compiler/ml_gen_info.m:
compiler/ml_lookup_switch.m:
compiler/ml_optimize.m:
compiler/ml_proc_gen.m:
compiler/ml_simplify_switch.m:
compiler/ml_switch_gen.m:
compiler/ml_unify_gen_construct.m:
compiler/optimize.m:
compiler/pd_util.m:
compiler/peephole.m:
compiler/polymorphism.m:
compiler/proc_gen.m:
compiler/simplify_goal_call.m:
compiler/simplify_goal_scope.m:
compiler/simplify_info.m:
compiler/simplify_proc.m:
compiler/simplify_tasks.m:
compiler/stack_layout.m:
compiler/stack_opt.m:
compiler/switch_gen.m:
compiler/switch_util.m:
compiler/tag_switch.m:
compiler/tupling.m:
compiler/unify_gen_construct.m:
compiler/unneeded_code.m:
compiler/unused_args.m:
    Conform to the changes above, mostly by looking up optimization options
    in the opt_tuple. In some places, replace bools containing optimization
    options with the bespoke type of that specific optimization option.

library/getopt_template:
    Fix a bug that screwed up an error message.

    The bug happened when processing a --file option. If one of the
    options in the file was a special option whose special handler failed,
    the code handling that failing option returned both an error indication,
    and the rest of the argument list read in from the file. The code
    handling the --file option then *ignored* the error indication from
    the failed special option, and returned an error message of its own
    complaining about the unconsumed remaining arguments in the file,
    believing them to be non-option arguments, even though these arguments
    were never looked it to see if they were options.

    The fix is for the code handling --flag options to check whether
    the code processing the file contents found any errors, and if so,
    return that error *without* looking at the list of remaining arguments.

    In an unrelated change, factor out a duplicate call.
2020-09-28 18:16:13 +10:00
Zoltan Somogyi
c2f92d5454 Partition extensions into ".m" and "all others".
This is a first step towards a much finer grained partition.

compiler/file_names.m:
    Split the ext type into ext_src and ext_other, as mentioned above.

    Add the first predicate for checking whether a string falls into
    a given category of extensions.

    Add an XXX proposing a better solution for an old problem that does not
    actually arise in practice.

compiler/compile_target_code.m:
    Split the two-moded predicate maybe_pic_object_file_extension into
    two separate one-mode predicates, one for each old mode. The
    implementations of the two modes were already separate, because
    the two modes already did different jobs: while one went from PIC
    to an "extension", the other went from an "extension string" to PIC.
    Until now, "extension" and "extension string" were equivalent;
    after this diff, they aren't anymore.

    Delete an unused argument.

compiler/make.util.m:
    Split the two-moded predicate target_extension into
    two separate one-mode predicates, one for each old mode,
    for the same reason as maybe_pic_object_file_extension above:
    the fact that "extension" and "extension string" are now distinct.

compiler/options_file.m:
    Move debug infrastructure here from mercury_compile_main.m, to help
    debug possible problems with options files. (I had such a problem
    while writing this diff.)

    Improve how progress messages are printed.

compiler/options.m:
    Make an error message more useful.

compiler/mercury_compile_main.m:
    Add infrastructure for debugging possible problems with command lines.
    (I had such a problem while writing this diff.)

compiler/analysis.m:
    Conform to the changes above. Put the arguments of some methods
    into the same order as similar predicates in file_names.m.

compiler/find_module.m:
    Conform to the changes above. Delete an unused argument,

compiler/analysis.file.m:
compiler/du_type_layout.m:
compiler/elds_to_erlang.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.deps_set.m:
compiler/make.m:
compiler/make.module_dep_file.m:
compiler/make.module_target.m:
compiler/make.program_target.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_llds_back_end.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.check.m:
compiler/recompilation.usage.m:
compiler/source_file_map.m:
compiler/write_deps_file.m:
compiler/write_module_interface_files.m:
compiler/xml_documentation.m:
2020-08-17 23:43:15 +10:00
Zoltan Somogyi
52c0919975 Make filename extensions a separate type, ...
... to allow later changes to its definition.

compiler/file_names.m:
    We used to represent filename extensions simply as strings. This meant
    all calls to the predicates in file_names.m that convert module names
    to file names with various suffixes had to go through a complicated
    sequence of tests that effectively partition the extensions into
    several classes, with all extensions in a class being treated the same
    but different classes being treated differently. And since this general
    translation process is quite convoluted (which is not helped by it
    being spread across several predicates), it is very hard to construct
    a correctness argument for it.

    It would be better to represent the different classes of extensions
    explicitly, in a du type, with each function symbol of that type
    representing all the extensions in the corresponding class (in the sense
    of the paragraph above). However, getting there in one diff would make
    that diff far too hard to test and to review. So this first diff
    starts by simply making extension a notag type.

    The above is the first step in implementing one old XXX. This diff
    fully implements another old XXX, which is to make the argument order
    of several predicates friendly to higher order code.

    Add infrastructure for profiling how often this code makes directories.

    Delete an unused type.

    Add comments outlining proposed future improvements.

compiler/analysis.file.m:
compiler/analysis.m:
compiler/compile_target_code.m:
compiler/du_type_layout.m:
compiler/elds_to_erlang.m:
compiler/export.m:
compiler/fact_table.m:
compiler/file_kind.m:
compiler/find_module.m:
compiler/generate_dep_d_files.m:
compiler/grab_modules.m:
compiler/llds_out_file.m:
compiler/make.build.m:
compiler/make.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_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/module_imports.m:
compiler/parse_tree_out.m:
compiler/prog_foreign.m:
compiler/read_modules.m:
compiler/recompilation.check.m:
compiler/recompilation.usage.m:
compiler/write_deps_file.m:
compiler/write_module_interface_files.m:
compiler/xml_documentation.m:
    Conform to the change to file_names.m.

    Consistently use "Ext" for the abstract representation of extensions
    and "ExtStr" for their string representation.

    In a few places, add "XXX EXT" where the code manipulates extensions
    as strings in a way that potentially inferferes with the partition
    of extensions into classes.

    In a few places, rename predicates to avoid ambiguities. factor out
    common code, delete unneeded arguments, replace bools with bespoke types,
    and make similar minor improvements.

    In a few places, remove rafe-isms, such as the use ^elem.
2020-08-14 20:30:36 +10:00
Zoltan Somogyi
6b06bc4e40 Use simplest_msg when possible. 2020-08-10 00:19:08 +10:00
Zoltan Somogyi
2d2272a9ee Compute dependencies of .opt files just once.
compiler/grab_modules.m:
    We used to scan the contents of each .opt file for dependencies twice
    (with default option settings): once when deciding what .opt files
    to read, and once when deciding what .int files to read to make sense
    of those .opt files. Simplify and optimize this: avoid the second scan
    by remembering the results of the first scan.

compiler/get_dependencies.m:
    Since the first scan is all that is left, and it scans each .opt file
    individually, compute the dependencies of each .opt file by itself.

    Return the modules that a .opt file imports explicitly from the ones
    it imports implicitly, in order to allow the latter to be represented
    as a set of flags. ORing the flags of different .opt files together,
    and then converting the resulting flags to a set of modules should be
    faster than converting each .opt files' flags to a set of modules,
    and then unioning those sets. Provide a predicate to OR the flags.
2020-05-28 21:39:04 +10:00
Zoltan Somogyi
14dbd4a46b Simplify implicit dependency on builtin.m.
compiler/get_dependencies.m:
    The interface of the predicates that computed implicit dependencies
    used to return
    (a) the set of modules a piece of code needs to ":- import_module", and
    (b) the set of modules a piece of code needs to ":- use_module".
    However, set (a) *always* contained only one module: builtin.m.
    This lead to a lot of unnecessary operations on this "set".
    The problem with those operations was not the performance impact,
    which is negligible, but the fact that they made the code harder
    to understand.

    This diff therefore changes that interface to return only (b),
    and to document what callers should use for (a).

compiler/grab_modules.m:
compiler/hlds_module.m:
compiler/module_imports.m:
    Conform to the change above.
2020-05-28 08:02:11 +10:00
Zoltan Somogyi
e04e8c343d Delete two redundant fields of module_and_imports.
compiler/module_imports.m:
    Delete the fields of the module_imports data structure that hold
    the name of the module we are processing and its context, since
    that info is available in the parse tree of the module's source code.

compiler/prog_item.m:
    To make the above possible, fill in the context field of
    just initialized, not-yet-filled in source code parse trees.

compiler/grab_modules.m:
    Conform to the changes above.
2020-03-21 00:39:54 +11:00