Commit Graph

66 Commits

Author SHA1 Message Date
Zoltan Somogyi
e174c778ba Define initializer funcs in source code order.
The language manual guarantees this order, and we do *invoke* initializer
functions in this order, but we used to *define* them in reverse order
if they came from mutable declarations. This diff fixes that.

compiler/make_hlds_passes.m:
    The code for gathering the foreign_proc_exports (FPEs) used to implement
    mutables returned them as a list in source order. However, the code
    in make_hlds_passes.m itself treated that list as it were in reverse order
    (probably as a relic of a time when it *was* in reverse order), adding
    new entries to at the front to implement any non-mutable initialize (and
    finalise) declarations, and finally "unreversing" it. This "unreversing"
    of course *reversed* the originally in-order part. (The order of their
    *invocation* is controlled by a different mechanism.)

    Fix this by *consistently* using cords, instead of reversed lists,
    for everything in this module that needs appending at the logical "end".
    Do this even for kinds of items that were not involved in this bug.

compiler/add_mutable_aux_preds.m:
    Return the list foreign_proc_exports created as a cord, to allow later
    operations to append to its end.

compiler/add_pragma.m:
    Return the list of tabled pragmas whose addition to the HLDS is deferred
    until a slightly later pass as a cord.
2023-05-21 14:13:45 +10:00
Zoltan Somogyi
307b1dc148 Split up error_util.m into five modules.
compiler/error_spec.m:
    This new module contains the part of the old error_util.m that defines
    the error_spec type, and some functions that can help construct pieces
    of error_specs. Most modules of the compiler that deal with errors
    will need to import only this part of the old error_util.m.

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

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

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

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

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

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

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

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

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

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

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

