Commit Graph

61 Commits

Author SHA1 Message Date
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
a32d6a16f4 Add the format_call pragma to the language.
doc/reference_manual.texi:
NEWS:
    Document and announce the new pragma.

compiler/prog_data_pragma.m:
compiler/prog_item.m:
    Provide a representation for the new pragma. The part that ends up
    being referred to from the HLDS goes into prog_data_pragma.m,
    the part that is not needed once the HLDS has been constructed
    goes into prog_item.m.

compiler/hlds_pred.m:
    Add a slot to pred_infos for info from the new pragma.

    Fix a bug in the comment on marker_has_format_call.

compiler/add_pragma.m:
    Add the information in these pragmas to the HLDS.

compiler/check_pragma_format_call.m:
    A new module to check the validity of format_call pragmas.
    These checks test whether the arguments named in such pragmas
    have the expected types and modes, which means that
    the check must be done after both type and mode checking.

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

compiler/hlds_module.m:
    Add a field to the module_info that records the set of pred_ids
    that have format_call pragmas.

compiler/mercury_compile_front_end.m:
    Invoke the check_pragma_format_call pass *provided* that
    the new field in the module_info says it has any pragmas to check.

compiler/parse_pragma.m:
    Add code to parse the new pragma.

compiler/format_call.m:
    Check calls to predicates and functions with the new pragma
    the same way as we check calls to string.format, io.format,
    and stream.string_writer.format.

    This required separating the code that checked calls to such predicates
    from the code that optimized calls to such predicates, since

    - a predicate or function with a format_call pragma that specifies
      more than one argument pair has to have its correctness checked
      for each pair, and

    - a predicate or function with a format_call pragma does not actually
      do any formatting, so that formatting cannot be optimized.

    Fix an old bug, where we included the function result in the function's
    reported arity, which meant that an error message could mention a call
    to a nonexistent function. As part of that fix, the error message
    now specifies whether it is complaining about a call to a predicate
    or a function.

    Change the exported interface of this module a bit
    in order to allow the factoring out of repeated code.

compiler/parse_string_format.m:
    Separate the parsing of format strings from their optimization,
    again because calls to predicates and functions with format_call
    pragmas need to be checked but cannot be optimized.

compiler/polymorphism.m:
    Record the effect on argument numbers of any type_info and/or
    typeclass_info arguments added by this pass.

compiler/convert_parse_tree.m:
compiler/det_analysis.m:
compiler/direct_arg_in_out.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/hlds_out_pred.m:
compiler/item_util.m:
compiler/module_qual.qualify_items.m:
compiler/parse_tree_out_pragma.m:
compiler/prog_item_stats.m:
compiler/recompilation.version.m:
compiler/simplify_proc.m:
    Conform to the changes above.

tests/invalid/bad_format_call.{m,err_exp}:
    A new test case to see whether check_pragma_format_call.m detects
    and reports invalid format_call pragmas as expected.

tests/warnings/format_call_warning.{m,exp}:
tests/warnings/format_call_warning_helper.m:
    A new test case to see whether we generate the expected set of error
    messages for incorrect calls to a predicate with a format_call pragma.

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

tests/invalid/string_format_bad.err_exp:
tests/invalid/string_format_unknown.err_exp:
tests/warnings/disabled_warning.exp:
    Expect the predicate vs function distinction to the printed in
    error messages about bad calls to formatting predicates and functions.
2022-09-24 08:42:36 +10:00
Zoltan Somogyi
752bb66f5b Carve four modules out of term.m.
Most modules that imported the old term.m need only a small subset
of its functionality. After this diff, most modules that used to import
term.m will need to import just one more module, and will import many
fewer predicates and functions in total.

library/term_int.m:
    A new module carved out of term.m containing the predicates
    that recognize terms containing integers, and the functions
    that construct such terms.

    While this job has *some* similarity to the job of the existing
    term_conversion.m module, most modules in the compiler use only one
    of those two modules, so merging them would not be a good idea.

library/term_subst.m:
    A new module carved out of term.m containing code to do
    substitutions and renames of various kinds.

    Rename the occurs predicate as var_occurs_in_subst_term,
    and occurs_list as var_occurs_in_subst_terms, since the latter
    are much more descriptive. Change the argument order to match
    the new names (var, subst, term/terms), as the old one did not
    even have the term/terms and the substitution next to each other,
    even though neither makes sense without the other.

library/term_unify.m:
    A new module carved out of term.m containing code to do unifications.

    Give all the predicates more meaningful names:

    unify_term ->                   unify_terms
    unify_term_list ->              unify_term_lists
    unify_term_dont_bind ->         unify_terms_dont_bind
    unify_term_list_dont_bind ->    unify_term_lists_dont_bind
    list_subsumes ->                first_term_list_subsumes_second

library/term_vars.m:
    A new module carved out of term.m containing code that find variables
    in terms.

    Give all the predicates more meaningful names:

    vars ->                         vars_in_term
    vars_2 ->                       vars_in_term_acc
    vars_list ->                    vars_in_terms
    contains_var ->                 term_contains_var
    contains_var_list ->            terms_contain_var

    Don't move the function version of vars_2 to term_vars.m, effectively
    deleting it, since operations that update an accumulator are awkward
    for functions.

library/term.m:
    Keep the moved predicates and functions in term.m, but

    - change their implementation to simply call the moved copy, and
    - obsolete the original in favor of the moved copy.

    Eventually, after either the next release or the release after the next,
    we should delete the obsoleted predicates and functions.

library/MODULES_DOC:
library/library.m:
    Add the new modules as documented parts of the standard library.

browser/interactive_query.m:
compiler/analysis.file.m:
compiler/det_util.m:
compiler/hlds_out_goal.m:
compiler/hlds_out_pred.m:
compiler/hlds_out_util.m:
compiler/intermod.m:
compiler/make.module_dep_file.m:
compiler/make_hlds_passes.m:
compiler/parse_class.m:
compiler/parse_inst_mode_defn.m:
compiler/parse_item.m:
compiler/parse_mutable.m:
compiler/parse_pragma.m:
compiler/parse_pragma_analysis.m:
compiler/parse_sym_name.m:
compiler/parse_tree_to_term.m:
compiler/parse_type_defn.m:
compiler/parse_util.m:
compiler/prog_ctgc.m:
compiler/prog_util.m:
compiler/recompilation.used_file.m:
compiler/recompilation.version.m:
compiler/superhomogeneous.m:
compiler/switch_detection.m:
compiler/typecheck.m:
library/io.m:
library/term_conversion.m:
library/varset.m:
    Conform to the changes above.
2022-08-21 01:01:21 +10:00
Zoltan Somogyi
1a5ba3fcb2 Forbid empty type_substs in type_spec pragmas.
compiler/prog_data_pragma.m:
    Encode the requirement that a type_subst, which used to be a list
    contain at least one element. This type is used only to represent
    the type substitution in a type_spec pragma, and it a type specialization
    using a type substitution containing no type variables is a no-op.

compiler/parse_pragma.m:
    We already enforced this requirement when reading in type_spec pragmas,
    but the new representation we now construct lets users of that
    representation to depend on it without runtime tests.

compiler/add_pragma_type_spec.m:
    Delete such a runtime test.

    Simplify the related code, mostly by using the new maybe_error5 type
    to avoid constructing return values that wore destined to be ignored.

compiler/maybe_error.m:
    Add the maybe_error5 type to the existing maybe_errorN for N in {1,2,3,4}.

compiler/parse_tree_out_pragma.m:
    Don't put parentheses around type substitution lists that contain
    only one entry, since in that case, we won't have a comma separating
    entries that, if not inside parentheses, would indicate an extra argument
    in the type_spec pragma.

compiler/equiv_type.m:
compiler/hlds_pred.m:
compiler/layout_out.m:
compiler/module_qual.qualify_items.m:
compiler/pred_name.m:
compiler/recompilation.usage.m:
compiler/recompilation.version.m:
    Conform to the changes above.
2022-07-20 23:22:03 +10:00
Zoltan Somogyi
08365979d0 Move pred_name.m to the HLDS package.
This is so that it can become the home of the type currently named
pred_origin in hlds_pred.m, which (after being given new name) will become
a structured representation of predicate names.

The only thing that kept pred_name.m in the parse_tree package was the fact
that parse_pragma.m, which has no access to the hlds package, called it
to create the name of a type-specialized predicate when parsing
type_spec pragmas. The main part of this diff, apart from the trivial
updates to import hlds.pred_name instead parse_tree.pred_name, deals
with this issue.

The problem is how to ensure that the compiler invocations that create
type-specialized predicates (invocations that compile the module containing
the type_spec pragma that calls for this) and the invocations that create
the calls to those predicates (invocations that mostly compile other modules)
agree on the name of the name of the type-specialized predicate.

