Commit Graph

67 Commits

Author SHA1 Message Date
Zoltan Somogyi
5eca1f9666 Improve presentation of actual/expected types.
Before this diff, typecheck_error.m could generate error messages like this:

a02x.m:020: In clause for predicate `p1'/3:
a02x.m:020:   in argument 1 of call to predicate `foldl'/4:
a02x.m:020:   type error: type of argument does not match its expected type;
a02x.m:020:   argument has overloaded actual/expected types {
a02x.m:020:     (expected) pred(L, A, A),
a02x.m:020:     (expected) pred(character, A, A),
a02x.m:020:     (inferred) pred(int, a02x.dir, int),
a02x.m:020:     (inferred) pred(int, a02x.dir, int)

As evidenced by a post on m-users, this can be confusing, because the message
says nothing about where the expected types came from.

This diff changes the way we generate error message for errors in which
there is one actual inferred type, but two or more expected types.
It changes the output in two ways:

- it identifies the sources of the expected types, and
- it prints the inferred type just once.

The message we generate for the same code is now

a02x.m:020: In clause for predicate `p1'/3:
a02x.m:020:   in argument 1 of call to predicate `foldl'/4:
a02x.m:020:   type error: type of argument does not match its expected type;
a02x.m:020:   its inferred type is
a02x.m:020:     pred(int, a02x.dir, int),
a02x.m:020:   the type expected by predicate `list.foldl'/4 is:
a02x.m:020:     pred(L, A, A),
a02x.m:020:   the type expected by predicate `string.foldl'/4 is:
a02x.m:020:     pred(character, A, A).

compiler/type_assign.m:
    Expand the args_type_assign type to include a source of the expected type.

    To make this possible, move the cons_type_info type here from
    typecheck_info.m.

    In the process, both simplify and expand one of the cons_type_info type's
    components, the cons_type_info_source type. Simplify it by replacing
    the two sources source_{get}_field_access, which are always treated
    near-identically, with just one source, source_field_access, which has
    an extra field specifying get vs set. Expand it by specifying two details
    we didn't need before: the cons_id if the cons_type_info came from
    a data constructor in a type_ctor, and the field name if it came from
    a field access function.

    Give some fields less misleading names. Update the names of functions
    returning these fields accordingly.

compiler/typecheck_info.m:
    Delete the code moved to type_assign.m.

compiler/typecheck.m:
    Record the sources of args_type_assigns.

    Use more consistent variable names.

    Fix some misleading predicate names.

    Put loop-invarient input arguments before non-loop-invariant arguments.

    Fix bit-rot in some comments.

compiler/typecheck_errors.m:
    As mentioned above, if there is just one actual (inferred) type,
    but two or more expected types, then

    - print the inferred type just once, and
    - identify the sources of the expected types.

    Put the fields of the arg_type_stuff in the same order as our
    error message: inferred, then expected.

    Add some XXXs.

compiler/post_typecheck.m:
    Fix a comment.

tests/invalid/actual_more_expected.{m,err_exp}:
    Add this test case, which is derived from the program on m-users.

tests/invalid/Mmakefile:
tests/invalid/Mercury.options:
    Enable the new test case, and invoke it with -E.
2022-10-16 15:42:30 +11:00
Zoltan Somogyi
26be4bb8e3 Add --warn-ambiguous-pragmas.
The new option is on by default, and it generates a warning about pragmas
that specify a name/arity pair that matches both a predicate and a function,
but does not say which one it is intended to apply to.

compiler/options.m:
doc/user_guide.texi:
    Add the new option.

NEWS:
    Announce the new option.

compiler/add_pragma.m:
    Implement the new option.

    Move to one predicate, get_matching_pred_ids, the code for dealing with
    both the absence of any matches, and the presence of more than one match,
    when looking up name/arity pairs in the predicate table. This allows us
    to delete the mostly-duplicate code fragments that did the same thing
    in all of get_matching_pred_ids's callers.

    Simplify the handling of conflicts between marker pragmas.

compiler/hlds_pred.m:
    Separate out no_inline decisions made by the compiler itself from
    the similar decisions made by users, in order to allow that simplification.

    Move the two inline markers next to each other.

compiler/make_hlds_error.m:
    Change a predicate called from add_pragma*.m to take user arities
    in their semantic form, not their int form, which raises the level
    of the predicate's interface, and factors out duplicate code in its
    callers.

compiler/add_pragma_type_spec.m:
compiler/intermod.m:
compiler/table_gen.m:
    Conform to the changes above.

doc/reference_manual.texi:
    Document pred(...) and func(...) wrappers around name/arity pairs
    in pragmas.

    Delete the commented out section on reserve_tag pragmas, which were
    deleted a while ago.

tests/invalid/inline_conflict.m:
    Expand this test case to test the *absence* of a warning for an
    ambiguous pragma with --no-warn-ambiguous-pragma.

tests/invalid/inline_conflict_warn.{m,err_exp}:
tests/invalid/Mercury.options:
    Add a copy of the inline_conflict test case to test the presence of
    a warning for an actually ambiguous pragma.

tests/invalid_nodepend/fact_table_in_interface.err_exp:
    Expect the updated wording of a warning.
2022-07-31 18:17:02 +10:00
Julien Fischer
99cd93dcfb Shift some tests.
The tests below are not actually invalid, they cause the compiler to emit only
warnings and properly belong in the warnings directory.

tests/invalid/empty_interface.{m,err_exp}:
tests/invalid/foreign_singleton.{m,err_exp}:
tests/invalid/obsolete_proc_pragma.{m,err_exp}:
     Shift these tests into the warnings directory and use the
     appropriate extension for expected outputs in that directory

tests/invalid/Mmakefile:
tests/invalid/Mercury.options:
tests/warnings/Mercury.options:
tests/warnings/Mmakefile:
     Conform to the above changes.
2022-04-14 16:13:37 +10:00
Zoltan Somogyi
381847e3e1 Fix failure of invalid/duplicate_instance_2
by disabling intermodule optimization for it. The error we are looking for
is detected when building the .opt file, but the test's actions don't capture
the error message then.
2022-04-07 06:41:29 +10:00
Zoltan Somogyi
ec22ea43bd Specify --no-intermodule-opt for two tests.
For these two tests in tests/invalid, enabling intermodule optimization
allows the errors we are testing for to be detecting while making the .opt
files, which means we don't get to the compilation step whose output
we want to compare against the expected error output.
2022-01-10 14:44:19 +11:00
Zoltan Somogyi
6413b4fb08 Create invalid_nodepend and invalid_onlydepend.
tests/invalid_onlydepend:
    Move the one test case in tests/invalid for which we want to check
    the error messages generated during the generation of dependencies
    to this new test directory.

tests/invalid_nodepend:
    Move all test cases in tests/invalid which get errors during the
    generation of dependencies but for which we want to check the error
    messages generated during normal compilation to this new test directory.

tests/invalid_nodepend/Mmakefile:
tests/invalid_nodepend/Mercury.options:
tests/invalid_onlydepend/Mmakefile:
tests/invalid_onlydepend/Mercury.options:
    Versions of the same files in tests/invalid, but containing only
    the entries relevant to the moved test cases.

tests/invalid/Mmakefile:
tests/invalid/Mercury.options:
    Delete the entries that refer to the moved test cases.

tests/README:
    Document the two new test directories.

tools/bootcheck:
    Add invalid_onlydepend and invalid_nodepend to the list of
    test directories.
2021-07-28 00:59:04 +10:00
Zoltan Somogyi
bd6e6fca8c Diagnose names with non-full qualifications.
compiler/typecheck_errors.m:
    When the program refers to a predicate, function or data constructor
    from a module with only a use_module declaration, it must do so
    using its fully qualified name. If it refers to it with an unqualified
    or only partially qualified name, the typechecker won't find it,
    because the predicate_table and the cons_table record non-fully-qualified
    names only for the entities imported with import_module declarations.

    When generating error_specs for such errors, look for matches with
    the relevant name among the fully-qualified entries in the predicate
    and cons tables. If we find some, add a sentence to the error message
    about the modules defining such names being imported with use_module,
    not import_module.

compiler/hlds_cons.m:
    Add a way to look up the definitions of all the constructors with
    a given name.

compiler/pred_table.m:
    Add a way to look up the definitions of all the predicates or functions
    with a given name.

mdbcomp/sym_name.m:
    Add some functionality for use by typecheck_errors.m.

tests/invalid/type_error_use_module.m:
tests/invalid/type_error_use_module_2.m:
tests/invalid/type_error_use_module.err_exp:
    A test case for the new functionality.

tests/invalid/Mmakefile:
tests/invalid/Mercury.options:
    Enable the new test case. Sort the list of multimodule tests.

tests/invalid/errors2.err_exp:
    Expect the new addendum to an existing error message.
2021-04-26 23:47:03 +10:00
Peter Wang
d1522cbcb2 Make subtypes inherit user-defined equality/comparison from base type.
Since values of a subtype are tested for equality or compared
by first converting to the base type then testing/comparing,
it means that subtypes implicitly inherited any user-defined
equality/comparison from the base type. Allowing a subtype to also
define its own equality/comparison predicates seems more confusing
than useful, so disallow it.

compiler/prog_data.m:
    Add a option noncanon_subtype to maybe_canonical.

compiler/add_type.m:
    Report an error if a subtype defined in the current module
    has user-defined equality or comparison.

    Set the maybe_canonical field of hlds_type_defn for a subtype if the
    if the base type is noncanonical. Setting it to noncanon() makes the
    type_ctor_info have a MR_TypeCtorRep value of
    MR_TYPECTOR_REP_*_USEREQ.

compiler/unify_proc.m:
    Handle subtypes ahead of (other) noncanonical types when generating
    unify or compare proc clauses.

compiler/dead_proc_elim.m:
compiler/hlds_out_module.m:
compiler/intermod.m:
compiler/post_term_analysis.m:
compiler/special_pred.m:
    Conform to changes.

doc/reference_manual.texi:
    Document change.

tests/hard_coded/Mmakefile:
tests/hard_coded/subtype_user_compare.exp:
tests/hard_coded/subtype_user_compare.m:
tests/hard_coded/subtype_user_compare2.m:
tests/invalid/Mercury.options:
tests/invalid/Mmakefile:
tests/invalid/subtype_user_compare.err_exp:
tests/invalid/subtype_user_compare.m:
    Add test cases.
2021-04-13 11:38:15 +10:00
Peter Wang
ac70f6d36b Parse and check coerce expressions.
This change implements parsing, typechecking, and modechecking of
"coerce" expressions from my subtypes proposal, i.e. coerce(Term).
Backends currently will abort if asked to generate code for coercions,
as subtypes do not yet share data representations with their base types,
so most coercions would lead to crashes at runtime anyway.

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

compiler/hlds_goal.m:
    Add new type of generic_call to represent coerce expressions.

compiler/hlds_pred.m:
    Add new generic_call_id for coerce expressions.

compiler/superhomogeneous.m:
    Treat var-functor unifications of the form "Var = coerce(Term)"
    as special, producing coerce generic_calls.

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

compiler/type_assign.m:
    Add a field to type_assign to hold coerce constraints to be checked,
    or known to be unsatisfiable, in the given type assignment.

compiler/typecheck.m:
compiler/typecheck_errors.m:
    Implement typechecking of coerce expressions.

compiler/prog_type.m:
    Add a predicate type_is_ground_except_vars.

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

compiler/check_hlds.m:
    Add new module modecheck_coerce.

compiler/modecheck_coerce.m:
    Implement modechecking of coerce expressions.

compiler/modecheck_goal.m:
    Call modecheck_coerce at a coerce generic call.

compiler/mode_errors.m:
    Add two mode errors relating to coerce expressions.

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

compiler/arg_info.m:
compiler/build_mode_constraints.m:
compiler/bytecode_gen.m:
compiler/call_gen.m:
compiler/coverage_profiling.m:
compiler/deep_profiling.m:
compiler/exception_analysis.m:
compiler/float_regs.m:
compiler/follow_vars.m:
compiler/goal_util.m:
compiler/higher_order.m:
compiler/hlds_desc.m:
compiler/hlds_out_goal.m:
compiler/hlds_out_util.m:
compiler/intermod.m:
compiler/interval.m:
compiler/lambda.m:
compiler/live_vars.m:
compiler/ml_call_gen.m:
compiler/ml_code_gen.m:
compiler/mode_constraints.m:
compiler/old_type_constraints.m:
compiler/post_typecheck.m:
compiler/pre_quantification.m:
compiler/tabling_analysis.m:
compiler/term_traversal.m:
compiler/trailing_analysis.m:
compiler/tupling.m:
compiler/unique_modes.m:
compiler/unused_imports.m:
compiler/purity.m:
compiler/simplify_goal.m:
compiler/simplify_goal_call.m:
compiler/structure_reuse.direct.detect_garbage.m:
compiler/structure_reuse.indirect.m:
compiler/structure_sharing.analysis.m:
    Conform to changes.

compiler/prog_rep.m:
    Conform to changes. Reuse cast_rep for coercions for now.

compiler/hlds_statistics.m:
    Count coercions in proc stats.

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

tests/invalid/Mercury.options:
tests/invalid/Mmakefile:
tests/invalid/coerce_ambig.err_exp:
tests/invalid/coerce_ambig.m:
tests/invalid/coerce_clobbered.err_exp:
tests/invalid/coerce_clobbered.m:
tests/invalid/coerce_disambig.err_exp:
tests/invalid/coerce_disambig.m:
tests/invalid/coerce_implied_mode.err_exp:
tests/invalid/coerce_implied_mode.m:
tests/invalid/coerce_infer.err_exp:
tests/invalid/coerce_infer.m:
tests/invalid/coerce_instvar.err_exp:
tests/invalid/coerce_instvar.m:
tests/invalid/coerce_mode_error.err_exp:
tests/invalid/coerce_mode_error.m:
tests/invalid/coerce_non_du.err_exp:
tests/invalid/coerce_non_du.m:
tests/invalid/coerce_syntax.err_exp:
tests/invalid/coerce_syntax.m:
tests/invalid/coerce_type_error.err_exp:
tests/invalid/coerce_type_error.m:
tests/invalid/coerce_unify_tvars.err_exp:
tests/invalid/coerce_unify_tvars.m:
tests/invalid/coerce_uniq.err_exp:
tests/invalid/coerce_uniq.m:
tests/invalid/coerce_unreachable.err_exp:
tests/invalid/coerce_unreachable.m:
tests/invalid/coerce_void.err_exp:
tests/invalid/coerce_void.m:
    Add test cases.

tests/typeclasses/arbitrary_constraint_class.m:
tests/typeclasses/arbitrary_constraint_pred_1.m:
tests/typeclasses/arbitrary_constraint_pred_2.m:
    Wrap parentheses around calls to a coerce/1 method
    to prevent them being treated as coerce expressions.

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

doc/reference_manual.texi:
    Rewrite chapter on Type conversions (still commented out).
    In particular, the typechecking rules that I had written
    previously were insufficient.

NEWS:
    Mention backwards incompatibility.
2021-03-15 11:16:31 +11:00
Zoltan Somogyi
63dabcfcf8 Fix filling in partial terms that use direct_arg tags.
This fix uses the approach discussed on m-dev 2020 nov 16/17 for fixing
github issue #72, whose core problem is a need for information flow
back to a the caller from a callee when the callee fills in the
argument of a function symbol whose representation is a direct_arg tag.
In most cases when the callee fills in the value of an argument,
the caller can see it because the argument is in a word on the heap,
but when the function symbol uses a direct_arg tag, that is not the case.

compiler/direct_arg_in_out.m:
    A new module that implements the transformation proposed on m-dev.
    It creates a fresh clone variable every time an argument of a direct_arg
    tag function symbol is (or may be) updated. This can happen several
    times if a type has more than one function symbol with a direct_arg tag.
    Since the affected variable can be bound to only one function symbol
    at the start, its argument can be filled in only once, but the
    compiler cannot know in advance what function symbol the variable
    contains, and therefore which of the possibly several fill-in sites
    (which fill in the arguments of different function symbols) executed
    in sequence will actually update the variable.

    The transformation ensures that once a variable is cloned, it is
    never referred to again. It also ensures that in a branched control
    structure (if-then-else, disjunction or switch), all branches will use
    the *same* variable to represent the latest version of each cloned
    variable at the end, so that following code has a consistent view
    regardless of through which branch execution has reached it.

    There are three situations that the transformation cannot and does not
    handle.

    1. Situations in which the mode of an argument is either an inst variable,
       or an abstract inst. In either case, the pass cannot know whether
       it should apply its transformation to the argument.

    2. Situations where a procedure that has such an argument is
       exported to C code as a function. In that case, the C signature
       of the function we would generate would be different from what
       the user would normally expect. We could modify the documentation
       of the export pragma, but I don't think there much point due to
       lack of demand. (The problem cannot arise when targeting any language
       other than C, because we use direct_arg tags only with the low level
       data representation, which we only use for C.)

    3. Situations where a procedure that has such an argument is defined
       by foreign_proc. Again, dealing with the problem would require
       nontrivial changes to the documented interface between code in
       foreign_procs and the surrounding Mercury code, and I see no demand
       for code that could benefit from that.

    In these cases, this module generates error messages.

compiler/transform_hlds.m:
    Include the new module in the transform_hlds package.

    Delete unnecessary module qualification on some existing inclusions.
    Put some existing inclusions into a more meaningful order.

compiler/notes/compiler_design.html:
    Document the new pass. Fix some nearby prose.

compiler/lambda.m:
compiler/simplify_proc.m:
    Use a predicate exported by direct_arg_in_out.m to test, for each
    procedure, whether the procedure has any argument positions that are
    subject to the problem that direct_arg_in_out.m addresses.
    simplify_proc.m does this for all procedures it processes;
    lambda.m does this for all the procedures it creates from
    lambda expressions.

    Give a predicate in simplify_proc.m a better name.

    Sort a list of predicate names.

compiler/hlds_module.m:
    Add a field to the module_info that simplify_proc.m and lambda.m
    can use to tell direct_arg_in_out.m what work (if any) it needs to do.

compiler/mercury_compile_middle_passes.m:
    Invoke direct_arg_in_out.m if the new field in the HLDS indicates
    that it has some work to do. (In the vast majority of compiler invocations,
    it won't have any.)

compiler/hlds_pred.m:
    The new code in direct_arg_in_out.m creates a clone of each procedure
    affected by the problem, before deleting the originals (to make sure that
    no references to the unfixed versions of now-fixed procedures remain.)
    Make it possible to create exact clones of both predicates and procedures
    by adding two pairs of predicates, {pred,proc}_prepare_to_clone and
    {pred,proc}_create.

    Add the direct_arg_in_out transformation as a possible source
    of transformed predicates.

library/private_builtin.m:
    Add a new builtin operation, partial_inst_copy, that the new module
    generates calls to.

configure.ac:
    Require the installed compiler to recognize partial_inst_copy
    as a no_type_info builtin.

compiler/builtin_ops.m:
    Recognize the new builtin. (This was committed before the rest; the diff
    to private_builtin.m can be done only once the change to builtin_ops.m
    is part of the installed compiler.)

compiler/options.m:
    Add a way to test whether the builtin_ops.m in the installed compiler
    recognizes the new builtin.

compiler/dead_proc_elim.m:
    Do not delete the new primitive before direct_arg_in_out.m has had
    a chance to generate calls to it.

    Add an XXX.

compiler/error_util.m:
    Recognize the new module as a source of error messages.

compiler/pred_table.m:
    Add a pair of utility predicates to be used when looking up
    builtin predicates, for which the compiler writer knows that
    there should be exactly one match. These are used in direct_arg_in_out.m.

compiler/simplify_goal_call.m:
    Replace some existing code with calls to the new predicates
    in pred_table.m.

compiler/hlds_goal.m:
    Add modes to rename_vars_in_goal_expr that express the fact
    that when an atomic goal_expr has some variables renamed inside it,
    it does not suddenly become some *other* kind of goal_expr.
    New code in direct_arg_in_out.m relies on this.

compiler/hlds_out_goal.m:
    When the HLDS we are dumping out is malformed because it contains
    calls to predicates that have been deleted, the compiler used to abort
    at such calls. (I ran into this while debugging direct_arg_in_out.m.)

    Fix this. When such calls are encountered, we now print out as much
    information we can about the call, and prefix the call with an
    unmistakable prefix to draw attention to the problem.

compiler/inst_util.m:
    Fix a bug that prevented direct_arg_in_out.m from even being invoked
    on some test code for it.

    The bug was in code that we use to unify a headvar's initial inst
    with its final inst. When the initial inst was a non-ground bound_inst
    such as the ones used in tests/hard_coded/gh72.m, and the final inst
    was simply "ground", this code quite properly returned a bound_inst
    (which, unlike ground, can show the exact set of function symbols
    that the headvar could be bound to). The problem was that it
    reused the original bound_inst's test results, including the one
    that said the final inst is NOT ground, which of course is wrong
    for any inst unified with ground. Fix two instances of this bug.

compiler/modes.m:
    Make some of the code I had to traverse to find the bug in inst_util.m
    easier to read and understand.

    Replace some uses of booleans with bespoke enum types.

    Change the argument lists of some predicates to put related arguments
    next to each other.

    Give some variables more descriptive names.

compiler/layout_out.m:
    Conform to the change in hlds_pred.m.

compiler/var_locn.m:
    Fix a code generation bug. When filling-in the value of the argument
    of a function symbol represented by a direct_arg tag, the code we
    generated for it worked only if the direct_arg tag used 0
    as its ptag value. In the test cases we initially used for
    github issue 72, that was the case, but the new tests/hard_coded/gh72.m
    has direct_tag args that use other ptag values as well.

    Document the reason why the updated code works.

compiler/term_constr_initial.m:
    Add the new primitive predicate added to private_builtin.m,
    partial_inst_copy, to a table of builtins that do not take type_infos,
    even though their signatures contain type variables.

    Fix a bunch of old bugs: most other such primitives were not listed
    either.

mdbcomp/program_representation.m:
    Add partial_inst_copy to the master list of builtins that do not take
    type_infos even though their signatures contain type variables. (Done
    by an earlier commit.)

    Document the fact that any updates here require updates to
    term_constr_initial.m.

library/multi_map.m:
    We have long had multi_map.add and multi_map.set as synonyms,
    but we only had multi_map.reverse_set. Add multi_map.reverse_add
    as a synonym for it.

    Define the "set" versions in terms of the "add" versions,
    instead of vice versa.

NEWS:
    Document the new predicates in multi_map.m.

tests/hard_coded/gh72a.m:
    Fix typo.

tests/hard_coded/gh72.{m,exp}:
    A new, much more comprehensive test case than gh72a.m.
    This one tries to tickle github issue 72 in as many forms of code
    as I can think of.

tests/invalid/gh72_errors.{m,err_exp}:
    A test case for testing the generation of error messages for
    two out of the three kinds of situations that direct_arg_in_out.m
    cannot handle. (Proposals for how to test the third category welcome.)

tests/hard_coded/Mmakefile:
tests/invalid/Mmakefile:
    Enable the two new test cases, as well as two old ones, gh72[ab].m,
    that previously we didn't pass.

tests/invalid/Mercury.option:
    Do not compile gh72_error.m with --errorcheck-only, since its errors
    are reported by a pass that --errorcheck-only does not invoke.
2021-01-13 05:35:40 +11:00
Zoltan Somogyi
aea3b98033 Test the process of making .int files.
tests/Mmakefile:
tools/bootcheck:
    Add invalid_make_int and valid_make_int as new test directories.

tests/invalid_make_int/missing_interface_import.m:
tests/invalid_make_int/missing_interface_import.int_err_exp:
tests/invalid_make_int/missing_interface_import.int_err_exp2:
    Move this test case from invalid to invalid_make_int, since it was
    *already* testing the error message we get from "mmc --make-interface".

tests/invalid_make_int/Mercury.options:
tests/invalid_make_int/Mmakefile:
    Set up testing of whether we get the right error messages during
    the process of making .int files.

tests/Mmake.common:
    Provide a way for tests in invalid_make_int to compare a .int_err file
    against several .int_err_exp* files.

tests/invalid/Mercury.options:
tests/invalid/Mmakefile:
    Delete references to the test case moved to invalid_make_int.

tests/valid_make_int/bug499.m:
    Add the test case that motivated this change.

tests/valid_make_int/Mercury.options:
tests/valid_make_int/Mmakefile:
    Set up testing of whether we can generate .int files for modules.
2020-04-13 04:14:51 +10:00
Zoltan Somogyi
3e894a7a9d Remove the hl grade component.
As we discussed, it has fallen into disuse. Its main purpose was to
pave the way for the .net backend and later for the java and csharp grades.
Now that the .net backend is ancient history and the java and csharp grades
are established, that purpose is gone, and for every other purpose,
hlc is better because it is simpler and faster.

compiler/options.m:
    Delete the --high-level-data option. It is no longer needed,
    bacause the data representation scheme is now a direct function
    of the target language.

doc/user_guide.texi:
    Delete references to the --high-level-data option.

NEWS:
    Mention that --high-level-data is no longer supported.

compiler/compute_grade.m:
    Delete references to the hl grade component, and conform
    to the deletion of the --high-level-data option.

compiler/compile_target_code.m:
    Give some predicates more meaningful names, and conform to the
    deletion of the --high-level-data option.

compiler/const_struct.m:
compiler/du_type_layout.m:
compiler/globals.m:
compiler/handle_options.m:
compiler/lco.m:
compiler/mercury_compile_main.m:
compiler/ml_gen_info.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen_construct.m:
compiler/mlds_to_c_data.m:
compiler/mlds_to_c_func.m:
compiler/mlds_to_c_type.m:
compiler/mlds_to_c_util.m:
    Conform to the deletion of the --high-level-data option.

grade_lib/grade_spec.m:
grade_lib/grade_vars.m:
    Delete the datarep solver variable, since the data representation
    is now a direct function of the target language.

    Delete the requirements involving the deleted solver variable.

grade_lib/grade_structure.m:
    Delete the datarep component of the representation of MLDS C grades,
    since its value would now be fixed.

grade_lib/grade_solver.m:
grade_lib/grade_string.m:
grade_lib/try_all_grade_structs.m:
grade_lib/var_value_names.m:
    Conform to the changes above.

grade_lib/Mmakefile:
    Link the grade library's test programs statically, like we do
    the executables in the other directories.

library/io.m:
library/robdd.m:
library/rtti_implementation.m:
runtime/mercury_conf_param.h:
runtime/mercury_grade.h:
runtime/mercury_hlc_types.h:
    Remove references to MR_HIGHLEVEL_DATA, as well as any code
    that was guarded by #ifdef MR_HIGHLEVEL_DATA.

scripts/Mmake.vars.in:
scripts/canonical_grade.sh-subr:
scripts/final_grade_options.sh-subr:
scripts/init_grade_options.sh-subr:
scripts/mgnuc.in:
scripts/mgnuc_file_opts.sh-subr:
scripts/mmake.in:
scripts/mmc.in:
scripts/mtc:
scripts/parse_grade_options.sh-subr:
scripts/parse_ml_options.sh-subr.in:
    Remove references to --high-level-data options.

    In canonical_grade.sh-subr, compute the base grade more directly.

    Remove a few left-over references to the assembler backend.

    Add or fix vim modelines where relevant.

    Fix inconsistent indentation.

    Add missing ;;s in case statements.

    Switch to using ${var} references instead of just $var.

tests/invalid/Mercury.options:
    Make the test_feature_set test case run in grade java instead of hl.gc.

tests/invalid/test_feature_set.err_exp:
    Update the expected out for the grade change.
2020-04-11 19:30:58 +10:00
Zoltan Somogyi
0fcd509a02 Make M.{c,java,etc} depend on M.int.
To enable argument packing, we need to ensure that all modules that use
a type (say T) agree on its representation. The design I am working to
implement designates the .int file of the module that defines the type
(call it M) as the single source of truth for this. Every module that
imports the definition of the type, even through intermodule optimization,
gets that definition from M.int. The only module that depends on the type
that does not get its definition from M.int is M itself.

Before I can add code that makes the compiler get the representation of
T from M.int even when generating for M itself, I have to make sure that
at the time of that compiler invocation, M.int will (a) exist, and (b)
be up-to-date. That is why this change makes M.int a prerequisite
for generating target language code for M both when using mmc --make
and when using mmake.

compiler/make.dependencies.m:
    Add M.int to the list of dependencies for M's code generation.

compiler/write_deps_file.m:
    Add M.int as an extra source for the mmake rule containing
    code generation dependencies.

    Add an XXX.

tests/invalid/Mercury.options:
    Delete --compile-only from a test case's options. Since we now
    generate an interface file for the test case, the --compile-only
    would otherwise clash with the --make-interface option needed for that.
2020-03-17 11:51:31 +11:00
Zoltan Somogyi
9789375cc5 Make pre-HLDS passes use file-kind-specific parse trees.
Replacing item blocks file-kind-specific kinds of section markers with
file-kind-specific parse trees has several benefits.

- It allows us to encode the structural invariants of each kind of file
  we read in within the type of its representation. This makes the detection
  of any accidental violations of those invariants trivial.

- Since each file-kind-specific parse tree has separate lists for separate
  kinds of items, code that wants to operate on one or a few kinds of items
  can just operate on those kinds of items, without having to traverse
  item blocks containing many other kinds of items as well. The most
  important consequence of this is not the improved efficiency, though
  that is nice, but the increased clarity of the code.

- The new design is much more flexible. For example, it should be possible
  to record that e.g. an interface file we read in as a indirect dependency
  (i.e. a file we read not because its module was imported by the module
  we are compiling, but because its module was imported by *another* imported
  module) should be used *only* for the purpose it was read in for. This should
  avoid situations where deleting an import of A from a module, because it
  is not needed anymore, leads the compiler to generate an error message
  about a missing import of module B. This can happen if (a) module B
  always *should* have been imported, since it is used, but (b) module A's
  import of module B lead to module B's interface being available *without*
  an import of B.

  Specifically, this flexibility should enable us to establish each module's
  .int file as the single source of truth about how values of each type
  defined in that module should be represented. When compiling each source
  file, this approach requires the compiler to read in that module's .int file
  but using only the type_repn items from that .int file, and nothing else.

- By recording a single parse tree for each file we have read, instead of
  a varying number of item blocks, it should be significantly easier to
  derive the contents of .d files directly from the records of those
  parse trees, *without* having to maintain a separate set of fields
  in the module_and_imports structure for that purpose. We could also
  trivially avoid any possibility of inconsistencies between these two
  different sources of truth. (We currently fill in the fields used to
  drive the generation of .d files using two different pieces of code,
  one used for --generate-dependencies and one used for all other invocations,
  and these two *definitely* generate inconsistent results, as the significant
  differences in .d files between (a) just after an invocation of
  --generate-dependencies and (b) just after any other compiler invocation
  can witness.)

This change is big and therefore hard to review. Therefore in many files,
this change adds "XXX CLEANUP" comments to draw attention to places that
have issues that should be fixed, but whose fixes should come later, in
separate diffs.

compiler/module_imports.m:
    The compiler uses the module_and_imports structure defined here
    to go from a raw compilation unit (essentially a module to be compiled)
    to an augmented compilation unit (a raw compilation unit together
    with all the interface and optimization files its compilation needs).
    We used to store the contents of both the source file and of
    the interface and optimization files in the module_and_imports structure
    as item blocks. This diff replaces all those item blocks with
    file-kind-specific parse trees, for the reasons mentioned above.

    Separate out the .int0 files of ancestors modules from the .intN
    files for N>0 of directly imported modules. (Their item blocks
    used to be stored in the same list.)

    Maintain a database of the source, interface and optimization files
    we have read in so far. We use it to avoid reading in interface files
    if we have already read in a file for the same module that contains
    strictly more information (either an interface file with a smaller
    number as a suffix, or the source file itself).

    Shorten some field names.

compiler/prog_item.m:
    Define data structures for storing information about include_module,
    import_module and use_module declarations, both in a form that allows
    the representation of possibly erroneous code in actual source files,
    and in checked-and-cleaned-up form which is guaranteed to be free
    of the relevant kinds of errors. Add a block comment at the start
    of the module about the need for this distinction.

    Define parse_tree_module_src, a data structure for representing
    the source code of a single module. This is different from the existing
    parse_tree_src type, which represents the contents of a single source file
    but which may contain *more* than one module, and also different from
    a raw_compilation_unit, which is based on item blocks and is thus
    unable to express to invariants such as "no clauses in the interface".

    Modify the existing parse_tree_intN types to express the distinction
    mentioned just above, and to unify them "culturally", i.e. if they
    store the same information, make them store it using the same types.

    Fix a mistake by allowing promises to appear in .opt files.
    I originally ruled them out because the code that generates .opt files
    does not have any code to write out promises, but some of the predicates
    whose clauses it writes out have goal_type_promise, which means that
    they originated as promises, and get written out as promises.

    Split the existing pragma item kind into three item kinds, which have
    different invariants applying to them.

    - The decl (short for declarative) pragmas give the compiler some
      information, such as that a predicate is obsolete or that we
      want to type specialize some predicate or function, that is in effect
      part of the module's interface. Decl pragmas may appear in module
      interfaces, and the compiler may put them into interface files;
      neither statement is true of the other two kinds of pragmas.

    - The impl (short for implementation) pragmas are named so
      precisely because they may appear only in implementation sections.
      They give the compiler information that is private to that module.
      Examples include foreign_decls, foreign_codes, foreign_procs,
      and promises of clause equivalence, and requests for inlining,
      tabling etc. These will never be put into interface files,
      though some of them can affect the compilation of other modules
      by being included in .opt files.

    - The gen (short for generated) pragmas can never (legally) appear
      in source files at all. They record the results of compiler
      analyses e.g. about which arguments of a predicate are unused,
      or what exceptions a function can throw, and accordingly they
      should only ever occur in compiler-generated interface files.

    Use the new type differences between the three kinds of pragmas
    to encode the above invariants about which kinds of pragmas can appear
    where into the various kinds of parse trees.

    Make the augmented compilation unit, which is computed from
    the final module_and_imports structure, likewise switch from
    storing item blocks to storing the whole parse trees of the
    files that went into its construction. With each such parse tree,
    record *why* we read it, since this controls what permissions
    the source module being compiled has for access to the entities
    in the parse tree.

    Simplify the contains_foreign_code type, since one of three
    function symbols was equivalent to one possible use of another
    function symbol.

    Provide a way to record which method of which class a compiler-generated
    predicate is for. (See hlds_pred.m below.)

    Move the code of almost all utility operations to item_util.m
    (which is imported by many fewer modules than prog_item.m),
    keeping just the most "popular" ones.

compiler/item_util.m:
    Move most of the previously-existing utility operations here from
    prog_item.m, most in a pretty heavily modified form.

    Add a whole bunch of other utility operations that are needed
    in more than one other module.

compiler/convert_parse_tree.m:
    Provide predicates to convert from raw compilation units to
    parse_tree_module_srcs, and vice versa (though the reverse
    shouldn't be needed much longer).

    Update the conversion operations between the general parse_tree_int
    and the specific parse_tree_intN forms for the changes in prog_item.m
    mentioned above. In doing so, use a consistent approach, based on
    new operations in item_util.m, to detect errors such as duplicate
    include_module and import/use_module declarations in all kinds
    of parse trees.

    Enforce the invariants that the types of parse trees of various kinds
    can now express in types, generating error messages for their violations.

    Delete some utility operations that have been moved to item_util.m
    because now they are also needed by other modules.

compiler/grab_modules.m:
    Delete code that did tests on raw compilation units that are now done
    when that raw compilation unit is converted to a parse_tree_module_src.
    Use the results of the checks done during that conversion to decide
    which modules are imported/used and in which module section.

    Record a single reason for why we reading in each interface and
    optimization file. The code of make_hlds_separate_items.m will use
    this reason to set up the appropriate permissions for each item
    in those files.

    Use separate code for handling different kinds of interface and
    optimization files. Using generic traversal code was acceptable economy
    when we used the same data structure for every kind of interface file,
    but now that we *can* express different invariants for different kinds
    of interface and optimization file, we want to execute not just different
    code for each kind of file, but the data structures we want to work on
    are also of different types. Using file-kind-specific code is a bit
    longer, but it is significantly simpler and more robust, and it is
    *much* easier to read and understand.

    Delete the code that separates the parts of the implementation section
    that are exported to submodules, and the part that isn't, since that task
    is now done in make_hlds_separate_items.m.

    Pass a database of the files we have read through the relevant predicates.

    Give some predicates more meaningful names.

compiler/notes/interface_files.html:
    Note a problem with the current operation of grab_modules.

compiler/get_dependencies.m:
    Add operations to gather implicit references to builtin modules
    (which have to be made available even without an explicit import_module
    or use_module declaration) in all kinds of parse trees. These have
    more code overall, but will be at runtime, since we need only look at
    the item kinds that may *have* such implicit references.

    Add a mechanism to record the result of these gathering operations
    in import_and_or_use_maps.

    Give some types, function symbols, predicates and variables
    more meaningful names.

compiler/make_hlds_separate_items.m:
    When we stored the contents of the source module and the
    interface and optimization files we read in to augment it
    in the module_and_imports structure as a bunch of item blocks,
    the job of this module was to separate out the different kinds of items
    in the item blocks, returning a single list of each kind of item,
    with each such item being packaged up with its status (which encodes
    a set of permissions saying what the source module is allowed
    to do with it).

    Now that the module_and_imports structure stores this info in
    file-kind-specific parse trees, all of which have separate lists
    for each kind of item and none of which contain item blocks,
    the job of this module has changed. Now its job is to convert
    the reason why each file was read in into the (one or more) statuses
    that apply to the different kinds of items stored in it, wrap up
    each item with its status, and return the resulting overall list
    of status/item pairs for each kind of item.

compiler/read_modules.m:
    Add predicates that, when reading an interface file, return its contents
    in the tightest possible file-kind-specific parse tree.

    Refine the database of files we have read to allow us to store
    more file-kind-specific parse trees.

    Don't require that files in the database have associated timestamps,
    since in some cases, we read files we can put into the database
    *without* getting their timestamps.

    Allow the database to record that an attempt to read a file failed.

compiler/split_parse_tree_src.m:
    Rearchitect how this module separates out nested submodules from within
    the main module in a file.

    Another of the jobs of this module is to generate error messages for
    when module A includes module B twice, whether via nesting or via
    include_module declarations, with one special exception for the case
    where A's interface contains nested submodule A.B's interface,
    and A's implementation contains nested submodule A.B's implementation.
    The problem ironically was that while it reported duplicate include_module
    declarations as errors, split_parse_tree_src.m also *generated*
    duplicate include_module declarations. Since it replaced each nested
    submodule occurrence with an include_module declaration, in the scenario
    above, it generated two include_module declarations for A.B. Even worse,
    the interface incarnation of submodule A.B could contain
    (the interface of) its own nested submodule A.B.C, while its
    implementation incarnation could contain (the implementation section of)
    A.B.C. Each occurrence of A.B.C would be its only occurrence in the
    including part of its parent A.B, which means local tests for duplicates
    do not work. (I found this out the hard way.)

    The solution we now adopt adds include_module declarations to the
    parents of any submodule only once the parse tree of the entire
    file has been processed, since only then do we know all the
    includer/included relationships among nested modules. Until then,
    we just record such relationships in a database as we discover them,
    reporting duplicates when needed (e.g. when A includes B twice
    *in the same section*), but not reporting duplicates when not needed
    (e.g. when A.B includes A.B.C in *different* sections).

compiler/prog_data.m:
    Add a new type, pf_sym_name_and_arity, that exactly specifies
    a predicate or function. It is a clone of the existing simple_call_id
    type, but its name does NOT imply that the predicate or function
    is being called.

    Add XXXs that call for some other improvements in type names.

compiler/prog_data_foreign.m:
    Give a type, and the operations on that type, a more specific name.

compiler/error_util.m:
    Add an id field to all error_specs, which by convention should be
    filled in with $pred. Print out the value in this field if the compiler
    is invoked with the developer-only option --print-error-spec-id.
    This allows a person debugging the compiler find out where in the code
    an undesired error message is coming from significantly easier
    than was previously possible.

    Most of the modules that have changes only "to conform to the changes
    above" will be for this change. In many cases, the updated code
    will also simplify the creation of the affected error_specs.

    Fix a bug that looked for a phase in only one kind of error_spec.

    Add some utility operations needed by other parts of this change.

    Delete a previously internal function that has been moved to
    mdbcomp/prim_data.m to make it accessible in other modules as well.

compiler/Mercury.options:
    Ask the compiler to warn about dead predicates in every module
    touched by this change (at least in one its earlier versions).

compiler/add_foreign_enum.m:
    Replace a check for an inappropriately placed foreign_enum declaration
    with a sanity check, since with this diff, the error should be caught
    earlier.

compiler/add_mutable_aux_preds.m:
    Delete a check for an inappropriately placed mutable declaration,
    since with this diff, the error should be caught earlier.

compiler/add_pragma.m:
    Instead of adding pass2 and pass3 pragmas, add decl and impl and
    generated pragmas.

    Delete the tests for generated pragma occurring anywhere except
    .opt files, since those tests are now done earlier.

    Shorten some too-long predicate names.

compiler/comp_unit_interface.m:
    Operate on as specific kinds of parse trees as the interface of this
    module will allow. (We could operate on more specific parse trees
    if we changed the interface, but that is future work).

    Use the same predicates for handling duplicate include_module,
    import_module and use_module declarations as everywhere else.

    Delete the code of an experiment that shouldn't be needed anymore.

compiler/equiv_type.m:
    Replace code that operated on item blocks with code that operates
    on various kinds of parse trees.

    Move a giant block of comments to the front, where it belongs.

compiler/hlds_module.m:
    Add a field to the module_info that lets us avoid generating
    misleading error messages above missing definitions of predicates
    or functions when those definitions were present but were not
    added to the HLDS because they had errors.

    Give a field and its access predicates a more specific name.

    Mark a spot where an existing type cannot express everything
    it is supposed to.

compiler/hlds_pred.m:
    For predicates which the compiler creates to represent a class method
    (the virtual function, in OOP terms), record not just this fact,
    but the id of the class and of the method. Using this extra info
    in progress messages (with mmc -V) prevents the compiler from printing e.g.

        % Checking typeclass constraints on class method
        % Checking typeclass constraints on class method
        % Checking typeclass constraints on class method

    when checking three such predicates.

compiler/make.m:
    Provide a slot in the make_info structure to allow the database
    of the files we have read in to be passed around.

compiler/make_hlds_error.m:
    Delete predicates that are needed in just one other module,
    and have therefore been moved there.

compiler/make_hlds_passes.m:
    Add decl, impl and generated pragma separately, instead of adding
    pass2 and pass3 pragmas separately.

    Do not generate error messages for clauses, initialises or finalises
    in module interfaces, since with this diff, such errors should be
    caught earlier.

compiler/mercury_compile_main.m:
compiler/recompilation.check.m:
    Explicitly pass around the expanded database of parse trees
    of files that have been read in.

compiler/module_qual.collect_mq_info.m:
compiler/module_qual.m:
compiler/module_qual.qualify_items.m:
    Collect module qualification information, and do module qualification
    respectively on parse trees of various kinds, not item blocks.
    Take information about what the module may do with the contents
    of each interface or optimization file from the record of why
    we read that file, not from the section markers in item blocks.

    Break up some too-large predicates by carving smaller ones out of them.

compiler/options.m:
    Add an option to control whether errors and/or warnings detecting
    when deciding what should go into a .intN file be printed,
    thus (potentially) preventing the creation of that file.

    Add commented-out documentation for a previously totally undocumented
    option.

doc/user_guide.texi:
    Document the new option.

NEWS:
    Announce the new option.

    Mention that we now generate warnings for unused import_module and
    use_module declarations in the interface even if the module has
    submodules.

compiler/write_module_interface_files.m:
    Let the new option control whether we filter out any messages generated
    when deciding what should go into a .intN file.

compiler/parse_item.m:
    Delete actually_read_module_opt, since it is no longer needed;
    its callers now call actually_read_module_{plain,trans}_opt instead.

    Delete unneeded arguments from some predicates.

compiler/parse_module.m:
    Delete some long unused predicates.

compiler/parse_pragma.m:
    When parsing pragmas, wrap them up in the new decl, impl or generated
    pragma kinds.

compiler/parse_tree_out.m:
    Add predicates to write out each of the file-kind-specific parse trees.

compiler/parse_tree_out_pragma.m:
    Add predicates to write out decl, impl and generated pragmas.

compiler/polymorphism.m:
    Add a conditionally-enabled progress message, which can be useful
    in tracking down problems.

compiler/prog_item_stats.m:
    Conform NOT to the changes above beyond what is needed to let this module
    compile. Let that work be done the next time the functionality of
    this module is needed, by which time the affected data structures
    maybe have changed further.

compiler/typecheck.m:
    Fix a performance problem. With intermodule optimization, we read in
    .opt files, some of which (e.g. list.opt and int.opt) contain promises.
    These promises are read in as predicates with goal_type_promise,
    but they do not have declarations of the types of their arguments
    (since promises do not have declarations as such). Those argument types
    therefore have to be inferred. That inference replaces the original
    "I don't know" argument types with their actual types.

    The performance problem is that when we change the recorded argument types
    of a predicate, we require another loop over all the predicates in the
    module, so that any calls to this predicate can be checked against
    the updated types. This is as it should be for callable predicates,
    but promises are not callable. So if all the *only* predicates whose
    recorded argument types change during the first iteration to fixpoint
    are promises, then a second iteration is not needed, yet we used to do it.

    The fix is to replace the "Have the recorded types of this predicate
    changed?" boolean flag with a bespoke enum that says "Did the checking
    of this predicate discover a need for another iteration", and not
    setting it when processing predicates whose type is goal_type_promise.

compiler/typecheck_errors.m:
    Do not generate an error message for a predicate missing its clauses
    is the clauses existed but were not added to the HLDS because they were
    in the interface section.

    When reporting on ambiguities (when a call can match more than one
    predicate or function), sort the possible matches before reporting
    them.

compiler/accumulator.m:
compiler/add_class.m:
compiler/add_clause.m:
compiler/add_foreign_proc.m:
compiler/add_mode.m:
compiler/add_pragma_tabling.m:
compiler/add_pragma_type_spec.m:
compiler/add_pred.m:
compiler/add_type.m:
compiler/canonicalize_interface.m:
compiler/check_for_missing_type_defns.m:
compiler/check_parse_tree_type_defns.m:
compiler/check_promise.m:
compiler/check_raw_comp_unit.m:
compiler/check_typeclass.m:
compiler/common.m:
compiler/compile_target_code.m:
compiler/compiler_util.m:
compiler/dead_proc_elim.m:
compiler/deps_map.m:
compiler/det_analysis.m:
compiler/det_report.m:
compiler/du_type_layout.m:
compiler/field_access.m:
compiler/find_module.m:
compiler/float_regs.m:
compiler/format_call.m:
compiler/goal_expr_to_goal.m:
compiler/handle_options.m:
compiler/hlds_out_module.m:
compiler/hlds_out_pred.m:
compiler/hlds_out_util.m:
compiler/inst_check.m:
compiler/intermod.m:
compiler/introduce_parallelism.m:
compiler/layout_out.m:
compiler/make.dependencies.m:
compiler/make.module_dep_file.m:
compiler/make_hlds_warn.m:
compiler/mark_tail_calls.m:
compiler/mercury_compile_llds_back_end.m:
compiler/ml_top_gen.m:
compiler/mmakefiles.m:
compiler/mode_errors.m:
compiler/mode_robdd.equiv_vars.m:
compiler/modes.m:
compiler/module_qual.qual_errors.m:
compiler/oisu_check.m:
compiler/old_type_constraints.m:
compiler/options_file.m:
compiler/parse_class.m:
compiler/parse_dcg_goal.m:
compiler/parse_goal.m:
compiler/parse_inst_mode_defn.m:
compiler/parse_inst_mode_name.m:
compiler/parse_mutable.m:
compiler/parse_sym_name.m:
compiler/parse_type_defn.m:
compiler/parse_type_name.m:
compiler/parse_type_repn.m:
compiler/parse_types.m:
compiler/parse_util.m:
compiler/parse_vars.m:
compiler/post_term_analysis.m:
compiler/post_typecheck.m:
compiler/prog_event.m:
compiler/prog_mode.m:
compiler/purity.m:
compiler/qual_info.m:
compiler/recompilation.version.m:
compiler/resolve_unify_functor.m:
compiler/simplify_goal.m:
compiler/simplify_goal_call.m:
compiler/simplify_goal_disj.m:
compiler/simplify_goal_ite.m:
compiler/simplify_proc.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/trace_params.m:
compiler/unused_args.m:
compiler/unused_imports.m:
compiler/write_deps_file.m:
compiler/xml_documentation.m:
    Conform to the changes above.

mdbcomp/prim_data.m:
    Move a utility function on pred_or_funcs here from a compiler module,
    to make it available to other compiler modules as well.

scripts/compare_s1s2_lib:
    A new script that helped debug this diff, and may help debug
    similar diffs the future. It can compare (a) .int* files, (b) .*opt
    files, (c) .mh/.mih files or (d) .c files between the stage 1 and
    stage 2 library directories. The reason for the restriction
    to the library directory is that any problems affecting the
    generation of any of these kinds of files are likely to manifest
    themselves in the library directory, and if they do, the bootcheck
    won't go on to compile any of the other stage 2 directories.

tests/debugger/breakpoints.a.m:
tests/debugger/breakpoints.b.m:
    Move import_module declarations to the implementation section
    when they are not used in the interface. Until now, the compiler
    has ignored this, but this diff causes the compiler to generate
    a warning for such misplaced import_module declarations even modules
    that have submodules. The testing of such warnings is not the point
    of the breakpoints test.

tests/invalid/Mercury.options:
    Since the missing_interface_import test case tests error messages
    generated during an invocation of mmc --make-interface, add the
    new option that *allows* that invocation to generate error messages.

tests/invalid/ambiguous_overloading_error.err_exp:
tests/invalid/max_error_line_width.err_exp:
tests/warnings/ambiguous_overloading.exp:
    Expect the updated error messages for ambiguity, in which
    the possible matches are sorted.

tests/invalid/bad_finalise_decl.m:
tests/invalid/bad_initialise_decl.m:
    Fix programming style.

tests/invalid/bad_item_in_interface.err_exp:
    Expect an error message for a foreign_export_enum item in the interface,
    where it should not be.

tests/invalid/errors.err_exp:
    Expect the expanded wording of a warning message.

tests/invalid/foreign_enum_invalid.err_exp:
    Expect a different wording for an error message. It is more "standard"
    but slightly less informative.

tests/invalid_submodules/children2.m:
    Move a badly placed import_module declaration, to avoid having
    the message the compiler now generates for it from affecting the test.

tests/submodules/parent2.m:
    Move a badly placed import_module declaration, to avoid having
    the message the compiler now generates for it from affecting the test.

    Update programming style.
2020-03-13 12:58:33 +11:00
Zoltan Somogyi
d5ade25753 Implement the obsolete_proc pragma.
While the existing obsolete pragma declares an entire predicate or function
obsolete, the new obsolete_proc pragma does this for only THE NAMED MODE
of a predicate or function.

NEWS:
doc/reference_manual.texi:
    Mention and document the new pragma.

compiler/prog_item.m:
    Add the new pragma. Rename the old pragma to "obsolete_pred". (This affects
    only the compiler's internal name; the user visible name stays the same.)

    Move a type definition next to its related types.

compiler/parse_pragma.m:
    Read in the new pragma.

compiler/hlds_pred.m:
    Create a slot in proc_infos for the information in the new pragma.

compiler/add_pragma.m:
    Add the new pragma to the HLDS.

    To avoid adding to the substantial existing code duplication in this
    module, factor out two commonly recurring pieces of code: one that
    looks up the (hopefully unique) pred_id specified by a pragma, and
    one that looks up and (if found) transforms the procedure specified
    by a pragma.

    Use error-message phraseology consistent with that employed by
    the newly-factored-out predicate even in places that cannot use them.

    Move the code handling foreign_export pragma here from add_foreign_proc.m
    to take advantage of the newly-factored out predicates.

compiler/add_foreign_proc.m:
    Delete the code moved to add_pragma.m.

    Fix the structure of the remaining code by putting related code fragments
    next to each other.

compiler/simplify_goal_call.m:
    Generate warnings to obsolete procedures as well as obsolete predicates.

compiler/parse_tree_out_pragma.m:
    Output the new pragma.

    Factor out existing common code.

compiler/hlds_code_util.m:
    Put a predicate's arguments into a more meaningful order.

compiler/make_hlds_error.m:
    Allow the caller of report_undefined_pred_or_func_error to specify
    whether the error applies to a predicate or a function. Most callers
    don't have that info, but some do, and using this info when available
    allows us to generate a more specific error message.

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

    Make a predicate easier to read by moving unimportant code out-of-line.

compiler/intermod.m:
    Conform to the changes above. Do this in a way that is adaptable to
    making intermod.m generate lists of items instead of simply writing
    stuff out, even though this makes the diff to this file more complex
    than immediately necessary.

compiler/add_mutable_aux_preds.m:
compiler/add_pragma_type_spec.m:
compiler/canonicalize_interface.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/item_util.m:
compiler/make_hlds_passes.m:
compiler/make_hlds_separate_items.m:
compiler/module_qual.qualify_items.m:
compiler/prog_data_pragma.m:
compiler/prog_item_stats.m:
compiler/recompilation.version.m:
    Conform to the changes above.

compiler/options.m:
    Provide a simple way for the configure script to test for the presence
    of this new addition.

tests/invalid/obsolete_proc_pragma.{m,err_exp}:
    A test case for the new pragma.

tests/invalid/Mmakefile:
tests/invalid/Mercury.options:
    Enable the new test case, and set it to run with --halt-at-warn.

tests/invalid/bug83.err_exp:
tests/invalid/require_tailrec_invalid.err_exp:
    Update these two files to expect updated error messages.
2019-10-23 05:04:41 +11:00
Zoltan Somogyi
c45719f5cb Don't report errors when creating interface files.
When deciding the contents of interface files, we used to generate
messages for these three kinds of errors:

- clauses in the module interface
- not-allowed-in-the-interface pragmas in the module interface
- empty module interface

None of these affected the interface file we were building, and their
reporting can easily be delayed until we are compiling the affected module
to target language code. At that time, the error messages get put into
.err files, whereas any messages printed when creating interface files
tends to get lost in the overall sea of compiler invocation messages
when running mmake.

compiler/comp_unit_interface.m:
    Do not generate error messages when building the contents of interface
    files.

compiler/write_module_interface_files.m:
    Do not print the error messages that are no longer being generated.
    We *do* still print any of the other kinds of error messages we have
    been printing, such as for those when a needed .int3 file cannot be read,
    or when ambiguity prevents full module qualification. (The contents of
    .int and .int2 files must be fully module qualified to do their jobs.)

compiler/add_pragma.m:
    Report an error when processing a pass 3 pragma that occurs in the
    interface but is not allowed in the interface.

    add_pragma.m has already been doing this for all other kinds of pragmas,
    and in general, compiler invocations that generate target language code
    do generate the messages for all the conditions whose messages we are
    no longer printing when generating interface files.

tests/invalid/bad_item_in_interface.{m,err_exp}:
tests/invalid/ft_examples:
    A new test case to test the above assertion with respect to
    inappropriate items in the interface of a module.

tests/invalid/empty_interface.{m,err_exp}:
    A new test case to test the above assertion with respect to
    the interface of a module being empty.

tests/invalid/Mercury.options:
    Specify the right options for the empty_interface test case.

tests/invalid/Mmakefile:
    Enable the new test cases.
2019-08-27 06:06:17 +10:00
Zoltan Somogyi
bd7d7db57d Move nested-module programs from invalid to invalid_submodules.
This is to compile them with "mmake -j1", and thus avoid the intermittent
failures caused by interface files of nested submodules not being ready
when another job, executed in parallel by mmake, wants to read them.

tests/invalid_submodules/children.m:
tests/invalid_submodules/children2.m:
tests/invalid_submodules/duplicate_module.m:
tests/invalid_submodules/duplicate_module_test.err_exp:
tests/invalid_submodules/duplicate_module_test.m:
tests/invalid_submodules/exported_unify3.err_exp:
tests/invalid_submodules/exported_unify3.err_exp2:
tests/invalid_submodules/exported_unify3.m:
tests/invalid_submodules/func_class.err_exp:
tests/invalid_submodules/func_class.m:
tests/invalid_submodules/import_in_parent.err_exp:
tests/invalid_submodules/import_in_parent.m:
tests/invalid_submodules/missing_parent_import.err_exp:
tests/invalid_submodules/missing_parent_import.m:
tests/invalid_submodules/nested_impl_in_int.err_exp:
tests/invalid_submodules/nested_impl_in_int.m:
tests/invalid_submodules/sub_a.m:
tests/invalid_submodules/sub_c.err_exp:
tests/invalid_submodules/sub_c.m:
tests/invalid_submodules/undef_mod_qual.err_exp:
tests/invalid_submodules/undef_mod_qual.m:
tests/invalid_submodules/unresolved_overloading.err_exp:
tests/invalid_submodules/unresolved_overloading.m:
    Move these files, which contain the source code and expected outputs
    of the affected test cases, from the invalid directory to the new
    invalid_submodules directory.

tests/invalid/Mercury.options:
tests/invalid/Mmakefile:
    Delete any mentions of the moved test cases.

    Improve sh programming style in actions.

tests/invalid_submodules/Mercury.options:
tests/invalid_submodules/Mmakefile:
    List *only* the moved test cases. Specify the -j1 flag for mmake.

tests/Mmakefile:
tools/bootcheck:
    Mention the new test directory.

    Request that the list of test directories in these two places be kept
    in sync.

    Note that the feedback test directory is not yet ready.
2019-08-14 23:28:00 +10:00
Zoltan Somogyi
756ed140d3 Improve non-tail recursion warnings from the MLDS code generator.
Consider two mutually recursive procedures p and q, where p tailcalls q
but q does not tailcall p. The LLDS backend can optimize the tailcall
from p to q, but the MLDS backend cannot, because it can optimize only
*mutual* tail recursion. In such cases, and in other cases where the
MLDS cannot implement a recursive call as a tail call even though the
LLDS backend can, add to the warning message we generate a description
of the reason why the MLDS code generator cannot do what the programmer
may expect them to do.

compiler/ml_gen_info.m:
    Include in the state of the MLDS code generator tail-call-related
    information not just about all the procedures in the current TSCC,
    but about all the procedures in the current SCC. And instead of
    storing warning messages about non-tail recursive calls in the code
    generator state, store a list of the non-tail recursive calls themselves.
    These two changes together allow us to gather a description of all
    the non-tail recursive calls before we generate even the first warning.
    This should allow a later to use this information to generate messages
    such as "the recursive call from p to q here cannot be optimized
    because the recursive call from q to p at this *other* context
    cannot be optimized".

    Make the names of some types and function symbols clearer.

compiler/ml_call_gen.m:
    Whenever a recursive call cannot be optimized as a tail call,
    record the reason behind that fact.

    Use pred_proc_ids instead of separate pred_ids and proc_ids,
    since this simplifies the code and should speed paramater passing.

compiler/ml_proc_gen.m:
    Pass tail-call-related information about the procedures of the SCC along
    as we generate code for the SCC's procedures.

    Once we have generated code for all of the SCC's procedures,
    turn the final list of the non-tail calls in the SCC into a list
    of warnings for them.

compiler/options.m:
doc/user_guide.texi:
    Add a compiler option that controls whether we report as non-tail
    calls recursive calls that *obviously* cannot be tail calls, because
    they are followed by other recursive calls. The standard example
    is the first recursive call in qsort.

    A comment by Paul has long called for such an option, and this diff
    touches the same code anyway.

    Fix an unrelated old blemish: document both of the old options
    --warn-non-tail-recursion-{self,mutual}, but in a commented out form,
    since they are internal-use options. Before this diff, only one was
    documented, and only user_guide.texi.

compiler/mark_tail_calls.m:
    Add parameters to the predicates that generate warnings that specify
    why the recursive call cannot be optimized as a tail call (describing
    the reason if it is a result of a limitation in the compiler, and
    not a problem in the program being compiled), and whether the call
    is obviously a non-tail call.

    When marking a call as recursive, but the recursive call is obviously
    not a tail call, mark it as such using a new goal feature. The MLDS
    backend needs this to allow it to filter warnings for obviousness
    the same way as mark_tail_calls.m itself.

compiler/hlds_goal.m:
    Add the new goal feature mentioned above.

compiler/ml_closure_gen.m:
compiler/ml_tailcall.m:
compiler/rtti_to_mlds.m:
compiler/saved_vars.m:
    Conform to the changes above.

tests/invalid/require_tailrec_1.err_exp2:
tests/invalid/require_tailrec_2.err_exp2:
tests/invalid/require_tailrec_3.err_exp2:
    Add the expected warnings from the MLDS code generator.

tests/invalid/Mercury.options:
    Specify -E for one of the tests above, to test the handling of the
    verbose-only part of the warnings.

tests/EXPECT_FAIL_TESTS.hlc.gc:
    Do not expect tests/invalid/require_tailrec_[123] to fail
    in grade hlc.gc anymore.
2017-10-12 01:08:30 +11:00
Paul Bone
d4ef274451 Enable non-tail-call warnings for mutually-recursive code
This change enables warnings for mutual recursion for the low level C
backend.

--warn-non-tail-recursion currently only works for direct recursion.  This
change renames it to --warn-non-tail-recursion-self and adds
--warn-non-tail-recursion which is intended to produce warnings for self
and mutual recursion.

compiler/options.m:
    Add new option.

compiler/handle_options.m:
    Make --warn-non-tail-recursion imply --warn-non-tail-recursion-self.

compiler/ml_tailcall.m:
    Conform to changes in options.m.

compiler/mark_tail_calls.m:
    Simplify the code that interprets tail recursion warning options, this
    avoids the need for the warn_non_tail_rec_calls_opt which was only used
    here in an unnecessary step.  This logic has also been moved to a
    separate predicate.

    Add a warning for mutually recursive calls that are not tail recursive.

    Update these warning/error messages to say if the call is self or
    mutually recursive.  Also in the case of mutually recursive calls, name
    the callee.

compiler/mercury_compile_llds_back_end.m:
    Compute the dependency information before running the pre-LLDS passes.
    This makes sure that we do this once for the whole module, and
    independently of --trad-passes.

compiler/dependency_graph.m:
    Add a method for getting the SCC of a given node from a dependency_info
    structure.  The SCC is retrieved from a lazily built map.

doc/user_guide.texi:
    Document the changes.

tests/invalid/Mmakefile:
tests/invalid/require_tailrec_1.err_exp:
tests/invalid/require_tailrec_1.m:
tests/invalid/require_tailrec_2.err_exp:
tests/invalid/require_tailrec_2.m:
tests/invalid/require_tailrec_3.err_exp:
tests/invalid/require_tailrec_3.m:
tests/valid/Mmakefile:
tests/valid/require_tailrec_1.m:
tests/valid/require_tailrec_2.m:
tests/valid/require_tailrec_3.m:
    Test the tail recursion warnings a lot more extensively, some of these
    are new test programs, others just have many more test cases within
    them.

tests/invalid/Mercury.options:
tests/valid/Mercury.options:
    Add new test files.

    Disable most optimisations as these could optimise away the mutual tail
    recursions.

tests/EXPECT_FAIL_TESTS.hlc.gc:
    New test case failures.
2017-03-30 17:14:46 +11:00
Julien Fischer
46bd356d66 Improve error reporting for foreign_type pragmas.
compiler/parse_pragma.m:
     Use parse_foreign_language/4 to parse the foreign language argument of a
     foreign_type pragmas; there is no reason for foreign type pragmas to
     use separate code for parsing their first argument.

     Do not allow the foreign type descriptor for C, C# and Java foreign type
     pragmas to be an empty string.

     Do not allow the foreign type descriptor for Erlang foreign type pragmas to
     be a non-empty string.

     In the case of a repeated foreign type assertion, report *which* assertion
     is repeated in the error message.

compiler/parse_type_defn.m:
     Distinguish between when we are parsing a type definition head for an
     actual type definition and when we are parsing it as the second argument
     of a foreign_type pragma.  Currently, we do not make the distinction and
     this causes nonsensical error messages in the case of foreign_type
     pragmas (e.g. in the case where the foreign type descriptor is a type
     variable).

tests/invalid/bad_foreign_type.{m,err_exp}:
     Extend this test to cover the new error messages and also cover other
     cases that we were not previously testing.

tests/invalid/Mercury.options:
     Enable --verbose-error-messages for the above test.

tests/invalid/where_direct_arg2.err_exp:
     Conform to the above change.
2017-03-13 21:35:39 +11:00
Julien Fischer
ced413438c Add workarounds for bugs #184 and #214.
Bug #184 is a compiler abort due to the code that generates an error message
for an unsatisfied type class constraint.  That code is either making an
incorrect assumption about the constraint_map type or the there is a bug in the
type checker.  Bug #214 is also concerned with the error message for
unsatisfied type class constraints: in that case we attempt to list which goals
that are causing the unsatisfied constraints, but that list of goals is empty
and we end up with an incomplete looking error message.   (This is related to
bug #184 as once the the workaround for the abort is in place, the same thing
occurs there.)

compiler/post_typecheck.m:
     Do not assume that all unproven constraints will appears as values
     in the constraint map: that isn't true for the program in bug #184.

     If the list of goals that are causing unsatisfied type class constraints
     is empty, then omit the prefix "The unsatisfied constraints are
     due to:" from the error message.

tests/invalid/Mmakefile:
tests/invalid/Mercury.options.m:
tests/invalid/bug184.{m,err_exp}:
tests/invalid/bug214.{m,err_exp}:
     Add the test cases for the above bugs.
2016-06-29 21:54:40 +10:00
Julien Fischer
934f5eee9a Improve error messages for missing foreign values in foreign_enum pragmas.
Currently, if a foreign_enum pragma is missing cases in the constructor -
foreign value mapping we report that there are some missing foreign values but
do not list the affected constructors unless --verbose-error-messages is
enabled.  For cases where there are a small number of missing foreign values
this is a bit irritating as you need to recompile to find out what they are.
Change the compiler so the error message lists upto the first 10 constructors
that do not have a foreign value.
(If --verbose-error-messages is enabled then we list all of them as before.)

compiler/add_foreign_enum.m:
    Make the above change.

    In error messages for foreign_enum and foreign_export_enum pragmas, add
    the word "type" before the name that is printed in error messages.

tests/invalid/Mmakefile:
tests/invalid/Mercury.options:
tests/fe_unmapped_nonverbose.{m,err_exp}:
tests/fe_napped_verbose.{m,err_exp}:
    Test the new error messages for missing constructors in the constructor -
    foreign value mapping.

tests/invalid/ee_invalid.err_exp:
tests/invalid/foreign_enum_import.err_exp:
tests/invalid/foreign_enum_invalid.err_exp:
    Conform to the above changes.
2016-06-17 22:43:16 +10:00
Julien Fischer
0365e7ce5d Workaround an abort in the polymorphism pass.
post_typecheck.m deletes all but one of the any indistinguishable modes that a
predicate has.  For the predicates that the compiler introduces for type class
methods, this means that we end up with dangling references to proc_ids in the
HLDS class table.  This causing an abort in the polymorphism pass.

compiler/polymorphism.m:
    Workaround the above problem by only expanding method bodies if the
    proc_id is present in the proc_table.  (This should be safe since
    post_typecheck.m is currently the only part of the compiler that
    deletes proc_ids.)

compiler/post_typecheck.m:
    Add an XXX comment explaining why deleting all but the first
    of a set of indistinguishable modes is a bit dodgy.

tests/invalid/Mmakefile:
    Enable the typeclass_dup_method_mode test since we now pass it.

tests/invalid/Mercury.options:
    Run the typeclass_dup_method_mode test with verbose error messages
    enabled.

tests/invalid/typeclass_dup_method_mode.err_exp:
    Update the expected output.
2016-03-18 12:06:10 +11:00
Paul Bone
3452e25fd6 Improve tail call warnings for the low level C grade.
This patch reduces spurious tail call warnings by warning only for the last
of a sequence of recursive calls along an execution path, for example it
no-longer emits a warning for the first of the two recursive calls in
quicksort.  I have already made a change to this effect for the MLDS
backends.

This patch also implements the new the require_tail_recursion pragma.  This
change has already been made for the MLDS backends.

The require_tail_recursion pragma does not yet handle mutual recursion or
raise an error if the code is not recursive at all.  These will be my next
tasks.

compiler/mark_tail_calls.m:
    Combine marking tail calls with warning about tail calls.

    Handle scopes more accurately.

compiler/mercury_compile_llds_back_end.m:
    Conform to changes in mark_tail_calls.m

    No longer warn for tail calls, this is now done in the same pass that
    marks tail calls.  The decision to run this pass is now made on a
    per-procedure basis and in mark_tail_calls.m

tests/invalid/require_tailrec_1.m:
tests/invalid/require_tailrec_2.m:
tests/invalid/Mmakefile:
tests/invalid/Mercury.options:
tests/valid/require_tailrec_1.m:
tests/valid/require_tailrec_2.m:
tests/valid/Mmakefile:
tests/valid/Mercury.options:
    Add new tests.

tests/invalid/Mmakefile:
tests/invalid/Mercury.options:
tests/invalid/require_tail_recursion.{m,err_exp} ->
        require_tailrec_invalid.{m,exp}:
    Rename existing test.
2015-12-16 22:47:08 +11:00
Paul Bone
c6cbc43448 Add new require_tail_recursion pragma.
This patch allows the pragma to be parsed, and records the information from
the pragma in the proc_info structure for the relevant procedures.

The patch uses the pragma for the MLDS backend.  However because mutual
recursion is not yet supported on the MLDS backend, mutually recursive calls
are ignored by the pragma.

The patch also documents the pragma in the reference manual, this
documentation is commented out until it is implemented for both LLDS and
MLDS backends.

The patch does not implement the SCC feature discussed on the mailing list.
That can be added later.

compiler/prog_data.m:
compiler/prog_item.m:
    Add new require_tail_recursion pragma.

compiler/prog_io_pragma.m:
    Parse the new pragma.

    Remove the arity_and_modes type and use pred_name_arity_mpf_mmode
    type from prog_item.m

compiler/parse_tree_out_pragma.m:
    Support pretty printing the new pragma.

compiler/hlds_pred.m:
    Add require_tailrec_info to the proc_info structure.

compiler/add_pragma.m:
    Add information from the pragma to the proc_info structure after
    parsing.

compiler/compiler_util.m:
    Add a general warning_or_error type.

compiler/mlds.m:
    Add require_tailrec_info to MLDS functions.

compiler/ml_proc_gen.m:
    Copy the require_tailrec_info information from the HLDS to the MLDS.

compiler/ml_tailcall.m:
    Generate errors and warnings with respect to the require_tail_recursion
    pragma.

compiler/mercury_compile.m:
compiler/mercury_compile_mlds_back_end.m:
    Return errors from the MLDS tailcall optimisation pass.

compiler/add_pragma.m:
compiler/comp_unit_interface.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/item_util.m:
compiler/make_hlds_separate_items.m:
compiler/module_qual.qual_errors.m:
compiler/module_qual.qualify_items.m:
compiler/prog_item_stats.m:
compiler/recompilation.version.m:
compiler/write_module_interface_files.m:
    Conform to changes in prog_item.m.

compiler/ml_code_util.m:
compiler/ml_elim_nested.m:
compiler/ml_optimize.m:
compiler/ml_type_gen.m:
compiler/ml_util.m:
compiler/mlds_to_c.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
    Conform to changes in mlds.m.

doc/reference_manual.texi
    Document the require_tail_recursion pragma

tests/invalid/Mercury.options:
tests/invalid/Mmakefile:
tests/invalid/require_tail_recursion.err_exp:
tests/invalid/require_tail_recursion.m:
    Add require_tail_recursion test case
2015-12-08 22:54:59 +11:00
Zoltan Somogyi
c6ab550db8 Remove the code for automatic initialization of solver vars.
We haven't supported it in years, and keeping it in the compiler
is just a maintenance burden and a performance problem.

mdbcomp/prim_data.m:
    Delete the spec_pred_init functor, since we don't support special
    "init" predicates anymore.

compiler/prog_data.m:
    Delete the slot in solver type details that record the name of the
    auto-initialization predicate.

compiler/prog_io_type_defn.m:
    Don't allow a type definition to specify an auto-initialization predicate.

compiler/options.m:
compiler/globals.m:
    Delete the option that allowed support for auto-initialization to be
    turned back on.

compiler/inst_match.m:
compiler/inst_util.m:
    Delete comments about auto-initialization.

compiler/mode_info.m:
    Delete the record of whether we have variables that can be
    auto-initialized (we never do anymore) and the flag that controls whether
    auto-initialization is permitted or not.

compiler/modecheck_conj.m:
    Simplify the code that modechecks conjunctions, since it no longer
    has to figure out where to insert auto-initializations of solver vars.

compiler/modecheck_goal.m:
    Delete the code that ensured that if one branch of a branched
    control structure auto-initialized a solver variable, then they
    all did.

compiler/modecheck_unify.m:
    Don't auto-initializate variables before unifications.

compiler/modecheck_util.m:
    Delete the code that auto-initialized solver variables at the ends
    of procedure bodies if this needed to be done and wasn't done before.

compiler/add_special_pred.m:
compiler/equiv_type.m:
compiler/equiv_type_hlds.m:
compiler/get_dependencies.m:
compiler/hlds_module.m:
compiler/hlds_pred.m:
compiler/modecheck_call.m:
compiler/modes.m:
compiler/module_qual.qualify_items.m:
compiler/parse_tree_out.m:
compiler/post_term_analysis.m:
compiler/smm_common.m:
compiler/special_pred.m:
compiler/term_constr_errors.m:
compiler/term_constr_initial.m:
compiler/term_util.m:
compiler/termination.m:
compiler/trace_params.m:
compiler/type_util.m:
compiler/unify_proc.m:
    Delete code that handled stuff related to auto-initialization,
    and now always take the path that would normally be taken in the
    absence of auto-initialization.

deep_profiler/read_profile.m:
runtime/mercury_layout_util.c:
runtime/mercury_stack_trace.c:
util/mdemangle.c:
    Remove code that recognized the compiler-generated name of initialization
    predicates.

tests/debugger/solver_test.m:
tests/hard_coded/solver_construction_init_test.m:
tests/hard_coded/solver_disj_inits.m:
tests/hard_coded/solver_ite_inits.m:
tests/invalid/missing_init_pred.m:
tests/invalid/zinc2mer_lib.m:
tests/valid/fz_conf.m:
tests/valid/solver_type_bug_2.m:
tests/valid/solver_type_mutable_bug.m:
    These tests tested the handling of auto-initialization, which we
    no longer support. Keep them around (and a bit more visible than
    inside the git repo) in case we need them again, but add a comment
    to each saying that the test is disabled.

tests/debugger/Mercury.options:
tests/debugger/Mmakefile:
tests/hard_coded/Mercury.options:
tests/hard_coded/Mmakefile:
tests/invalid/Mercury.options:
tests/invalid/Mmakefile:
tests/valid/Mercury.options:
tests/valid/Mmakefile:
    Disable those tests.

tests/warnings/non_term_user_special.{m,exp}:
    Part of this test tested the handling of auto-initialization;
    delete that part.

tests/warnings/Mercury.options:
    Delete the flag required by the deleted part, since we don't support it
    anymore.
2015-12-03 05:06:28 +11:00
Paul Bone
20b3309d84 Fix formatting in in tests/invalid/Mercury.options
tests/invalid/Mercury.options:
    As above.
2015-12-01 16:28:18 +11:00
Julien Fischer
3dd02876a5 Delete the MLDS->IL backend.
compiler/mlds_to_il.m:
compiler/mlds_to_ilasm.m:
compiler/mlds_to_managed.m:
compiler/il_peephole.m:
compiler/ilasm.m:
compiler/ilds.m:
    Delete the modules making up the MLDS->IL code generator.

compiler/globals.m:
compiler/prog_data.m:
    Delete IL as a target and foreign language.

compiler/prog_io_pragma.m:
    Delete the max_stack_size/1 foreign proc attribute.  This was only
    ever required by the IL backend.

compiler/options.m
    Delete options used for the IL backend.

compiler/write_deps_file.m:
    Don't generate mmake targets for .il files etc.

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

compiler/notes/compiler_design.html
compiler/notes/work_in_progress.html
    Conform to the above changes.

library/*.m:
    Delete IL foreign_proc and foreign_export pragmas.

README.DotNet:
    Delete this file.

browser/Mmakefile:
compiler/Mmakefile:
deep_profiler/Mmakefile:
mdbcomp/Mmakefile:
mfilterjavac/Mmakefile:
profiler/Mmakefile:
runtime/Mmakefile:
slice/Mmakefile:
    Conform the above changes.

configure.ac:
    Don't check that IL is a supported foreign language when performing the
    up-to-date check.

    Delete the '--enable-dotnet-grades' option.

scripts/Mmake.vars.in:
    Delete variables used for the IL backend (and in on case by the Aditi
    backend).

scripts/Mercury.config.bootstrap.in:
scripts/Mercury.config.in:
scripts/Mmake.rules:
scripts/canonical_grade.sh-subr:
tools/bootcheck:
    Delete stuff related to the 'il' and 'ilc' grades.

doc/reference_manual.texi:
     Delete the documentation of the 'max_stack_size' option.

doc/user_guide.texi:
     Delete stuff related to the IL backend.

tests/hard_coded/csharp_test.{m,exp}:
tests/invalid/foreign_type_missing.{m,err_exp}:
tests/valid/csharp_hello.m:
	Delete these tests: they are no longer relevant.

tests/hard_coded/equality_pred_which_requires_boxing.m:
tests/hard_coded/foreign_import_module.m:
tests/hard_coded/foreign_import_module_2.m:
tests/hard_coded/foreign_type.m:
tests/hard_coded/foreign_type2.m:
tests/hard_coded/foreign_type3.m:
tests/hard_coded/intermod_foreign_type2.m:
tests/hard_coded/lp.m:
tests/hard_coded/user_compare.m:
tests/invalid/foreign_type_2.m:
tests/invalid/foreign_type_missing.{m,err_exp}:
tests/invalid/foreign_type_visibility.m:
tests/invalid/illtyped_compare.{m,err_exp}:
tests/submodules/external_unification_pred.m
tests/valid/big_foreign_type.m
tests/valid/solver_type_bug.m
tests/valid_seq/foreign_type_spec.m
tests/valid_seq/intermod_impure2.m
    Delete IL foreign_procs where necessary.

tests/hard_coded/Mmakefile
tests/invalid/Mercury.options
tests/invalid/Mmakefile
tests/submodules/Mmakefile
tests/valid/Mercury.options
tests/valid/Mmake.valid.common
tests/valid/Mmakefile
tests/valid_seq/Mmakefile
tests/valid_seq/Mercury.options
    Conform to the above changes.
2015-09-21 11:34:46 +10:00
Zoltan Somogyi
62ec97d443 Report imports shadowed by other imports.
If a module has two or more import_module or use_module declarations
for the same module, (typically, but not always, one being in its interface
and one in its implementation), generate an informational message about
each redundant declaration if --warn-unused-imports is enabled.

compiler/hlds_module.m:
    We used to record the set of imported/used modules, and the set of
    modules imported/used in the interface of the current module. However,
    these sets

    - did not record the distinction between imports and uses;
    - did not allow distinction between single and multiple imports/uses;
    - did not record the locations of the imports/uses.

    The first distinction was needed only by module_qual.m, which *did*
    pay attention to it; the other two were not needed at all.

    To generate messages for imports/uses shadowing other imports/uses,
    we need all three, so change the data structure storing such information
    for *direct* imports to one that records all three of the above kinds
    of information. (For imports made by read-in interface and optimization
    files, the old set of modules approach is fine, and this diff leaves
    the set of thus *indirectly* imported module names alone.)

compiler/unused_imports.m:
    Use the extra information now available to generate a
    severity_informational message about any import or use that is made
    redundant by an earlier, more general import or use.

    Fix two bugs in the code that generated warnings for just plain unused
    modules.

    (1) It did not consider that a use of the builtin type char justified
    an import of char.m, but without that import, the type is not visible.

    (2) It scanned cons_ids in goals in procedure bodies, but did not scan
    cons_ids that have been put into the const_struct_db. (I did not update
    the code here when I added the const_struct_db.)

    Also, add a (hopefully temporary) workaround for a bug in
    make_hlds_passes.m, which is noted below.

    However, there are at least three problems that prevent us from enabling
    --warn-unused-imports by default.

    (1) In some places, the import of a module is used only by clauses for
    a predicate that also has foreign procs. When compiled in a grade that
    selects one of those foreign_procs as the implementation of the predicate,
    the clauses are discarded *without* being added to the HLDS at all.
    This leads unused_imports.m to generate an uncalled-for warning in such
    cases. To fix this, we would need to preserve the Mercury clauses for
    *all* predicates, even those with foreign procs, and do all the semantic
    checks on them before throwing them away. (I tried to do this once, and
    failed, but the task should be easier after the item list change.)

    (2) We have two pieces of code to generate import warnings. The one in
    unused_imports.m operates on the HLDS after type and mode checking,
    while module_qual.m operates on the parse tree before the creation of
    the HLDS. The former is more powerful, since it knows e.g. what types and
    modes are used in the bodies of predicates, and hence can generate warnings
    about an import being unused *anywhere* in a module, as opposed to just
    unused in its interface.

    If --warn-unused-imports is enabled, we will get two separate set of
    reports about an interface import being unused in the interface,
    *unless* we get a type or mode error, in which case unused_imports.m
    won't be invoked. But in case we do get such errors, we don't want to
    throw away the warnings from module_qual.m. We could store them and
    throw them away only after we know we won't need them, or just get
    the two modules to generate identical error_specs for each warning,
    so that the sort_and_remove_dups of the error specs will do the
    throwing away for us for free, if we get that far.

    (3) The valid/bug100.m test case was added as a regression test for a bug
    that was fixed in module_qual.m. However the bug is still present in
    unused_imports.m.

compiler/make_hlds_passes.m:
    Give hlds_module.m the extra information it now needs for each item_avail.

    Add an XXX for a bug that cannot be fixed right now: the setting of
    the status of abstract instances to abstract_imported. (The "abstract"
    part is correct; the "imported" part may not be.)

compiler/intermod.m:
compiler/try_expand.m:
compiler/xml_documentation.m:
    Conform to the change in hlds_module.m.

compiler/module_qual.m:
    Update the documentation of the relationship of this module
    with unused_imports.m.

compiler/hlds_data.m:
    Document a problem with the status of instance definitions.

compiler/hlds_out_module.m:
    Update the code that prints out the module_info to conform to the change
    to hlds_module.m.

    Print status information about instances, which was needed to diagnose
    one of the bugs in unused_imports.m. Format the output for instances
    nicer.

compiler/prog_item.m:
    Add a convenience predicate.

compiler/prog_data.m:
    Remove a type synonym that makes things harder to understand, not easier.

compiler/modules.m:
    Delete an XXX that asks for the feature this diff implements.
    Add another XXX about how that feature could be improved.

compiler/Mercury.options.m:
    Add some more modules to the list of modules on which the compiler
    should be invoked with --no-warn-unused-imports.

compiler/*.m:
library/*.m:
mdbcomp/*.m:
browser/*.m:
deep_profiler/*.m:
mfilterjavac/*.m:
    Delete unneeded imports. Many of these shadow other imports, and some
    are just plain unneeded, as shown by --warn-unused-imports. In a few
    modules, there were a *lot* of unneeded imports, but most had just
    one or two.

    In a few cases, removing an import from a module, because it *itself*
    does not need it, required adding that same import to those of its
    submodules which *do* need it.

    In a few cases, conform to other changes above.

tests/invalid/Mercury.options:
    Test the generation of messages about import shadowing on the existing
    import_in_parent.m test case (although it was also tested very thoroughly
    when giving me the information needed for the deletion of all the
    unneeded imports above).

tests/*/*.{m,*exp}:
    Delete unneeded imports, and update any expected error messages
    to expect the now-smaller line numbers.
2015-08-25 00:38:49 +10:00
Zoltan Somogyi
8ae2551a44 Standardize the contents of .mih files.
compiler/mlds_to_c.m:
    Take two steps to avoid unnecessary changes in .mih files when a Mercury
    module is changed.

    The first step is to sort the list of definitions whose declarations
    get printed in the .mih file. This ensures that changes to Mercury source
    files that reorder exported predicates but do not otherwise change them
    won't result in rebuilding all the .o files that depend on the changed
    module's .mih file.

    The second step is to include line numbers in .mih files only if a
    new options line_numbers_for_c_headers option is set, which by default
    it isn't.

    Delete some unused predicates.

compiler/options.m:
doc/user_guide.texi:
    Add the option line_numbers_for_c_headers, defaulting to `no'.

tests/invalid/Mercury.options:
    Turn line_numbers_for_c_headers back on for this test case, to allow us
    to keep the existing .err_exp* files.

compiler/export.m:
    Don't add #ifndef #define #endif guards around nothing.

compiler/prog_foreign.m:
    Add some utility predicates to be used in export.m,
2015-01-01 22:51:54 +11:00
Zoltan Somogyi
29eeb36628 Implement --no-max-error-line-width, as requested in Mantis #308.
compiler/options.m:
   Change the type of the max_error_line_width option from int to maybe_int.
   Change its documentation accordingly.

doc/user_guide.texi:
   Change the option's documentation here as well.

compiler/globals.m:
   Since this is the compiler's first maybe_int option, add a predicate
   to look up such options.

compiler/error_util.m:
   If the user specifies --no-max-error-line-width, do not try to pack the
   words of an error paragraph into lines; just return all the words on one
   line.

   Factor out some common code in the group_words predicate, and give that
   predicate a more accurate name.

tests/invalid/any_to_ground_in_ite_cond_nomax.{m,err_exp}:
   Add this copy of the existing any_to_ground_in_ite_cond test case.

tests/invalid/Mercury.options::
   Specify --no-max-error-line-width for the new test case.

tests/invalid/Mmakefile:
   Enable the new test.
2014-02-21 15:32:39 +11:00
Zoltan Somogyi
55733f46e6 Fix Mantis bug 238.
Estimated hours taken: 0.5
Branches: main

compiler/mercury_compile.m:
	Fix Mantis bug 238.

tests/invalid/bug238.{m,err_exp}:
	New test case for Mantis bug 238.

tests/invalid/Mmakefile:
tests/invalid/Mercury.options:
	Enable the new test case.
2011-12-01 04:59:33 +00:00
Peter Wang
11696d60e7 Add an option `--max-error-line-width <n>' to adjust the maximum line width for
Branches: main, 10.04

Add an option `--max-error-line-width <n>' to adjust the maximum line width for
error messages.

compiler/options.m:
doc/user_guide.texi:
NEWS:
        Add and document the option.

compiler/error_util.m:
        Make error message output predicates take globals arguments and get the
        maximum line width from that.

        Delete write_error_pieces_not_first_line and
        write_error_pieces_maybe_first_line which are obsolete and unused.

compiler/abstract_mode_constraints.m:
compiler/accumulator.m:
compiler/compile_target_code.m:
compiler/complexity.m:
compiler/fact_table.m:
compiler/mercury_compile.m:
compiler/mercury_compile_mlds_back_end.m:
compiler/module_cmds.m:
compiler/options_file.m:
compiler/ordering_mode_constraints.m:
compiler/pred_table.m:
compiler/prop_mode_constraints.m:
compiler/term_constr_errors.m:
compiler/term_errors.m:
        Conform to changes.

tests/invalid/Mercury.options:
tests/invalid/Mmakefile:
tests/invalid/max_error_line_width.err_exp:
tests/invalid/max_error_line_width.m:
        Add a test case.
2010-03-30 23:57:27 +00:00
Zoltan Somogyi
5eed614821 Specify --warn-non-contiguous-clauses for the types2 test, since
Estimated hours taken: 0.1
Branches: main

tests/invalid/Mercury.options:
	Specify --warn-non-contiguous-clauses for the types2 test, since
	it is not now switched on implicitly.
2009-08-19 11:21:00 +00:00
Peter Wang
527293047f Make the java (and il) grade not require intermodule optimisation.
Branches: main

Make the java (and il) grade not require intermodule optimisation.  It did so
because the compiler needs be able to expand out equivalence types, even if
the equivalence is defined in the implementation section of another module.

Simon had, later on, implemented a better solution, where the definitions of
abstract equivalence types are written to the _implementation_ sections of
interface files (plus supporting imports and definitions).

This change therefore just stops the java grades implying intermodule
optimisation, and fixes a couple of problems that surfaced.  I also made the
changes for the il grade (untested).

compiler/equiv_type_hlds.m:
        Expand out equivalence types in the cons_table part of the HLDS.

compiler/type_ctor_info.m:
        Create type_ctor_infos for equivalence types even on java (and il)
        as they will be referred to by generated code.

compiler/add_type.m:
        Add special predicates for equivalence types even on java (and il)
        as they will be referred to by RTTI structures.

compiler/hlds_code_util.m:
        Delete are_equivalence_types_expanded as it is no longer used.

compiler/handle_options.m:
compiler/options.m:
tests/invalid/Mercury.options:
tests/invalid/purity/Mmakefile:
        Delete the --automatic-intermodule-optimization developer option.

compiler/special_pred.m:
        Fix formatting.
2009-06-12 05:21:27 +00:00
Julien Fischer
607b78adc3 Fix bug #83. The compiler was incorrectly reporting ambiguous predicate
Estimated hours taken: 1
Branches: main

Fix bug #83.  The compiler was incorrectly reporting ambiguous predicate
or function names in `pragma foreign_export' declarations as not existing.

compiler/add_pragma.m:
	Report ambiguous predicate or function names in foreign_export
	pragmas properly.

tests/invalid/Mercury.options:
tests/invalid/Mmakefile:
tests/invalid/bug83.{m,err_exp}:
	Test for the above.
2009-04-05 16:48:35 +00:00
Julien Fischer
a7b19e13cb Improve the consistency check for type class instances.
Estimated hours taken: 1
Branches: main

Improve the consistency check for type class instances.  In particular,
inconsistent instances in parent and child modules will now be detected
without --intermodule-optimization being enabled.

compiler/check_typeclass.m:
	If --intermodule-optimization is not enabled then don't filter
	out imported abstract instances before doing the consistency check.
	(If --intermodule-optimization *is* enabled then we don't need
	the abstract instances because we will have the concrete ones for
	the .opt files.)

tests/invalid/Mmakefile:
tests/invalid/Mercury.options:
tests/invalid/ii_parent.m:
tests/invalid/ii_parent.ii_child.m:
tests/invalid/ii_parent.ii_child.err_exp:
	Test the above inconsistent instances in parent and child modules
	are detected when --intermodule-optimzation is not enabled.

tests/invalid/sub_c.m:
	Unrelated change: update the syntax for module qualifiers.
2009-04-05 12:16:48 +00:00
Peter Wang
6d7262d44b Fix the failure of invalid/unresolved_overloading on hosts that build with
Branches: main

Fix the failure of invalid/unresolved_overloading on hosts that build with
`--intermodule-optimisation' enabled.

tests/invalid/Mercury.options:
	Disable intermodule optimisation when running the
	unresolved_overloading test case.
2008-09-09 05:26:04 +00:00
Julien Fischer
368a359bb3 Add a new pragma that allows dependencies on optional features of the
Estimated hours taken: 8
Branches: main

Add a new pragma that allows dependencies on optional features of the
compilation models to be checked by the compiler.  The new pragma
has the form

	:- pragma require_feature_set(<list_of_features>).

where <list_of_features> is a list of optional compilation model features
whose presence is required by the module containing the pragma.

For example,

	:- pragma require_feature_set([trailing, double_prec_float, memo]).

asserts that the module requires trailing, double precision floats and
memoisation.  The compiler will emit an error message if these features
are not available in the current compilation grade.  This is particularly
helpful in cases like memoisation and parallel conjunction that are ignored
by default in grades that do not support them.

Fix a bug where we where not emitting a warning about memo and loopcheck
pragmas being ignored in grades that use --highlevel-data.

compiler/prog_item.m:
	Represent require_feature_set pragmas in the parse tree.

compiler/prog_data.m:
	Add a type that represents optional features of the compilation
	model whose presence is required.

compiler/prog_io_pragma.m:
	Parse the new pragma.

	Turn an if-then-else into a switch.

compiler/add_pragma.m:
	Process require_feature_set pragmas and emit error messages
	concerning required features that are not supported by the
	compilation grade.

compiler/globals.m:
	Add three predicates that check whether tabling, threads and
	parallel conjunctions are support by the current grade respectively.
	(Some of this code used to be in table_gen.m and dep_par_conj.m
	and has been moved here since it now called from more than one place).

	Fix a bug where we were not emitting a message about memo
	and loopcheck pragmas being ignored in grades where --highlevel-data
	was enabled.

compiler/make_hlds_passes.m:
compiler/mercury_to_mercury.m:
	Handle require_feature_set pragmas.

compiler/module_qual.m:
compiler/recompilation.version.m:
compiler/dep_par_conj.m:
compiler/table_gen.m:
	Conform to the above change.

doc/reference_manual.texi:
	Document the new pragma.

tests/invalid/Mmakefile:
tests/invalid/Mercury.options:
tests/invalid/conflicting_fs.{m,err_exp}
tests/invalid/test_feature_set.{m,err_exp}:
	Test the new pragma.
2007-12-05 05:07:45 +00:00
Julien Fischer
dc1e59e48b Fix a bug (#27) reported by Ralph. The compiler was aborting on
Estimated hours taken: 1
Branches: main

Fix a bug (#27) reported by Ralph.  The compiler was aborting on
instances that contained type variables that were not wrapped in functors.
The problem is that the name mangling scheme used to mangle the names of
method wrapper predicates cannot handle instances that contain unwrapped
type variables.  The compiler already has code to check for this, but that
check was not being performed until *after* it had attempted to introduce
the method wrapper predicates.

The fix is to reorder the phases of check_typeclass.m so that we perform
the check on the types in an instance first and only run the remaining
phases if the first one succeeds.

compiler/check_typeclass.m:
	Reorder the phases within this module so that we don't attempt
	to introduce method wrapper predicates for invalid instances.

	Update the documentation in this module to conform to the above
	change.

	Remove some unnecessary module qualification.

tests/invalid/Mercury.options:
tests/invalid/Mmakefile:
tests/invalid/instance_var_bug.{m,err_exp}:
	Test for the above bug.

tests/invalid/bad_instance.err_exp:
	Update this.  The error message for the missing concrete instance
	won't be emitted with the above change.  Note, we have a separate
	test case, tests/invalid/missing_concrete_instance, that exercises
	that error message.
2007-11-14 04:00:06 +00:00
Julien Fischer
bcec8a99e7 Remove support for the `initialisation is ...' attribute from solver types.
Estimated hours taken: 2
Branches: main

Remove support for the `initialisation is ...' attribute from solver types.
This attribute is now a syntax error, unless the developer-only option
`--solver-type-auto-init' is enabled -- in which case things will work
as before.

Update the test suite to conform to the above change.

compiler/globals.m:
	Add a mutable that stores whether or not we support automatic
	solver type initialisation.  The value of this mutable is used in
	the parser to decide if `initialisation is ...' attributes in solver
	type definitions are legal syntax or not.

compiler/prog_io.m:
	Only accept `initialisation is ...' attributes in solver type
	definitions as legal syntax if the value of the above mutable indicates
	that `--solver-type-auto-init' is enabled.

NEWS:
	Announce the removal of support for automatic initialisation.

tests/debugger/Mercury.options:
	Run the solver_test test with `--solver-type-auto-init' enabled.

tests/hard_coded/Mercury.options:
	Run tests that check if automatic initialisation is working
	with `--solver-type-auto-init' enabled.

	Delete a reference to a test case was deleted some time ago.


tests/warnings/Mercury.options:
tests/invalid/Mercury.options:
	Enable `--solver-type-auto-init' for some tests.

tests/invalid/any_mode.m:
tests/invalid/any_passed_as_ground.m:
tests/invalid/any_should_not_match_bound.m:
tests/invalid/any_ground_in_ite_cond.m:
tests/valid/solv.m:
tests/hard_coded/any_call_hoist_bug.m:
tests/hard_coded/any_free_unify.m:
tests/hard_coded/sub-modules/ts.m:
	Remove `initialisation is ...' attributes from the solver type
	definitions in these tests.
2007-11-14 03:45:14 +00:00
Julien Fischer
3ed0c61d74 Workaround a bug reported by Nick Nethercote where compiling with
Estimated hours taken: 1.5
Branches: main

Workaround a bug reported by Nick Nethercote where compiling with
`--errorcheck-only' enabled was triggering a sanity check in error_util.
This sanity check required that something was actually printed out if the spec's
severity required something to be printed.  This condition is violated by the
code in mode_errors.m, which generates error specs that have severity error,
but whose messages are all conditional.  (These specs. are used for
--debug-modes.) The sanity check will fail when the message conditions
are all false because then nothing will be printed.
The workaround is to omit the sanity check for the time being.

compiler/error_util.m:
	Comment out the above sanity check and add an XXX comment
	explaining why it is commented out.

	Document the effects of this change on how write_error_spec(s)/6
	set the exit status.

	Change an if-then-else into a switch.

tests/invalid/Mmakefile:
tests/invalid/Mercury.options:
tests/invalid/zinc2mer_lib.{m,err_exp}:
	A regression test for the above bug, derived from Nick's
	original example.
2007-10-25 05:05:14 +00:00
Julien Fischer
1fac629e6d Add support for foreign enumerations to Mercury.
Estimated hours taken: 50
Branches: main

Add support for foreign enumerations to Mercury.  These allow the
programmer to assign foreign language values as the representation of
enumeration constructors.

e.g.
	:- type status
		--->	optimal
		;	infeasible
		;	unbounded
		;	unknown.

	:- pragma foreign_enum("C", status/0, [
		optimal    - "STATUS_OPTIMAL",
		infeasible - "STATUS_INFEASIBLE",
		unbounded  - "STATUS_UNBOUNDED",
		unknown    - "STATUS_UNKNOWN"
	]).

The advantage of this is that when values of type status/0 are passed to
foreign code (C in this case) no translation is necessary.  This should
simplify the task of writing bindings to foreign language libraries.

Unification and comparison for foreign enumerations are the usual
unification and comparison for enumeration types, except that the default
ordering on them is determined by the foreign representation of the
constructors.  User-defined equality and comparison also work for foreign
enumeration types.

In order to implement foreign enumerations we have to introduce two
new type_ctor representations.  The existing ones for enum type do not
work since they use the value of an enumeration constructor to perform
table lookups in the RTTI data structures.  For foreign enumerations
we need to perform a linear search at the corresponding points.  This
means that some RTTI operations related to deconstruction are more
expensive.

The dummy type optimisation is not applied to foreign enumerations as
the code generators currently initialise the arguments of non-builtin
dummy type foreign_proc arguments to zero.  For unit foreign enumerations
they should be initialised to the correct foreign value.  (This is could be
implemented but in practice it's probably not going to be worth it.)

Currently, foreign enumerations are only supported by the C backends.

compiler/prog_io_pragma.m:
	Parse foreign_enum pragmas.

	Generalise the code used to parse association lists of sym_names
	and strings since this is now used by the code to parse foreign_enum
	pragmas as well as that for foreign_export_enum pragmas.

	Fix a typo: s/foreign_expor_enum/foreign_export_enum/

compiler/prog_item.m:
	Represent foreign_enum pragmas in the parse tree.

compiler/prog_type.m:
	Add a new type category for foreign enumerations.

compiler/modules.m:
	Add any foreign_enum pragmas for enumeration types defined in the
	interface of a module to the interface files.

	Output foreign_import_module pragmas in the interface file
	if any foreign_enum pragmas are included in it.  This ensures that
	the contents that any foreign declarations that are needed by the
	foreign_enum pragmas are visible.

compiler/make_hlds_passes.m:
compiler/add_pragma.m:
	Add pragma foreign_enum items to the HLDS after all the types
	have been added.  As they are added, error check them.

	Change the constructor tag values of foreign enum types to their
	foreign values.

compiler/module_qual.m:
	Module qualify pragma foreign_enum items.

compiler/mercury_to_mercury.m:
	Output foreign_enum pragmas.

	Generalise some of the existing code for writing out association
	lists in foreign_export_enum pragmas for use with foreign_enum
	pragmas as well.

compiler/hlds_data.m:
	Add the alternative `is_foreign_type' to the type enum_or_dummy/0.

	Add new type of cons_tag, foreign_tag, whose values are directly
	embedded in the target language.

compiler/intermod.m:
	Write out any foreign_enum pragmas for opt_exported types.
	(The XXX concerning attaching language information to foreign tags
	will be addressed in a subsequent change.)

compiler/llds.m:
compiler/mlds.m:
	Support new kinds of rval constants: llconst_foreign and
	mlconst_foreign respectively.  Both of these represent tag values
	as strings that are intended to be directly embedded in the target
	language.

compiler/llds_out.m:
	Add code to write out the new kind of rval_const.

	s/Integer/MR_Integer/ in a spot.
	s/Float/MR_Float/ in a spot.

compiler/rtti.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
compiler/type_ctor_info.m:
	Add support the RTTI required by foreign enums.

compiler/switch_util.m:
	Handle switches on foreign_enums as-per normal enumerations.

compiler/table_gen.m:
	Tabling of foreign_enums is also like normal enumerations.

compiler/type_util.m:
	Add a predicate that tests whether a type is a foreign enumeration.

compiler/unify_gen.m:
compiler/unify_proc.m:
compiler/ml_unify_gen.m:
	Handle unification and comparison of foreign enumeration values.
	They are treated like normal enumerations for the purposes of
	implementing these operations.

compiler/ml_type_gen.m:
	Handle foreign enumerations when generating the MLDS representation
	of enumerations.

compiler/ml_util.m:
	Add a function to create an initializer for an object with a
	foreign tag.

compiler/mlds_to_c.m:
	Handle mlconst_foreign/1 rval constants.

compiler/bytecode_gen.m:
compiler/dupproc.m:
compiler/erl_rtti.m:
compiler/exception_analysis.m:
compiler/export.m:
compiler/exprn_aux.m:
compiler/global_data.m:
compiler/hlds_out.m:
compiler/higher_order.m:
compiler/inst_match.m:
compiler/jumpopt.m:
compiler/llds_to_x86_64.m:
compiler/ml_code_util.m:
compiler/mlds_to_gcc.m:
compiler/mlds_to_il.m:
compiler/mlds_to_java.m:
compiler/mlds_to_managed.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/polymorphism.m:
compiler/recompilation.version.m:
compiler/term_norm.m:
compiler/trailing_analysis.m:
	Conform to the above changes.

doc/reference_manual.texi:
	Document the new pragma.

	Fix some typos: s/pramga/pragma/, s/behavior/behaviour/

library/construct.m:
	Handle the two new type_ctor reps.

	Break an over-long line.

library/rtti_implementation.m:
	Support the two new type_ctor reps.
	(XXX The Java versions of some of this cannot be implemented until
	support for foreign enumerations is added to mlds_to_java.m.)

	Reformat the inst usereq/0 and extend it to include foreign enums.

runtime/mercury_type_info.h:
	Add two new type_ctor reps.  One for foreign enumerations and
	another for foreign enumerations with user equality.

	Define new types (and extend existing ones) in order to support
	RTTI for foreign enumerations.

runtime/mercury_unify_compare_body.h:
	Implement generic unify and compare for foreign enumerations.
	(It is the same as that for regular enumerations.)

runtime/mercury_construct.[ch]:
runtime/mercury_deconstruct.h:
	Handle (de)construction of foreign enumeration values.

runtime/mercury_deep_copy_body.h:
	Implement deep copy for foreign enumerations.

runtime/mercury_table_type_body.h:
runtime/mercury_term_size.c:
	Handle the new type_ctor representations.

java/runtime/ForeignEnumFunctorDesc.java:
	Add a Java version of the MR_ForeignEnumFuntorDesc structure.
	(Note: this is untested, as the java grade runtime doesn't work
	anyway.)

java/runtime/TypeFunctors.java:
	Add a constructor method for foreign enumerations.
	(Likewise, untested.)

NEWS:
	Announce pragma foreign_enum.

vim/syntax/mercury.vim:
	Highlight the new pragma appropriately.

tests/hard_coded/.cvsignore:
	Ignore executables generated by the new tests.

	Ignore a bunch of other files create by the Mercury compiler.

tests/hard_coded/Mmakefile:
tests/hard_coded/foreign_enum_rtti.{m,exp}:
	Test RTTI for foreign enumerations.

tests/hard_coded/foreign_enum_dummy.{m,exp}:
	Check that dummy type optimisation is disabled for foreign
	enumerations.

tests/hard_coded/Mercury.options:
tests/hard_coded/foreign_enum_mod1.{m,exp}:
tests/hard_coded/foreign_enum_mod2.m:
	Test that foreign_enum pragmas are hoisted into interface files
	and that they are handled correctly in optimization interfaces.

tests/invalid/Mercury.options:
tests/invalid/Mmakefile:
tests/invalid/foreign_enum_import.{m,err_exp}:
tests/invalid/foreign_enum_invalid.{m,err_exp}:
	Test that errors in foreign_enum pragmas are reported.

tests/tabling/Mmakefile:
tests/hard_coded/table_foreign_enum.{m,exp}:
	Test case for tabling of foreign enumerations.
2007-08-20 03:39:31 +00:00
Julien Fischer
75a8a4a9b3 Add a new pragma, foreign_export_enum, that allows the names of constructors
Estimated hours taken: 30
Branches: main

Add a new pragma, foreign_export_enum, that allows the names of constructors
of Mercury enumeration types to be exported across the foreign language
interface and referred to by code in the foreign language.

The new pragma is intended to be used to avoid a situation that frequently
occurs when creating Mercury bindings to foreign language libraries, namely
arguments and return values being passed across the foreign language boundary
as small integers.  Exporting the names of enumeration values to foreign
languages should make this task less error prone and more portable.

Using the new construct programmers can either specify a foreign language name
for each enumeration constructor, or since this is tedious, there is also a
default mapping defined for each foreign language that should work in most
cases for that language.  (In the cases where it does not work the compiler
requires the programmer to provide a valid name.)

Currently, pragma foreign_export_enum is only supported by the C backends.

compiler/prog_data.m:
compiler/prog_item.m:
	Add a new item to the parse tree for representing
	foreign_export_enum pragmas.

compiler/prog_io_pragma.m:
	Parse the new pragma.

compiler/module_qual.m:
	Handle foreign_export_enum pragmas.

	Add a predicate to for module qualifying type_ctors, i.e. a
	type identified by its sym_name and arity, for use by the
	above.

compiler/mercury_to_mercury.m:
	Write out foreign_export_enum pragmas.

compiler/hlds_module.m:
	Add a type to represent exported enumerations.

	Add a field to the module_info to hold information about
	exported enumerations.  Add access procedures for this.

compiler/make_hlds_passes.m:
compiler/add_pragma.m:
	Handle foreign_export_enum pragmas: generate the set of foreign names
	for each of the constructors of an enumeration type and check that
	their validity in the foreign language.  Attach this information to
	the HLDS.

compiler/export.m:
	Output #defined constants for C foreign_export_enum pragmas in
	.mh files.

compiler/mlds.m:
	Add an MLDS specific representation of exported enumerations.

compiler/ml_type_gen.m:
	Convert the HLDS representation of exported enumerations into
	an MLDS specific one.

compiler/mlds_to_c.m:
	Output #defined constants for C foreign_export_enum pragmas in
	.mih files.

compiler/ml_code_gen.m:
compiler/ml_elim_nested.m:
compiler/ml_tailcall.m:
compiler/mlds_to_gcc.m:
compiler/mlds_to_il.m:
compiler/mlds_to_ilasm.m:
compiler/mlds_to_java.m:
compiler/mlds_to_managed.m:
	Conform to the above changes to the MLDS.

compiler/mercury_compile.m:
	Pass the list of export enumerations to the code that writes
	out .mh files.

compiler/c_util.m:
	Add a predicate that tests if a string is a valid C identifier.

compiler/modules.m:
compiler/recompilation.version.m:
	Conform to the above changes.

doc/reference_manual.texi:
	Document the new pragma.

tests/hard_coded/Mmakefile:
tests/hard_coded/ee_dummy.{m,exp}:
tests/hard_coded/ee_valid.{m,exp}:
	Test valid uses of foreign_export_enum pragmas.

tests/invalid/Mmakefile:
tests/invalid/Mercury.options:
tests/invalid/ee_invalid.{m,err_exp}:
	Check we generate error messages for invalid
	foreign_export_enum pragmas.

NEWS:
	Announce the new pragma.

vim/syntax/mercury.vim:
	Highlight the new syntax.
2007-07-25 06:12:32 +00:00
Julien Fischer
e2bdc66a56 Fix the failure of invalid/actual_expected on hosts that build with
Estimated hours taken: 0
Branches: main

Fix the failure of invalid/actual_expected on hosts that build with
`--intermodule-optimisation' enabled.

tests/invalid/Mercury.options:
	Disable intermodule optimisation when running the actual_expected
	test case.
2007-05-25 06:45:53 +00:00
Simon Taylor
cd6e1db934 Update for changed error messages.
Estimated hours taken: 0.2
Branches: main

Update for changed error messages.

tests/invalid/types.err_exp:
	We now correctly stop after finding errors in make_hlds,

tests/invalid/types.err_exp2:
	This file hasn't been updated for a while and doesn't seem
	to be needed, so remove its contents.

tests/invalid/Mmakefile:
tests/invalid/Mercury.options:
tests/invalid/types2.{m,err_exp}:
	New file containing the errors from types.m which occur
	after make_hlds.
2007-05-17 06:15:34 +00:00
Simon Taylor
aa671f1974 Fix failure of tests/valid/foreign_type_spec.
Estimated hours taken: 3
Branches: main

Fix failure of tests/valid/foreign_type_spec.

compiler/add_type.m:
        Fix a place where error codes were being `and'ed together
        rather than `or'ed, resulting in missing foreign type
        declarations not being reported and compiler aborts later.

        Remove code to only test GRADEFLAGS when generating code.
        GRADEFLAGS is passed for all compilation targets now.

library/bitmap.m:
        Uncomment the IL definition of the bitmap type to allow
        the interface files to be used by tests in grade `il'.

tests/invalid/Mmakefile:
tests/invalid/Mercury.options:
tests/invalid/foreign_type_missing.{m,err_exp}:
        Test case for missing foreign type declarations for
        the current back-end.

tests/valid/Mercury.options:
        Fix a typo which caused different parts of the foreign_type_spec
        test case to be compiled in different grades.

tests/EXPECT_FAIL_TESTS.all_grades:
        Remove foreign_type_spec.
2007-05-02 06:16:40 +00:00
Simon Taylor
eb80b329bb Check MLLIBS contains only `-l' options.
Estimated hours taken: 3
Branches: main

compiler/options_file.m:
        Check MLLIBS contains only `-l' options.

tests/invalid/Mmakefile:
tests/invalid/invalid_mllibs.{m,err_exp}:
tests/invalid/Mercury.options:
tests/invalid/Mercury.options.invalid:
        Test case.
2006-12-15 03:58:44 +00:00
Zoltan Somogyi
544aae2355 Implement synthesized attributes at user events.
Estimated hours taken: 32
Branches: main

Implement synthesized attributes at user events.

doc/user_guide.texi:
	Document synthesized attributes.

runtime/mercury_stack_layout.h:
	Include information about synthesized attributes in layout structures.

	Move the the information about user events that is not specific to a
	given event occurrence to a central table of user event specifications
	in the module layout structure, to reduce the space overhead, and allow
	a future Ducasse style execution monitor to look up information about
	each event without having to search all label layout structures (e.g.
	when compiling a set of user commands about what to do at each event
	into a state machine).

	Update the current layout structure version number.

	Introduce a named type to represent HLDS variable numbers in layout
	structures.

runtime/mercury_types.h:
	Add typedefs for the new types in mercury_stack_layout.h.

compiler/prog_data.m:
compiler/prog_event.m:
	Record the call that synthesizes synthesized attributes in terms of
	attribute numbers (needed by the layout structures) as well as in terms
	of attribute names (the user-friendly notation). Record some other
	information now needed by the layout structures, e.g. the evaluation
	order of synthesized attributes. (Previously, we computed this order
	-in reverse- but then threw it away.)

	Do not separate out non-synthesized attributes, now that we can handle
	even synthesized ones. Return *all* attributes to call_gen.m.

	Pass the filename of the event set specification file to the event
	spec parser, for use in error messages.

	Generate better error messages for semantic errors in event set
	specifications.

compiler/continuation_info.m:
compiler/layout.m:
compiler/layout_out.m:
compiler/stack_layout.m:
	Generate the new layout structures, the main changes being the
	inclusion of synthesized attributes, and generating information about
	event attribute names, types and maybe synthesis calls for all possible
	events at once (for the module layout) instead of separately at each
	user event occurrence.

	In stack_layout.m, rename a couple of predicates to avoid ambiguities.

	In layout_out.m, eliminate some repetitions of terms.

compiler/call_gen.m:
	When processing event calls, match the supplied attributes against the
	list of all attributes, and include information about the synthesized
	attributes in the generated layout structures.

compiler/equiv_type.m:
compiler/module_qual.m:
	Conform to the change in prog_data.m.

compiler/opt_debug.m:
	Conform to the change in layout.m.

compiler/hlds_out.m:
	Generate valid Mercury for event calls.

trace/mercury_event_spec.[ch]:
	Record the name of the file being parsed, for use in syntax error
	messages when the parser is invoked by the compiler.

	Add a field for recording the line numbers of attributes, for use in
	better error messages.

trace/mercury_event_parser.y:
trace/mercury_event_scanner.l:
	Record the line numbers of attributes.

	Modify the grammar for event set specifications to allow C-style
	comments.

trace/mercury_trace_internal.c
	Pass a dummy filename to mercury_event_spec. (The event set
	specifications recorded in layout structures should be free of errors,
	since the compiler generates them and it checked the original version
	for errors.)

trace/mercury_trace_tables.[ch]:
	Conform to the new design of layout structures, and record the extra
	information now available.

trace/mercury_trace_vars.[ch]:
	Record the values of attributes in two passes: first the
	non-synthesized attributes, then the synthesized attributes
	in the evaluation order recorded in the user event specification.

tests/debugger/synth_attr.{m,inp,exp}:
tests/debugger/synth_attr_spec:
	New test case to test the debugger's handling of synthesized
	attributes.

tests/debugger/Mmakefile:
tests/debugger/Mercury.options:
	Enable the new test case.

tests/invalid/syntax_error_event.{m,err_exp}:
tests/invalid/syntax_error_event_spec:
	New test case to test the handling of syntax errors in event set
	specifications.

tests/invalid/synth_attr_error.{m,err_exp}:
tests/invalid/synth_attr_error_spec:
	New test case to test the handling of semantic errors in event set
	specifications.

tests/invalid/Mmakefile:
	Enable the new test cases.
2006-12-14 04:36:04 +00:00
Zoltan Somogyi
45fd0daf5a Implement some of Mark's wish list for making user events more useful.
Estimated hours taken: 20
Branches: main

Implement some of Mark's wish list for making user events more useful.

1. When executing "print *" in mdb, we used to print both the values of all
   attributes and the values of all live variables. Since some attributes'
   values were given directly by live variables, this lead to some things being
   printed twice. This diff eliminates this duplication.

2. At user events, we now print the name of the event. Whether we print the
   other stuff we also print at events (the predicate containing the event,
   and its source location) is now controlled by a new mdb command,
   "user_event_context".

3. We would like different solvers to be compilable independently of one
   another. This means that neither solver's event set should depend on the
   existence of the events needed by the other solvers. This diff therefore
   eliminates the requirement that all modules of the program be compiled with
   the same event set specification. Instead, a program may contain modules
   that were compiled with different event sets. Each event set is named;
   the new requirement is that different named event sets may coexist in the
   program (each being used to compile some modules), but two event sets with
   the same name must be identical in all other respects as well (we need this
   requirement to prevent inconsistencies arising between different versions of
   the same event set).

4. We now generate user events even from modules compiled with --trace shallow.
   The problem here is that user events can occur in procedures that do not
   get caller events and whose ancestors may not get caller events either.
   Yet these procedures must still pass on debugger information such as call
   sequence numbers and the call depth to the predicate with the user event.
   This diff therefore decouples the generation of code for this basic debugger
   infrastructure information from the generation of call events by inventing
   two new trace levels, settable by the compiler only (i.e. not from the
   command line). The trace level "basic_user" is for procedures containing a
   user event whose trace level (in a shallow traced module) would otherwise be
   "none". The trace level "basic" is for procedures not containing a user
   event but which nevertheless may need to transmit information (e.g. depth)
   to a user event. For the foreseeable future, this means that shallow traced
   modules containing user events will have some debugging overhead compiled
   into *all* their procedures.

runtime/mercury_stack_layout.h:
	Add a new field to MR_UserEvent structures, giving the HLDS number of
	the variable representing each attribute.

	Add a new field to module layout structures, giving the name of the
	event set (if any) the module was compiled with.

	Add the new trace levels to the MR_TraceLevel type.

	Update the current layout structure version number.

runtime/mercury_stack_trace.[ch]:
	Allow the printing of the containing predicate's name and/or the
	filename/linenumber context to be turned off when printing contexts.
	Factor out some of the code involved in this printing.

	Give a bunch of variables better names.

	Rename a type to get rid of unnecessary underscores.

compiler/prog_data.m:
compiler/prog_event.m:
	Include the event set name in the information we have about the event
	set.

compiler/simplify.m:
	Mark each procedure and each module that contains user events
	as containing user events.

	Use the same technique to mark each procedure that contains parallel
	conjunctions as containing parallel conjunctions, instead of marking
	the predicate containing the procedure. (Switch detection may eliminate
	arbitrary goals, including parallel conjunctions, from switch arms
	that are unreachable due to initial insts, and in any case we want to
	handle the procedures of a predicate independently from each other
	after mode analysis.)

	Also, change the code handling generic calls to switch on the generic
	call kind, and factor out some common code.

compiler/hlds_module.m:
compiler/hlds_pred.m:
	Provide slots in the proc_info and the module_info for the information
	gathered by simplify.

compiler/trace_params.m:
	Implement the new trace levels described above. This required changing
	the signature of some of the predicates of this module.

compiler/code_info.m:
	Record whether the compiler generated any trace events. We need to know
	this, because if it did, then we must generate a proc layout structure
	for it.

compiler/proc_gen.m:
	Act on the information recorded by code_info.m.

	Factor out the code for generating the call event and its layout
	structure, since the conditions for generating this event have changed.

compiler/continuation_info.m:
compiler/call_gen.m:
	For each user event, record the id of the variables corresponding to
	each argument of a user event.

compiler/layout.m:
compiler/layout_out.m:
compiler/stack_layout.m:
	Generate the new field (giving the HLDS variable number of each
	attribute) in user event structures, and the new field (event set name)
	in module layout structures.

	Allow the call event's layout structure to be missing. This is needed
	for user events in shallow traced modules.

compiler/options.m:
compiler/handle_options.m:
compiler/mercury_compiler.m:
	Rename the option for specifying event sets from --event-spec-file-name
	to --event-set-file-name, since it specifies only one event set, not
	all events.

compiler/jumpopt.m:
	Give some predicates better names.

compiler/dep_par_conj.m:
compiler/deforest.m:
compiler/granularity.m:
compiler/hlds_out.m:
compiler/inlining.m:
compiler/intermod.m:
compiler/lambda.m:
compiler/liveness.m:
compiler/modes.m:
compiler/opt_debug.m:
compiler/optimize.m:
compiler/size_proc.m:
compiler/stack_alloc.m:
compiler/store_alloc.m:
compiler/table_gen.m:
compiler/trace_gen.m:
compiler/typecheck.m:
	Conform to the changes above.

doc/mdb_categories:
	Mention the new mdb command.

doc/user_guide.texi:
	Update the documentation of user events to account for the changes
	above.

trace/mercury_event_parser.y:
trace/mercury_event_scanner.l:
	Modify the grammar for event set specifications to a name for the
	event set.

trace/mercury_event_spec.[ch]:
	Instead of recording information about event sets internally
	in this module, return a representation of each event set read in
	to the callers, for them to do with as they please.

	Include the event set name when we print the Mercury term for
	compiler/prog_event.m.

trace/mercury_trace.c:
	Do not assume that every procedure that contains an event contains a
	call event (and hence a call event layout structure), since that
	is not true anymore.

trace/mercury_trace_cmd_parameter.[ch]:
	Implement the new mdb command "user_event_context".

trace/mercury_trace_cmd_internal.[ch]:
	Include "user_event_context" in the list of mdb commands.

	Print the user event name at user events. Let the current setting
	of the user_event_context mdb command determine what else to print
	at such events.

	Instead of reading in one event set on initialization, read in
	all event sets that occur in the program.

trace/mercury_trace_tables.[ch]:
	Allow the gathering of information for more than one event set
	from the modules of the program.

trace/mercury_trace_vars.[ch]:
	For each attribute value of a user event, record what the HLDS variable
	number of the attribute is. When printing all variables at an event,
	mark the variable numbers of printed attributes as being printed
	already, causing the variable with the same number not to be printed.

	Include the name of the variable (if it has one) in the description
	of an attribute. Without this, users may wonder why the value of the
	variable wasn't printed.

trace/mercury_trace_cmd_browsing.[ch]:
	Pass the current setting of the user_event_context mdb command to
	runtime/mercury_stack_trace.c when printing the context of an event.

tests/debugger/user_event_shallow.{m,inp,exp}:
	New test case to test the new functionality. This test case is the same
	as the user_event test case, but it is compiled with shallow tracing,
	and its mdb input exercises the user_event_context mdb command.

tests/debugger/user_event_spec:
tests/invalid/invalid_event_spec:
	Update these event set spec files by adding an event set name.

tests/debugger/Mmakefile:
tests/debugger/Mercury.options:
	Enable the new test case.

tests/debugger/user_event.exp:
	Update the expected output of the old user event test case, which now
	prints event names, but doesn't print attribute values twice.

tests/debugger/completion.exp:
	Expect the new "user_event_context" mdb command in the command list.

tests/debugger/mdb_command_test.inp:
	Test the existence of the documentation for the new mdb command.

tests/invalid/Mercury.options:
	Conform to the name change of the --event-spec-file-name option.
2006-12-05 03:51:22 +00:00