compiler/*.m:
    Conform to the changes above, mostly by updating import_module
    declarations, and renaming format_component to format_piece.
2022-10-12 20:50:16 +11:00
Zoltan Somogyi
92438b2ec6 Make make_hlds.m a package.
compiler/make_hlds.m:
    This module used to both

    - include several submodules, and
    - define several types and predicates.

    For some years now, we have preferred to do these two kinds of things
    in separate modules, with package modules containing *only* include_module
    declarations, and other modules containing *no* include_module
    declarations. The reason is that submodules of a package automatically
    get the imports of their parent, which creates unwanted coupling
    between the submodule and its parent. This problem vanishes if
    the parent module contains no imports, but the only practical way
    to sustain that over time is for the parent to define nothing.

    This diff therefore moves the definitions of types and predicates
    out of make_hlds.m. It moves the types to a new submodule,
    make_hlds_types.m. Since the predicates it defined were only
    forwarding predicates, they can be deleted without replacement,
    provided that the predicates they forwarded to are in *public*
    submodules of make_hlds.m. This diff therefore arranges that.
    It does the same with a forwarding type.

compiler/make_hlds_types.m:
    A new submodule of make_hlds.m that contains the type definitions
    that used to be in make_hlds.m itself.

compiler/instance_method_clauses.m:
    A new submodule of make_hlds.m that contains the parts of add_class.m
    that generate the clauses that define predicates that implement
    instance methods. This part of add_class.m was completely separate
    from the rest of add_class.m (it wasn't even invoked from there),
    so putting it in its own module eliminates unnecessary coupling.

compiler/notes/compiler_design.html:
    Document the new modules.

compiler/add_class.m:
    Delete the code that has been moved to instance_method_clauses.m.

compiler/add_clause.m:
compiler/add_foreign_proc.m:
compiler/add_mode.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pragma.m:
compiler/add_pred.m:
compiler/add_solver.m:
compiler/add_type.m:
compiler/check_typeclass.m:
compiler/goal_expr_to_goal.m:
compiler/make_hlds_passes.m:
compiler/make_hlds_warn.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_main.m:
compiler/qual_info.m:
compiler/state_var.m:
compiler/superhomogeneous.m:
    Conform to the changes above, mostly by adding explicit import_module
    declarations to replace a subset of the import_module declarations
    that these modules used to implicitly inherit from their parent.
2022-03-31 16:54:33 +11:00
Zoltan Somogyi
c1f0913996 Simplify the logic of prog_mutable.m.
compiler/prog_mutable.m:
    The old logic was complicated by the need to have some decisions
    made by prog_mutable.m and some by add_mutable_aux_preds.m,
    which had different tasks (generating public declarations
    vs generating both public and private definitions), and thus
    used different approaches.

    Replace this with code in which for each kind of auxiliary predicate,
    the code to generate its declaration is just before the code
    to generate its definition. And the code that decides what public
    declarations to generate is just before the code that decides
    what public and private definitions to generate.

    Make this latter logic operate as directly as possible on the mutable's
    attributes, instead of first calling a separate predicate to compute
    the set of auxiliary predicates the mutable needs, recording the results
    in the mutable_target_params structure, and then generating definitions
    as directed by this structure.

    To make this possible, split some existing predicates that used
    to do two related but nevertheless separate jobs, such as defining
    get and set predicates for both constant and nonconstant mutables.

    Give a bunch of predicates names that better reflect whether they
    generate declarations only, definitions only, or both.

    Consistently refer to the name of the mutable as MutableName,
    since the code handles the names of other kinds of things as well.

    Give some predicates slightly shorter names, so calls to them
    fit on just one line.

compiler/prog_item.m:
    Change the arg type of a function based on the updated needs of
    prog_mutable.m.

compiler/add_mutable_aux_preds.m:
compiler/comp_unit_interface.m:
    Conform to the changes above.
2021-05-29 20:40:18 +10:00
Zoltan Somogyi
e10bc34a74 Implement mutables only in prog_mutable.m.
compiler/prog_mutable.m:
    Move code implementing mutables here, mostly from add_mutable_aux_preds.m,
    but some from comp_unit_interface.m. Export only what those two modules
    need.

    Replace the

compiler/add_mutable_aux_preds.m:
compiler/comp_unit_interface.m:
    Delete the code moved to prog_mutable. In add_mutable_aux_preds.m,
    make minor rearrangements to make this possible.

compiler/hlds_module.m:
compiler/prog_foreign.m:
    Move the pred_target_names type, and two predicates that operate
    on it, from hlds_module.m to prog_foreign.m, to make it accessible
    from prog_mutable.m, which is part of the parse_tree package, and thus
    should not import anything from the hlds package.

compiler/prog_item.m:
    Move a (renamed) type here from add_mutable_aux_preds.m, since
    prog_mutable.m now needs access to it as well.

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

compiler/prog_data.m:
    Fix some old comments.
2021-05-27 22:06:33 +10:00
Zoltan Somogyi
28de3b7ff2 Move a big block comment to notes/mutables. 2021-05-25 23:21:57 +10:00
Zoltan Somogyi
854d63d1ce Make illegal mutable attributes unrepresentable.
compiler/prog_item.m:
    Change the representation of mutable_var_attributes,
    in two different ways.

    The first is replacing a list of elements that each say
    "in this language, use this name", which allowed duplicate entries
    for a language, with a map from languages to names, which does not.

    The second is replacing of a set of four boolean-equivalent flags,
    many of whose 16 possible combinations are invalid, with
    a structured type that allows the representation of only
    the valid combinations.

    To allow code working on attributes to exploit this defense against
    illegal attribute sets, export the new representation. (Fully taking
    advantage of this will require moving the code that creates the
    declarations and definitions of each aux predicate next to each other.)

compiler/parse_mutable.m:
    Previously, the code that parsed mutable declarations checked for
    *some* invalid combinations of attributes, but not *all*. Since
    invalid combinations are no longer representable, the new parsing code
    does check for a reject all invalid combinations.

    Diagnose repeated attributes, as well as conflicting attributes.

    Improve error messages, even when not related to this change,
    e.g. by quoting echoed user code.

compiler/add_mutable_aux_preds.m:
    Delete the code that used to check for illegal combinations of mutable
    values, since these cannot happen anymore.

    Conform to the change above.

    Delete an unneeded field from the parameters. The old ImplLang and Lang
    fields contained exactly the same information, so keep only Lang.

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

tests/invalid/bad_mutable.m:
    Add some more bad mutable declarations to diagnose.

    Add an XXX pointing out an error for which we generate *two* error
    messages (one in add_mutable_aux_preds.m, and one during module
    qualification).

tests/invalid/bad_mutable.err_exp:
    Expect the updated error messages for both the old and the new
    bad mutable declarations.

tests/invalid/bad_finalise.err_exp:
    Expect quoting of echoed user code.
2021-05-25 21:39:58 +10:00
Zoltan Somogyi
b6c056ec4d Fix style issues.
compiler/add_mutable_aux_preds.m:
    Give some predicates more meaningful names.

    Use only the required parts of module_infos when possible.

    Fix nonstandard argument order.

    Document a function.
2021-05-25 02:36:32 +10:00
Zoltan Somogyi
e1e2136dbb Centralize HLDS building in make_hlds_passes.m.
compiler/add_mutable_aux_preds.m:
compiler/add_solver.m:
    When invoked on mutables and solver types respectively, these modules
    added did all the additions to the HLDS directly themselves,
    in two phases: first declarations, then definitions.

    Change this so that instead, they simply return the items needed
    to declare and define mutables and solver types to make_hlds_passes.m,
    which will then add them to the HLDS with the other items of the same kind.

compiler/make_hlds_passes.m:
    Add to the HLDS the items returned by add_mutable_aux_preds.m and
    add_solver.m. Doing the adding here makes it much easier to see
    both the full set of items that mutables and solver types, as well as
    the dependencies between them and other kinds of items.

compiler/add_foreign_proc.m:
    Add a utility predicate for use by the code above.

compiler/add_pragma.m:
    Add a utility predicate for use by the code above, replacing another,
    which can now be kept private.

compiler/make_hlds.m:
    Define types that are now needed in more than one of its submodules.

compiler/make_hlds_separate_items.m:
    Delete the type definitions that have been moved to make_hlds.m.

compiler/hlds_module.m:
    Rename pred_c_names as pred_target_names, since they can also refer to
    C# and Java names.

    Change the predicates that add pred_target_names so that they add them
    to just the data structure that contains them, not the whole module_info.
    This makes the code of the callers clearer.

    Fix a bug I introduced when I changed make_hlds_passes.m to add items
    by kind, not by position in an item block. The bug was that the
    reference manual promised that in the event of a code sequence such as

        :- initialise foo/2.
        :- mutable(bar, int, 561, ground, [untrailed]).
        :- initialise baz/2.

    the initialization of bar would happen *between* the calls to
    foo/2 and baz/2, but since make_hlds_passes.m processed all initialise
    declarations together, this could not happen. The fix is to record
    initializations in a map whose key is an item sequence number
    (which cannot be item_no_seq_num), and then take the initialization
    sequence from those keys.

compiler/parse_type_defn.m:
    Include valid seq_nums (the seq_num of the solver type definition)
    in the mutable items returned for solver types, for use in the
    pred_target_names map in hlds_module.m.

compiler/mercury_compile_llds_back_end.m:
compiler/ml_top_gen.m:
    Conform to the change in hlds_module.m.
2021-05-24 22:01:17 +10:00
Zoltan Somogyi
2bb42f9e61 Move checks on mutables to end of module. 2021-05-20 11:38:11 +10:00
Zoltan Somogyi
a72627888e Make the goal_type type more fit for purpose.
compiler/hlds_pred.m:
    Separate out goal types that implement a promise from those that do not.
    Document the latter. (The former is documented elsewhere.)

    When creating a new predicate, require the caller to specify
    the goal type; do not supply a default that may be wrong.

    Give some predicates more meaningful names.

compiler/add_pred.m:
    When adding an implicit predicate declaration for a promise,
    specify that the new predicate is for a promise, instead of letting
    hlds_pred.m assume by default that it is NOT for a promise.

compiler/add_clause.m:
    When adding a clause to the HLDS, do not require callers to supply
    information that they cannot possibly know.

    Specify the goal_type for a promise when creating its predicate,
    not later.

compiler/pre_typecheck.m:
    Record the goal type of field access functions, whose Mercury definition
    we just created, as containing only Mercury code. Previously, we falsely
    recorded it as containing both Mercury clauses and foreign procs.

compiler/accumulator.m:
compiler/add_class.m:
compiler/add_foreign_proc.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pragma_tabling.m:
compiler/add_pragma_type_spec.m:
compiler/add_special_pred.m:
compiler/check_promise.m:
compiler/check_typeclass.m:
compiler/intermod.m:
compiler/lambda.m:
compiler/make_hlds_passes.m:
compiler/par_loop_control.m:
compiler/purity.m:
compiler/stm_expand.m:
compiler/structure_reuse.versions.m:
compiler/table_gen.m:
compiler/typecheck.m:
compiler/untupling.m:
    Conform to the changes above.
2021-05-20 00:46:18 +10:00
Zoltan Somogyi
094d6ab0f7 Add clauses by item_clause_info.
compiler/add_clause.m:
    Change the signature of the predicate that adds clauses to the HLDS
    to take its input in the form of an item_clause_info, instead of a
    bunch of separate arguments.

    Change the signature of the predicate that adds clauses to a clauses_info
    to put the original and updated versions of the same data structure
    next to each other, as with state variables. (It cannot usefully take
    its input in the form of an item_clause_info.)

compiler/add_pred.m:
    Fix weird argument order in some predicates.

compiler/add_class.m:
compiler/add_foreign_proc.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pragma_tabling.m:
compiler/make_hlds_passes.m:
    Conform to the changes above.
2021-05-19 17:45:56 +10:00
Zoltan Somogyi
99334e8469 Switch to structured item sequence numbers.
compiler/prog_data.m:
    Define a data type that encodes the distinction between valid
    and dummy item sequence numbers in the type. Previously, different
    parts of the compiler expressed this distinction in two different ways,
    either using "-1" to represent a dummy sequence number, or using "no"
    in a maybe(int) type.

compiler/prog_item.m:
    Use the new type instead of plain "int" as the sequence number in items.

compiler/hlds_pred.m:
    Use the new type instead of plain "int" as the sequence number
    in cur_user_decl_infos. Document the fact that the presence of a
    cur_user_decl_info in a pred_info does NOT guarantee a valid
    item sequence number.

compiler/add_foreign_proc.m:
    When adding a foreign_proc to the HLDS, pass a whole item_pragma_info,
    not its components. (This change is what this diff started as, before
    the item_seq_num changes overwhelmed it.)

compiler/accumulator.m:
compiler/add_class.m:
compiler/add_clause.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pragma.m:
compiler/add_pragma_tabling.m:
compiler/add_pred.m:
compiler/add_solver.m:
compiler/add_special_pred.m:
compiler/check_typeclass.m:
compiler/comp_unit_interface.m:
compiler/decide_type_repn.m:
compiler/default_func_mode.m:
compiler/hlds_clauses.m:
compiler/intermod.m:
compiler/item_util.m:
compiler/lambda.m:
compiler/make_hlds_passes.m:
compiler/par_loop_control.m:
compiler/parse_class.m:
compiler/parse_dcg_goal.m:
compiler/parse_inst_mode_defn.m:
compiler/parse_item.m:
compiler/parse_module.m:
compiler/parse_mutable.m:
compiler/parse_pragma.m:
compiler/parse_pragma_analysis.m:
compiler/parse_pragma_foreign.m:
compiler/parse_pragma_tabling.m:
compiler/parse_type_defn.m:
compiler/parse_type_repn.m:
compiler/parse_types.m:
compiler/proc_requests.m:
compiler/prog_mutable.m:
compiler/split_parse_tree_src.m:
compiler/stm_expand.m:
compiler/style_checks.m:
compiler/table_gen.m:
    Conform to the changes above.
2021-05-19 13:27:27 +10:00
Zoltan Somogyi
2d00217a43 Simplify adding pred and mode decls to HLDS.
compiler/add_pred.m:
    When adding a mode_decl to the HLDS, pass the item_mode_decl_info,
    not its components.

    In one place, stop using the absence/presence of an item_mercury_status
    to signify whether a mode declaration is part of a predmode declaration
    or not. Use a bespoke enum instead.

    In another place, stop using the absence/presence of an argument mode list
    to signify whether a pred declaration is actually a predmode declaration.
    Use an (existing) bespoke enum instead.

    Move some semantic checks on pred and mode declarations that used
    to be done in make_hlds_passes.m to here, where all the other
    semantic checks on those declarations are.

    Rename a predicate to fit in with the module's naming scheme.

    Move the code of some subtasks out into separate predicates.

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

    Replace a function with a non-meaningful name and obscure body
    with a predicate with a meaningful name and a readable body.

    Do not pass around sequence numbers that are always dummies;
    create them just before the only use.

compiler/add_mutable_aux_preds.m:
compiler/add_pragma.m:
compiler/add_pragma_tabling.m:
compiler/add_solver.m:
    Conform to the changes above.

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

    Delete the checks moved to add_pred.m.

compiler/prog_util.m:
    Delete a type synomym with very few uses.
2021-05-19 02:19:42 +10:00
Zoltan Somogyi
dcb728e22a Record section info with lists of items.
compiler/make_hlds.m:
    Make the representation of sec_lists and ims_lists more efficient.

    The old definition of sec_list(T), where T is item_X_info for some X, was

    :- type sec_list(T) == list(sec_item(T)).
    :- type sec_item(T)
        --->    sec_item(sec_info, T).

    while the new definition is

    :- type sec_list(T) == list(sec_sub_list(T)).
    :- type sec_sub_list(T)
        --->    sec_sub_list(sec_info, list(T)).

    The change to the ims_list type is analogous.

    The new definition has sevaral advantages.

    - There is no need to allocate a sec_item cell for each item_X_info.
    - The parse trees from which we take the item_X_infos already have them
      in a list. The old representation had to rebuild this list around the
      sec_items, while the new representation does not: it allocates just
      one cell for each list in each parse_tree.
    - To ensure that the predicate built the list of sec_infos in the old
      approach, it built this list accumulator style by appending to the front
      in order to guarantee tail recursion. Preserving the original order
      in the final result thus requires a list reversal with yet more
      memory allocation.

    The one disadvantage of the new type definition is that it requires
    a two level traversal: first of the sublists, then of the items within
    them. However, even this minor disadvantage is offset by the fact that
    it allows for a simple form of loop invariant optimization. Specifically,
    for some item kinds, computations on the sec_info can be done once
    per sublist, and do not have to be repeated once per item.

compiler/make_hlds_separate_items.m:
    Accumulate item_X_infos in the form of cords of sublists. Being able
    to append to these cords in constant time means that we never have to
    reverse or re-reverse lists of items, and the cords are trivial to
    transform to sec_lists and ims_lists at the end.

compiler/make_hlds_passes.m:
    Add the list of each kind of item to the HLDS using the two level loop
    described above.

compiler/add_class.m:
compiler/add_mode.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pragma.m:
compiler/add_pred.m:
    Export predicates that add whole two level lists of items, not just
    predicates that add a single item. Move computations from the inner loop
    to the outer loop when possible.
2021-05-18 17:13:15 +10:00
Zoltan Somogyi
8355718b16 Allow pred pragmas to specify pred_or_func.
Pragmas that apply to a pred_info have traditionally specified that
pred_info by a symname/arity pair. However, this can be ambiguous
if there is both a predicate and a function with that symname/arity pair.
This diff therefore allows pragmas that previously took "symname/arity"
to also take "pred(symname/arity)" and "func(symname/arity").
If e.g. there is both a pred foo/2 and a func foo/2 accessible from
the current module, the old form applied to both, while the new forms
apply to just one.

Later, we could change the behavior of the old form to insist on a
unique match, but before we do, we should have a mechanism that allows
programmers to resolve the ambiguity. (They could rename either the
pred or the func, but it is less intrusive for the compiler not to
insist on that.) This is that mechanism.

In the process of implementing this change, I had to update lots of code
that dealt with arities, since one main difference between predicates
and functions is that for the latter, the user visible arity and
the internal compiler arity are different, in that the former does not
count the return value, and the latter does. The existing "arity" type
is an equivalence to int, and thus does not indicate which notion is meant.
I therefore added two notag types, user_arity and pred_form_arity,
for the two notions above respectively, and made a start on using them,
though for now, only in the code sections affected by the main change above.

compiler/prog_item.m:
    Change the types that represent the specifications of predicates
    (in the sense of pred_infos) and functions to allow the representation
    of not just "symname/arity," but also "pred(symname/arity)" and
    "func(symname/arity"). There is one exception: for the oisu (order
    independent state update) pragma, require the presence of either
    a pred() vs func() wrapper. This is not a breaking change, since oisu
    pragmas are neither publicly documented or really implemented.

    Pragmas that allow the representation of argument modes implicitly
    specify pred vs func by taking the mode list either as
    (m1, m2, ... mn) or as (m1, m2, ...) = mn. Encode this invariant
    in the representation type. Make this type also include an arity
    only in the absence of a mode list, to make unrepresentable
    any inconsistent state in which the stated arity and the length
    of the mode list disagree.

    Give the new types used for these updated representations names
    that state whether they specify a pred_info or a proc_info
    (or in one case that we should later fix, that they can specify either).

    Put the pred or func indication before the symname and arity
    both in these new types, and in some old types. Do this both because
    the pred or func indication comes before the name in Mercury declarations,
    and to help the compiler find all the places where code using the old
    forms had to be revisited and checked for any needed updates.

    Provide utility operations on the new types involved in the
    updated representations.

compiler/prog_data.m:
    Add the user_arity and pred_form_arity types, as mentioned above.

    Add a type that is mostly used in item representations, but is also
    useful elsewhere.

compiler/parse_pragma.m:
compiler/parse_pragma_analysis.m:
compiler/parse_pragma_foreign.m:
compiler/parse_pragma_tabling.m:
compiler/parse_util.m:
    Accept the pred() or func() wrappers mentioned above, and generate
    the updated representations when parsing terms containing pragmas.

compiler/parse_tree_out_pragma.m:
    Accept the updated representations of pragmas when printing them out.

compiler/add_pragma.m:
compiler/add_pragma_tabling.m:
compiler/add_pragma_type_spec.m:
    Use the updated representations when adding pragmas to the HLDS.

compiler/error_util.m:
    Provide mechanisms for use above when printing references to pred_infos
    using user arities, to complement the existing mechanisms which use
    arities that they treat as pred form arities. The latter is what
    you want when generating error messages about pred_infos that
    already included functions' return types in the argument list;
    the former is what you want when generating error messages
    about user input that has not yet been subject to that treatment,
    such as a pragma that has just been read in. (The difference is
    only in what form of arity these mechanisms take as *input*;
    the output is always user arity, which after all is what users
    are interested in.)

compiler/hlds_error_util.m:
    Provide a user_arity equivalent to a piece of existing pred_form_arity
    functionality, for use by the modules above.

    Provide utility functions used when generating error messages.

compiler/fact_table.m:
    Replace most uses of the "arity" type with the "user_arity" type.
    Done mostly in the process of figuring out which kind of arity
    the top predicates took as arguments.

    Put argument lists into a sensible order.

compiler/prog_out.m:
compiler/prog_util.m:
    Add utility functionality needed above.

compiler/add_mutable_aux_preds.m:
compiler/convert_parse_tree.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/intermod.m:
compiler/item_util.m:
compiler/make_hlds_passes.m:
compiler/module_qual.qualify_items.m:
compiler/recompilation.usage.m:
compiler/recompilation.version.m:
compiler/typecheck_errors.m:
compiler/unused_args.m:
    Conform to the changes above.

compiler/hlds_pred.m:
    Add an XXX.

compiler/notes/order_indep_state_update:
    Fix typos.

tests/hard_coded/bad_direct_reuse.m:
tests/hard_coded/bad_indirect_reuse.m:
tests/hard_coded/bitmap_simple.m:
tests/hard_coded/constraint_order.m:
tests/hard_coded/equality_pred_which_requires_boxing.m:
tests/hard_coded/fact_table_test_1.m:
tests/hard_coded/float_consistency.m:
tests/hard_coded/foreign_enum_rtti.m:
tests/hard_coded/foreign_enum_switch.m:
tests/hard_coded/foreign_import_module_2.m:
tests/hard_coded/gh72.m:
tests/hard_coded/gh72a.m:
tests/hard_coded/heap_ref_mask_tag.m:
tests/hard_coded/intermod_multimode.m:
tests/hard_coded/mode_check_clauses.m:
tests/hard_coded/multimode_addr.m:
tests/hard_coded/type_spec_ho_term.m:
tests/hard_coded/user_defined_equality2.m:
    Add pred() or func() wrappers to symname/arity pairs in pragmas,
    to test whether the parser accepts them.

    Fix deviations from our current coding standards.

tests/hard_coded/oisu_check_db.m:
tests/invalid/oisu_check_add_pragma_errors.{m,err_exp}:
tests/invalid/oisu_check_semantic_errors.m:
    Add the pred() wrappers now required in oisu pragmas.
    Expect the improved wording of an error message.
2021-05-06 07:19:25 +10:00
Peter Wang
e9dafb3ec6 Add foreign_proc attributes may_export_body/may_not_export_body.
Add an attribute may_not_export_body to prevent a foreign_proc from
being opt-exported. Also add may_export_body for completeness.

compiler/prog_data_foreign.m:
    Add type to represent those attributes.

    Add a field for that attribute to pragma_foreign_proc_attributes,
    plus getters and setters.

compiler/parse_pragma_foreign.m:
    Parse may_export_body and may_not_export_body attributes on
    foreign_proc declarations.

    Detect conflicting attributes.

compiler/parse_tree_out_pragma.m:
    Write out may_export_body and may_not_export_body attributes.

compiler/intermod.m:
    Do not write a foreign_proc with may_not_export_body to .opt files.

compiler/simplify_proc.m:
    Report an error if a foreign_proc with may_export_body is
    also marked with pragma no_inline.

compiler/add_mutable_aux_preds.m:
    Mark auxiliary predicates for mutables with may_not_export_body
    instead of may_not_duplicate. This allows calls to those predicates
    to be inlined.

doc/reference_manual.texi:
    Document the new attributes.

tests/hard_coded/Mercury.options:
tests/hard_coded/Mmakefile:
tests/hard_coded/intermod_may_export_body.exp:
tests/hard_coded/intermod_may_export_body.m:
tests/hard_coded/intermod_may_export_body2.m:
tests/invalid/Mmakefile:
tests/invalid/test_may_export_body.err_exp:
tests/invalid/test_may_export_body.m:
    Add test cases.

vim/syntax/mercury.vim:
    Update vim syntax file.

NEWS:
    Announce addition.
2021-04-20 11:05:29 +10:00
Zoltan Somogyi
185e4c4e96 Delete all stale code for Erlang from the compiler.
compiler/Mercury.options:
    Delete a workaround we needed only for Erlang.

compiler/add_mutable_aux_preds.m:
    Delete the implementation of mutables for Erlang.

compiler/builtin_ops.m:
    Document the fact that the Erlang backend was the only user of
    two operations.

compiler/compile_target_code.m:
compiler/module_cmds.m:
    Delete the predicates that handled the compilation of Erlang code.

compiler/file_names.m:
    Delete code dealing with file names used only by the Erlang backend.

compiler/options.m:
    Delete the old internal-only order_constructors_for_erlang option.

    Add an XXX about another option intended for Erlang being unused.

    Leave the other erlang-related options alive for now, to avoid breaking
    Mmakefiles, Mercury.options files etc that may still refer to them.

    Delete references to Erlang in help and/or error messages.

compiler/handle_options.m:
    Don't both updating options that were used only by the Erlang backend,
    and which are now unused.

    Delete references to Erlang in help and/or error messages.

compiler/unify_proc.m:
    Delete the code handling the Erlang-specific option deleted from options.m.

compiler/check_libgrades.m:
compiler/delay_partial_inst.m:
compiler/llds_out_data.m:
compiler/make_hlds_passes.m:
compiler/mlds_to_c_data.m:
compiler/prog_item.m:
compiler/simplify_goal_call.m:
compiler/write_deps_file.m:
    Either delete comments referring to Erlang or the Erlang backend,
    or, where their existence was the motivation for some design decisions,
    shift the comments to the past tense.

tests/mmc_make/Mmakefile:
    Delete a reference to a recently deleted .hrl file.
2020-10-29 23:29:36 +11:00
Zoltan Somogyi
a19a5f0267 Delete the Erlang backend from the compiler.
compiler/elds.m:
compiler/elds_to_erlang.m:
compiler/erl_backend.m:
compiler/erl_call_gen.m:
compiler/erl_code_gen.m:
compiler/erl_code_util.m:
compiler/erl_rtti.m:
compiler/erl_unify_gen.m:
compiler/erlang_rtti.m:
compiler/mercury_compile_erl_back_end.m:
    Delete these modules, which together constitute the Erlang backend.

compiler/notes/compiler_design.html:
    Delete references to the deleted modules.

compiler/parse_tree_out_type_repn.m:
    Update the format we use to represent the sets of foreign_type and
    foreign_enum declarations for a type as part of its item_type_repn_info,
    now that Erlang is no longer a target language.

compiler/parse_type_repn.m:
    Accept both the updated version of the item_type_repn_info and the
    immediately previous version, since the installed compiler will
    initially generate that previous version. However, stop accepting
    an even older version that we stopped generating several months ago.

compiler/parse_pragma_foreign.m:
    When the compiler finds a reference to Erlang as a foreign language,
    add a message about support for Erlang being discontinued to the error
    message.

    Make the code parsing foreign_decls handle the term containing
    the foreign language the same way as the codes parsing foreign
    codes, procs, types and enums.

    Add a mechanism to help parse_mutable.m to do the same.

compiler/parse_mutable.m:
    When the compiler finds a reference to Erlang as a foreign language,
    print an error message about support for Erlang being discontinued.

compiler/compute_grade.m:
    When the compiler finds a reference to Erlang as a grade component,
    print an informational message about support for Erlang being discontinued.

compiler/pickle.m:
compiler/make.build.m:
    Delete Erlang foreign procs and types.

compiler/add_foreign_enum.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pred.m:
compiler/add_solver.m:
compiler/add_type.m:
compiler/check_libgrades.m:
compiler/check_parse_tree_type_defns.m:
compiler/code_gen.m:
compiler/compile_target_code.m:
compiler/compute_grade.m:
compiler/const_struct.m:
compiler/convert_parse_tree.m:
compiler/dead_proc_elim.m:
compiler/decide_type_repn.m:
compiler/deps_map.m:
compiler/du_type_layout.m:
compiler/export.m:
compiler/foreign.m:
compiler/globals.m:
compiler/granularity.m:
compiler/handle_options.m:
compiler/hlds_code_util.m:
compiler/hlds_data.m:
compiler/hlds_module.m:
compiler/inlining.m:
compiler/int_emu.m:
compiler/intermod.m:
compiler/item_util.m:
compiler/lambda.m:
compiler/lco.m:
compiler/llds_out_file.m:
compiler/make.dependencies.m:
compiler/make.m:
compiler/make.module_dep_file.m:
compiler/make.module_target.m:
compiler/make.program_target.m:
compiler/make.util.m:
compiler/make_hlds_separate_items.m:
compiler/make_hlds_warn.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mercury_compile_main.m:
compiler/mercury_compile_middle_passes.m:
compiler/mercury_compile_mlds_back_end.m:
compiler/ml_code_util.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_target_util.m:
compiler/ml_top_gen.m:
compiler/mlds.m:
compiler/mlds_dump.m:
compiler/mlds_to_c_export.m:
compiler/mlds_to_c_file.m:
compiler/mlds_to_cs_data.m:
compiler/mlds_to_cs_export.m:
compiler/mlds_to_cs_file.m:
compiler/mlds_to_cs_type.m:
compiler/mlds_to_java_export.m:
compiler/mlds_to_java_file.m:
compiler/mlds_to_java_type.m:
compiler/module_imports.m:
compiler/parse_pragma_foreign.m:
compiler/parse_tree_out.m:
compiler/polymorphism.m:
compiler/pragma_c_gen.m:
compiler/prog_data.m:
compiler/prog_data_foreign.m:
compiler/prog_foreign.m:
compiler/prog_item.m:
compiler/simplify_goal_scope.m:
compiler/special_pred.m:
compiler/string_encoding.m:
compiler/top_level.m:
compiler/uint_emu.m:
compiler/write_deps_file.m:
    Remove references to Erlang as a backend or as a target language.

tests/invalid/bad_foreign_code.{m,err_exp}:
tests/invalid/bad_foreign_decl.{m,err_exp}:
tests/invalid/bad_foreign_enum.{m,err_exp}:
tests/invalid/bad_foreign_export.{m,err_exp}:
tests/invalid/bad_foreign_export_enum.{m,err_exp}:
tests/invalid/bad_foreign_import_module.{m,err_exp}:
tests/invalid/bad_foreign_proc.{m,err_exp}:
tests/invalid/bad_foreign_type.{m,err_exp}:
    Add a test for Erlang as an invalid foreign language. Expect both the
    new error message for this new error, and the updated list of now-valid
    foreign languages on all errors.
2020-10-29 13:24:49 +11:00
Zoltan Somogyi
4f32c50822 Let clauses with unknown warnings be processed.
This implements Mantis feature request #497.

compiler/parse_goal.m:
compiler/parse_dcg_goal.m:
    When we find that a disable_warnings scope contains an unrecognized
    warning name, generate a warning for it, and return this warning
    *alongside*, not *instead of*, the disable_warnings scope goal.
    This requires passing around not a maybe1(goal), as we have been doing
    till now, but a maybe2(goal, list(warning_spec)), so this change
    affects both (1) most of these two modules, and (2) most of the
    modules below.

compiler/error_util.m:
    Provide warning_spec as a synonym for error_spec, to be used in
    situations like this where the "error_spec" is intended contain
    something with severity_warning.

compiler/maybe_error.m:
    Provide some new utility predicates now needed in parse_goal.m
    and elsewhere.

compiler/prog_item.m:
    Provide room in the representation of clauses for the warnings
    generated by parsing the clause body goal.

compiler/add_class.m:
compiler/add_clause.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pragma_tabling.m:
compiler/du_type_layout.m:
compiler/get_dependencies.m:
compiler/make_hlds_passes.m:
compiler/parse_item.m:
compiler/parse_tree_out_clause.m:
compiler/prog_item_stats.m:
compiler/superhomogeneous.m:
    Conform to the changes above.

tests/valid/unknown_warning.m:
    Add this test case that checks whether a source file with an unknown
    warning name in a disable_warnings scope can have code generated for it.

tests/warnings/unknown_warning.{m,exp}:
    Add the same source file to this directory as well, to check whether
    we get the right set of warnings.

tests/valid/Mmakefile:
tests/valid/Mercury.options:
tests/warnings/Mmakefile:
    Enable the two new test cases.
2020-04-05 19:09:31 +10:00
Zoltan Somogyi
5c52cf0cde Standardize on "sym_name_arity" ...
... replacing "sym_name_AND_arity".
2020-03-15 19:37:18 +11:00
Zoltan Somogyi
c5a65723c3 Replace {inst,mode}_id with {inst,mode}_ctor ...
.. since these two types play the same role for insts and modes respectively
as type_ctors do for types.

compiler/prog_data.m:
    As above.

compiler/add_mode.m:
compiler/add_mutable_aux_preds.m:
compiler/equiv_type.m:
compiler/hlds_defns.m:
compiler/hlds_inst_mode.m:
compiler/hlds_out_module.m:
compiler/inst_check.m:
compiler/inst_user.m:
compiler/intermod.m:
compiler/mode_util.m:
compiler/prog_mode.m:
compiler/recompilation.m:
compiler/recompilation.usage.m:
compiler/unused_imports.m:
    Conform to the above changes.
2020-03-15 11:45:04 +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
d4a175407e Add all pragmas in one pass.
compiler/hlds_module.m:
    Split the field containing foreign_decls into two: the decls added
    by the user, and the decls added by the compiler. The latter can refer
    to entities defined in the former, but not the reverse.

compiler/erl_code_gen.m:
compiler/export.m:
compiler/mercury_compile_llds_back_end.m:
compiler/ml_top_gen.m:
    Always put the foreign decls generated by the compiler *after* the ones
    written by the user. The other way around could cause the target language
    compiler to see a use of a type name before its definition.

compiler/add_mutable_aux_preds.m:
compiler/add_pragma.m:
    Add both user-provided and compiler-generated foreign decls to the
    relevant field of the HLDS.

compiler/make_hlds_passes.m:
    Document why we don't have to add any pragmas in the modern equivalent
    of the old pass 2 anymore. The separation of user and auxiliary foreign
    decls was the last issue tying us to that old scheme.

compiler/prog_foreign.m:
    Delete two type synonyms that are not really needed.
2019-11-27 00:12:10 +11:00
Zoltan Somogyi
ab8c2771f7 Move towards generating .opt/.trans_opt files via items.
compiler/prog_item.m:
    Add types for representing .opt and .trans_opt files that specify
    exactly what kinds of items may appear in them.

    Provide a mechanism for representing just the kinds of pragmas
    that we may want to put into .opt files to represent a predicate marker.

    To make the above possible, generalize the item_pragma_info type.

    Do not store the "maybe attributes" field in all pragmas; store it
    in just the one pragma for which it had pragma-specific code (which code
    is dubious anyway). Its only use is to suppress error messages about
    incorrect pragmas if that pragma was created by the compiler, on the
    theory that the user cannot do anything about any such error messages.
    However, if such errors are never reported to anyone, then they won't
    be fixed. I think it is better to allow such problems to be discovered,
    even if they cause a bit of annoyance to the discoverer. The default
    content of the field as set by the parser, item_origin_user, can be
    misleading anway; it is correct when the pragma is read in from a .m file
    or from a .int* file, but it is wrong when read in from a .*opt file,
    since the contents of those are decided by the compiler.

    Store a varset and tvarset in structure sharing and reuse pragmas,
    since without this, one cannot print them out properly.

compiler/intermod.m:
    Change the predicates that write out .opt and .trans_opt files
    to return as large a fraction of the parse trees of those files
    as possible, as a step towards generating those files not directly,
    but by building and then writing out those parse trees. For now,
    we cannot do this fully for .opt files, because for a few item kinds,
    it is far from obvious how to represent as a item what we write out.

    Leave the opening and closing of the file streams for writing out
    .opt and .trans_opt files to our caller, because for .opt files,
    this allows us to avoid having to open the file *twice*.

    Put the output of result-of-analysis pragmas into a standard order.

    Factor out as common code the process for deciding what should go into
    .opt files.

    Give a field of the intermod_info structure a more precise name.

compiler/mercury_compile_front_end.m:
    Hold the stream of the .opt file open between the two different pieces
    of code that write out the two different parts of .opt files.

    If --experiment5 is set, write out the parse tree of the .opt file
    to the .optx file, to enable comparison with the .opt file.

compiler/mercury_compile_middle_passes.m:
    If --experiment5 is set, write out the parse tree of the .trans_opt file
    to the .trans_optx file, to enable comparison with the .trans_opt file.

    Reset a memo table for structure_{sharing,reuse}.analysis.

compiler/structure_reuse.analysis.m:
compiler/structure_sharing.analysis.m:
    Don't take an I/O state pair as arguments, since we needed them *only*
    for that reset, and for progress messages.

    Give the main predicates more descriptive names.

compiler/trailing_analysis.m:
    Give the main predicate a more descriptive names.

compiler/closure_analysis.m:
    Don't take an I/O state pair as arguments, since we needed them *only*
    for progress messages.

compiler/add_pragma.m:
    Don't ignore an error, since one of the other changes in this diff
    could have fixed its cause.

compiler/convert_interface.m:
    Export utility functions needed by code added by this diff.

ompiler/lp_rational.m:
    Tighten the inst of an output argument for use by intermod.m.

    Bring programming style up to date.

compiler/parse_pragma.m:
    Don't put a maybe attributes field into item_pragma_infos.

    Include the varset in structure sharing and reuse pragmas.

    Use simplest_spec where possible.

compiler/parse_tree_out.m:
    Add predicates for writing out the new parse trees of .opt and
    .trans_opt files.

compiler/parse_tree_out_pragma.m:
    Add predicates needed by the new code in parse_tree_out.m.

compiler/add_mutable_aux_preds.m:
compiler/canonicalize_interface.m:
compiler/comp_unit_interface.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/grab_modules.m:
compiler/item_util.m:
compiler/make_hlds_error.m:
compiler/make_hlds_passes.m:
compiler/make_hlds_separate_items.m:
compiler/module_qual.qualify_items.m:
compiler/prog_item_stats.m:
compiler/recompilation.version.m:
    Conform to the changes above.
2019-10-30 10:43:39 +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
0f6941447e Use simplest_spec and simplest_msg where appropriate. 2019-10-15 21:48:09 +11:00
Zoltan Somogyi
3248c11c11 Move a comment to the code it describes. 2019-09-02 00:48:39 +10:00
Zoltan Somogyi
315c7758a4 Add all predicates via item_pred_decl_infos.
compiler/add_pred.m:
    Don't export the predicate that used to allow other parts of the compiler
    to create new predicates without constructing a new item_pred_decl_info.
    In fact, inline this predicate in its only caller.

    Base decisions about what predicates are exported based on the predicate
    status, which is always there, not on an optionally supplied
    item_mercury_status.

    Standardize some variable names.

compiler/prog_item.m:
    Since the change to add_pred.m does not allow other compiler modules
    to specify a pred_origin for the new predicate *directly*, make it
    possible for them to specify it *indirectly*. This centralises handling
    of the implications of the origins of new compiler-generated predicates
    in one place in add_pred.m.

    Delete the maybe_allow_export attribute from items. It had no meaningful
    semantics, so there was no correct way to fill in that field.

compiler/prog_data.m:
    Move the definitions of the types that describe the auxiliary predicates
    used by solver types and tabling here from hlds_pred.m, since prog_item.m
    now needs access to them.

compiler/hlds_pred.m:
    Delete the type definitions moved to prog_data.m.

    Add three new kinds of origins for predicates, which we have previously
    ignored.

compiler/add_class.m:
compiler/add_foreign_proc.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pragma_tabling.m:
compiler/add_solver.m:
    Change the code that adds new predicates to the HLDS to conform
    to the changes above.

compiler/hlds_out_pred.m:
compiler/hlds_out_util.m:
compiler/layout_out.m:
compiler/make_hlds_passes.m:
compiler/mode_errors.m:
compiler/polymorphism.m:
compiler/prog_mutable.m:
compiler/trace_params.m:
    Conform to the changes above.
2019-09-02 00:45:45 +10:00
Zoltan Somogyi
0829e01622 Fix redundant import. 2019-09-01 18:58:19 +10:00
Zoltan Somogyi
a39adc549d Centralize decisions about which aux preds a mutable needs.
The implementation of a mutable requires several predicates, some user visible,
some not. Exactly what set of predicates a mutable needs depends both on its
attributes and on the target platform. Previously, we computed that set of
predicates three times:

- when adding their declarations to the HLDS,
- when adding their definitions to the HLDS, and
- when adding (a subset of) their declarations to a .int0 file.

This diff tries to centralizes these decisions in one place. It does not
quite get there, because getting there would require compromises that are
undesirable for other reasons, but it gets close.

compiler/prog_data.m:
    Document the uses of the various kinds of predicates we can generate
    for a mutable.

compiler/prog_mutable.m:
    Add a predicate that decides which public auxiliary predicates
    a mutable needs, for use by both add_mutable_aux_preds.m and by
    comp_unit_interface.m.

    Add a predicate that constructs the pred_decl item of any given
    mutable auxiliary predicate, again for use by add_mutable_aux_preds.m
    and by comp_unit_interface.m.

    Move predicates that are used only by add_mutable_aux_preds.m
    to add_mutable_aux_preds.m.

    Delete predicates that are no longer needed.

compiler/add_mutable_aux_preds.m:
    Add a predicate that decides which private auxiliary predicates
    a mutable needs,

    Use the new mechanisms above to declare a mutable's auxiliary procedures.

    Use the new mechanisms above to define a mutable's auxiliary procedures,
    mostly. There is still some code that repeats the logic of the decision
    predicate for public auxiliary predicates, but now a sanity check
    ensures that the two decision procedures arrived at the same result.

    Move predicates that are used only by add_mutable_aux_preds.m
    here from prog_mutable.m.

    Delete predicates that are no longer needed.

    Give several predicates more descriptive names. Standardize
    argument orders.

compiler/add_pred.m:
    Add a mechanism for adding a pred_decl item as a whole to the HLDS.
    (Previously, we could a pred_decl to the HLDS by first breaking it down
    to its components.) The code is mostly copied from make_hlds_passes.m.

compiler/comp_unit_interface.m:
    Use the new mechanisms above to declare a mutable's auxiliary procedures.
    The new code does not need any knowledge of what auxiliary predicates
    a mutable needs.

compiler/make_hlds_passes.m:
    Use the new mechanism in add_pred.m, in order to avoid code duplication.

library/set.m:
    Add a new predicate for add_mutable_aux_preds.m.
2019-09-01 18:22:06 +10:00
Zoltan Somogyi
0b60daa112 Record the origin of mutable aux predicates.
compiler/prog_item.m:
    If a predicate declaration is created for an auxiliary predicate
    for an operation on a mutable, add slots for recording the details
    of the item's origin.

compiler/hlds_pred.m:
compiler/prog_data.m:
    Move the mutable_pred_kind type from hlds_pred.m to prog_data.m
    to make the above possible.

compiler/prog_mutable.m:
    Fill the slots added to prog_item.m for some kinds of mutable
    aux predicates.

compiler/add_mutable_aux_preds.m:
    Fill the slots added to prog_item.m for the other kinds of mutable
    aux predicates.

    Fix an old typo: record a mutable's init predicate as its init predicate,
    not as its pre-init predicate.

compiler/make_hlds_passes.m:
    Use the new info in predicate declaration items to create an accurate
    predicate origin for mutable aux predicates.

compiler/dead_proc_elim.m:
    Conform to the change above.
2019-05-30 12:13:54 +02:00
Zoltan Somogyi
580ce2d42f Compute foreign_export languages using the standard traversal.
compiler/get_dependencies.m:
    Get the predicate that computes various summary pieces of information
    about item lists to compute the set of foreign languages in which those
    items export code.

    To avoid excessive argument passing costs, wrap the rarely updated
    state var arguments of this predicate in a structure.

compiler/module_imports.m:
    Have init_module_and_imports compute the contains_foreign_export field
    of the new module_and_imports structure both by (a) post-processing
    the newly extended result of the standard traversal, and (b) using
    the old algorithm, and require two to agree.

    Have make_module_and_imports compute the contains_foreign_export field
    of the new module_and_imports structure by post-processing
    the newly extended result of the standard traversal. It used to
    always fill in the field with a nonmeaningful dummy value.

compiler/modules.m:
    Conform to the change in module_imports.m.

compiler/prog_item.m:
    Fix out-of-date code in the old algorithm used by init_module_and_imports
    revealed by the agreement requirement above. It assumed that mutables
    and initialize/finalize declarations are implemented only for C,
    even though they have also been implemented for the other backend
    languages as well.

compiler/add_mutable_aux_preds.m:
    Delete a maybe wrapper around a type. It was "no" only for backend
    languages that do not implement mutables, and now there is no such
    language.
2019-05-12 14:17:14 +10:00
Zoltan Somogyi
c1bdd2100b Delete unneeded $module args from aborts. 2019-04-16 04:13:35 +10:00
Zoltan Somogyi
e08b8505e9 Import the parents of *all* imported modules. 2019-03-29 12:56:35 +11:00
Zoltan Somogyi
acfe86aace Implement abstract insts and modes for use in .int3 files.
The syntax is

    :- abstract_inst((inst_name(instvar1, ..., instvarN))).
    :- abstract_mode((inst_name(instvar1, ..., instvarN))).

The rationale for that syntax is as follows.

First, I ruled out using the same scheme as for types, which would yield
the syntax

    :- inst (inst_name(V_1, ..., V_N)).
    :- mode (inst_name(V_1, ..., V_N)).

It would work for insts, but not for modes, because ":- mode p." would be
ambiguous: one couldn't tell whether it was defining a *mode* named p
of arity 0, or it was declaring a mode for a *predicate* named p
of arity 0. And I thought it made more sense for the syntax of insts
to follow the syntax of modes than to follow the syntax of types.
Hence the addition of the "abstract_" prefix. Since I intend to put
abstract insts and modes automatically into .int3 files, but NOT to add them
to the user visible part of the language, this should be fine.

Second, I wanted to avoid changing the set of operators in the language,
which is why there is no space after "abstract_inst" and "abstract_mode".

Third, there is a redundant set of parentheses around the argument
of those function symbols, just as there is around the inst name in
the non-abstract inst and mode definitions in .int3 file right now,
for the same reason: to guard against case that the inst or mode name
*is* an operator.

Fourth, the reason for listing the argument inst vars, instead of adding
a "/arity" suffix to the name, is to reuse the existing machinery
for reading in and writing out the heads of inst and mode definitions.

NOTE: the compiler still puts inst and mode definitions into .int3 files
in their original, non-abstract state. Changing that is for a later diff.

compiler/prog_item.m:
    Change the representation of inst and mode definitions to allow
    the inst or mode being defined to be abstract. These abstract versions
    do not make it into the HLDS.

compiler/prog_data.m:
compiler/hlds_inst_mode.m:
    We used to have a representation for abstract inst definitions inside
    both the parse tree and the HLDS, but any attempt to add the parse tree
    version to the HLDS would yield a compiler abort.

    Delete these representations, since they never worked, and are now not
    needed.

compiler/parse_inst_mode_defn.m:
compiler/parse_item.m:
    Parse the new syntax for abstract inst and mode definitions.

    Stop parsing the old syntax, which we have never used.

compiler/parse_tree_out.m:

compiler/add_mode.m:
    Add only nonabstract insts and modes to the HLDS. The abstract versions
    are used only during module qualification, which is done on the parse tree.

compiler/add_mutable_aux_preds.m:
compiler/equiv_type.m:
compiler/hlds_out_module.m:
compiler/inst_check.m:
compiler/inst_user.m:
compiler/intermod.m:
compiler/mode_util.m:
compiler/module_qual.qualify_items.m:
compiler/recompilation.usage.m:
compiler/unused_imports.m:
    Conform to the changes above.
2019-03-20 17:04:24 +11:00
Zoltan Somogyi
fc903a0911 Eliminate the double storage of types in the MLDS.
compiler/mlds.m:
    When we record a Mercury type in the MLDS, we used to record with it
    not just its type category (which some aux predicates need), but also
    the name by which it is known to the target language compiler, if the
    type is defined in that foreign language. Unfortunaly, the data structure
    we used to represent the name of the foreign type (and any assertions
    on it) also stored a duplicate copy of the Mercury type in the usual
    case where the Mercury type was *not* defined in the foreign language.
    Having two copies of the same information was dangerous, due to the
    possibility of inconsistency between them. It was also unnecessary work
    for the compiler passes that had to create the duplicate copies.

    Eliminate these problems by always storing *one* copy of the Mercury type.

    Store the Mercury and foreign type information next to each other.

compiler/foreign.m:
    Make the above possible by deleting up the old exported_type type,
    which contained the duplicate copy of the Mercury type in usual case
    of a type that is not defined by foreign code, and replacing it
    with a type that contains information about just a foreign type.

    In the argument lists of the predicates and functions of this module,
    replace arguments that used to be type exported_type with a pair
    of the Mercury type and a maybe of the new type, which is yes(...)
    iff the Mercury type *is* defined in foreign code.

    Give some predicates and functions more meaningful names.

    Make specialized versions of these functions available (specialized
    e.g. to a target language) where these would be useful.

    Delete the auxiliary predicates that aren't needed with the
    new data structure design.

compiler/export.m:
compiler/ml_accurate_gc.m:
compiler/ml_code_util.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_global_data.m:
compiler/ml_simplify_switch.m:
compiler/ml_switch_gen.m:
compiler/ml_unify_gen.m:
compiler/mlds_to_c.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
compiler/rtti_to_mlds.m:
    Conform to the changes above.
2018-05-08 00:17:34 +02:00
Zoltan Somogyi
28e9a29fc2 Carve hlds_inst_mode.m out of hlds_data.m.
compiler/hlds_class.m:
    New module containing the parts of hlds_data.m that deal with
    insts and modes.

compiler/hlds_data.m:
    Delete the moved code.

compiler/hlds.m:
    Include the new module.

compiler/notes/compiler_design.html:
    Document the new module.

compiler/*.m:
    Conform to the changes above.
2018-02-06 06:20:52 +11:00
Zoltan Somogyi
fb97df69ed Make "compute type representations" a separate pass.
The ultimate purpose of this diff is to prepare for future improvements
in type representations, allowing values of some data types to be represented
more compactly than up to now.

The main way this diff does that is by creating a separate pass for deciding
how values of each type should be represented. We have traditionally decided
data representations for each type as its type definition was processed
during the make_hlds pass, but these decisions were always tentative,
and could be overridden later, e.g. when we processed foreign_type or
foreign_enum pragmas for the type. This dispersed decision making algorithm
is hard to understand, and therefore to change.

This diff centralizes decisions about type representations in a separate
pass that does nothing else. It leaves the algorithm distributed among
several files (du_type_layout.m, make_tags.m, and add_foreign_enum.m) for now,
to make reviewing this diff easier, but soon after it is committed I intend
to move all the relevant code to du_type_layout.m, to centralize the decision
code in "space" as well as in time.

For the reason why this pass runs before any of the semantic analysis
passes, instead of after all of them as I originally intended and as we
discussed on m-dev in late october 2017, see the big comment at the start of
du_type_layout.m.

As per another part of that same discussion on m-dev, this diff
makes a start on implementing a new type of item, the type_repn item,
which is intended *only* to be used in compiler-generated interface files,
*not* in source files. It is only a start because we can use these items
only *after* the creation of a separate type representation decision pass,
and this diff is already very big. The code for making the compiler understand
these items will be added later. The code for generating them will be added
later still, once the code for understanding them has been installed on
all our systems.

Since I was going to be working on the affected code anyway, this diff
also carries out two other decisions that came out of that discussion:

- the deletion of the ability to reserve a tag in a type for HAL,
  either via a compiler option or via a pragma, and

- the deletion of the ability to represent a functor using the address
  of a statically allocated object (which we haven't used and won't use,
  because it slows down accesses to *all the other functors* of the type).

compiler/mercury_compile_front_end.m:
    Invoke the new pass for making decisions about type representations
    after the make_hlds pass. (We used to do only the final part of it then.)

    Fix a bad dump stage name.

    Add an extra check for what it means for a module to be error free.

    Make a sub-switch explicit.

compiler/hlds.m:
compiler/make_hlds.m:
    Move the modules that implement the new pass from the make_hlds package
    to the hlds package, to give the compiler's top level access to them.

    Make the same move for the modules that the new pass's modules need.
    Since they are now part of hlds, they cannot reach into make_hlds,
    and I think this is a cleaner solution than forwarding predicates.

    Delete some forwarding predicates that are no longer needed.

compiler/notes/compiler_design.html:
    Document the updated location of the moved modules.

    Add an XXX to note a place where the documentation has not been
    updated in the past.

compiler/du_type_layout.m:
    Add code to implement the new pass.

    Keep the algorithm for deciding type representations as close
    to the previously used algorithm as possible, since this diff
    is already big enough. (The previous algorithm was scattered across
    add_type.m, add_foreign_enum.m, and make_hlds_passes.m.)

    Simplifications and optimizations will come later, after this module
    is merged with make_tags.m and with (at least) the foreign_enum half of
    add_foreign_enum.m.

compiler/make_tags.m:
    Keep the functionality of this module, which does both the first part
    of deciding type representations (tentatively assigning tags to functors,
    an assignment that may be overridden later), and the last part (packing
    multiple adjacent less-than-word-sized enum args into a single word,
    if possible.), but simplify it where possible, and note possibilities
    for further improvements.

compiler/add_foreign_enum.m:
    This module has two halves, one dealing with foreign_enum pragmas
    and one dealing with foreign_export_enum pragmas.

    Change the half that deals with foreign_enum pragmas to just build
    a data structure that du_type_layout.m will need to make its decisions,
    this structure being a map from type_ctors to the foreign enum
    specification applicable to the current target language. Include
    in this structure a component that add_foreign_enum.m itself can use
    to report better error messages for duplicate foreign_enum pragmas;
    this component records, for each type_ctor and language, the context
    of the previous foreign_enum pragma for that combo.

    Change the input for the half that deals with foreign_export_enum pragmas
    to reflect the fact that it is invoked by du_type_layout.m after all
    decisions about type representations have already been made.

compiler/add_special_pred.m:
    Move this module from the make_hlds package to the hlds package,
    since the code that adds special preds for type is now called from
    du_type_layout.m.

    Change the names of predicates to make clear whether they add
    only the declaration of a predicate, only its definition, or both.

    Don't try to pre-guess whether the implementation of a type's
    compare predicate will need an index predicate. Let the code
    that generates calls to the index predicate both declare and define
    the index predicate. This change removes the potential for
    inconsistencies between the two pieces of code.

compiler/add_pred.m:
    Move this module from the make_hlds package to the hlds package,
    since add_special_pred.m needs access to it.

compiler/add_type.m:
    When adding a type definition to the HLDS, don't try to decide
    its representation. Any such decision was tentative anyway, due
    to the possibility of e.g. the later processing of foreign_type
    or foreign_enum pragmas for the type. Likewise, don't try to
    create the special (unify, compare) predicates for the type.
    Leave both tasks to the du_type_layout pass.

    Likewise, don't try to pack the representation of types, or record
    no_tag types in the table of no_tag types, during the post-processing
    pass either; leave both of these to du_type_layout as well.
    Rename the predicate that post_processes type definitions to reflect
    the two tasks left for it to do.

compiler/prog_data.m:
    Do not store width information about the arguments of those data
    constructors in the parse tree. That information is not computed
    until later; until then, it was always filled in with dummy values.
    (But see hlds_data.m below.)

    Use bespoke types to represent the presence or absence of user-specified
    unify and compare predicates.

    Change the representation of data constructors to use a single "maybe"
    type, not two lists, to denote the presence or absence of existentially
    typed arguments.

    Give the HLDS the ability to hold representation information about
    abstract types that in the future we will get from type_repn items
    in the defining modules' interface files.

    Delete the uses_reserved_tag type, since we never use reserved tags
    anymore.

compiler/prog_item.m:
    Add the new type_repn item type, which is not used yet.

    Delete the reserve_tag pragma.

    Fix an earlier mistake in the wording of a context message.

compiler/hlds_data.m:
    Put all the fields of hlds_du_type (the type definition variant dealing
    with discriminated union types) that deal with type representation
    issues in a single "maybe" field that is set to "no" before the
    type representation decision pass has been run.

    Add new type, constructor_repn, that stores the same information as the old
    constructor type (defined in prog_data.m), PLUS the information
    describing how terms with that data constructor are stored.

    Likewise, add a new type ctor_arg_rep, which likewise stores
    the widths of each constructor argument. When we implement
    argument reordering, we would store the offset of the arg as well.

    Since the parse tree representations of constructors and their arguments
    don't store representation information anymore, the cons_table they
    are stored in doesn't either. Make the lookup of representation information
    for a given constructor possible by adding a map to the new "maybe" field
    of hlds_du_type.

    Provide some utility predicates.

    Optimize some existing predicates.

    Rename some types to better reflect their meaning.

compiler/hlds_module.m:
    Provide a slot in the module_info for storing the information
    gathered by make_hlds.m that is needed by the new pass.

compiler/make_hlds_separate_items.m:
    When we see either a foreign_enum or a foreign_export_enum pragma,
    return values of a bespoke type for them (a type defined in
    hlds_module.m), instead of an item_pragma. This makes handling them
    considerably easier.

compiler/make_hlds_passes.m:
    With the changes in this diff, adding a type to the HLDS won't
    decide its representation. Therefore delete the code that used
    to loop over foreign_export_enum pragmas; in the absence of
    the final type representation information, it won't work right.

    Record the information that the du_type_layout pass will need
    in the module_info.

compiler/add_pragma.m:
    Delete the code for passing on foreign_enum and foreign_export_enum
    pragmas to add_foreign_enum.m; they are now passed to add_foreign_enum.m
    by du_type_layout.m.

    Move a utility predicate to make_hlds_error.m, to allow add_foreign_enum.m
    to call it.

compiler/make_hlds_error.m:
    Add the utility predicate moved from add_pragma.m.

    Move the module from the make_hlds to the hlds package.

compiler/module_qual.m:
    Provide a mechanism for recording error messages about e.g. undefined
    types without recording that we found an undefined type. This sounds
    strange, but there is a valid use case.

    When a type definition declares a functor's argument to be of an
    undefined type, that error is usually fatal; we stop the compiler
    from proceeding even to typechecking, since the typechecker will
    probably abort with a map lookup failure. Most other references
    to undefined types are similarly fatal for the same reason. However,
    if e.g. a foreign_export_enum pragma refers to an undefined type,
    that error *won't* be visible to the typechecker, and therefore
    won't crash it. The error will still cause the compiler to exit
    without generating any target language code, but at least it will be
    able to run the typechecker and other semantic analysis passes.

    Without this change, the compiler will report only one error in
    the ee_invalid.m test case; with it, it reports *every* error
    in the test case expected output.

compiler/module_qual.qualify_items.m:
    Use the capability describe above for undefined types in
    foreign_export_enum pragmas.

compiler/module_qual.qual_errors.m:
    Delete a (somewhat incorrect) copy of a predicate in prog_item.m,
    to reduce code duplication.

compiler/prog_type.m:
    Add ways to represent abstract types whose representations are nevertheless
    known (from type_repn items in the defining modules' interface files)
    to be notag or dummy types. This will be needed to fix Mantis bug #441,
    a fix that will probably be one of the first later changes to build
    on this diff.

    Delete a type moved to type_util.m.

compiler/type_util.m:
    Provide extra versions of some predicates, with the difference between
    the old and the new versions being that one requires type representations
    to have been decided already, and the other one does not.

    Move the definition of the ctor_defn type here from prog_type.m,
    since prog_type.m itself does not use it, but type_util.m does.

    Give some predicates more meaningful names.

compiler/parse_type_defn.m:
    Simplify the code for parsing type definitions, to make it easier
    to reuse to parse type_repn items.

    Add a sanity check that requires existential constraints to have
    *some* existential variables to apply to.

    Allow "type_is_representable_in_n_bits" as a synonym for
    "type_is_abstract_enum", since in the future we want to be able to pack
    e.g. multiple int8s, not just multiple enums, into a single word.

    Generate more specific error messages for some classes of malformed input.

compiler/parse_type_repn.m:
    New module to parse type_repn items.

compiler/polymorphism.m:
    Make some predicates that operate on type constructors take
    the type constructors themselves as input arguments, not a whole type
    *using* that type constructor. Put the arguments of those predicates
    in a more standard order.

    Note that some predicates don't belong in this module.

compiler/special_pred.m:
    Make the code that decides whether a special predicate for a type
    constructor can be defined lazily avoid using type representation
    information. (Actually, we now make decisions about lazy vs eager
    definitions after type representation is available, but that was
    not so in an earlier version of this change, and the new code
    is more robust.)

compiler/unify_proc.m:
    When we decide to generate code for a compare predicate that needs
    the type to have an index predicate, don't presume that the index
    predicate has already been declared and defined; instead, declare
    and define it then and there. (Index predicates are *never* called
    from anywhere else.)

    Pack the information needed to define a special predicate
    into a single structure, to simplify the above.

    Since the creation of a clause for a compare predicate may now require
    the declaration and definition of an index predicate, the module_info
    field of the unify_proc_info is now a writeable field.

    Give some predicates and function symbols more meaningful names.

    Note some problems with the existing code.

compiler/add_class.m:
compiler/add_clause.m:
compiler/add_foreign_proc.m:
compiler/add_mode.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pragma_tabling.m:
compiler/add_pragma_type_spec.m:
compiler/add_solver.m:
compiler/check_typeclass.m:
compiler/code_info.m:
compiler/comp_unit_interface.m:
compiler/ctgc.selector.m:
compiler/ctgc.util.m:
compiler/default_func_mode.m:
compiler/det_report.m:
compiler/equiv_type.m:
compiler/equiv_type_hlds.m:
compiler/erl_code_gen.m:
compiler/export.m:
compiler/foreign.m:
compiler/get_dependencies.m:
compiler/goal_expr_to_goal.m:
compiler/hhf.m:
compiler/higher_order.m:
compiler/hlds_code_util.m:
compiler/hlds_out_module.m:
compiler/inst_check.m:
compiler/inst_test.m:
compiler/inst_util.m:
compiler/intermod.m:
compiler/item_util.m:
compiler/make_hlds_warn.m:
compiler/ml_accurate_gc.m:
compiler/ml_simplify_switch.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
compiler/mode_util.m:
compiler/modecheck_goal.m:
compiler/module_qual.collect_mq_info.m:
compiler/modules.m:
compiler/parse_item.m:
compiler/parse_pragma.m:
compiler/parse_tree.m:
compiler/parse_tree_out.m:
compiler/parse_tree_out_pragma.m:
compiler/post_term_analysis.m:
compiler/proc_requests.m:
compiler/prog_item_stats.m:
compiler/qual_info.m:
compiler/recompilation.check.m:
compiler/recompilation.usage.m:
compiler/recompilation.version.m:
compiler/resolve_unify_functor.m:
compiler/rtti.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
compiler/simplify_goal_ite.m:
compiler/stack_opt.m:
compiler/state_var.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/superhomogeneous.m:
compiler/switch_gen.m:
compiler/switch_util.m:
compiler/table_gen.m:
compiler/term_constr_build.m:
compiler/term_norm.m:
compiler/trailing_analysis.m:
compiler/type_constraints.m:
compiler/type_ctor_info.m:
compiler/typecheck.m:
compiler/unify_gen.m:
compiler/untupling.m:
compiler/unused_imports.m:
compiler/write_module_interface_files.m:
compiler/xml_documentation.m:
    Conform to the changes above.

tests/invalid/Mmakefile:
    Disable the reserve_tag test case, as it is not applicable anymore.

tests/invalid/exported_foreign_enum.{m,err_exp}:
tests/invalid/pragma_qual_error.{m,err_exp}:
    Delete reserve_tag pragmas from these test cases, and its effects
    from the expected outputs.

tests/invalid/bad_foreign_type.err_exp:
tests/invalid/bigtest.err_exp:
tests/invalid/foreign_enum_invalid.err_exp:
tests/invalid/type_lhs_var.err_exp:
tests/invalid/uu_type.err_exp:
tests/invalid/where_abstract_enum.err_exp:
tests/invalid/where_direct_arg.err_exp:
    Expect the updated messages for some errors.

tests/valid/Mmake.valid.common:
tests/valid/Mmakefile:
    Disable any reserve_tag test cases, as they are not applicable anymore.
2018-01-31 17:54:40 +11:00
Zoltan Somogyi
7b82c59c40 Remove unneeded module qualifications from error messages.
This should make error messages easier to read by removing clutter.

compiler/error_util.m:
    Split each of the sym_name and sym_name_and_arity error pieces into two;
    one which prints any module qualification present in the given sym_name,
    and one which does not. This forces people who use these pieces
    to think about whether they want the sym_name module qualified
    in the error message or not.

compiler/add_class.m:
compiler/add_clause.m:
compiler/add_foreign_enum.m:
compiler/add_foreign_proc.m:
compiler/add_mode.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pragma.m:
compiler/add_pragma_tabling.m:
compiler/add_pred.m:
compiler/add_type.m:
compiler/check_for_missing_type_defns.m:
compiler/check_promise.m:
compiler/check_raw_comp_unit.m:
compiler/check_typeclass.m:
compiler/det_report.m:
compiler/equiv_type.m:
compiler/format_call.m:
compiler/hlds_error_util.m:
compiler/inst_check.m:
compiler/introduce_parallelism.m:
compiler/make_hlds_error.m:
compiler/make_hlds_passes.m:
compiler/make_tags.m:
compiler/mercury_compile_main.m:
compiler/mode_errors.m:
compiler/modes.m:
compiler/module_qual.qual_errors.m:
compiler/modules.m:
compiler/oisu_check.m:
compiler/parse_inst_mode_defn.m:
compiler/parse_item.m:
compiler/parse_module.m:
compiler/parse_pragma.m:
compiler/parse_type_defn.m:
compiler/polymorphism.m:
compiler/post_term_analysis.m:
compiler/prog_out.m:
compiler/recompilation.check.m:
compiler/resolve_unify_functor.m:
compiler/split_parse_tree_src.m:
compiler/type_constraints.m:
compiler/typecheck_errors.m:
compiler/unused_args.m:
compiler/unused_imports.m:
    Conform to the change above. For sym_name references for which
    the module qualifier is obvious (usually because it *has* to be
    the module being compiled), change the reference to the variant
    that omits that qualifier; otherwise, keep the qualifier.

    In a few places, improve the wording of an error message.

tests/invalid/bad_instance.err_exp:
tests/invalid/bug17.err_exp:
tests/invalid/builtin_int.err_exp:
tests/invalid/foreign_purity_mismatch.err_exp:
tests/invalid/foreign_type_visibility.err_exp:
tests/invalid/fp_dup_bug.err_exp:
tests/invalid/fundeps_vars.err_exp:
tests/invalid/impl_def_literal_syntax.err_exp:
tests/invalid/inline_conflict.err_exp:
tests/invalid/inst_list_dup.err_exp:
tests/invalid/instance_no_type.err_exp:
tests/invalid/invalid_typeclass.err_exp:
tests/invalid/missing_interface_import.err_exp:
tests/invalid/missing_interface_import2.err_exp:
tests/invalid/oisu_check_semantic_errors.err_exp:
tests/invalid/tc_err1.err_exp:
tests/invalid/tc_err2.err_exp:
tests/invalid/transitive_import.err_exp:
tests/invalid/type_with_no_defn.err_exp:
tests/invalid/typeclass_bogus_method.err_exp:
tests/invalid/typeclass_missing_mode_2.err_exp:
tests/invalid/typeclass_test_10.err_exp:
tests/invalid/typeclass_test_3.err_exp:
tests/invalid/typeclass_test_4.err_exp:
tests/invalid/typeclass_test_5.err_exp:
tests/invalid/typeclass_test_9.err_exp:
tests/invalid/types2.err_exp:
tests/invalid/undef_inst.err_exp:
tests/invalid/undef_mode.err_exp:
tests/invalid/undef_mode_and_no_clauses.err_exp:
tests/invalid/undef_type.err_exp:
tests/invalid/undef_type_mod_qual.err_exp:
tests/invalid/uu_type.err_exp:
tests/invalid/where_direct_arg.err_exp:
tests/invalid/where_direct_arg2.err_exp:
tests/invalid/wrong_type_arity.err_exp:
tests/recompilation/add_type_re.err_exp.2:
tests/recompilation/field_r.err_exp.2:
tests/recompilation/remove_type_re.err_exp.2:
tests/warnings/inst_with_no_type.exp:
    Expect the updated versions of error messages.
2017-04-01 20:20:57 +11:00
Zoltan Somogyi
95ff02b1bf Add options to check the ordering of module contents.
One option, --warn-non-contiguous-decls, generates warnings if the
mode declarations of a predicate or function aren't in a contiguous block
immediately following the pred or func declaration. Since this is a rare
kind of "style error", this option is enabled by default.

Two options, --warn-inconsistent-pred-order-clauses and
--warn-inconsistent-pred-order-foreign-procs, warn about inconsistencies
between (a) the order in which predicates (and functions) are declared,
and (b) the order in which they are defined. The two options differ in
their scope. The latter applies to all predicates and functions defined
in the module, while the former applies only to those whose definitions
include Mercury clauses.

Since an exported predicate or function may need nonexported auxiliary
predicates and/or functions, imposing a single order the declarations and
definitions of *all* the predicates and functions in a module is not a good
idea. Instead, both options divide the predicates and functions defined
in a module two groups, the exported and the nonexported, and expect
a consistent order only within each group.

The result is output that looks like this:

    time.m:021: Warning: the order of the declarations and definitions of the
    time.m:021:   exported predicates is inconsistent, as shown by this diff:
    time.m:021:
    time.m:021:   --- declaration order
    time.m:021:   +++ definition order
    time.m:021:   @@ -1,7 +1,7 @@
    time.m:021:    predicate `clock'/3
    time.m:021:   -predicate `time'/3
    time.m:021:    predicate `times'/4
    time.m:021:    function `clk_tck'/0
    time.m:021:   +predicate `time'/3
    time.m:021:    function `difftime'/2
    time.m:021:    predicate `localtime'/4
    time.m:021:    function `localtime'/1

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

compiler/style_checks.m:
    A new module that generates the new warnings if warranted.

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

compiler/mercury_compile_front_end.m:
    Invoke the new module if any of the three new options is set.

compiler/hlds_pred.m:
    Record the item number of every predicate, function, and mode declaration
    in the module being compiled. We need this for information for the
    new warnings.

compiler/hlds_module.m:
    Record the context of the module declaration. We use this context
    for warnings about inconsistent order, since there isn't a better one.

compiler/hlds_clauses.m:
    Add a mechanism to retrieve the item numbers of a set of clauses
    even if they are contiguous.

    Document some old data types.

compiler/error_util.m:
    Add a new phase for style checks.

compiler/accumulator.m:
compiler/add_class.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pragma_tabling.m:
compiler/add_pred.m:
compiler/add_solver.m:
compiler/add_special_pred.m:
compiler/check_typeclass.m:
compiler/clause_to_proc.m:
compiler/from_ground_term_util.m:
compiler/lambda.m:
compiler/make_hlds.m:
compiler/make_hlds_passes.m:
compiler/mercury_compile.m:
compiler/par_loop_control.m:
compiler/polymorphism.m:
compiler/stm_expand.m:
compiler/table_gen.m:
compiler/unify_proc.m:
    Conform the changes to the HLDS above.

compiler/typecheck_errors.m:
    Fix style of error messages.

library/array2d.m:
library/assoc_list.m:
library/benchmarking.m:
library/bit_buffer.write.m:
library/bool.m:
library/builtin.m:
library/construct.m:
library/cord.m:
library/counter.m:
library/float.m:
library/injection.m:
library/lazy.m:
library/lexer.m:
library/ops.m:
library/private_builtin.m:
library/profiling_builtin.m:
library/prolog.m:
library/queue.m:
library/rational.m:
library/require.m:
library/stack.m:
library/std_util.m:
library/store.m:
library/thread.semaphore.m:
library/tree234.m:
library/univ.m:
library/version_store.m:
    Move declarations or definitions around to avoid some of the warnings
    that we can now generate. (There are many more left.)

    Make some minor style improvements in the process.

tests/warnings/inconsistent_pred_order.{m,exp}:
tests/warnings/non_contiguous_decls.{m,exp}:
    New test cases to test the new options. They are both copies of
    tests/benchmarks/queens.m, with intentionally-screwed-up style.

tests/warnings/Mmakefile:
    Enable the new test cases.

tests/warnings/Mercury.options:
    Specify the options being tested for the new test cases.

tests/benchmarks/queens.m:
    Bring the style of this module up to date (before copying it).

tests/invalid/mode_decl_in_wrong_section.err_exp:
    Expect the warnings we now generate.
2016-10-15 17:26:32 +11:00
Zoltan Somogyi
1da267e9f0 Fix a bug in handling instances with --warn-unused-imports.
This fixes Mantis bug #412.

compiler/unused_imports.m:
    Consider that an instance declaration makes a module "used" only if
    it occurs in the module being compiled, not in an imported or ancestor
    module. (Mantis bug 412 was caused by instance declarations in implicitly
    imported modules.)

    Fixing #412 also exposed another bug. When computing the set of modules
    used by predicates, we considered (besides some non-type entities)
    only the types of the predicate's arguments, not the types of non-argument
    variables. In one case in the compiler (mmc_analysis.m), this lead to
    some actually-used modules not being marked as such, which lead to
    false unused-import warnings to be generated for them. Fix this by scanning
    the types of all variables in all of a predicate's procedures, not just
    the arguments.

    Improve the infrastructure for debugging similar problems.

    Note some possibilities for future improvement.

    Change a predicate name to fit the naming scheme.

compiler/analysis.m:
    Add an XXX about a possible improvement.

compiler/hlds_out_module.m:
    Make the output we generate for instance methods more readable.
    As part of this, fix an old bug in the printing of the instance table:
    the first line of the first method of each concrete instance declaration
    was accidentally commented out.

compiler/parse_tree_out.m:
    Export a different utility predicate for hlds_out_module.m. Make its name
    conform to the scheme used by related predicates.

browser/browse.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pred.m:
compiler/add_special_pred.m:
compiler/check_for_missing_type_defns.m:
compiler/check_promise.m:
compiler/exception_analysis.m:
compiler/handle_options.m:
compiler/inst_match.m:
compiler/mercury_to_mercury.m:
compiler/ml_tailcall.m:
compiler/module_qual.m:
compiler/op_mode.m:
compiler/parse_inst_mode_defn.m:
compiler/parse_tree_out_clause.m:
compiler/parse_tree_out_info.m:
compiler/parse_tree_out_inst.m:
compiler/parse_tree_out_pragma.m:
compiler/parse_tree_out_pred_decl.m:
compiler/parse_tree_out_term.m:
compiler/parse_type_defn.m:
compiler/parse_type_name.m:
compiler/parse_util.m:
compiler/parse_vars.m:
compiler/prog_ctgc.m:
compiler/recompilation.usage.m:
compiler/resolve_unify_functor.m:
compiler/term_constr_main.m:
compiler/term_constr_main_types.m:
compiler/write_deps_file.m:
library/bt_array.m:
    Delete unused imports.

compiler/module_qual.qual_errors.m:
    Import a module that the parent module_qual.m doesn't import anymore.

tests/warnings/bug412.{m,exp}:
    The test case for this bug.

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

tests/invalid/import_in_parent.err_exp:
    Update the expected output for this test case. The parent module
    does not use the imported module (bool) at all, so this is what the
    error message says after this diff, though its submodule does use bool.
2016-07-17 10:20:29 +02:00
Zoltan Somogyi
961046dbb0 Avoid using some Mercury keywords.
compiler/prog_data_foreign.m:
compiler/prog_data_pragma.m:
    Avoid using the names of foreign code attributes and pragma components
    as the names of function symbols (and one type) that represent those
    attributes and components. Do this by giving them type-specific prefixes.

    Delete the ref_or_val type, which has been unused since the IL backend
    was deleted.

compiler/*.m
    Conform to the changes above.
2016-05-14 10:24:13 +10:00
Zoltan Somogyi
9d4f1e6ae5 Avoid using some Mercury keywords.
compiler/pred_table.m:
compiler/prog_data.m:
    Avoid using / as a function symbol.

    Rename some function symbols to avoid ambiguity.

compiler/add_class.m:
compiler/add_clause.m:
compiler/add_foreign_enum.m:
compiler/add_foreign_proc.m:
compiler/add_mode.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pragma.m:
compiler/add_pragma_tabling.m:
compiler/add_pred.m:
compiler/add_type.m:
compiler/check_for_missing_type_defns.m:
compiler/check_typeclass.m:
compiler/complexity.m:
compiler/det_report.m:
compiler/equiv_type.m:
compiler/error_util.m:
compiler/format_call.m:
compiler/hlds_error_util.m:
compiler/hlds_module.m:
compiler/hlds_out_pred.m:
compiler/hlds_out_util.m:
compiler/inst_check.m:
compiler/introduce_parallelism.m:
compiler/make_hlds_error.m:
compiler/make_hlds_passes.m:
compiler/make_tags.m:
compiler/mercury_to_mercury.m:
compiler/mode_errors.m:
compiler/modes.m:
compiler/module_qual.qual_errors.m:
compiler/oisu_check.m:
compiler/parse_mutable.m:
compiler/parse_sym_name.m:
compiler/parse_type_defn.m:
compiler/post_term_analysis.m:
compiler/prog_out.m:
compiler/recompilation.check.m:
compiler/recompilation.version.m:
compiler/resolve_unify_functor.m:
compiler/type_constraints.m:
compiler/typecheck_errors.m:
compiler/unused_args.m:
compiler/write_module_interface_files.m:
    Conform to the changes above.

    In a few places, improve the format of error messages.

tests/invalid/cyclic_typeclass.err_exp:
tests/invalid/cyclic_typeclass_2.err_exp:
tests/invalid/cyclic_typeclass_3.err_exp:
tests/warnings/inst_with_no_type.exp:
    Expect the updated error messages.
2016-05-13 11:46:37 +10:00
Zoltan Somogyi
4ebc3ffa04 Carve four modules out of prog_data.m.
The prog_data.m module is imported by most modules of the compiler; by
359 modules out of 488, to be exact. Yet it has many parts that most of
those 359 modules don't need. This diff puts those parts into four new
modules. The number of imports of these modules:

    348 modules import prog_data.m
     84 modules import prog_data_foreign.m
     62 modules import prog_data_pragma.m
     12 modules import prog_data_event.m
      5 modules import prog_data_used_modules.m

compiler/prog_data_event.m:
compiler/prog_data_foreign.m:
compiler/prog_data_pragma.m:
compiler/prog_data_used_modules.m:
    New modules. They contain the parts of the parse tree that deal
    respectively with the specification of events and event sets,
    interfacing to foreign languages, pragmas, and the sets of used
    (i.e. not unused) modules.

compiler/prog_data.m:
    Delete the stuff that is now in the new modules. Put the remaining parts
    of the module into a logical order.

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

compiler/globals.m:
    Move a type here from prog_data.m, since this is where it belongs.

compiler/add_foreign_proc.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pragma.m:
compiler/add_solver.m:
compiler/add_trail_ops.m:
compiler/call_gen.m:
compiler/code_gen.m:
compiler/code_loc_dep.m:
compiler/comp_unit_interface.m:
compiler/compile_target_code.m:
compiler/complexity.m:
compiler/continuation_info.m:
compiler/coverage_profiling.m:
compiler/ctgc.datastruct.m:
compiler/ctgc.livedata.m:
compiler/ctgc.selector.m:
compiler/deep_profiling.m:
compiler/dep_par_conj.m:
compiler/deps_map.m:
compiler/det_analysis.m:
compiler/det_report.m:
compiler/elds_to_erlang.m:
compiler/equiv_type.m:
compiler/erl_call_gen.m:
compiler/exception_analysis.m:
compiler/export.m:
compiler/fact_table.m:
compiler/foreign.m:
compiler/frameopt.m:
compiler/get_dependencies.m:
compiler/goal_form.m:
compiler/goal_util.m:
compiler/granularity.m:
compiler/hlds_goal.m:
compiler/hlds_module.m:
compiler/hlds_out_goal.m:
compiler/hlds_out_module.m:
compiler/hlds_out_pred.m:
compiler/hlds_pred.m:
compiler/inlining.m:
compiler/intermod.m:
compiler/ite_gen.m:
compiler/item_util.m:
compiler/jumpopt.m:
compiler/layout.m:
compiler/layout_out.m:
compiler/live_vars.m:
compiler/livemap.m:
compiler/llds.m:
compiler/llds_out_file.m:
compiler/llds_out_global.m:
compiler/llds_out_instr.m:
compiler/make.dependencies.m:
compiler/make.module_dep_file.m:
compiler/make_hlds.m:
compiler/make_hlds_warn.m:
compiler/mark_tail_calls.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mercury_compile_main.m:
compiler/ml_call_gen.m:
compiler/ml_code_gen.m:
compiler/ml_code_util.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_proc_gen.m:
compiler/ml_tailcall.m:
compiler/ml_unify_gen.m:
compiler/mlds.m:
compiler/mlds_to_c.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
compiler/modecheck_goal.m:
compiler/module_imports.m:
compiler/module_qual.m:
compiler/module_qual.qualify_items.m:
compiler/modules.m:
compiler/opt_debug.m:
compiler/par_conj_gen.m:
compiler/parse_pragma.m:
compiler/parse_tree_out_info.m:
compiler/parse_tree_out_pragma.m:
compiler/pd_cost.m:
compiler/polymorphism.m:
compiler/pragma_c_gen.m:
compiler/proc_gen.m:
compiler/prog_ctgc.m:
compiler/prog_event.m:
compiler/prog_foreign.m:
compiler/prog_item.m:
compiler/prog_out.m:
compiler/prog_util.m:
compiler/purity.m:
compiler/rbmm.points_to_analysis.m:
compiler/rbmm.points_to_graph.m:
compiler/simplify_goal_call.m:
compiler/simplify_goal_scope.m:
compiler/simplify_proc.m:
compiler/smm_common.m:
compiler/stack_layout.m:
compiler/structure_reuse.analysis.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/structure_reuse.direct.detect_garbage.m:
compiler/structure_reuse.domain.m:
compiler/structure_reuse.indirect.m:
compiler/structure_sharing.analysis.m:
compiler/structure_sharing.domain.m:
compiler/table_gen.m:
compiler/tabling_analysis.m:
compiler/term_constr_build.m:
compiler/term_constr_initial.m:
compiler/term_constr_main.m:
compiler/term_constr_main_types.m:
compiler/term_constr_pass2.m:
compiler/term_constr_util.m:
compiler/term_errors.m:
compiler/term_pass1.m:
compiler/term_pass2.m:
compiler/term_traversal.m:
compiler/term_util.m:
compiler/termination.m:
compiler/trace_gen.m:
compiler/trailing_analysis.m:
compiler/type_constraints.m:
compiler/typecheck.m:
compiler/unique_modes.m:
compiler/unused_args.m:
compiler/unused_imports.m:
compiler/use_local_vars.m:
compiler/write_deps_file.m:
    Conform to the changes above.
2016-03-13 18:19:31 +11:00
Zoltan Somogyi
f1df5d2dd1 Give parsing-related modules more meaningful names.
The mapping from the old to the new module names is:

    prog_io ->                  parse_module
    prog_io_dcg ->              parse_dcg_goal
    prog_io_error ->            parse_error
    prog_io_find ->             find_module
    prog_io_goal ->             parse_goal
    prog_io_inst_mode_defn ->   parse_inst_mode_defn
    prog_io_inst_mode_name ->   parse_inst_mode_name
    prog_io_iom ->              parse_types
    prog_io_item ->             parse_item
    prog_io_mutable ->          parse_mutable
    prog_io_pragma ->           parse_pragma
    prog_io_sym_name ->         parse_sym_name
    prog_io_type_defn ->        parse_type_defn
    prog_io_type_name ->        parse_type_name
    prog_io_typeclass ->        parse_class
    prog_io_util ->             parse_util
    prog_io_vars ->             parse_vars
    unparse ->                  parse_tree_to_term
2016-02-09 13:50:37 +11:00
Zoltan Somogyi
a0760327b6 Do stricter checking of mode and determinism declarations.
Specifically, we now do three new checks:

BAD_DETISM: We now generate error messages for predicate declarations
that specify a determinism without also specifying argument modes.

BAD_PREDMODE: We now generate error messages for standalone mode declarations
for predicates whose predicate declaration includes modes for the arguments.

BAD_MODE_SECTION: We now generate error messages for standalone mode
declarations that are not in the same section as the predicate's (or
function's) type declaration.

compiler/hlds_pred.m:
    Add a slot to the pred_sub_info. If the predicate is explicitly defined by
    the user in the current module, this contains the id of the section that
    contains its predicate declaration (for the BAD_MODE_SECTION check)
    and whether that predicate declaration also had modes for the arguments
    (for the BAD_PREDMODE check).

compiler/add_pred.m:
    When adding adding new predicate declarations, perform the BAD_DETISM
    check, and record the info needed for the BAD_PREDMODE and BAD_MODE_SECTION
    checks.

    When adding adding new mode declarations, perform the BAD_PREDMODE
    and BAD_MODE_SECTION checks.

compiler/add_class.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pragma_tabling.m:
compiler/add_pragma_type_spec.m:
compiler/add_solver.m:
compiler/add_special_pred.m:
compiler/check_typeclass.m:
compiler/dep_par_conj.m:
compiler/higher_order.m:
compiler/make_hlds_passes.m:
compiler/table_gen.m:
compiler/unused_args.m:
    Conform to the changes above.

mdbcomp/builtin_modules.m:
    Add a utility predicate for use by new code in add_pred.m.

compiler/comp_unit_interface.m:
compiler/goal_util.m:
compiler/prog_rename.m:
compiler/quantification.m:
deep_profiler/program_representation_utils.m:
library/calendar.m:
library/mutvar.m:
library/pretty_printer.m:
library/random.m:
library/set_ctree234.m:
library/solutions.m:
library/stream.string_writer.m:
profiler/globals.m:
tests/accumulator/nonrec.m:
tests/accumulator/out_to_in.m:
tests/declarative_debugging/library_forwarding.m:
tests/dppd/applast_impl.m:
tests/dppd/grammar_impl.m:
tests/dppd/regexp.m:
tests/dppd/transpose_impl.m:
tests/hard_coded/copy_pred.m:
tests/hard_coded/ho_func_default_inst.m:
tests/recompilation/unchanged_pred_nr_2.m.1:
tests/recompilation/unchanged_pred_nr_2.m.2:
tests/valid/det_switch.m:
tests/valid/inlining_bug.m:
    Delete determinism declarations from predicate and function declarations
    that have no argument mode information, since the BAD_DETISM check
    now makes these errors.

tests/valid/two_pragma_c_codes.m:
    Move some mode declarations to the right section, since the
    BAD_MODE_SECTION check now generates an error for the old code.

tests/invalid/typeclass_bad_method_mode.{m,err_exp}:
    New test case to test for the BAD_PREDMODE check.

tests/invalid/mode_decl_in_wrong_section.{m,err_exp}:
    New test case to test for the BAD_MODE_SECTION check.

tests/invalid/bad_detism.err_exp:
    Add an expected output for this old, but never enabled test case,
    which tests for new check BAD_DETISM.

tests/invalid/Mmakefile:
    Enable the new test cases.

tests/invalid/typeclass_dup_method_mode.m:
    This test case used to have two bugs. One is now by itself in the new
    typeclass_bad_method_mode.m test case, so modify it to contain only
    the other (indistinguishable modes).

tests/invalid/func_errors.err_exp:
tests/invalid/tc_err1.err_exp:
tests/invalid/undef_lambda_mode.err_exp:
tests/invalid/undef_type_mode_qual.err_exp:
    Expect an extra error message from the BAD_DETISM check.
2016-01-13 02:03:16 +11:00
Zoltan Somogyi
5da837cc30 Carve error_msg_inst.m out of mode_errors.m.
compiler/error_msg_inst.m:
compiler/mode_errors.m:
    As above.

    Generalize the code now in error_msg_inst.m to allow it to be also used
    from add_mutable_aux_preds.m.

compiler/add_mutable_aux_preds.m:
    Use the facilities of error_msg_inst.m.

compiler/hlds.m:
compiler/notes/compiler_design.html:
    Add the new module.

compiler/hlds_out_mode.m:
compiler/parse_tree_out_inst.m:
    Add comments about obsolescence.
2015-11-30 03:36:32 +11:00
Zoltan Somogyi
b1a1d51881 Don't print "No clauses for p/n" if p/n has a clause with an error.
compiler/prog_item.m:
    Allow the representation of a clause whose body couldn't be parsed
    due to one or more syntax errors.

compiler/hlds_clauses.m:
    Change the clauses_info type to allow us to record that one or more
    clauses were not added to it because their bodies had syntax errors.

compiler/prog_io_item.m:
compiler/prog_io_dcg.m:
    Parse the head of a clause even if the body has errors. If we can
    parse the clause head, and can thus identify the predicate or function
    it is for, then record the clause, even if we can't parse the body goal.
    (If both the head and body have syntax errors, previously we found
    and printed only the errors from the body; we now find and print both.)

    Harmonize the treatment of varsets casts in the predicates that parse
    DCG and non-DCG clauses.

compiler/prog_io_goal.m:
    Include the word "Error" in error messages that didn't have them.

compiler/add_clause.m:
    When we add a clause to the clauses_info, if that clause has a
    syntax error in the body, then record that fact.

    If there are several things wrong with a clause, print error messages
    for all of them, not just the first one we find.

    Reorder the arguments of a predicate to put all the state vars last.

compiler/typecheck.m:
    If a predicate has no valid clauses, but its clauses_info records that
    it did have clauses with syntax errors, then do not generate an error
    message saying "Error: no clauses for predicate p/n", since that would
    be incorrect and therefore misleading. However, DO record the presence
    of the error INDEPENDENT of the error message, so that we don't try
    to continue processing a procedure body that isn't actually there.

compiler/add_class.m:
compiler/add_foreign_proc.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pragma_tabling.m:
compiler/add_pragma_type_spec.m:
compiler/add_pred.m:
compiler/check_typeclass.m:
compiler/clause_to_proc.m:
compiler/get_dependencies.m:
compiler/higher_order.m:
compiler/hlds_out_pred.m:
compiler/hlds_pred.m:
compiler/make_hlds_passes.m:
compiler/parse_tree_out_clause.m:
compiler/polymorphism.m:
compiler/prog_item_stats.m:
compiler/unify_proc.m:
    Conform to the changes above.

compiler/prog_io_sym_name.m:
    Fix an unrelated problem I came across.

tests/invalid/malformed_ite.err_exp:
tests/invalid/record_syntax_errors.err_exp:
tests/invalid/some.err_exp:
tests/invalid/trace_goal_env.err_exp:
    Don't expect misleading "Error: no clauses for predicate p/n" messages.

tests/invalid/try_bad_params.err_exp:
    Don't expect misleading "Error: no clauses for predicate p/n" messages.
    Do expect other error messages with their updated wording.
2015-11-28 07:46:33 +11:00
Zoltan Somogyi
4536d4271a Further improve error messages for bad insts in mutables.
compiler/add_mutable_aux_preds.m:
    Special case the error message for the insts "dead" and "mostly_dead",
    as requested by Julien.

    Make the wording of the error messages for different non-allowed insts
    more consistent.

tests/invalid/bad_mutable.err_exp:
tests/invalid/user_mutable.err_exp:
    Expect the updated error messages.
2015-11-16 22:41:49 +11:00