The old approach was this.

    When reading in (say) mod1.m which contains a type_spec pragma,
    we construct the name of the type-specialized predicate from

    - the name of the module (mod1),
    - the name of the predicate to be specialized, and
    - the type substitution in the pragma.

    We then record this name in the pragma.

    If the compiler invocation generates code, we use this name in the
    predicate definition. If the compiler invocation creates a .int file,
    we record the name in the third argument of the type_spec pragma.
    This third argument is NOT allowed to exist in .m files.

    Other compiler invocations that read in mod1.int when compiling
    another module, e.g. mod2.m, use the specialized name in the third argument
    of the type_spec pragma as the name to use in calls.

In this approach, the single-source-of-truth about the name of the
type-specialized predicate is the name constructed when parsing mod1.m,
which is conveyed to compiler invocations on other modules through
the third argument of the type_spec pragma.

The new approach is this:

    When reading in (say) mod1.m which contains a type_spec pragma,
    we give guaranteed-to-be-unique names to all the anonymous variables
    in the type_spec pragma. We also record in the type_spec pragma
    the name of the module whose (source or interface) file we read
    the pragma from. The name of the predicate to be specialized
    was of course already in the pragma.

    If the compiler invocation generates code, we construct the name
    of the type-specialized version of the predicate when we add the
    all-tvars-are-named type_spec pragma to the HLDS. If the compiler
    invocation creates a .int file, we write out the all-tvars-are-named
    version of the type_spec pragma. The pragma also contains the predicate
    name to be specialized. It does not contain the name of the module,
    but we will write out type_spec pragmas from module_x.m *only* to
    module_x.int, never to any other .int file, so any readers of
    the type_spec pragma from mod1.int will also know the name of the
    module that the pragma came from.

    Other compiler invocations that read in mod1.int when compiling
    another module, e.g. mod2.m, therefore get exactly the same

    - module name,
    - the name of the predicate to be specialized, and
    - the type substitution in the pragma

    as the compiler invocations on mod1.m. The module name are the
    predicate name are never changed by being written out and then
    read back in, and *due to the explicit names given to any formerly
    anonymous variables*, the type substitution is changed by this either.
    This means that the compiler invocations on mod1.m and mod2.m
    give the same parameters to the same function, and therefore they are
    guaranteed to get the same string as the name of the type-specialized
    version of the predicate.

In this approach, the single-source-of-truth about the name of the
type-specialized predicate is the function constructing that name
and its inputs.

compiler/hlds.m:
compiler/parse_tree.m:
compiler/pred_name.m:
    Move pred_name.m from the parse_tree package to the hlds package.

compiler/prog_item.m:
    Change the representation of type_spec pragmas to

    - delete the name of the specialized predicate, and replace it with
    - the name of the module the pragma was read in from.

compiler/parse_pragma.m:
    Delete the code for parsing the third argument of type_spec pragmas.
    Allow them to exist for a short transition period, but ignore them.
    (If we read in files containing them, the result will be a link error
    if the type substitution contains anonymous variables. In that case,
    a rebuild of the program with all modules compiled using the *same
    compiler version* will work.)

    Give guaranteed-to-be-unique names to all anonymous type variable
    in the type substitution part of the type_spec pragma we construct.

compiler/add_pragma_type_spec.m:
    Construct the name of the type-specialized predicate as the type_spec
    pragma is added to the HLDS.

compiler/parse_tree_out_pragma.m:
    Never write out a type_spec par_loop_control with a third argument.

    Delete the var_name_print argument of the predicate that writes out
    type_spec pragmas. Instead, *always* use print_name_only.

compiler/options.m:
    Add a way of testing whether the installed compiler has this change.

compiler/accumulator.m:
compiler/add_pragma_tabling.m:
compiler/add_special_pred.m:
compiler/base_typeclass_info.m:
compiler/check_typeclass.m:
compiler/dep_par_conj.m:
compiler/distance_granularity.m:
compiler/higher_order.m:
compiler/hlds_code_util.m:
compiler/intermod.m:
compiler/lambda.m:
compiler/layout_out.m:
compiler/lco.m:
compiler/loop_inv.m:
compiler/make_hlds_passes.m:
compiler/name_mangle.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/par_loop_control.m:
compiler/parse_tree_out.m:
compiler/pd_info.m:
compiler/prog_rep.m:
compiler/ssdebug.m:
compiler/stm_expand.m:
compiler/structure_reuse.versions.m:
compiler/table_gen.m:
compiler/tupling.m:
compiler/untupling.m:
compiler/unused_args.m:
2022-07-20 21:33:09 +10:00
Zoltan Somogyi
7d11ba1e5c Fix a bug in handling badly qualified sym names.
Type specialization pragmas allow the procedure to be specialized
to be specified either as a sym_name/arity pair, or as a sym_name
followed by a list of argument modes. In both cases, the sym_name
is implicitly qualified with the name of the current module.

