mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-15 01:13:30 +00:00
configure.ac:
Require the installed compiler to support that option.
STANDARD_MCFLAGS:
Specify that option.
compiler/canonicalize_interface.m:
compiler/comp_unit_interface.m:
compiler/inst_user.m:
compiler/parse_module.m:
compiler/switch_util.m:
compiler/type_ctor_info.m:
deep_profiler/mdprof_dump.m:
library/digraph.m:
slice/mcov.m:
Delete unused equivalence types that were picked up by the option.
272 lines
12 KiB
Mathematica
272 lines
12 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%---------------------------------------------------------------------------%
|
|
% Copyright (C) 2019-2020, 2023, 2026 The Mercury team.
|
|
% This file may only be copied under the terms of the GNU General
|
|
% Public License - see the file COPYING in the Mercury distribution.
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% File: canonicalize_interface.m.
|
|
% Main author: zs.
|
|
%
|
|
% The original job of this module was to put the contents of an interface file
|
|
% into a canonical order. Without this, a semantically-null change such as
|
|
% reordering some declarations in a module's interface would cause
|
|
% that module's interface files to change, which would then require
|
|
% the recompilation of all *other* modules that import those interface files.
|
|
%
|
|
% Since we switched to representing the contents of interface files using
|
|
% file-kind-specific parse_tree_intNs instead of generic parse_tree_ints,
|
|
% in which the different kinds of items are already separated from each other,
|
|
% most of this task is now done by mercury_output_parse_tree_intN in
|
|
% parse_tree_out.m. The one part that remains to be done here is putting
|
|
% predicate and mode declarations into canonical order.
|
|
%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- module parse_tree.canonicalize_interface.
|
|
:- interface.
|
|
|
|
:- import_module parse_tree.prog_item.
|
|
|
|
:- import_module list.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- type pred_or_mode_decl_item
|
|
---> pomd_pred(item_pred_decl_info)
|
|
; pomd_mode(item_mode_decl_info).
|
|
|
|
:- pred order_pred_and_mode_decls(
|
|
list(item_pred_decl_info)::in, list(item_mode_decl_info)::in,
|
|
list(pred_or_mode_decl_item)::out) is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module mdbcomp.
|
|
:- import_module mdbcomp.prim_data.
|
|
:- import_module mdbcomp.sym_name.
|
|
:- import_module parse_tree.prog_data.
|
|
|
|
:- import_module cord.
|
|
:- import_module map.
|
|
:- import_module maybe.
|
|
:- import_module term.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
order_pred_and_mode_decls(PredDecls, ModeDecls, PredOrModeDecls) :-
|
|
some [!PredRelatedMap] (
|
|
map.init(!:PredRelatedMap),
|
|
list.foldl(classify_item_pred_decl, PredDecls, !PredRelatedMap),
|
|
list.foldl(classify_item_mode_decl, ModeDecls, !PredRelatedMap),
|
|
map.foldl_values(append_pred_related, !.PredRelatedMap,
|
|
cord.init, PredOrModeDeclsCord)
|
|
),
|
|
PredOrModeDecls = cord.list(PredOrModeDeclsCord).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- type pred_related_items_map == map(sym_name, pred_related_items).
|
|
|
|
:- type are_arities_pfs_known
|
|
---> some_arities_pfs_are_unknown
|
|
; all_arities_pfs_are_known.
|
|
|
|
:- type arity_pf
|
|
---> arity_pf(int, pred_or_func).
|
|
|
|
:- type pred_related_items
|
|
---> pred_related_items(
|
|
prs_arities_pfs_known :: are_arities_pfs_known,
|
|
|
|
% The next two field contain redundant information;
|
|
% we only use one. Which one that is depends on the
|
|
% value of prs_arities_pfs_known.
|
|
|
|
% If there is a pred_decl and/or mode_decl item for this
|
|
% sym_name for which we don't know either its arity
|
|
% or whether it applies to a predicate or a function
|
|
% (due to their use of with_type and/or with_inst annotations),
|
|
% then we print all the pred and mode declarations
|
|
% for this sym_name in their original order. This field
|
|
% contains them in that order.
|
|
prs_all_items :: cord(pred_or_mode_decl_item),
|
|
|
|
% If we know the arity and the pred_or_func for all the
|
|
% pred_decl and mode_decl items for this sym_name, then
|
|
% we can and do print the pred and mode declarations
|
|
% for each arity/pf combination separately. This field
|
|
% contains all the predicate and mode declarations
|
|
% for which we know the arity and the pred_or_func.
|
|
prs_arity_pf_items :: map(arity_pf, arity_pf_items)
|
|
).
|
|
|
|
:- type arity_pf_items
|
|
---> arity_pf_items(
|
|
apfi_pred_decl_items :: cord(item_pred_decl_info),
|
|
% There should be exactly one item_pred_decl for any
|
|
% sym_name/arity/pred_or_func combination that has any
|
|
% item_mode_decl, but using a cord simplifies the code.
|
|
|
|
apfi_mode_decl_items :: cord(item_mode_decl_info)
|
|
% There may be any number of item_mode_decls for any
|
|
% sym_name/arity/pred_or_func combination that has
|
|
% an item_pred_decl, from zero on up.
|
|
|
|
% We could have a third field here for pragmas related
|
|
% to the predicate, for more "natural-looking" output.
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred classify_item_pred_decl(item_pred_decl_info::in,
|
|
pred_related_items_map::in, pred_related_items_map::out) is det.
|
|
|
|
classify_item_pred_decl(ItemPredDeclInfo, !PredRelatedMap) :-
|
|
ItemPredDeclInfo = item_pred_decl_info(SymName, PorF, Args,
|
|
MaybeWithType, MaybeWithInst, _, _, _, _, _, _, _, _, _),
|
|
( if
|
|
MaybeWithType = no,
|
|
MaybeWithInst = no
|
|
then
|
|
pred_form_arity(Arity) = types_and_maybe_modes_arity(Args),
|
|
ArityPf = arity_pf(Arity, PorF),
|
|
( if map.search(!.PredRelatedMap, SymName, PredRelated0) then
|
|
PredRelated0 =
|
|
pred_related_items(Known, AllItems0, ArityPfMap0),
|
|
cord.snoc(pomd_pred(ItemPredDeclInfo), AllItems0, AllItems),
|
|
( if map.search(ArityPfMap0, ArityPf, ArityPfItems0) then
|
|
ArityPfItems0 = arity_pf_items(PredItems0, ModeItems),
|
|
cord.snoc(ItemPredDeclInfo, PredItems0, PredItems),
|
|
ArityPfItems = arity_pf_items(PredItems, ModeItems),
|
|
map.det_update(ArityPf, ArityPfItems,
|
|
ArityPfMap0, ArityPfMap)
|
|
else
|
|
PredItems = cord.singleton(ItemPredDeclInfo),
|
|
ModeItems = cord.init,
|
|
ArityPfItems = arity_pf_items(PredItems, ModeItems),
|
|
map.det_insert(ArityPf, ArityPfItems,
|
|
ArityPfMap0, ArityPfMap)
|
|
),
|
|
PredRelated = pred_related_items(Known, AllItems, ArityPfMap),
|
|
map.det_update(SymName, PredRelated, !PredRelatedMap)
|
|
else
|
|
Known = all_arities_pfs_are_known,
|
|
AllItems = cord.singleton(pomd_pred(ItemPredDeclInfo)),
|
|
PredItems = cord.singleton(ItemPredDeclInfo),
|
|
ModeItems = cord.init,
|
|
ArityPfItems = arity_pf_items(PredItems, ModeItems),
|
|
ArityPfMap = map.singleton(ArityPf, ArityPfItems),
|
|
PredRelated = pred_related_items(Known, AllItems, ArityPfMap),
|
|
map.det_insert(SymName, PredRelated, !PredRelatedMap)
|
|
)
|
|
else
|
|
Known = some_arities_pfs_are_unknown,
|
|
( if map.search(!.PredRelatedMap, SymName, PredRelated0) then
|
|
PredRelated0 =
|
|
pred_related_items(_Known0, AllItems0, ArityPfMap),
|
|
cord.snoc(pomd_pred(ItemPredDeclInfo), AllItems0, AllItems),
|
|
PredRelated = pred_related_items(Known, AllItems, ArityPfMap),
|
|
map.det_update(SymName, PredRelated, !PredRelatedMap)
|
|
else
|
|
AllItems = cord.singleton(pomd_pred(ItemPredDeclInfo)),
|
|
map.init(ArityPfMap),
|
|
PredRelated = pred_related_items(Known, AllItems, ArityPfMap),
|
|
map.det_insert(SymName, PredRelated, !PredRelatedMap)
|
|
)
|
|
).
|
|
|
|
:- pred classify_item_mode_decl(item_mode_decl_info::in,
|
|
pred_related_items_map::in, pred_related_items_map::out) is det.
|
|
|
|
classify_item_mode_decl(ItemModeDeclInfo, !PredRelatedMap) :-
|
|
ItemModeDeclInfo = item_mode_decl_info(SymName, MaybePorF, Args,
|
|
MaybeWithInst, _, _, _, _),
|
|
( if
|
|
MaybePorF = yes(PorF),
|
|
MaybeWithInst = no
|
|
then
|
|
list.length(Args, Arity),
|
|
ArityPf = arity_pf(Arity, PorF),
|
|
( if map.search(!.PredRelatedMap, SymName, PredRelated0) then
|
|
PredRelated0 =
|
|
pred_related_items(Known, AllItems0, ArityPfMap0),
|
|
cord.snoc(pomd_mode(ItemModeDeclInfo), AllItems0, AllItems),
|
|
( if map.search(ArityPfMap0, ArityPf, ArityPfItems0) then
|
|
ArityPfItems0 = arity_pf_items(PredItems, ModeItems0),
|
|
cord.snoc(ItemModeDeclInfo, ModeItems0, ModeItems),
|
|
ArityPfItems = arity_pf_items(PredItems, ModeItems),
|
|
map.det_update(ArityPf, ArityPfItems,
|
|
ArityPfMap0, ArityPfMap)
|
|
else
|
|
PredItems = cord.init,
|
|
ModeItems = cord.singleton(ItemModeDeclInfo),
|
|
ArityPfItems = arity_pf_items(PredItems, ModeItems),
|
|
map.det_insert(ArityPf, ArityPfItems,
|
|
ArityPfMap0, ArityPfMap)
|
|
),
|
|
PredRelated = pred_related_items(Known, AllItems, ArityPfMap),
|
|
map.det_update(SymName, PredRelated, !PredRelatedMap)
|
|
else
|
|
Known = all_arities_pfs_are_known,
|
|
AllItems = cord.singleton(pomd_mode(ItemModeDeclInfo)),
|
|
PredItems = cord.init,
|
|
ModeItems = cord.singleton(ItemModeDeclInfo),
|
|
ArityPfItems = arity_pf_items(PredItems, ModeItems),
|
|
ArityPfMap = map.singleton(ArityPf, ArityPfItems),
|
|
PredRelated = pred_related_items(Known, AllItems, ArityPfMap),
|
|
map.det_insert(SymName, PredRelated, !PredRelatedMap)
|
|
)
|
|
else
|
|
Known = some_arities_pfs_are_unknown,
|
|
( if map.search(!.PredRelatedMap, SymName, PredRelated0) then
|
|
PredRelated0 =
|
|
pred_related_items(_Known0, AllItems0, ArityPfMap),
|
|
cord.snoc(pomd_mode(ItemModeDeclInfo), AllItems0, AllItems),
|
|
PredRelated = pred_related_items(Known, AllItems, ArityPfMap),
|
|
map.det_update(SymName, PredRelated, !PredRelatedMap)
|
|
else
|
|
AllItems = cord.singleton(pomd_mode(ItemModeDeclInfo)),
|
|
map.init(ArityPfMap),
|
|
PredRelated = pred_related_items(Known, AllItems, ArityPfMap),
|
|
map.det_insert(SymName, PredRelated, !PredRelatedMap)
|
|
)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred append_pred_related(pred_related_items::in,
|
|
cord(pred_or_mode_decl_item)::in, cord(pred_or_mode_decl_item)::out)
|
|
is det.
|
|
|
|
append_pred_related(PredRelated, !PredOrModeDeclsCord) :-
|
|
PredRelated = pred_related_items(Known, AllItems, ArityPfMap),
|
|
(
|
|
Known = all_arities_pfs_are_known,
|
|
map.foldl_values(append_arity_pf, ArityPfMap,
|
|
!PredOrModeDeclsCord)
|
|
;
|
|
Known = some_arities_pfs_are_unknown,
|
|
!:PredOrModeDeclsCord = !.PredOrModeDeclsCord ++ AllItems
|
|
).
|
|
|
|
:- pred append_arity_pf(arity_pf_items::in,
|
|
cord(pred_or_mode_decl_item)::in, cord(pred_or_mode_decl_item)::out)
|
|
is det.
|
|
|
|
append_arity_pf(ArityPfItems, !PredOrModeDeclsCord) :-
|
|
ArityPfItems = arity_pf_items(PredDecls, ModeDecls),
|
|
WrapPred = (func(P) = pomd_pred(P)),
|
|
WrapMode = (func(M) = pomd_mode(M)),
|
|
!:PredOrModeDeclsCord = !.PredOrModeDeclsCord ++
|
|
cord.map(WrapPred, PredDecls) ++
|
|
cord.map(WrapMode, ModeDecls).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
:- end_module parse_tree.canonicalize_interface.
|
|
%---------------------------------------------------------------------------%
|