mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-16 18:03:36 +00:00
compiler/prog_item.m:
Predicate declarations have a slot for describing the arguments
of the predicate (or function). The type of this slot allowed
the representation of an argument list in which some arguments
contained only a type, but others contained both a type and a mode.
Change this to a representation that enforces the invariant that
- either all arguments contain only types
- or all arguments contain both types and modes.
Add a third alternative to this type, which describes predicate
declarations that contain NO visible arguments. The correct handling
of this kind of predicate is far from trivial, due to the possible
presence of with_type and with_inst annotations; adding this alternative
requires det code dealing with argument lists to include a switch arm
dealing with this situation specifically.
Move this types here from prog_data.m, since it is used only during
the initial construction of the HLDS. Likewise, move a utility operation
on this type here from prog_util.m.
Add some other utility operations on this type. One of them,
get_declared_types_and_maybe_modes, factors out what used to be
repeated code in other modules. It contains a fix for what seem to be some
not-tested-for bugs in the old code's handling of arity-zero predicates.
This fix is commented out due to a limitation in the syntax rules
of the language. Document this issue.
compiler/parse_item.m:
compiler/parse_type_name.m:
Enforce the invariant when constructing item_pred_decl_infos.
Add indentation to an error message (which the test suite does not test).
compiler/add_pred.m:
Update the logic of when an item_pred_decl_info represents a predmode
declaration, and thus requires adding a mode to the HLDS as well.
compiler/recompilation.version.m:
Update the logic of when an item_pred_decl_info represents a predmode
declaration, and thus requires checking whether the mode information
has changed since the last version.
compiler/equiv_type.m:
Update and simplify the code that checks with_type and with_inst
annotations for consistency.
Update the wording of an error message. Stop module qualifying
the predicate name involved in the error, since it is implicit
in the context of the error message, and therefore hurts more
as clutter than it helps.
Fix a misleading predicate name.
compiler/prog_mode.m:
Change the interface of a predicate to generate an error message
unconditionally, not conditionally.
Shorten some predicate names.
compiler/prog_data.m:
compiler/prog_util.m:
Delete the stuff moved to prog_item.m.
compiler/parse_tree_out_pred_decl.m:
Fix a quoting issue that are arises if the fix for the handling of
arity-zero predicates is *not* commented out.
compiler/add_class.m:
compiler/add_pragma_tabling.m:
compiler/add_solver.m:
compiler/canonicalize_interface.m:
compiler/handle_options.m:
compiler/intermod.m:
compiler/make_hlds_passes.m:
compiler/module_qual.qualify_items.m:
compiler/parse_tree_out.m:
compiler/prog_mutable.m:
compiler/recompilation.check.m:
compiler/recompilation.usage.m:
Conform to the changes above.
tests/invalid_nodepend/test_with_type.err_exp:
Expect the updated error message from equiv_type.m.
tests/invalid_nodepend/invalid_float_literal.err_exp:
Expect the fix in declaration formatting from parse_tree_out_pred_decl.m.
tests/recompilation/two_module_debug:
Update this debug script to help debug this diff.
tests/recompilation/unchanged_with_type_nr_2.m.2:
Fix an old inadvertent white space change.
221 lines
7.6 KiB
Bash
Executable File
221 lines
7.6 KiB
Bash
Executable File
#!/bin/sh
|
|
# vim: ts=4 sw=4 expandtab ft=sh
|
|
#
|
|
# A version of two_module_test that should be more useful for debugging,
|
|
# because instead of hiding the action behind shell functions, it exposes
|
|
# the details of each step. This allows a Mercury developer to (temporarily)
|
|
# modify this script to observe not just the final result of a call to a shell
|
|
# function, but also its intermediate results, e.g. by copying files
|
|
# suspected to be constructed incorrectly to safe locations before later steps
|
|
# overwrite them. It also allows running some compiler invocations under mdb.
|
|
# When you suspect, or know, that a step is screwing up, this can be extremely
|
|
# helpful. Smart recompilation is NOT idempotent; executing even part of
|
|
# a compiler invocation (until e.g. a compiler abort) can, and often will,
|
|
# change the contents of files in a way that will cause later, seeming
|
|
# identical compiler invocations to take a different execution path.
|
|
# By rerunning the whole test process from the start, recreating all
|
|
# the relevant files from scratch each time, this script can sidestep
|
|
# that problem.
|
|
#
|
|
# This script also has some limitations compared with two_module_test.
|
|
# The main one is that it covers only grades that target C.
|
|
# It also handles the <mmake_test 2 should_fail> block differently
|
|
# than two_module_test.
|
|
|
|
# It is easier to look up the contents of e.g. .used files
|
|
# if they are in the current directory.
|
|
/bin/rm -fr Mercury
|
|
|
|
test_prog="unchanged_with_type_nr"
|
|
expected_mmake_result=should_succeed
|
|
module_1="${test_prog}"
|
|
module_2="${test_prog}_2"
|
|
modules="${module_1} ${module_2}"
|
|
|
|
tested_compiler="/home/zs/ws/ws31/compiler/mercury_compile"
|
|
MERCURY_COMPILER="${tested_compiler}"
|
|
export MERCURY_COMPILER
|
|
|
|
grade_opts="--grade hlc.gc"
|
|
dir_opts="--flags ../TESTS_FLAGS"
|
|
opt_opts="--no-intermodule-optimization"
|
|
smart_opts="--smart-recompilation --find-all-recompilation-reasons"
|
|
std_opts="${grade_opts} ${dir_opts} ${opt_opts} ${smart_opts}"
|
|
|
|
echo "Testing ${test_prog}"
|
|
|
|
echo "block <test_module ${module_1} ${module_2}>"
|
|
rm -f "${module_1}.m"
|
|
cp "${module_1}.m.1" "${module_1}.m"
|
|
chmod -w "${module_1}.m"
|
|
rm -f "${module_2}.m"
|
|
cp "${module_2}.m.1" "${module_2}.m"
|
|
chmod -w "${module_2}.m"
|
|
rm -f "${module_1}.res"
|
|
touch "${module_1}.res"
|
|
sleep 1
|
|
|
|
echo "block <mmake_depend>"
|
|
mmc --generate-dependencies ${std_opts} ${module_1} > ${module_1}.dep_err 2>&1
|
|
|
|
echo "block <mmake_test 1 should_succeed>"
|
|
mmc --make-short-interface ${std_opts} ${module_2}
|
|
mmc --make-interface ${std_opts} ${module_2}
|
|
mmc --make-interface ${std_opts} ${module_1}
|
|
mmc --compile-to-c ${std_opts} ${module_1} > ${module_1}.err 2>&1
|
|
mmc --compile-to-c ${std_opts} ${module_2} > ${module_2}.err 2>&1
|
|
cp -f ${module_2}.int ${module_2}.int.step1
|
|
cp -f ${module_2}.used ${module_2}.used.step1
|
|
mgnuc ${grade_opts} -- -c ${module_1}.c -o ${module_1}.o
|
|
mgnuc ${grade_opts} -- -c ${module_2}.c -o ${module_2}.o
|
|
ml ${grade_opts} -- -o ${module_1} ${module_1}_init.o \
|
|
${module_1}.o ${module_2}.o
|
|
case "$?" in
|
|
0)
|
|
;;
|
|
*)
|
|
echo "exiting due to failure of <mmake_test 1 should_succeed>"
|
|
exit 1
|
|
;;
|
|
esac
|
|
exp_file="${module_1}.exp.1"
|
|
res_file="${module_1}.out"
|
|
./${module_1} > "${res_file}"
|
|
# We assume ${exp_file} exists.
|
|
if diff ${DIFF_OPTS-"-c"} "${exp_file}" "${res_file}" >> "${module_1}.res"
|
|
then
|
|
true
|
|
else
|
|
echo "** Error in mmake_test 1 should_succeed: ${exp_file} and ${res_file} differ."
|
|
cat "${module_1}.res"
|
|
exit 1
|
|
fi
|
|
|
|
echo "block <update_module ${module_2} 2>"
|
|
sleep 1
|
|
rm -f "${module_2}.m"
|
|
cp "${module_2}.m.2" "${module_2}.m"
|
|
chmod -w "${module_2}.m"
|
|
sleep 1
|
|
|
|
case "${expected_mmake_result}" in
|
|
should_succeed)
|
|
echo "block <mmake_test 2 should_succeed>"
|
|
mmc --make-short-interface ${std_opts} ${module_2}
|
|
mmc --make-interface ${std_opts} ${module_2}
|
|
mmc --make-interface ${std_opts} ${module_1}
|
|
cp -f ${module_2}.int ${module_2}.int.step2
|
|
cp -f ${module_2}.used ${module_2}.used.step2
|
|
# mdb mmc --compile-to-c ${std_opts} ${module_1}
|
|
mmc --compile-to-c ${std_opts} ${module_1} \
|
|
> ${module_1}.err 2>&1
|
|
echo --- ${module_1}.err ---
|
|
cat ${module_1}.err
|
|
echo status = $?
|
|
exit 0
|
|
mmc --compile-to-c ${std_opts} ${module_2} \
|
|
> ${module_2}.err 2>&1
|
|
mgnuc ${grade_opts} -- -c ${module_1}.c -o ${module_1}.o
|
|
mgnuc ${grade_opts} -- -c ${module_2}.c -o ${module_2}.o
|
|
ml ${grade_opts} -- -o ${module_1} ${module_1}_init.o \
|
|
${module_1}.o ${module_2}.o
|
|
case "$?" in
|
|
0)
|
|
;;
|
|
*)
|
|
echo "Error: <mmake_test 2 should_succeed> has failed"
|
|
exit 1
|
|
;;
|
|
esac
|
|
exp_file="${module_1}.exp.2"
|
|
res_file="${module_1}.out"
|
|
./${module_1} > "${res_file}"
|
|
# We assume ${exp_file} exists.
|
|
if diff ${DIFF_OPTS-"-c"} "${exp_file}" "${res_file}" \
|
|
>> "${module_1}.res"
|
|
then
|
|
true
|
|
else
|
|
echo "** Error in mmake_test 2 should_succeed: ${exp_file} and ${res_file} differ."
|
|
cat "${module_1}.res"
|
|
exit 1
|
|
fi
|
|
;;
|
|
should_fail)
|
|
echo "block <mmake_test 2 should_fail>"
|
|
> "${module_1}.should_fail"
|
|
( \
|
|
mmc --make-short-interface ${std_opts} ${module_2}; \
|
|
if test "$?" != 0; \
|
|
then \
|
|
echo "failure" >> "${module_1}.should_fail"; \
|
|
fi; \
|
|
mmc --make-interface ${std_opts} ${module_2}; \
|
|
if test "$?" != 0; \
|
|
then \
|
|
echo "failure" >> "${module_1}.should_fail"; \
|
|
fi; \
|
|
mmc --make-interface ${std_opts} ${module_1}; \
|
|
if test "$?" != 0; \
|
|
then \
|
|
echo "failure" >> "${module_1}.should_fail"; \
|
|
fi; \
|
|
mmc --compile-to-c ${std_opts} ${module_1} \
|
|
> ${module_1}.err 2>&1; \
|
|
if test "$?" != 0; \
|
|
then \
|
|
echo "failure" >> "${module_1}.should_fail"; \
|
|
fi; \
|
|
mmc --compile-to-c ${std_opts} ${module_2} \
|
|
> ${module_2}.err 2>&1; \
|
|
if test "$?" != 0; \
|
|
then \
|
|
echo "failure" >> "${module_1}.should_fail"; \
|
|
fi; \
|
|
) > "${module_1}.failing_make_output"
|
|
if test ! -s "${module_1}.should_fail)"
|
|
then
|
|
echo "Error: <mmake_test 2 should_fail> has succeeded"
|
|
exit 1
|
|
fi
|
|
;;
|
|
*)
|
|
echo "** Error: bad expected_mmake_result ${expected_mmake_result}"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
echo "block <check_err_file ${module_1} 2>"
|
|
sed -e '/has CHANGED/d' -e 's/Mercury\/.*\///g' "${module_1}.err" \
|
|
> "${module_1}.err2"
|
|
mv "${module_1}.err2" "${module_1}.err"
|
|
exp_file="${module_1}.err_exp.2"
|
|
res_file="${module_1}.err"
|
|
# We assume ${exp_file} exists.
|
|
if diff ${DIFF_OPTS-"-c"} "${exp_file}" "${res_file}" >> "${module_1}.res"
|
|
then
|
|
true
|
|
else
|
|
echo "** Error in check_err_file ${module_1} 2: ${exp_file} and ${res_file} differ."
|
|
cat "${module_1}.res"
|
|
exit 1
|
|
fi
|
|
|
|
echo "block <check_err_file ${module_2} 2>"
|
|
sed -e '/has CHANGED/d' -e 's/Mercury\/.*\///g' "${module_2}.err" \
|
|
> "${module_2}.err2"
|
|
mv "${module_2}.err2" "${module_2}.err"
|
|
exp_file="${module_2}.err_exp.2"
|
|
res_file="${module_2}.err"
|
|
# We assume ${exp_file} exists.
|
|
if diff ${DIFF_OPTS-"-c"} "${exp_file}" "${res_file}" >> "${module_2}.res"
|
|
then
|
|
true
|
|
else
|
|
echo "** Error in check_err_file ${module_2} 2: ${exp_file} and ${res_file} differ."
|
|
cat "${module_2}.res"
|
|
exit 1
|
|
fi
|
|
|
|
exit 0
|