The problem that this diff fixes arose when the type_spec pragma
specified the procedure as a sym_name/arity pair, but the sym_name
had a qualification that is inconsistent with the current module.
The code for parsing such pragmas should report this qualification
inconsistency, but the old code did not do that. Instead, it took
the failure of the attempt to parse the sym_name/arity pair as a
*properly qualified* sym_name pair to mean that the procedure specification
must be a sym_name applied to argument modes, and as a consequence,
generated a report that said "In the first argument `:- pragma type_spec'
declaration: error: `1' is not a valid inst", which definitely violates
the law of least astonishment.

The fix is to commit to interpreting a procedure specification
as a sym_name/arity pair as soon as we see that the relevant term
has this structure, and report any problem during the implicit qualification
of the sym_name using an error message appropriate to that commitment.

compiler/parse_util.m:
    Delete parse_implicitly_qualified_name_and_arity, because it inherently
    does not allow the failure of implicitly module qualifying of a sym_name
    to be treated differently from the failure to parse a term as a sym_name
    and arity pair. This deletion thus requires all its callers to handle
    the implicit qualification themselves.

    Rename the parse_unqualified_name_and_arity predicate, which does the
    initial part of the job of the deleted predicate, to just
    parse_sym_name_and_arity, because the sym_name it returns may in fact
    be qualified in the input data; the predicate just doesn't *force* it
    to be qualified.

compiler/parse_pragma.m:
compiler/parse_type_defn.m:
    Replace calls to the deleted predicate with code that explicitly does
    implicit qualification of the symbol name in sym_name/arity pairs.

compiler/parse_sym_name.m:
    When implicitly module qualifying sym_names fails, replace the word
    "definition" in the error message with the sym_name itself, since
    the sym_name does not HAVE to be the name of something being defined.
    In the two test cases affected by this diff, they are in fact a type_spec
    pragma, and an include_module declaration.

    In another pair of cases, change the wording of some error messages
    to match our usual phraseology. Those error messages are apparently
    not tested by any test case.

compiler/parse_inst_mode_defn.m:
compiler/parse_pragma_foreign.m:
compiler/parse_type_repn.m:
compiler/recompilation.used_file.m:
    Conform to the rename above.

tests/invalid/type_spec.{m,err_exp}:
    Extend this existing test case with an incorrectly module-qualified
    procedure name in a type_spec declaration.

tests/invalid_nodepend/bad_include.err_exp:
    Expect the updated wording of the error message about an incorrectly
    module-qualified include declaration.
2022-07-05 14:52:56 +10:00
Zoltan Somogyi
94affaec76 Separate fatal and nonfatal module reading errors, ...
... and bundle sets of error kinds and their associated lists of error_specs
into a single structure.

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

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

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

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

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

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

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

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

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

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

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

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

compiler/deps_map.m:
compiler/generate_dep_d_files.m:
compiler/make.module_dep_file.m:
compiler/mercury_compile_main.m:
compiler/parse_item.m:
compiler/parse_pragma.m:
compiler/parse_type_defn.m:
compiler/read_modules.m:
compiler/recompilation.check.m:
compiler/write_deps_file.m:
compiler/write_module_interface_files.m:
    Conform to the changes above.
2022-04-23 20:56:12 +10:00
Zoltan Somogyi
a096154002 Avoid the possibility of a misleading error message. 2022-02-21 01:35:23 +11:00
Zoltan Somogyi
3231caa4d1 Don't use unqualified("") as dummy during parsing.
compiler/parse_sym_name.m:
    Several operations in this module have two versions:

    - one that returns parsed sym_names as they are, and
    - one that implicitly qualifies those sym_names with a given
      default module name.

    In some cases, the former was implemented by calling the latter,
    passing it a special dummy module name, unqualified(""), which the code
    that actually did the implicit module qualification interpreted to mean
    "don't actually do any implicit qualification". Since we actually do
    want implicit qualification in almost all cases, this may have been
    useful for performance in the 1990s, but the days when such things
    mattered are long past. Therefore this diff reverses things,
    and builds predicates that do implicit quantification either
    on top of predicates that don't, or, if the code is short enough
    (which occurs in parse_util.m), by duplicating their code
    and adding an extra step.

    In some cases, these two kinds of predicates doing the same operation
    took the same arguments in different orders: fix that.

    Make try_to_implicitly_qualify_sym_name stop paying attention
    to unqualified(""), and clarify its remaining code.

    Stop exporting predicates that aren't used outside this module, and
    delete predicates that aren't used at all. (In one case, inlining a call
    to a predicate with a two-line body deleted the last call to it.)

    The special module name unqualified("") was also exported via
    the root_module_name function, which three other parsing modules used;
    all are fixed below. This diff also fixed some of the direct references
    (i.e. not through root_module_name) to unqualified("") in the rest
    of the compiler, the ones I was sure of. The rest are future work.

compiler/parse_module.m:
    The read_first_module_decl predicate used to pass root_module_name
    to read_term_to_iom_result. This was unnecessary, as the module name
    being passed in that call has no effect. The reason for this is that

    - read_first_module_decl processes the result of that call in a
      meaningful fashion only if that result is a marker for a
      ":- module" declaration; and

    - the code that parses ":- module" declarations ignores the default
      module name passed to read_term_to_iom_result.

    The code for every other return value from read_term_to_iom_result either

    - likewise ignores the default module_name (true for source file name
      markers),
    - gets turned into an error message that ignores the returned item or
      marker, or
    - is itself already an error indication.

    Therefore passing the default module name for the file to
    read_term_to_iom_result works just well as passing root_module_name did.

    (That is the longest explanation I have ever written
    for a one-line change.)

compiler/parse_type_repn.m:
    The parsing of type_repn items used to pass root_module_name,
    but since such items are all generated by the compiler, they are
    (or at least should be) fully and correctly module qualified already.
    And if that is the case, then the default module name we pass for
    implicit module qualification does not matter, because it will
    never be used.

compiler/parse_class.m:
    The last parsing module that used to use root_module_name was parse_class.
    It used it when parsing clauses inside instance declarations, to stop
    the implicit module qualification of the predicate or function name
    in the clause head.

    Replace this mechanism by changing the code that expects these clauses to

    - not parse any declarations beyond the top level ":-" function symbol,
      and
    - invoking a modified version of the predicate that parses clauses,
      which now takes an *optional* default module name, telling it that
      there is no default module name.

compiler/parse_item.m:
compiler/parse_dcg_goal.m:
    Modify the predicates that parse all clauses, non-DCG clauses and DCG
    clauses respectively to take an optional default name instead of an
    always-present module name, and perform implicit module qualification
    if the caller does specify a default module name. And since parse_class.m
    expects a clause, return a clause, instead of an item_or_marker.

    Export the relevant predicate from parse_item.m for parse_class.m.

    Simplify some other code.

compiler/parse_util.m:
    Avoid using unqualified("") to stop implicit module qualification.
    Instead, simply call predicates that don't do implicit module qualification
    in the first place.

    Inline the only call to a predicate to allow its deletion.

compiler/parse_pragma.m:
    Inline the only call to a predicate to allow its deletion.

compiler/inst_check.m:
    Delete some references to unqualified("") that I believe
    were never needed.

compiler/parse_inst_mode_defn.m:
compiler/parse_pragma_analysis.m:
compiler/parse_type_defn.m:
    Conform to the changes above.
2022-02-21 00:15:47 +11:00
Zoltan Somogyi
5750c35e64 Move pred-name-constructing code to pred_name.m.
compiler/pred_name.m:
    Support the construction of predicate names for more predicate transforms,
    including those done by higher_order.m and table_gen.m. Neither conformed
    to the naming scheme of the other predicate transformations. For the
    transforms done by higher_order.m, add XXXs noting this. For the transform
    done by table_gen.m, make it generate names that do conform to our pattern.
    We can do this because we only generate the affected predicates (and their
    names) in minimal model own stack grades, which are not operational :-(

    Move code to create names for the predicates implementing typeclass
    methods here.

    Move code to create names for unify, compare and index predicates here.

    Include "sym_name" in the names of the predicates that construct sym_names.

    Rename one of the existing transform_names to avoid ambiguity.

compiler/hlds_pred.m:
    Change the argument order of pred_info_init, partly to put first things
    first, but also to flush out places that construct predicate names.

compiler/add_special_pred.m:
compiler/check_typeclass.m:
compiler/hlds_code_util.m:
    Delete the code moved to pred_name.m.

compiler/accumulator.m:
compiler/add_pragma_type_spec.m:
compiler/add_pred.m:
compiler/base_typeclass_info.m:
compiler/dep_par_conj.m:
compiler/distance_granularity.m:
compiler/higher_order.m:
compiler/lambda.m:
compiler/layout_out.m:
compiler/loop_inv.m:
compiler/name_mangle.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/par_loop_control.m:
compiler/parse_pragma.m:
compiler/pd_info.m:
compiler/prog_rep.m:
compiler/special_pred.m:
compiler/structure_reuse.versions.m:
compiler/table_gen.m:
compiler/tupling.m:
compiler/untupling.m:
compiler/unused_args.m:
    Conform to the changes above.

tests/debugger/mmos_print.exp:
    Update the only minimal_model_own_stack generator predicate name
    outside the compiler.
2022-02-09 11:07:10 +11:00
Zoltan Somogyi
b80ba7095a Move to a unified scheme for pred name transforms.
compiler/pred_name.m:
    Put all the information needed to create a name for a transformed
    predicate or function into one data structure. This centralizes
    knowledge about the format of transformed names here, for the
    compiler components that use pred_name.m to construct new pred names.
    (Making all the *other* compiler components that now construct
    new pred names switch to use pred_names.m is future work.)

    This central data structure, transform_name, contains information
    that used to supplies using separate arguments, such as the initial
    prefix identifying the program transformation that creates the name,
    and an indication whether it is being applied to a predicate or a function.
    In cases where callers used to post-process the sym_name we return
    to add a procedure # as a suffix (to go after the suffix that pred_name.m
    adds to the name :-(), make such shenanigans unnecessary by making
    the proc_id number part of the transform_name.

    Replace the code that constructs lists of things (integers and
    substitutions for type vars) with shorter code, whose functionality
    is underdtandable at a glance. It is slower, but the construction
    of predicate names is rare it for that not to matter.

compiler/accumulator.m:
compiler/dep_par_conj.m:
compiler/distance_granularity.m:
compiler/lambda.m:
compiler/loop_inv.m:
compiler/par_loop_control.m:
compiler/parse_pragma.m:
compiler/pd_info.m:
compiler/structure_reuse.versions.m:
compiler/tupling.m:
compiler/untupling.m:
compiler/unused_args.m:
    Conform to the changes above.

    In pd_info.m, delete unneeded module qualifications on clause heads.

    In distance_granularity.m, delete code that duplicates code in pred_name.m.

    In structure_reuse.versions.m, delete an unhelpful type synonym.

    In several places, improve variable names.
2022-02-08 13:43:58 +11:00
Zoltan Somogyi
2eeeddaae0 Carve pred_name.m out of prog_util.m.
compiler/pred_name.m:
compiler/prog_util.m:
    As above.

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

compiler/accumulator.m:
compiler/dep_par_conj.m:
compiler/distance_granularity.m:
compiler/lambda.m:
compiler/loop_inv.m:
compiler/par_loop_control.m:
compiler/parse_pragma.m:
compiler/parse_tree.m:
compiler/pd_info.m:
compiler/structure_reuse.versions.m:
compiler/tupling.m:
compiler/untupling.m:
compiler/unused_args.m:
    Conform to the change above.
2022-02-08 06:30:34 +11:00
Zoltan Somogyi
7e9d6294bb Stricter checking of tabling pragmas vs grades.
compiler/globals.m:
compiler/table_gen.m:
    Apply stricter checking of whether a tabling pragma conflicts
    with the selected grade. The version in globals.m just says
    whether a tabling pragma is compatible with the selected grade;
    the version in table_gen.m also generates a specific error message
    for each incompatility. (These error messages are not used just yet,
    since the callers of the code in globals.m preempt them.)

compiler/prog_data_pragma.m:
    Separate out tabled eval methods from non-tabled eval methods.
    This enables us to use an eval method type specific to tabling
    (tabled_eval_method) in the several contexts that benefit from one.

compiler/prog_item.m:
    Use the tabled_eval_method type in the representation of tabling
    pragmas.

compiler/llds.m:
    Use the tabled_eval_method type in the tabling_info_struct.

compiler/hlds_pred.m:
    Use the tabled_eval_method type in the proc_table_info_struct.

    Replace functions that operated on eval_methods with functions
    that operate on tabled_eval_methods, when these were the only
    eval_methods (a) they make sense for, or (b) were ever used with.

    Delete a function which would now just duplicate the eval_normal
    vs eval_tabled distinction.

compiler/add_pragma.m:
compiler/add_pragma_tabling.m:
compiler/dead_proc_elim.m:
compiler/det_report.m:
compiler/hlds_out_pred.m:
compiler/item_util.m:
compiler/layout_out.m:
compiler/llds_out_global.m:
compiler/ml_top_gen.m:
compiler/modes.m:
compiler/parse_pragma.m:
compiler/parse_pragma_tabling.m:
compiler/parse_tree_out_pragma.m:
compiler/prog_out.m:
compiler/simplify_goal_call.m:
compiler/tabling_analysis.m:
    Conform to the changes above.

    In several places, fix or improve error messages.
    (Shame that none of them have tests in tests/invalid.)
2021-06-14 14:11:13 +10:00
Zoltan Somogyi
715121485c Don't import unneeded modules in the interface. 2021-05-29 12:55:02 +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
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
Zoltan Somogyi
125d437199 Break up parse_pragma.m.
It was one of the largest modules in the compiler, and it had low cohesion.

This diff contains no algorithmic changes.

compiler/parse_pragma_analysis.m:
compiler/parse_pragma_foreign.m:
compiler/parse_pragma_tabling.m:
    Add these three modules carved out of parse_pragma.m. They handle
    - pragmas that record the results of analyses,
    - pragmas that deal with foreign languages, and
    - tabling pragmas
    respectively.

compiler/parse_tree.m:
    Include the three new modules.

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

compiler/parse_pragma.m:
    Delete the code moved to the new modules. Group related predicates
    together. Rename a few predicates.

    Move the utility predicates that are needed both b parse_pragma.m
    and one of the new modules to parse_util.m

compiler/parse_util.m:
    Add the modules moved from parse_pragma.m.

    Rename some existing predicates to differentiate them from the moves
    predicates.

compiler/parse_item.m:
compiler/parse_mutable.m:
compiler/parse_type_repn.m:
    Conform to the changes above.
2020-08-24 05:39:41 +10:00
Zoltan Somogyi
35a4f3a2dd Fix some error messages for malformed pragmas.
compiler/parse_pragma.m:
    Improve error handling in several respects.

    First, for several kinds of pragmas the only error message we printed
    was some form of "something went wrong". Fix this by generating messages
    that say what part of the pragma has a problem, and what that problem is.

    Second, specify the "where" part more precisely, as a nested context
    (in construct A: in construct B: etc).

    Third, make the text of error messages more consistent, using patterns
    such as "expected abc, got def", and "In the Nth argument of xyz:".

    Fourth, don't stop looking for errors after finding one; keep looking
    for others.

    Also, replace a bunch of if-then-elses with switches, and break up
    a too-large predicate.

compiler/parse_sym_name.m:
    Add parse_sym_name_and_no_args, a version of the existing predicate
    try_parse_sym_name_and_no_args that generates an error message if it
    does not find what it is asked to look for.

    Use the same consistent error message phraseology as above (which we
    also use elsewhere in the compiler).

compiler/parse_item.m:
    Put a newline at the end of context pieces such as "In clause head:",
    so that the "error:" that follows is not buried in the middle of a line.

tests/invalid/bad_pragma.{m,err_exp}:
    Add a news test case for some of the updated error messages.

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

tests/invalid/bad_foreign_enum.m:
    Add another bad foreign_enum to this test.

tests/invalid/bad_detism_category.err_exp:
tests/invalid/bad_foreign_code.err_exp:
tests/invalid/bad_foreign_enum.err_exp:
tests/invalid/bad_foreign_export.err_exp:
tests/invalid/bad_foreign_export_enum.err_exp:
tests/invalid/bad_foreign_import_module.err_exp:
tests/invalid/bad_foreign_proc.err_exp:
tests/invalid/bad_foreign_type.err_exp:
tests/invalid/bad_with_inst.err_exp:
tests/invalid/impl_def_literal_syntax.err_exp:
tests/invalid/invalid_float_literal.err_exp:
tests/invalid/null_char.err_exp:
tests/invalid/predmode.err_exp:
tests/invalid/require_tailrec_invalid.err_exp:
tests/invalid/some.err_exp:
tests/invalid/specified.err_exp:
tests/invalid/vars_in_wrong_places.err_exp:
    Expect the updated error messages.
2020-08-23 10:29:34 +10:00
Zoltan Somogyi
75b88b03c7 Implement memo attribute disable_warning_if_ignored.
NEWS:
doc/reference_manual.texi:
    Document the new attribute, which, if specified on a pragma memo,
    shuts up the warning that the compiler would otherwise generate
    about that pragma if it had to ignore it because the targeted backend
    does not support memoing.

compiler/prog_data_pragma.m:
    Add the new attributes to the set of tabling attributes.

    Add the new attribute to the eval_memo eval_method as an argument
    in order to preserve it until table_gen.m can act on it. (The other
    tabling attributes are implemented way before that, so the attribute
    structure itself doesn't survive to reach table_gen.m.)

compiler/parse_pragma.m:
    Parse the new pragma, and copy it to the eval method.

compiler/table_gen.m:
    Generate a warning about ignoring a pragma memo only if the new attribute
    does not disable that warning.

compiler/options.m:
    Provide a simple way for the configure script to test whether
    the installed compiler contains this diff.

compiler/hlds_out_module.m:
compiler/hlds_out_pred.m:
compiler/hlds_pred.m:
compiler/item_util.m:
compiler/layout_out.m:
compiler/parse_tree_out_pragma.m:
compiler/prog_out.m:
compiler/tabling_analysis.m:
    Conform to the changes above.
2020-08-19 06:14:58 +10:00
Zoltan Somogyi
9cbe5d2caf Put type_repn items for complex types into .int files.
compiler/decide_type_repn.m:
    Previously, this module computed type_repn items to put into .int3 files
    for a subset of the type constructors defined in the current module:
    the direct_dummy, enum and notag types (the *simple* types),
    and the du types whose representation is guaranteed to be
    a word-aligned pointer when targeting C. (We care about pointers
    being word-aligned only when applying the direct arg optimization.
    This optimization is applicable only with the low level data
    representation, which we use only when targeting C.)

    This diff adds code to decide the representations of *all* the
    type constructors defined in the current module.

    This code is based on the existing code in du_type_layout.m,
    which it is intended to eventually replace, but its job is more general,
    because it decides the representation of each type not just for
    one platform (the one we want to generate code), but for all possible
    platforms. This is because we want to put the descriptions of type
    representations into the module's .int file to serve as a single source
    of truth for all modules that use the types defined in this module,
    and the contents of .int files should be platform-independent.
    For our purposes, there are six kinds of platforms, which are
    distinguished along three axes: 64 vs 32 bit machines, spf vs non-spf
    grades, and direct arg optimization enabled vs disabled. That is eight
    combinations, but on 64 bit machines, a float takes up one word whether
    that float is single or double precision, so two combinations aren't valid.

    Some of the change to this module consists of generalizing the existing
    code so that it can decide simple types not just when targeting .int3 files
    but .int files as well. However, the bulk of it is code for deciding
    the representations of non-simple types. The code is not lifted straight
    from du_type_layout.m. There are two main kinds of changes.

    First, I took the opportunity to simplify the algorithms used.
    For example, while du_type_layout.m passes over each function symbol
    in the most general kind of type twice: once to assign it a cons_tag,
    and once to decide how to pack its arguments, the code here does both jobs
    in one pass. Another example is that for historical reasons,
    du_type_layout.m computed the amount of space needed for an argument
    in one place for sub-word-sized arguments, and in another place
    for more-than-word-sized arguments; decide_type_repn.m does it all
    in one place.

    Second, since we compute a representation for each type six times,
    I tried to avoid obvious inefficiencies, but only if the code
    remained simple. In the future, we may want to use an approach
    based on the idea that in the process of computing the first
    representation, we look out for any indication that the representation
    may be different on any of the other five platforms, and if not,
    we just reuse the first representation on the other five platforms as well.
    However, that would be appropriate only *after* we have a simpler
    system that has proven to work in practice.

    There is a third, smaller change: when deciding whether an argument
    is packable, we take into account not just equivalence type
    definitions, but the definitions of notag types as well.
    This takes advantage of the fact that if a notag type is abstract
    exported, its representation is put into the relevant .int3 file
    even though its definition isn't. (This is why du_type_layout.m
    couldn't "see through" notag types: it couldn't depend on knowing
    which types were notags.)

compiler/prog_item.m:
    Change the types we use for type representation information.
    Their previous definitions baked in the assumption that the only
    distinction between platforms that mattered was the 64 vs 32 bit
    distinction, which is not the case.

    Use a more consistent naming scheme for the types we use
    to represent type representation information.

    Include the "dereferenced" types of the arguments in functors'
    representations. (I use "dereferencing" here to mean expanding
    equivalence types and throwing away any notag wrappers.).
    We don't need it when generating C code using the low level
    data representation, but we do need it to create constructors
    when generating e.g. Java code that uses the high level data
    representation.

compiler/parse_type_repn.m:
    Rewrite most of this module due to the changes in prog_item.m.

compiler/parse_tree_out_type_repn.m:
    A new module containing the code for writing out type representations.
    The original code used to be in parse_tree_out.m, but it has been
    mostly rewritten. Partly this is due the changes in prog_item.m,
    but partly it is to provide much more structured output for humans,
    since this makes debugging so much easier.

compiler/parse_tree.m:
    Add the new module to the parse_tree package.

compiler/parse_tree_out.m:
    Delete the code moved to parse_tree_out_type_repn.m.

compiler/parse_tree_out_info.m:
    Provide a mechanism for selecting between output for machines
    (the default) and output for humans.

compiler/hlds_data.m:
compiler/prog_data.m:
    Move the ptag type from hlds_data.m to prog_data.m, to make it
    accessible in prog_item.m.

    Add some documentation in prog_data.m.

compiler/comp_unit_interface.m:
    If the experiment1 option is enabled, invoke decide_type_repn.m
    to decide what type_repn items to put into the .int file we are
    generating. Otherwise, maintain the status quo.

compiler/write_module_interface_files.m:
    Pass the globals to comp_unit_interface.m so it can look up experiment1.

compiler/equiv_type.m:
    Add a predicate for expanding equivalence types for use by
    decide_type_repn.m. This predicate expands just one type,
    but reports any use of circular equivalence types in that type.

    Improve the error message for circular equivalence types by *naming*
    the type constructors involved. To make this possible, pass around
    sets of such type constructors instead of just a boolean saying
    *whether* we have found *some* circular equivalence type.

    Replace bools used as changed/unchanged flag with a bespoke type.

    Standardize some variable names.

compiler/options.m:
    Add the developer-only option --pack-everything, which, if set,
    tells decide_type_repn.m to turn on all the packing options
    that currently work. This is to allow the testing of decide_type_repn.m
    in the eventual intended mode of operation, even if the various
    allow-packing-... options used by du_type_layout.m are set to "no".

compiler/disj_gen.m:
compiler/equiv_type_hlds.m:
compiler/llds_out_data.m:
compiler/lookup_util.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/mlds_to_c_data.m:
compiler/rtti.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
compiler/tag_switch.m:
    Conform to the changes above (mostly the move of ptag to prog_data.m.)

compiler/parse_pragma.m:
    Improve indentation.

tests/valid_make_int/test_repn.m:
tests/valid_make_int/test_repn_sub.m:
    A fairly comprehensive test case of the new functionality.
    test_repn_sub.m defines one ore more simple type constructors
    of each possible kind, and test_repn.m uses them to define types
    that use each possible kind of complex type representation.

tests/valid_make_int/Mmakefile:
tests/valid_make_int/Mercury.options:
    Enable the new test case.
2020-05-28 07:41:44 +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
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
36c2000516 Add the one_or_more and one_or_more_map modules to the library.
library/one_or_more.m:
    We used to have a type named one_or_more in the list module representing
    nonempty lists. It had literally just two predicates and two functions
    defined on it, three of which did conversions to and from lists, which
    limited their usefulness.

    This new module is the new home of the one_or_more type, together with
    a vastly expanded set of utility predicates and functions. Specifically,
    it implements every operation in list.m which makes sense for nonempty
    lists.

library/list.m:
    Delete the code moved over to one_or_more.m.

library/one_or_more_map.m:
    This new module is a near copy of multi_map.m, with the difference being
    that while the multi_map type defined in multi_map.m maps each key
    to a list(V) of values (a list that happens to always be nonempty),
    the one_or_more_map type defined in one_or_more_map.m maps each key
    to a one_or_more(V) of values (which enforces the presence of at least
    one value for each key in the type).

library/map.m:
    Mention the existence of one_or_more_map.m as well as multi_map.m.

library/MODULES_DOC:
library/library.m:
    List the new modules as belonging to the standard library.

NEWS:
    Mention the new modules, and the non-backwards-compatible changes to
    list.m.

compiler/*.m:
    Import the one_or_more module when needed.

tests/hard_coded/test_one_or_more_chunk.{m,exp}:
    Test the one predicate in one_or_more.m that is non-trivially different
    from the corresponding predicate in list.m: the chunk predicate.

tests/hard_coded/Mmakefile:
    Enable the new test case.
2020-02-28 14:29:05 +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
96c94d8ab4 Fix typos. 2019-10-23 10:34:51 +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
9a60a1268f Don't qualify constant names in foreign_enum pragmas.
compiler/parse_tree_out.m:
    As a first step toward disallowing any module qualification on the names
    of constants in foreign_enum pragmas, do not generate any such qualifiers
    when writing foreign_enum pragmas to interface files.

compiler/parse_pragma.m:
    When reading in constant names in foreign_enum pragmas, insist on any
    module qualification to be for the current module. This is to allow
    the checks for this error to be removed from the rest of the compiler,
    which will be needed when the representation of foreign_enums is changed
    to store constant names as just strings, not sym_names.

compiler/options.m:
    Provide a mechanism to test whether the installed compiler has this change.
    The second step of this change will require this first step in order to
    avoid problems with module qualified constant names in .int files.

doc/reference_manual.texi:
    Make the proposed rule against module qualification of constants
    in foreign_enums explicit.

tests/hard_coded/foreign_enum_mod2.m:
    Delete qualifiers on constant names.
2019-10-04 16:33:20 +10:00
Zoltan Somogyi
3d37c6a442 Report wrongly qualified type names in foreign enums when parsing.
This fixes Mantis bug #486.

compiler/parse_pragma.m:
    Read in the name of the type in a foreign enum in whatever qualified
    form it is in the source code, and then try to implicitly qualify it,
    generating a specific error message if that attempt is unsuccessful.

compiler/parse_sym_name.m:
    To make the above possible, expose the code that does the
    implicit qualification. Do so not just in the form now needed
    by parse_pragma.m, but in the other forms used by other predicates
    in parse_sym_name.m as well, since they probably will be needed
    sooner or later. (The lack of such separated-out capability
    is what led to the code that caused bug 486 in the first place.)

    Avoid an unneeded asymmetry by providing mechanisms to parse
    implicitly qualified sym_names without arguments, as well as
    with arguments.

compiler/parse_util.m:
    Give several of the predicates involved in the above more expressive names.

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

compiler/error_util.m:
    Fix a bug that silently deleted the newly-added simplest_specs,
    which this diff uses for the first time. Add determinism requirements
    to avoid similar problems in the future.

compiler/add_foreign_enum.m:
    Note that the old code that diagnosed attempts to define foreign_enums
    for types in other modules should not be needed anymore.

tests/invalid/foreign_enum_import.err_exp:
    Expect the error message now generated by parse_pragma.m,
    which is more specific than the one generated by add_foreign_enum.m
    until now.

tests/valid/bug486.m:
tests/valid/bug486.window.m:
    A regression test for the bug.

tests/valid/Mmakefile:
    Enable the new test.
2019-09-29 13:26:44 +10:00
Zoltan Somogyi
19ef98b66f Check the type definitions in a module for consistency ...
... when generating interface files.

compiler/check_parse_tree_type_defns.m:
    A new module for doing the checking.

compiler/parse_tree.m:
    Add the new module.

compiler/comp_unit_interface.m:
    When computing what should go into a .intN file, use the new module
    to check for inconsistencies in the source code of the module.

    Making the above possible requires retaining some information
    (such as contexts in foreign enum definitions, and the presence
    of definitions, as opposed to declarations, for some types)
    for longer than was needed until now.

    Give some predicates more descriptive names.

    Move the record_foreign_enum_spec predicate near where it is used.

compiler/write_module_interface_files.m:
    If comp_unit_interface.m reports any errors when generating the
    would-be contents of an interface file, do NOT create that
    interface file.

    The errors comp_unit_interface.m and check_parse_tree_type_defns.m
    now generate are the kinds of inconsistencies whose resolution requires
    everything depending on this module to be recompiled anyway,
    so stopping the compilation process *without* producing
    the would-be-erroneous interface file should be a net win
    almost all the time.

compiler/prog_item.m:
    Factor out some commonalities in data structures.

    When converting the generic parse_tree_int we get from reading
    in a .intN file to the parse tree type specific to that N,
    check the definitions we read in for consistency.

    As in comp_unit_interface, making the above possible requires
    retaining some information for longer than was needed until now.

    Never output two or more declarations of the same type_ctor
    in the same section of an interface file, since the code
    *reading* interface files now reports such redundancies
    (but see the change to options.m).

compiler/options.m:
    Disable the printing of error messages for problems found in
    interface files, since the new code in check_parse_tree_type_defns.m
    now finds problems in interface files generated by currently
    installed compilers. Specifically, many contain duplicate
    declarations for Mercury types. One declaration is written
    by the programmer, the other is the type's actual definition
    turned into the redundant declaration by the compiler.

compiler/parse_pragma.m:
    When parsing foreign enum pragmas, implicitly qualify the
    name of the type constructor they are for with the current module name.
    This is semantically sound, since foreign_enum pragmas *must* be
    for a type constructor defined in the same module. It is desirable
    because type_ctors in type definitions are module qualified.
    The code of check_parse_tree_type_defns.m needs to process
    the type definitions and foreign enums for a type_ctor at the
    same time, and doing so would be more needlessly complicated
    if the type ctor keys in the "type_ctor to type definitions"
    and "type_ctor to foreign enums" maps were incompatible due to
    the difference in qualification.

    The type_ctor in a foreign enum definition may still be manually
    module qualified by programmers; it just happens that any qualification
    other than the default is a semantic error.

compiler/module_qual.qual_errors.m:
    When printing error messages about undefined type_ctors in
    foreign enum definitions, do not print this implicitly
    added qualification, since it adds only clutter.

compiler/error_util.m:
    Provide a mechanism for printing type_ctors directly,
    i.e. without converting them to a sym_name/arity pair.

    Put a qual_ prefix in front of top_ctor_of_type, since it
    always prints module qualification. (This is to remind people
    who may use this component about that qualification.)

    Factor out some common code.

compiler/det_analysis.m:
    Conform to the change in error_util.m.

compiler/parse_module.m:
    Fix too-long lines.

compiler/Mercury.options:
    Require some of the modules above to have no dead predicates.

library/erlang_rtti_implementation.m:
library/io.m:
    Delete declarations of types that are unneeded because the types
    also have definitions.

tests/typeclasses/unqualified_method2.m:
    Move an import out of the interface, since we now print the warning
    generated for its improper location.
2019-09-28 02:57:00 +10:00
Zoltan Somogyi
2c68193c08 Mark some redundant library predicates obsolete.
library/set.m:
library/set_bbbtree.m:
library/set_ctree234.m:
library/set_ordlist.m:
library/set_tree234.m:
library/set_unordlist.m:
    Mark empty/1 and non_empty/1 as obsolete with is_empty and is_non_empty
    as suggested replacements, and mark set/1 as obsolete with list_to_set/1
    as suggested replacement.

NEWS:
    Mention the above changes.

configure.ac:
    Require the installed compiler to handle suggested replacements
    in obsolete pragmas.

compiler/analysis.m:
    Avoid calling the newly obsolete predicates.

    Remove a workaround that probably hasn't been needed in a long time.

compiler/error_util.m:
compiler/hlds_args.m:
compiler/intermod.m:
compiler/make.dependencies.m:
compiler/make.module_dep_file.m:
compiler/mercury_compile_main.m:
compiler/module_cmds.m:
compiler/old_type_constraints.m:
compiler/options.m:
compiler/ordering_mode_constraints.m:
compiler/par_conj_gen.m:
compiler/parse_pragma.m:
compiler/prog_ctgc.m:
compiler/rbmm.add_rbmm_goal_infos.m:
compiler/rbmm.live_region_analysis.m:
compiler/structure_reuse.domain.m:
compiler/structure_reuse.versions.m:
compiler/structure_sharing.domain.m:
compiler/switch_detection.m:
compiler/term_constr_fixpoint.m:
compiler/term_constr_util.m:
compiler/tupling.m:
deep_profiler/analysis_utils.m:
deep_profiler/autopar_annotate.m:
deep_profiler/autopar_calc_overlap.m:
deep_profiler/recursion_patterns.m:
deep_profiler/var_use_analysis.m:
    Avoid calling the newly obsolete predicates.
2019-09-13 20:03:01 +10:00
Zoltan Somogyi
8e62f93c4d Use maps for several kinds of items in interface file parse trees.
Using lists to store type-, inst- and mode definitions, foreign enum
definitions and type representation items does nothing to enforce
uniqueness requirements, such as "every inst constructor should have
at most one one non-abstract definition in the interface of a module".
However, one can encode such requirements using maps.

This diff therefore changes the representation of these kinds of items
inside the interface-kind-specific parse trees of interface files to use
these kinds of maps. It does not take advantage of the possilities
offered by this diff; that is for a later change.

compiler/prog_item.m:
    Make the change described above.

    Since after this diff, the info in foreign_enum pragmas will be in a map,
    while the info in other kinds of pragmas will still be in a list, avoid
    the possibility of being able to represent invalid states by giving
    foreign enums their own item kind, separate from that of pragmas.
    Since foreign export enums are handled very similarly to foreign enum
    pragmas in many places, given them their own item kind as well.

    Update the predicates converting generic interface file parse trees
    to interface-kind-specific parse trees, and vice versa, to conform
    to the changes above.

compiler/comp_unit_interface.m:
    Convert lists to maps before putting them into interface-kind-specific
    parse trees where the above change requires it.

compiler/hlds_module.m:
    Delete types that contain almost exactly the same info as the item
    information we now keep for foreign enum and foreign export enum items.

    Include the item status next to foreign enum items, since that is the
    one piece of info the deleted types had that we need.

compiler/parse_pragma.m:
compiler/parse_tree_out.m:
compiler/parse_tree_out_pragma.m:
    Parse and print out foreign enums and foreign export enums as their
    own item kinds, not as kinds of pragmas.

compiler/add_foreign_enum.m:
compiler/canonicalize_interface.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/grab_modules.m:
compiler/intermod.m:
compiler/item_util.m:
compiler/make_hlds.m:
compiler/make_hlds_separate_items.m:
compiler/module_qual.collect_mq_info.m:
compiler/module_qual.qual_errors.m:
compiler/module_qual.qualify_items.m:
compiler/prog_item_stats.m:
compiler/recompilation.check.m:
compiler/recompilation.version.m:
    Conform to the changes above.
2019-09-12 03:52:10 +10:00
Zoltan Somogyi
d113e2f206 Use similar foreign type representations for parse_tree and HLDS.
The parse tree need to represent foreign_type pragmas without knowing which
foreign language it is for, while the HLDS wants to represent all the
foreign_type pragmas for a given type constructor for all foreign languages.
They used to use separate types to do this. This diff eliminates as much
of this difference as possible.

compiler/prog_data.m:
    Generalize the type (type_details_foreign) we use to represent the
    information content of foreign type pragma. Document the use of
    this type both in the parse tree (the generic version) and in the HLDS
    (versions specific to each foreign language).

compiler/hlds_data.m:
    Use instances of the newly generalized type_details_foreign type
    instead of a separate type.

compiler/add_type.m:
compiler/dead_proc_elim.m:
compiler/du_type_layout.m:
compiler/foreign.m:
compiler/intermod.m:
compiler/mlds.m:
compiler/mlds_to_java_type.m:
compiler/parse_pragma.m:
compiler/pragma_c_gen.m:
compiler/prog_foreign.m:
2019-09-10 21:53:09 +10:00
Zoltan Somogyi
0584bc300d Expand obsolete pragmas with an optional "suggested replacements" field.
doc/reference_manual.texi:
NEWS:
    Document the extension.

compiler/prog_item.m:
    Add a field to the representation of obsolete pragmas to hold
    an optional list of suggested possible replacements.

compiler/parse_pragma.m:
    Parse the optional second argument in obsolete pragmas.

    Improve the error messages we generate for several kinds of errors
    we may encounter when parsing pragmas by making them more specific.

compiler/hlds_pred.m:
    Since an obsolete pragma now contains more than one bit of information
    (present vs not present), change their representation from a simple marker
    to a field containing the possible replacements.

    Make a comment about access stats more useful by sorting its contents
    on frequency of access, and putting it before the structure it is about.

compiler/simplify_goal_call.m:
    When generating warnings about calls to obsolete predicates or functions,
    mention the suggested replacements, if there are any.

compiler/add_pragma.m:
    Fill in the new field when adding an obsolete pragma to the HLDS.

compiler/globals.m:
    Add a function for use by new codee in parse_pragma.m.

compiler/canonicalize_interface.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/hlds_out_pred.m:
compiler/intermod.m:
compiler/item_util.m:
compiler/make_hlds_separate_items.m:
compiler/module_qual.qualify_items.m:
compiler/parse_tree_out_pragma.m:
compiler/prog_item_stats.m:
compiler/recompilation.version.m:
compiler/table_gen.m:
    Conform to the changes above.

tests/invalid/bad_foreign_code.err_exp:
tests/invalid/bad_foreign_enum.err_exp:
tests/invalid/bad_foreign_export.err_exp:
    Expect the improved error messages from parse_pragma.m.

tests/warnings/simple_code.{m,exp}:
    Add tests of the new forms of the obsolete pragma.
2019-09-09 13:53:21 +10:00
Zoltan Somogyi
615d2795c8 Take foreign_import_modules out of the item type.
compiler/prog_item.m:
    Even though we express foreign import module declarations syntactically
    as pragmas, semantically, they are much closer to import_module
    declarations. This means that the treatment they require in most places
    in the compiler is similar to the treatment of import_module declarations,
    and quite different from the treatment of other kinds of items.
    Therefore this diff takes foreign_import_module declarations (FIMs
    for short) out of item type. From now on, in parse trees and their
    components, FIMs are stored in data structures of their own, next to
    import_module declarations.

compiler/parse_types.m:
    Provide a mechanism for the parser to return FIMs as an entity kind
    of its own, not as an item.

compiler/comp_unit_interface.m:
    Conform to the changes above, and give a predicate a more specific name.

compiler/module_qual.m:
    Conform to the changes above, and require .int3 files to contain no FIMs.

compiler/canonicalize_interface.m:
compiler/check_raw_comp_unit.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/grab_modules.m:
compiler/hlds_module.m:
compiler/item_util.m:
compiler/make_hlds_passes.m:
compiler/make_hlds_separate_items.m:
compiler/module_imports.m:
compiler/module_qual.collect_mq_info.m:
compiler/module_qual.qualify_items.m:
compiler/parse_module.m:
compiler/parse_pragma.m:
compiler/parse_tree_out.m:
compiler/prog_item_stats.m:
compiler/read_modules.m:
compiler/recompilation.check.m:
compiler/recompilation.version.m:
compiler/split_parse_tree_src.m:
    Conform to the changes above.
2019-08-22 09:31:10 +10:00
Zoltan Somogyi
2da44f8367 Improve programming style. 2019-06-05 12:04:09 +02:00
Zoltan Somogyi
e9430b115a Prep for recording simple type representations in .int3 files.
compiler/decide_type_repn.m:
    New module for computing the set of type representation items
    to put into the interface files of a module. For now, it generates
    this information only for .int3 files.

compiler/parse_tree.m:
compiler/notes/compiler_design.html:
    Add the new module to the parse_tree package.

compiler/comp_unit_interface.m:
    Invoke the new module to add type representation items to .int3 files
    if the experiment option has the right value. Give it the information
    it needs to do its job.

compiler/add_foreign_enum.m:
    Export a predicate for use by decide_type_repn.m. Maybe eventually
    it should be *moved* to decide_type_repn.m.

compiler/hlds_data.m:
compiler/prog_data.m:
    Change the representation of lists of constructors in a type
    from lists, which can be empty, with one_or_more, which cannot.
    This encodes the invariant that a type constructor cannot have
    zero data constructors in the structure of the type.

compiler/prog_item.m:
    Change the representation of lists of constructors in a type
    from lists, which can be empty, with one_or_more, which cannot.
    This encodes the invariant that a type constructor cannot have
    zero data constructors in the structure of the type.

    Include information about assertions in type representation items
    about foreign types.

    Do not record whether a type whose representation item says its values
    are guaranteed to be word aligned is a Mercury type or a foreign type.
    We generate such items only for Mercury types; for foreign types,
    their assertions will contain that information. We need this separation
    because when we generate .int3 files, we don't the backend that we will
    eventually generate code for, and thus do not know whether a given
    foreign type declaration is in effect on that backend or not.

compiler/parse_tree_out.m:
    Fix the printing of type representation items.

compiler/prog_type.m:
    Conform to the changes above, and delete an unused predicate.

compiler/parse_type_repn.m:
    Factor out some common code.

    Fix an old bug about yes/no vs du_repn/no_du_repn.

    Conform to the changes above.

compiler/parse_pragma.m:
    Export a predicate for parse_type_repn.m.

    Note a possible improvement.

    Conform to the changes above.

compiler/add_special_pred.m:
compiler/add_type.m:
compiler/check_typeclass.m:
compiler/det_report.m:
compiler/du_type_layout.m:
compiler/equiv_type.m:
compiler/hlds_out_module.m:
compiler/inst_check.m:
compiler/intermod.m:
compiler/mode_util.m:
compiler/module_qual.qualify_items.m:
compiler/parse_tree_out_pragma.m:
compiler/parse_type_defn.m:
compiler/recompilation.check.m:
compiler/recompilation.usage.m:
compiler/resolve_unify_functor.m:
compiler/special_pred.m:
compiler/switch_util.m:
compiler/table_gen.m:
compiler/term_norm.m:
compiler/type_util.m:
compiler/untupling.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
    Conform to the changes above.

compiler/simplify_goal_ite.m:
    Add a comment.

compiler/canonicalize_interface.m:
compiler/get_dependencies.m:
    Do not abort when seeing type representation items.

compiler/mmakefiles.m:
    Delete a predicate that this diff adds to list.m.

library/list.m:
    Add new predicates to convert from one_or_more to list
    and vice versa.

NEWS:
    Announce the new predicates.

library/bimap.m:
library/map.m:
library/tree234.m:
    Expand a comment.
2019-05-27 11:45:10 +02:00
Zoltan Somogyi
de0a5f13b7 Delete item_nothing.
compiler/prog_item.m:
    Delete item_nothing as an alternative in the item type.

    These items never occur in parse trees, being handled fully at the time
    when the parse tree is constructed. Nevertheless, their presence in
    the item type required code that handles parse trees to worry NOW about
    how they should handle item_nothings in case a possible future change
    let them survive the parse tree construction process.

compiler/parse_types.m:
    Replace item_nothing with iom_handled in the item_or_marker type,
    whose values are used only during the parse tree construction process.

    The replacement is significantly simplified compared with the original,
    containing only the functionality that our current use cases need.

compiler/parse_error.m:
    Remove rme_warn_item_nothing from the read_module_error type.
    It was being added to error sets, but nothing ever tested for its presence.
    Its task as a signifier of the presence of a compilation-stopping error
    now belongs to the severity of the associated error_specs.

compiler/parse_item.m:
    Fix the logic of the code that decides whether the format of the
    version_numbers_map item is recorded in an obsolete format
    (i.e. whether its *own* version is too old). Specificially,
    treat non-numerical "version number" terms as being malformed,
    not as being obsolete.

compiler/canonicalize_interface.m:
compiler/check_raw_comp_unit.m:
compiler/comp_unit_interface.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/item_util.m:
compiler/make_hlds_separate_items.m:
compiler/module_qual.collect_mq_info.m:
compiler/module_qual.qualify_items.m:
compiler/modules.m:
compiler/parse_module.m:
compiler/parse_pragma.m:
compiler/parse_tree_out.m:
compiler/prog_item_stats.m:
compiler/recompilation.check.m:
compiler/recompilation.version.m:
    Conform to the changes above.
2019-04-15 03:30:15 +10:00
Zoltan Somogyi
5cf4d9608f Make foreign_import_module a separate kind of item.
compiler/prog_item.m:
    Change foreign_import_module from being a kind of pragma item, to being
    an item in its own right. Although we use pragma syntax to represent them,
    they are NOT allowed in source files. (Though we do not yet enforce this.)

compiler/add_pragma.m:
compiler/comp_unit_interface.m:
compiler/equiv_type.m:
compiler/get_dependencies.m
compiler/hlds_module.m::
compiler/intermod.m:
compiler/make_hlds_passes.m:
compiler/make_hlds_separate_items.m:
compiler/module_qual.collect_mq_info.m:
compiler/module_qual.qualify_items.m:
compiler/modules.m:
compiler/parse_tree_out.m:
compiler/parse_tree_out_pragma.m:
compiler/prog_item_stats.m:
compiler/recompilation.check.m:
compiler/recompilation.version.m:
compiler/write_module_interface_files.m:
    Conform to the change above by treating the item kind as the pragma kind
    it replaced.

compiler/parse_pragma.m:
    As above, but also improve variable names.

compiler/item_util.m:
    Conform to the change above, but treat the item kind differently from
    the pragma kind it replaced, by not stating that foreign_import_module items
    require the presence of *other* module imports. (They don't.)
2019-01-29 02:58:01 +11:00
Zoltan Somogyi
de658e431c Improve error messages for some pragmas.
compiler/parse_pragma.m:
    As above. Instead of generating a "malform xyz" message, generate
    more specific error messages for each possible problem with xyz,
    for several of the xyzs parsed by this module.

    Put offending terms in quotes *consistently*.

compiler/parse_util.m:
    Add a mechanism for automatically detecting not just the fact that
    *some* features conflict, but also *which ones*, and generating
    a bespoke error message for possible conflict. This is used in
    new code in parse_pragma.m.

tests/invalid/bad_foreign_decl.err_exp:
tests/invalid/bad_foreign_export_enum.err_exp:
tests/invalid/conflicting_fs.err_exp:
    Expect the new, improved error messages.
2018-02-02 05:54:55 +11:00
Zoltan Somogyi
2d6dccc386 Delete a previously-fixed XXX. 2018-02-02 00:51:05 +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
2ac8465659 Make the code adding new types to the HLDS readable.
The motivation for this diff was that I wanted the compiler to generate
a warning if a module declared the same type twice. (During the cleanup
of unify_proc.m I did recently, I found and fixed such a duplicate
declaration.)

compiler/add_type.m:
    The old code of module_add_type_defn was not just long (210+ lines),
    it is also very complex.

    Part of this complexity was sort-of justified. It dealt with adding
    three separate kinds of item_type_defns: abstract type "definitions",
    which are actually declarations; the definitions of Mercury types,
    and the definitions of foreign types. A single type could have more than
    one of these (e.g. declaration and a definition, or a Mercury definition
    and a foreign definition), and it had to be prepared to process these
    in any order.

    Part of this complexity was self-inflicted. The parts of the predicate
    that dealt with the same kind of definition were not always next to each
    other, and for some parts, it wasn't even clear *what* kind of definition
    it was dealing with. It did the same tests on both the old and updated
    versions of definitions, when those definitions were guaranteed to be
    identical; the "updating" predicate was a no-op. And it used completely
    different code for detecting and handling related errors.

    This diff fixes the above problems. It separates the task of adding
    an item_type_defn to the HLDS into three subtasks, done in three separate
    predicates: adding type declarations, adding Mercury definitions, and
    adding foreign definitions. It specializes each predicate to its task,
    and simplifies its decision flow. It also delegates the creation of
    (most) error messages to separate predicates. Together, these changes
    make each of module_add_type_defn_{abstract,mercury,foreign} easily
    understandable.

    Generate a warning if a type is declared twice, i.e. if e.g.
    ":- type x." is followed by another ":- type x.".

    Call module_info_incr_errors to register the presence of errors in just
    one central place. (Before, some of the places that generated error
    messages incremented the error count, and some places didn't.)

    Improve the wording of some error messages.

    Refer to type names in error messages by unqualified sym_names
    in cases where the module qualifier being elided is obvious from
    the name of the module being compiled.

    Add documentation.

    Add descriptions of potential future improvements.

    Add some XXXs at places that I think deserve them.

    Give some predicates and variables better names.

compiler/prog_data.m:
    Change the parse tree representation of type definitions by
    explicitly specifying a type for storing the contents of each kind
    of type definition.

compiler/hlds_data.m:
    Give a predicate a better name.

    Use one of the new types in prog_data.m in the HLDS version of type
    definitions, to minimize differences between the parse tree and HLDS
    versions.

compiler/add_foreign_enum.m:
compiler/add_pragma.m:
compiler/add_special_pred.m:
compiler/check_typeclass.m:
compiler/du_type_layout.m:
compiler/equiv_type.m:
compiler/equiv_type_hlds.m:
compiler/foreign.m:
compiler/get_dependencies.m:
compiler/hlds_code_util.m:
compiler/hlds_out_module.m:
compiler/inst_check.m:
compiler/intermod.m:
compiler/item_util.m:
compiler/make_hlds_passes.m:
compiler/make_hlds_separate_items.m:
compiler/make_tags.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/module_qual.qualify_items.m:
compiler/parse_pragma.m:
compiler/parse_tree_out.m:
compiler/parse_type_defn.m:
compiler/post_term_analysis.m:
compiler/recompilation.check.m:
compiler/recompilation.usage.m:
compiler/recompilation.version.m:
compiler/resolve_unify_functor.m:
compiler/simplify_goal_ite.m:
compiler/special_pred.m:
compiler/switch_util.m:
compiler/term_norm.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
compiler/unify_proc.m:
compiler/unused_imports.m:
compiler/write_module_interface_files.m:
compiler/xml_documentation.m:
    Conform to the changes in prog_data.m.

library/io.m:
library/store.m:
    Delete duplicate type declarations that add_type.m now complains about.

tests/invalid/bad_foreign_type.{m,err_exp}:
    Extend this test to test the new warning.

    Expect the updated versions of some error messages.

tests/invalid/extra_info_prompt.err_exp:
tests/invalid/foreign_type_visibility.err_exp:
tests/invalid/user_eq_dummy.err_exp:
    Expect the updated versions of some error messages.
2017-06-27 18:15:58 +02:00
Julien Fischer
123df4a333 Address review comments from Peter.
library/term.m:
library/term_conversion.m:
library/term_io.m:
     As above.

compiler/analysis_file.m:
compiler/hlds_out_goal.m:
compiler/intermod.m:
compiler/make.module_dep_file.m:
compiler/parse_class.m:
compiler/parse_item.m:
compiler/parse_pragma.m:
compiler/parse_sym_name.m:
compiler/parse_tree_to_term.m:
compiler/parse_type_defn.m:
compiler/parse_util.m:
compiler/prog_ctgc.m:
compiler/prog_util.m:
compiler/recompilation.check.m:
compiler/recompilation.version.m:
     Conform to the above changes.
2017-04-22 17:31:35 +10:00
Julien Fischer
e6e295a3cc Generalise the representation of integers in the term module.
In preparation for supporting uint literals and literals for the fixed size
integer types, generalise the representation of integers in the term module, so
that for every integer literal we record its base, value (as an arbitrary
precision integer), signedness and size (the latter two based on the literal's
suffix or lack thereof).

Have the lexer attach information about the integer base to machine sized ints;
we already did this for the 'big_integer' alternative but not the normal one.
In conjunction with the first change, this fixes a problem where the compiler
was accepting non-decimal integers in like arity specifications.  (The
resulting error messages could be improved, but that's a separate change.)

Support uints in more places; mark other places which require further work with
XXX UINT.

library/term.m:
     Generalise the representation of integer terms so that we can store
     the base, signedness and size of a integer along with its value.
     In the new design the value is always stored as an arbitrary precision
     integer so we no longer require the big_integer/2 alternative; delete it.

     Add some utility predicates that make it easier to work with integer terms.

library/term_conversion.m:
library/term_io.m:
     Conform to the above changes,

     Add missing handling for uints in some spots; add XXX UINT comments
     in others -- these will be addressed later.

library/lexer.m:
     Record the base of word sized integer literals.

library/parser.m:
compiler/analysis_file.m:
compiler/fact_table.m:
compiler/get_dependencies.m:
compiler/hlds_out_goal.m:
compiler/hlds_out_util.m:
compiler/intermod.m:
compiler/make.module_dep_file.m:
compiler/parse_class.m:
compiler/parse_inst_mode_name.m:
compiler/parse_item.m:
compiler/parse_pragma.m:
compiler/parse_sym_name.m:
compiler/parse_tree_out_term.m:
compiler/parse_tree_to_term.m:
compiler/parse_type_defn.m:
compiler/parse_util.m:
compiler/prog_ctgc.m:
compiler/prog_util.m:
compiler/recompilation.check.m:
compiler/recompilation.version.m:
compiler/superhomogeneous.m:
mdbcomp/trace_counts.m:
samples/calculator2.m:
extras/moose/moose.m:
    Conform to the above changes.

tests/hard_coded/impl_def_lex.exp:
tests/hard_coded/impl_def_lex_string.exp:
tests/hard_coded/lexer_bigint.exp*:
tests/hard_coded/lexer_zero.exp*:
tests/hard_coded/parse_number_from_string.exp*:
tests/hard_coded/term_to_unit_test.exp:
    Update these expected outputs.
2017-04-22 11:53:14 +10: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
Julien Fischer
275965bc47 Improve foreign_proc pragma error messages.
compiler/parse_pragma.m:
     Bring the error messages we generate for these into
     line with those of the other foreign language interface
     pragmas.

tests/invalid/bad_foreign_proc.err_exp:
     Conform to the above change.
2017-03-17 14:55:31 +11:00
Zoltan Somogyi
f94dcfba27 Improve error messages for malformed pragmas further.
compiler/parse_pragma.m:
    Instead of reporting that a pragma in a file has the "wrong number of
    arguments", explicitly say what the *right* number of arguments are.

    Fix a missing colon.

    Make a message conform to our 'expected X, got Y' pattern.

    Future proof some code against future changes that may make ContextPieces
    empty.

tests/invalid/bad_foreign_export_enum.err_exp:
tests/invalid/bad_foreign_import_module.err_exp:
tests/invalid/bad_foreign_type.err_exp:
tests/invalid/require_tailrec_invalid.err_exp:
    Update the expected outputs of these tests for the changes above..
2017-03-16 20:43:59 +11:00
Julien Fischer
7cb003f89e Improve error messages for foreign language interface pragmas.
compiler/parse_pragma.m:
	Provide more context for error messages concerning invalid
 	foreign language arguments in pragmas.

	Improve the error message for invalid second arguments of
	`foreign_enum' and `foreign_export_enum' pragmas.

tests/invalid/bad_foreign_enum.err_exp:
tests/invalid/bad_foreign_export_enum.err_exp:
tests/invalid/bad_foreign_export.err_exp:
tests/invalid/bad_foreign_import_module.err_exp:
tests/invalid/bad_foreign_type.err_exp:
    Conform to the above change.
2017-03-16 11:07:09 +11:00
Julien Fischer
440e66633d Improve error messages for foreign_export pragmas.
compiler/parse_pragma.m:
      Provide more context for error messages about misformed
      foreign_export pragmas.

      Address an XXX: generate a specific error message for the
      case where the third argument of a foreign_export pragma
      is the empty string.

tests/invalid/bad_foreign_export.{m,err}:
      Add a case for the new error message.

      Conform to the above changes.
2017-03-16 09:54:09 +11:00
Julien Fischer
6c17047625 Fix an incorrect pragma name.
compiler/parse_pragma.m:
     s/foreign_import_language/foreign_import_module/ in a spot.
2017-03-15 23:14:04 +11:00