mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-15 01:13:30 +00:00
compiler/prog_item.m:
compiler/prog_parse_tree.m:
Split prog_item.m into two modules, with the new module prog_parse_tree.m
containing the definitions of the file-kind-specific parse trees,
and prog_item.m continuing to contain the definitions of the items
that occur in those parse trees. Specialize the top-of-module comment
to the current contents of each module.
compiler/parse_tree.m:
compiler/notes/compiler_design.html:
Include and document the new module.
compiler/*.m:
Conform to the changes above.
962 lines
38 KiB
Mathematica
962 lines
38 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%---------------------------------------------------------------------------%
|
|
% Copyright (C) 2015-2024 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.
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% This module implements the first pass of module_qual.m; it records
|
|
% what entities are available from which modules and with what permissions.
|
|
%
|
|
|
|
:- module parse_tree.module_qual.collect_mq_info.
|
|
:- interface.
|
|
|
|
:- import_module parse_tree.module_qual.mq_info.
|
|
:- import_module parse_tree.prog_parse_tree.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- type int3_role
|
|
---> int3_as_src
|
|
; int3_as_direct_int(read_why_int3).
|
|
|
|
% Pass over the given parse tree collecting all defined module, type,
|
|
% inst, mode and class ids, together with their permissions.
|
|
%
|
|
:- pred collect_mq_info_in_parse_tree_module_src(parse_tree_module_src::in,
|
|
mq_info::in, mq_info::out) is det.
|
|
:- pred collect_mq_info_in_ancestor_int_spec(ancestor_int_spec::in,
|
|
mq_info::in, mq_info::out) is det.
|
|
:- pred collect_mq_info_in_direct_int1_spec(direct_int1_spec::in,
|
|
mq_info::in, mq_info::out) is det.
|
|
:- pred collect_mq_info_in_direct_int3_spec(direct_int3_spec::in,
|
|
mq_info::in, mq_info::out) is det.
|
|
|
|
:- pred collect_mq_info_in_parse_tree_int0(read_why_int0::in,
|
|
parse_tree_int0::in, mq_info::in, mq_info::out) is det.
|
|
:- pred collect_mq_info_in_parse_tree_int3(int3_role::in,
|
|
parse_tree_int3::in, mq_info::in, mq_info::out) is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module mdbcomp.
|
|
:- import_module mdbcomp.sym_name.
|
|
:- import_module parse_tree.item_util.
|
|
:- import_module parse_tree.module_qual.id_set.
|
|
:- import_module parse_tree.parse_sym_name.
|
|
:- import_module parse_tree.prog_data.
|
|
:- import_module parse_tree.prog_item.
|
|
|
|
:- import_module bool.
|
|
:- import_module list.
|
|
:- import_module map.
|
|
:- import_module maybe.
|
|
:- import_module one_or_more.
|
|
:- import_module one_or_more_map.
|
|
:- import_module require.
|
|
:- import_module set_tree234.
|
|
:- import_module term.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
collect_mq_info_in_parse_tree_module_src(ParseTreeModuleSrc, !Info) :-
|
|
IntPermInInt = may_use_in_int(may_be_unqualified),
|
|
ImpPermInInt = may_not_use_in_int,
|
|
PermInImp = may_use_in_imp(may_be_unqualified),
|
|
IntPermissions = module_permissions(IntPermInInt, PermInImp),
|
|
ImpPermissions = module_permissions(ImpPermInInt, PermInImp),
|
|
|
|
ParseTreeModuleSrc = parse_tree_module_src(_ModuleName, _ModuleNameContext,
|
|
InclMap, ImportUseMap,
|
|
_IntFIMSpecMap, _ImpFIMSpecMap, _IntSelfFIMLangs, _ImpSelfFIMLangs,
|
|
|
|
TypeCtorCheckedMap, InstCtorCheckedMap, ModeCtorCheckedMap,
|
|
_TypeSpecs, _InstModeSpecs,
|
|
|
|
IntTypeClasses, IntInstances, _IntPredDecls, _IntModeDecls,
|
|
_IntDeclPragmas, _IntDeclMarkers, IntPromises, _IntBadPreds,
|
|
|
|
ImpTypeClasses, ImpInstances, _ImpPredDecls, _ImpModeDecls,
|
|
_ImpClauses, _ImpForeignProcs, _ImpForeignExportEnums,
|
|
_ImpDeclPragmas, _ImpDeclMarkers, _ImpImplPragmas, _ImpImplMarkers,
|
|
ImpPromises, _ImpInitialises, _ImpFinalises, _ImpMutables),
|
|
|
|
mq_info_get_modules(!.Info, Modules0),
|
|
map.foldl(collect_mq_info_in_included_module_info(IntPermissions),
|
|
InclMap, Modules0, Modules),
|
|
mq_info_set_modules(Modules, !Info),
|
|
|
|
mq_info_get_imported_modules(!.Info, ImportedModules0),
|
|
mq_info_get_as_yet_unused_interface_modules(!.Info, UnusedIntModules0),
|
|
map.foldl2(collect_mq_info_in_src_avail_map_entry,
|
|
ImportUseMap, ImportedModules0, ImportedModules,
|
|
UnusedIntModules0, UnusedIntModules),
|
|
mq_info_set_imported_modules(ImportedModules, !Info),
|
|
mq_info_set_as_yet_unused_interface_modules(UnusedIntModules, !Info),
|
|
|
|
mq_info_get_types(!.Info, Types0),
|
|
type_ctor_checked_map_get_src_defns(TypeCtorCheckedMap,
|
|
IntTypeDefns, ImpTypeDefns, _ImpForeignEnums),
|
|
list.foldl(id_set_insert(IntPermissions),
|
|
list.map(item_type_defn_info_to_mq_id, IntTypeDefns), Types0, Types1),
|
|
list.foldl(id_set_insert(ImpPermissions),
|
|
list.map(item_type_defn_info_to_mq_id, ImpTypeDefns), Types1, Types),
|
|
mq_info_set_types(Types, !Info),
|
|
|
|
mq_info_get_insts(!.Info, Insts0),
|
|
inst_ctor_checked_map_get_src_defns(InstCtorCheckedMap,
|
|
IntInstDefns, ImpInstDefns),
|
|
list.foldl(id_set_insert(IntPermissions),
|
|
list.map(item_inst_defn_info_to_mq_id, IntInstDefns), Insts0, Insts1),
|
|
list.foldl(id_set_insert(ImpPermissions),
|
|
list.map(item_inst_defn_info_to_mq_id, ImpInstDefns), Insts1, Insts),
|
|
mq_info_set_insts(Insts, !Info),
|
|
|
|
mq_info_get_modes(!.Info, Modes0),
|
|
mode_ctor_checked_map_get_src_defns(ModeCtorCheckedMap,
|
|
IntModeDefns, ImpModeDefns),
|
|
list.foldl(id_set_insert(IntPermissions),
|
|
list.map(item_mode_defn_info_to_mq_id, IntModeDefns), Modes0, Modes1),
|
|
list.foldl(id_set_insert(ImpPermissions),
|
|
list.map(item_mode_defn_info_to_mq_id, ImpModeDefns), Modes1, Modes),
|
|
mq_info_set_modes(Modes, !Info),
|
|
|
|
list.foldl(collect_mq_info_in_item_typeclass(IntPermissions),
|
|
IntTypeClasses, !Info),
|
|
list.foldl(collect_mq_info_in_item_typeclass(ImpPermissions),
|
|
ImpTypeClasses, !Info),
|
|
list.foldl(collect_mq_info_in_item_instance, IntInstances, !Info),
|
|
list.foldl(collect_mq_info_in_item_instance, ImpInstances, !Info),
|
|
list.foldl(collect_mq_info_in_item_promise(mq_used_in_interface),
|
|
IntPromises, !Info),
|
|
list.foldl(collect_mq_info_in_item_promise(mq_not_used_in_interface),
|
|
ImpPromises, !Info).
|
|
|
|
:- pred collect_mq_info_in_src_avail_map_entry(
|
|
module_name::in, maybe_implicit_import_and_or_use::in,
|
|
set_tree234(module_name)::in, set_tree234(module_name)::out,
|
|
module_names_contexts::in, module_names_contexts::out) is det.
|
|
|
|
collect_mq_info_in_src_avail_map_entry(ModuleName, MaybeImplicit,
|
|
!ImportedModules, !UnusedIntModules) :-
|
|
set_tree234.insert(ModuleName, !ImportedModules),
|
|
( if
|
|
(
|
|
MaybeImplicit = implicit_avail(_Implicit, MaybeSection),
|
|
MaybeSection = yes(Section)
|
|
;
|
|
MaybeImplicit = explicit_avail(Section)
|
|
),
|
|
require_complete_switch [Section]
|
|
(
|
|
Section = int_import(IntContext)
|
|
;
|
|
Section = int_use(IntContext)
|
|
;
|
|
Section = int_use_imp_import(IntContext, _ImpContext)
|
|
;
|
|
( Section = imp_import(_ImpContext)
|
|
; Section = imp_use(_ImpContext)
|
|
),
|
|
fail
|
|
)
|
|
then
|
|
% Most of the time, ModuleName does not occur in !.UnusedIntModules.
|
|
% We therefore try the insertion first, and only if the insertion
|
|
% fails do we look up and update the existing entry (OldContexts)
|
|
% that caused that failure.
|
|
IntContexts = one_or_more(IntContext, []),
|
|
map.search_insert(ModuleName, IntContexts, MaybeOldContexts,
|
|
!UnusedIntModules),
|
|
(
|
|
MaybeOldContexts = no
|
|
;
|
|
MaybeOldContexts = yes(OldContexts),
|
|
% This is quadratic in the number of import_module/use_module
|
|
% declarations we see for the same module name in the interface,
|
|
% but this should not matter, because even two such declarations
|
|
% would be very rare, and three or more would virtually never occur
|
|
% in real life code (as opposed to in code that was specifically
|
|
% constructed as a stress test).
|
|
NewContexts = OldContexts ++ IntContexts,
|
|
map.det_update(ModuleName, NewContexts, !UnusedIntModules)
|
|
)
|
|
else
|
|
% Either there is no explicit import or use of ModuleName at all,
|
|
% or there is such an import or use, but only in the implementation
|
|
% section.
|
|
true
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
collect_mq_info_in_ancestor_int_spec(AncestorIntSpec, !Info) :-
|
|
AncestorIntSpec = ancestor_int0(ParseTreeInt0, ReadWhy0),
|
|
collect_mq_info_in_parse_tree_int0(ReadWhy0, ParseTreeInt0, !Info).
|
|
|
|
collect_mq_info_in_direct_int1_spec(DirectInt1Spec, !Info) :-
|
|
DirectInt1Spec = direct_int1(ParseTreeInt1, ReadWhy1),
|
|
collect_mq_info_in_parse_tree_int1(ReadWhy1, ParseTreeInt1, !Info).
|
|
|
|
collect_mq_info_in_direct_int3_spec(DirectInt3Spec, !Info) :-
|
|
DirectInt3Spec = direct_int3(ParseTreeInt3, ReadWhy3),
|
|
Role = int3_as_direct_int(ReadWhy3),
|
|
collect_mq_info_in_parse_tree_int3(Role, ParseTreeInt3, !Info).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
collect_mq_info_in_parse_tree_int0(ReadWhy0, ParseTreeInt0, !Info) :-
|
|
(
|
|
ReadWhy0 = rwi0_section,
|
|
% XXX Whether this module's interface can use an mq_id
|
|
% that was imported by an ancestor should depend on whether
|
|
% the ancestor imported that mq_id in its INTERFACE or not.
|
|
% Since we don't know where that import was, this is a
|
|
% conservative approximation.
|
|
IntPermInInt = may_use_in_int(may_be_unqualified),
|
|
IntPermInImp = may_use_in_imp(may_be_unqualified),
|
|
ImpPermInInt = may_use_in_int(may_be_unqualified),
|
|
ImpPermInImp = may_use_in_imp(may_be_unqualified),
|
|
|
|
IntPermissions = module_permissions(IntPermInInt, IntPermInImp),
|
|
ImpPermissions = module_permissions(ImpPermInInt, ImpPermInImp)
|
|
;
|
|
ReadWhy0 = rwi0_opt,
|
|
% Since we do not collect module qual info for int_for_opt_specs,
|
|
% we should never encounter this value of ReadWhy0.
|
|
unexpected($pred, "rwi0_opt")
|
|
),
|
|
|
|
ParseTreeInt0 = parse_tree_int0(_ModuleName, _ModuleNameContext,
|
|
_MaybeVersionNumbers, InclMap,
|
|
ImportUseMap, _IntFIMSpecs, _ImpFIMSpecs,
|
|
TypeCtorCheckedMap, InstCtorCheckedMap, ModeCtorCheckedMap,
|
|
IntTypeClasses, IntInstances, _IntPredDecls, _IntModeDecls,
|
|
_IntDeclPragmas, _IntDeclMarkers, IntPromises,
|
|
ImpTypeClasses, ImpInstances, _ImpPredDecls, _ImpModeDecls,
|
|
_ImpDeclPragmas, _ImpDeclMarkers, ImpPromises),
|
|
|
|
mq_info_get_modules(!.Info, Modules0),
|
|
map.foldl(collect_mq_info_in_included_module_info(IntPermissions),
|
|
InclMap, Modules0, Modules),
|
|
mq_info_set_modules(Modules, !Info),
|
|
|
|
mq_info_get_imported_modules(!.Info, ImportedModules0),
|
|
list.foldl(collect_mq_info_in_int0_import_or_use, map.keys(ImportUseMap),
|
|
ImportedModules0, ImportedModules),
|
|
mq_info_set_imported_modules(ImportedModules, !Info),
|
|
|
|
mq_info_get_types(!.Info, Types0),
|
|
map.foldl(
|
|
collect_mq_info_in_int_imp_type_defn(IntPermissions, ImpPermissions),
|
|
TypeCtorCheckedMap, Types0, Types),
|
|
mq_info_set_types(Types, !Info),
|
|
|
|
mq_info_get_insts(!.Info, Insts0),
|
|
map.foldl(
|
|
collect_mq_info_in_int_imp_inst_defn(IntPermissions, ImpPermissions),
|
|
InstCtorCheckedMap, Insts0, Insts),
|
|
mq_info_set_insts(Insts, !Info),
|
|
|
|
mq_info_get_modes(!.Info, Modes0),
|
|
map.foldl(
|
|
collect_mq_info_in_int_imp_mode_defn(IntPermissions, ImpPermissions),
|
|
ModeCtorCheckedMap, Modes0, Modes),
|
|
mq_info_set_modes(Modes, !Info),
|
|
|
|
list.foldl(collect_mq_info_in_item_typeclass(IntPermissions),
|
|
IntTypeClasses, !Info),
|
|
list.foldl(collect_mq_info_in_item_typeclass(ImpPermissions),
|
|
ImpTypeClasses, !Info),
|
|
list.foldl(collect_mq_info_in_item_instance, coerce(IntInstances), !Info),
|
|
list.foldl(collect_mq_info_in_item_instance, coerce(ImpInstances), !Info),
|
|
list.foldl(collect_mq_info_in_item_promise(mq_used_in_interface),
|
|
IntPromises, !Info),
|
|
list.foldl(collect_mq_info_in_item_promise(mq_not_used_in_interface),
|
|
ImpPromises, !Info).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred collect_mq_info_in_parse_tree_int1(read_why_int1::in,
|
|
parse_tree_int1::in, mq_info::in, mq_info::out) is det.
|
|
|
|
collect_mq_info_in_parse_tree_int1(ReadWhy1, ParseTreeInt1, !Info) :-
|
|
(
|
|
ReadWhy1 = rwi1_int_import,
|
|
IntPermInInt = may_use_in_int(may_be_unqualified),
|
|
IntPermInImp = may_use_in_imp(may_be_unqualified)
|
|
;
|
|
ReadWhy1 = rwi1_imp_import,
|
|
IntPermInInt = may_not_use_in_int,
|
|
IntPermInImp = may_use_in_imp(may_be_unqualified)
|
|
;
|
|
ReadWhy1 = rwi1_int_use,
|
|
IntPermInInt = may_use_in_int(must_be_qualified),
|
|
IntPermInImp = may_use_in_imp(must_be_qualified)
|
|
;
|
|
ReadWhy1 = rwi1_imp_use,
|
|
IntPermInInt = may_not_use_in_int,
|
|
IntPermInImp = may_use_in_imp(must_be_qualified)
|
|
;
|
|
ReadWhy1 = rwi1_int_use_imp_import,
|
|
IntPermInInt = may_use_in_int(must_be_qualified),
|
|
IntPermInImp = may_use_in_imp(may_be_unqualified)
|
|
;
|
|
ReadWhy1 = rwi1_opt,
|
|
% Since we do not collect module qual info for int_for_opt_specs,
|
|
% we should never encounter this value of ReadWhy1.
|
|
unexpected($pred, "rwi1_opt")
|
|
;
|
|
ReadWhy1 = rwi1_type_repn,
|
|
% Since we do not collect module qual info for type_repn_specs,
|
|
% we should never encounter this value of ReadWhy1.
|
|
unexpected($pred, "rwi1_opt")
|
|
),
|
|
IntPermissions = module_permissions(IntPermInInt, IntPermInImp),
|
|
% The implementation section of a .int1 file is abstract imported,
|
|
% which means we have no permission for any item defined there.
|
|
% We therefore do not need any ImpPermissions.
|
|
|
|
ParseTreeInt1 = parse_tree_int1(_ModuleName, _ModuleNameContext,
|
|
_MaybeVersionNumbers, InclMap,
|
|
_ImportUseMap, _IntFIMSpecs, _ImpFIMSpecs,
|
|
TypeCheckedMap, InstCheckedMap, ModeCheckedMap,
|
|
IntTypeClasses, IntInstances, _IntPredDecls, _IntModeDecls,
|
|
_IntDeclPragmas, _IntDeclMarkers, IntPromises, _IntTypeRepnMap,
|
|
_ImpTypeClasses),
|
|
|
|
mq_info_get_modules(!.Info, Modules0),
|
|
map.foldl(collect_mq_info_in_included_module_info(IntPermissions),
|
|
InclMap, Modules0, Modules),
|
|
mq_info_set_modules(Modules, !Info),
|
|
|
|
mq_info_get_types(!.Info, Types0),
|
|
map.foldl(collect_mq_info_in_int_type_defn(IntPermissions),
|
|
TypeCheckedMap, Types0, Types),
|
|
mq_info_set_types(Types, !Info),
|
|
|
|
mq_info_get_insts(!.Info, Insts0),
|
|
map.foldl(collect_mq_info_in_int_inst_defn(IntPermissions),
|
|
InstCheckedMap, Insts0, Insts),
|
|
mq_info_set_insts(Insts, !Info),
|
|
|
|
mq_info_get_modes(!.Info, Modes0),
|
|
map.foldl(collect_mq_info_in_int_mode_defn(IntPermissions),
|
|
ModeCheckedMap, Modes0, Modes),
|
|
mq_info_set_modes(Modes, !Info),
|
|
|
|
list.foldl(collect_mq_info_in_item_typeclass(IntPermissions),
|
|
IntTypeClasses, !Info),
|
|
list.foldl(collect_mq_info_in_item_instance, coerce(IntInstances), !Info),
|
|
list.foldl(collect_mq_info_in_item_promise(mq_used_in_interface),
|
|
IntPromises, !Info).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred collect_mq_info_in_int_imp_type_defn(
|
|
module_permissions::in, module_permissions::in,
|
|
type_ctor::in, type_ctor_checked_defn::in,
|
|
type_id_set::in, type_id_set::out) is det.
|
|
|
|
collect_mq_info_in_int_imp_type_defn(IntPermissions, ImpPermissions,
|
|
TypeCtor, CheckedDefn, !Types) :-
|
|
TypeId = type_ctor_to_mq_id(TypeCtor),
|
|
(
|
|
CheckedDefn = checked_defn_solver(SolverDefn, _),
|
|
(
|
|
SolverDefn = solver_type_abstract(AbsStatus, _),
|
|
(
|
|
AbsStatus = abstract_solver_type_exported,
|
|
id_set_insert(IntPermissions, TypeId, !Types)
|
|
;
|
|
AbsStatus = abstract_solver_type_private,
|
|
id_set_insert(ImpPermissions, TypeId, !Types)
|
|
)
|
|
;
|
|
SolverDefn = solver_type_full(MaybeAbsDefn, _),
|
|
(
|
|
MaybeAbsDefn = yes(_),
|
|
id_set_insert(IntPermissions, TypeId, !Types)
|
|
;
|
|
MaybeAbsDefn = no,
|
|
id_set_insert(ImpPermissions, TypeId, !Types)
|
|
)
|
|
)
|
|
;
|
|
CheckedDefn = checked_defn_std(StdDefn, _),
|
|
(
|
|
StdDefn = std_mer_type_eqv(EqvStatus, _),
|
|
(
|
|
( EqvStatus = std_eqv_type_mer_exported
|
|
; EqvStatus = std_eqv_type_abstract_exported
|
|
),
|
|
id_set_insert(IntPermissions, TypeId, !Types)
|
|
;
|
|
EqvStatus = std_eqv_type_all_private,
|
|
id_set_insert(ImpPermissions, TypeId, !Types)
|
|
)
|
|
;
|
|
StdDefn = std_mer_type_subtype(SubStatus, _),
|
|
(
|
|
( SubStatus = std_sub_type_mer_exported
|
|
; SubStatus = std_sub_type_abstract_exported
|
|
),
|
|
id_set_insert(IntPermissions, TypeId, !Types)
|
|
;
|
|
SubStatus = std_sub_type_all_private,
|
|
id_set_insert(ImpPermissions, TypeId, !Types)
|
|
)
|
|
;
|
|
(
|
|
StdDefn =
|
|
std_mer_type_du_all_plain_constants(DuStatus, _, _, _, _)
|
|
;
|
|
StdDefn =
|
|
std_mer_type_du_not_all_plain_constants(DuStatus, _, _)
|
|
),
|
|
(
|
|
( DuStatus = std_du_type_mer_ft_exported
|
|
; DuStatus = std_du_type_mer_exported
|
|
; DuStatus = std_du_type_abstract_exported
|
|
),
|
|
id_set_insert(IntPermissions, TypeId, !Types)
|
|
;
|
|
DuStatus = std_du_type_all_private,
|
|
id_set_insert(ImpPermissions, TypeId, !Types)
|
|
)
|
|
;
|
|
StdDefn = std_mer_type_abstract(AbsStatus, _, _),
|
|
(
|
|
( AbsStatus = std_abs_type_ft_exported
|
|
; AbsStatus = std_abs_type_abstract_exported
|
|
),
|
|
id_set_insert(IntPermissions, TypeId, !Types)
|
|
;
|
|
AbsStatus = std_abs_type_all_private,
|
|
id_set_insert(ImpPermissions, TypeId, !Types)
|
|
)
|
|
)
|
|
).
|
|
|
|
:- pred collect_mq_info_in_int_type_defn(module_permissions::in,
|
|
type_ctor::in, type_ctor_checked_defn::in,
|
|
type_id_set::in, type_id_set::out) is det.
|
|
|
|
collect_mq_info_in_int_type_defn(IntPermissions, TypeCtor, CheckedDefn,
|
|
!Types) :-
|
|
TypeId = type_ctor_to_mq_id(TypeCtor),
|
|
(
|
|
CheckedDefn = checked_defn_solver(SolverDefn, _),
|
|
(
|
|
SolverDefn = solver_type_abstract(AbsStatus, _),
|
|
(
|
|
AbsStatus = abstract_solver_type_exported,
|
|
id_set_insert(IntPermissions, TypeId, !Types)
|
|
;
|
|
AbsStatus = abstract_solver_type_private
|
|
)
|
|
;
|
|
SolverDefn = solver_type_full(MaybeAbsDefn, _),
|
|
(
|
|
MaybeAbsDefn = yes(_),
|
|
id_set_insert(IntPermissions, TypeId, !Types)
|
|
;
|
|
MaybeAbsDefn = no
|
|
)
|
|
)
|
|
;
|
|
CheckedDefn = checked_defn_std(StdDefn, _),
|
|
(
|
|
StdDefn = std_mer_type_eqv(EqvStatus, _),
|
|
(
|
|
( EqvStatus = std_eqv_type_mer_exported
|
|
; EqvStatus = std_eqv_type_abstract_exported
|
|
),
|
|
id_set_insert(IntPermissions, TypeId, !Types)
|
|
;
|
|
EqvStatus = std_eqv_type_all_private
|
|
)
|
|
;
|
|
StdDefn = std_mer_type_subtype(SubStatus, _),
|
|
(
|
|
( SubStatus = std_sub_type_mer_exported
|
|
; SubStatus = std_sub_type_abstract_exported
|
|
),
|
|
id_set_insert(IntPermissions, TypeId, !Types)
|
|
;
|
|
SubStatus = std_sub_type_all_private
|
|
)
|
|
;
|
|
(
|
|
StdDefn =
|
|
std_mer_type_du_all_plain_constants(DuStatus, _, _, _, _)
|
|
;
|
|
StdDefn =
|
|
std_mer_type_du_not_all_plain_constants(DuStatus, _, _)
|
|
),
|
|
(
|
|
( DuStatus = std_du_type_mer_ft_exported
|
|
; DuStatus = std_du_type_mer_exported
|
|
; DuStatus = std_du_type_abstract_exported
|
|
),
|
|
id_set_insert(IntPermissions, TypeId, !Types)
|
|
;
|
|
DuStatus = std_du_type_all_private
|
|
)
|
|
;
|
|
StdDefn = std_mer_type_abstract(AbsStatus, _, _),
|
|
(
|
|
( AbsStatus = std_abs_type_ft_exported
|
|
; AbsStatus = std_abs_type_abstract_exported
|
|
),
|
|
id_set_insert(IntPermissions, TypeId, !Types)
|
|
;
|
|
AbsStatus = std_abs_type_all_private
|
|
)
|
|
)
|
|
).
|
|
|
|
:- pred collect_mq_info_in_int_imp_inst_defn(
|
|
module_permissions::in, module_permissions::in,
|
|
inst_ctor::in, inst_ctor_checked_defn::in,
|
|
inst_id_set::in, inst_id_set::out) is det.
|
|
|
|
collect_mq_info_in_int_imp_inst_defn(IntPermissions, ImpPermissions,
|
|
InstCtor, CheckedDefn, !Insts) :-
|
|
CheckedDefn = checked_defn_inst(StdInstDefn, _),
|
|
StdInstDefn = std_inst_defn(Status, _),
|
|
(
|
|
( Status = std_inst_exported
|
|
; Status = std_inst_abstract_exported
|
|
),
|
|
id_set_insert(IntPermissions, inst_ctor_to_mq_id(InstCtor), !Insts)
|
|
;
|
|
Status = std_inst_all_private,
|
|
id_set_insert(ImpPermissions, inst_ctor_to_mq_id(InstCtor), !Insts)
|
|
).
|
|
|
|
:- pred collect_mq_info_in_int_inst_defn(module_permissions::in,
|
|
inst_ctor::in, inst_ctor_checked_defn::in,
|
|
inst_id_set::in, inst_id_set::out) is det.
|
|
|
|
collect_mq_info_in_int_inst_defn(IntPermissions, InstCtor, CheckedDefn,
|
|
!Insts) :-
|
|
CheckedDefn = checked_defn_inst(StdInstDefn, _),
|
|
StdInstDefn = std_inst_defn(Status, _),
|
|
(
|
|
( Status = std_inst_exported
|
|
; Status = std_inst_abstract_exported
|
|
),
|
|
id_set_insert(IntPermissions, inst_ctor_to_mq_id(InstCtor), !Insts)
|
|
;
|
|
Status = std_inst_all_private
|
|
).
|
|
|
|
:- pred collect_mq_info_in_int_imp_mode_defn(
|
|
module_permissions::in, module_permissions::in,
|
|
mode_ctor::in, mode_ctor_checked_defn::in,
|
|
mode_id_set::in, mode_id_set::out) is det.
|
|
|
|
collect_mq_info_in_int_imp_mode_defn(IntPermissions, ImpPermissions,
|
|
ModeCtor, CheckedDefn, !Modes) :-
|
|
CheckedDefn = checked_defn_mode(StdModeDefn, _),
|
|
StdModeDefn = std_mode_defn(Status, _),
|
|
(
|
|
( Status = std_mode_exported
|
|
; Status = std_mode_abstract_exported
|
|
),
|
|
id_set_insert(IntPermissions, mode_ctor_to_mq_id(ModeCtor), !Modes)
|
|
;
|
|
Status = std_mode_all_private,
|
|
id_set_insert(ImpPermissions, mode_ctor_to_mq_id(ModeCtor), !Modes)
|
|
).
|
|
|
|
:- pred collect_mq_info_in_int_mode_defn(module_permissions::in,
|
|
mode_ctor::in, mode_ctor_checked_defn::in,
|
|
mode_id_set::in, mode_id_set::out) is det.
|
|
|
|
collect_mq_info_in_int_mode_defn(IntPermissions, ModeCtor, CheckedDefn,
|
|
!Modes) :-
|
|
CheckedDefn = checked_defn_mode(StdModeDefn, _),
|
|
StdModeDefn = std_mode_defn(Status, _),
|
|
(
|
|
( Status = std_mode_exported
|
|
; Status = std_mode_abstract_exported
|
|
),
|
|
id_set_insert(IntPermissions, mode_ctor_to_mq_id(ModeCtor), !Modes)
|
|
;
|
|
Status = std_mode_all_private
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
collect_mq_info_in_parse_tree_int3(Role, ParseTreeInt3, !Info) :-
|
|
(
|
|
Role = int3_as_src,
|
|
PermInInt = may_use_in_int(may_be_unqualified),
|
|
PermInImp = may_use_in_imp(may_be_unqualified)
|
|
;
|
|
Role = int3_as_direct_int(ReadWhy3),
|
|
(
|
|
( ReadWhy3 = rwi3_direct_ancestor_import
|
|
; ReadWhy3 = rwi3_direct_int_import
|
|
),
|
|
PermInInt = may_use_in_int(may_be_unqualified),
|
|
PermInImp = may_use_in_imp(may_be_unqualified)
|
|
;
|
|
( ReadWhy3 = rwi3_direct_ancestor_use
|
|
; ReadWhy3 = rwi3_direct_int_use
|
|
; ReadWhy3 = rwi3_indirect_int_use
|
|
),
|
|
PermInInt = may_use_in_int(must_be_qualified),
|
|
PermInImp = may_use_in_imp(must_be_qualified)
|
|
;
|
|
ReadWhy3 = rwi3_direct_imp_import,
|
|
PermInInt = may_not_use_in_int,
|
|
PermInImp = may_use_in_imp(may_be_unqualified)
|
|
;
|
|
( ReadWhy3 = rwi3_direct_imp_use
|
|
; ReadWhy3 = rwi3_indirect_imp_use
|
|
),
|
|
PermInInt = may_not_use_in_int,
|
|
PermInImp = may_use_in_imp(must_be_qualified)
|
|
;
|
|
ReadWhy3 = rwi3_direct_int_use_imp_import,
|
|
PermInInt = may_use_in_int(must_be_qualified),
|
|
PermInImp = may_use_in_imp(may_be_unqualified)
|
|
)
|
|
),
|
|
Permissions = module_permissions(PermInInt, PermInImp),
|
|
|
|
ParseTreeInt3 = parse_tree_int3(_ModuleName, _ModuleNameContext,
|
|
IntInclMap, IntImportMap,
|
|
IntTypeDefnMap, IntInstDefnMap, IntModeDefnMap,
|
|
IntTypeClasses, IntInstances, _IntTypeRepns),
|
|
|
|
mq_info_get_modules(!.Info, Modules0),
|
|
list.foldl(collect_mq_info_in_int_incl_context(Permissions),
|
|
map.keys(IntInclMap), Modules0, Modules),
|
|
mq_info_set_modules(Modules, !Info),
|
|
|
|
mq_info_get_imported_modules(!.Info, ImportedModules0),
|
|
list.foldl(collect_mq_info_in_int3_import, map.keys(IntImportMap),
|
|
ImportedModules0, ImportedModules),
|
|
mq_info_set_imported_modules(ImportedModules, !Info),
|
|
|
|
mq_info_get_types(!.Info, Types0),
|
|
TypeIds = list.map(type_ctor_to_mq_id, map.keys(IntTypeDefnMap)),
|
|
list.foldl(id_set_insert(Permissions), TypeIds, Types0, Types),
|
|
mq_info_set_types(Types, !Info),
|
|
|
|
mq_info_get_insts(!.Info, Insts0),
|
|
InstIds = list.map(inst_ctor_to_mq_id, map.keys(IntInstDefnMap)),
|
|
list.foldl(id_set_insert(Permissions), InstIds, Insts0, Insts),
|
|
mq_info_set_insts(Insts, !Info),
|
|
|
|
mq_info_get_modes(!.Info, Modes0),
|
|
ModeIds = list.map(mode_ctor_to_mq_id, map.keys(IntModeDefnMap)),
|
|
list.foldl(id_set_insert(Permissions), ModeIds, Modes0, Modes),
|
|
mq_info_set_modes(Modes, !Info),
|
|
|
|
list.foldl(collect_mq_info_in_item_typeclass(Permissions),
|
|
coerce(IntTypeClasses), !Info),
|
|
list.foldl(collect_mq_info_in_item_instance, coerce(IntInstances), !Info).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- func type_ctor_to_mq_id(type_ctor) = mq_id.
|
|
|
|
type_ctor_to_mq_id(TypeCtor) = Id :-
|
|
TypeCtor = type_ctor(SymName, Arity),
|
|
Id = mq_id(SymName, Arity).
|
|
|
|
:- func inst_ctor_to_mq_id(inst_ctor) = mq_id.
|
|
|
|
inst_ctor_to_mq_id(InstCtor) = Id :-
|
|
InstCtor = inst_ctor(SymName, Arity),
|
|
Id = mq_id(SymName, Arity).
|
|
|
|
:- func mode_ctor_to_mq_id(mode_ctor) = mq_id.
|
|
|
|
mode_ctor_to_mq_id(ModeCtor) = Id :-
|
|
ModeCtor = mode_ctor(SymName, Arity),
|
|
Id = mq_id(SymName, Arity).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred collect_mq_info_in_included_module_info(module_permissions::in,
|
|
module_name::in, include_module_info::in,
|
|
module_id_set::in, module_id_set::out) is det.
|
|
|
|
collect_mq_info_in_included_module_info(IntPermissions, ModuleName, InclInfo,
|
|
!Modules) :-
|
|
InclInfo = include_module_info(Section, _Context),
|
|
% XXX Why do we test Section if we do the same thing for both int and imp?
|
|
(
|
|
Section = ms_interface,
|
|
Arity = 0,
|
|
id_set_insert(IntPermissions, mq_id(ModuleName, Arity), !Modules)
|
|
;
|
|
Section = ms_implementation,
|
|
Arity = 0,
|
|
id_set_insert(IntPermissions, mq_id(ModuleName, Arity), !Modules)
|
|
).
|
|
|
|
:- pred collect_mq_info_in_int_incl_context(module_permissions::in,
|
|
module_name::in, module_id_set::in, module_id_set::out) is det.
|
|
|
|
collect_mq_info_in_int_incl_context(IntPermissions, ModuleName, !Modules) :-
|
|
Arity = 0,
|
|
id_set_insert(IntPermissions, mq_id(ModuleName, Arity), !Modules).
|
|
|
|
:- pred collect_mq_info_in_int0_import_or_use(module_name::in,
|
|
set_tree234(module_name)::in, set_tree234(module_name)::out) is det.
|
|
|
|
collect_mq_info_in_int0_import_or_use(ModuleName, !ImportedModules) :-
|
|
set_tree234.insert(ModuleName, !ImportedModules).
|
|
|
|
:- pred collect_mq_info_in_int3_import(module_name::in,
|
|
set_tree234(module_name)::in, set_tree234(module_name)::out) is det.
|
|
|
|
collect_mq_info_in_int3_import(ModuleName, !ImportedModules) :-
|
|
set_tree234.insert(ModuleName, !ImportedModules).
|
|
|
|
:- func item_type_defn_info_to_mq_id(item_type_defn_info) = mq_id.
|
|
|
|
item_type_defn_info_to_mq_id(ItemTypeDefn) = MQId :-
|
|
ItemTypeDefn = item_type_defn_info(SymName, Params, _, _, _, _),
|
|
MQId = mq_id(SymName, list.length(Params)).
|
|
|
|
:- func item_inst_defn_info_to_mq_id(item_inst_defn_info) = mq_id.
|
|
|
|
item_inst_defn_info_to_mq_id(ItemInstDefn) = MQId :-
|
|
ItemInstDefn = item_inst_defn_info(SymName, Params, _, _, _, _, _),
|
|
MQId = mq_id(SymName, list.length(Params)).
|
|
|
|
:- func item_mode_defn_info_to_mq_id(item_mode_defn_info) = mq_id.
|
|
|
|
item_mode_defn_info_to_mq_id(ItemModeDefn) = MQId :-
|
|
ItemModeDefn = item_mode_defn_info(SymName, Params, _, _, _, _),
|
|
MQId = mq_id(SymName, list.length(Params)).
|
|
|
|
:- pred collect_mq_info_in_item_typeclass(module_permissions::in,
|
|
item_typeclass_info::in, mq_info::in, mq_info::out) is det.
|
|
|
|
collect_mq_info_in_item_typeclass(Permissions, ItemTypeClass, !Info) :-
|
|
ItemTypeClass = item_typeclass_info(SymName, Params, _, _, _, _, _, _),
|
|
list.length(Params, Arity),
|
|
mq_info_get_classes(!.Info, Classes0),
|
|
id_set_insert(Permissions, mq_id(SymName, Arity), Classes0, Classes),
|
|
mq_info_set_classes(Classes, !Info).
|
|
|
|
:- pred collect_mq_info_in_item_instance(item_instance_info::in,
|
|
mq_info::in, mq_info::out) is det.
|
|
|
|
collect_mq_info_in_item_instance(ItemInstance, !Info) :-
|
|
InstanceModule = ItemInstance ^ ci_module_containing_instance,
|
|
mq_info_get_imported_instance_modules(!.Info, ImportedInstanceModules0),
|
|
set_tree234.insert(InstanceModule,
|
|
ImportedInstanceModules0, ImportedInstanceModules),
|
|
mq_info_set_imported_instance_modules(ImportedInstanceModules, !Info).
|
|
|
|
:- pred collect_mq_info_in_item_promise(mq_in_interface::in,
|
|
item_promise_info::in, mq_info::in, mq_info::out) is det.
|
|
|
|
collect_mq_info_in_item_promise(InInt, ItemPromise, !Info) :-
|
|
ItemPromise = item_promise_info(_PromiseType, Goal, _ProgVarSet,
|
|
_UnivVars, _Context, _SeqNum),
|
|
collect_used_modules_in_promise_goal(Goal,
|
|
set_tree234.init, UsedModuleNames, no, FoundUnqual),
|
|
(
|
|
FoundUnqual = no,
|
|
set_tree234.fold(mq_info_set_module_used(InInt),
|
|
UsedModuleNames, !Info)
|
|
;
|
|
% Any unqualified symbol in the promise might come from *any* of
|
|
% the imported modules. There is no way for us to tell which ones,
|
|
% so we conservatively assume that it uses *all* of them.
|
|
FoundUnqual = yes,
|
|
map.init(UnusedModules),
|
|
mq_info_set_as_yet_unused_interface_modules(UnusedModules, !Info)
|
|
).
|
|
|
|
%---------------------%
|
|
|
|
% Scan Goal. Add the set of module names found in the qualified symbols
|
|
% in Goal to !UsedModuleNames. If there exists a single unqualified symbol,
|
|
% in Goal, set !Success to no.
|
|
%
|
|
:- pred collect_used_modules_in_promise_goal(goal::in,
|
|
set_tree234(module_name)::in, set_tree234(module_name)::out,
|
|
bool::in, bool::out) is det.
|
|
|
|
collect_used_modules_in_promise_goal(Goal, !UsedModuleNames, !FoundUnqual) :-
|
|
(
|
|
( Goal = conj_expr(_, SubGoalA, SubGoalsB)
|
|
; Goal = par_conj_expr(_, SubGoalA, SubGoalsB)
|
|
),
|
|
collect_used_modules_in_promise_goal(SubGoalA,
|
|
!UsedModuleNames, !FoundUnqual),
|
|
collect_used_modules_in_promise_goals(SubGoalsB,
|
|
!UsedModuleNames, !FoundUnqual)
|
|
;
|
|
( Goal = implies_expr(_, SubGoalA, SubGoalB)
|
|
; Goal = equivalent_expr(_, SubGoalA, SubGoalB)
|
|
),
|
|
collect_used_modules_in_promise_goal(SubGoalA,
|
|
!UsedModuleNames, !FoundUnqual),
|
|
collect_used_modules_in_promise_goal(SubGoalB,
|
|
!UsedModuleNames, !FoundUnqual)
|
|
;
|
|
Goal = disj_expr(_, SubGoal1, SubGoal2, SubGoals),
|
|
collect_used_modules_in_promise_goal(SubGoal1,
|
|
!UsedModuleNames, !FoundUnqual),
|
|
collect_used_modules_in_promise_goal(SubGoal2,
|
|
!UsedModuleNames, !FoundUnqual),
|
|
collect_used_modules_in_promise_goals(SubGoals,
|
|
!UsedModuleNames, !FoundUnqual)
|
|
;
|
|
( Goal = true_expr(_)
|
|
; Goal = fail_expr(_)
|
|
)
|
|
;
|
|
( Goal = not_expr(_, SubGoal)
|
|
; Goal = quant_expr(_, _, _, _, SubGoal)
|
|
; Goal = promise_purity_expr(_, _, SubGoal)
|
|
; Goal = promise_equivalent_solutions_expr(_, _, _, _, _, SubGoal)
|
|
; Goal = promise_equivalent_solution_sets_expr(_, _, _, _, _, SubGoal)
|
|
; Goal = promise_equivalent_solution_arbitrary_expr(_, _, _, _, _,
|
|
SubGoal)
|
|
; Goal = require_detism_expr(_, _, SubGoal)
|
|
; Goal = require_complete_switch_expr(_, _, SubGoal)
|
|
; Goal = require_switch_arms_detism_expr(_, _, _, SubGoal)
|
|
; Goal = trace_expr(_, _, _, _, _, SubGoal)
|
|
; Goal = disable_warnings_expr(_, _, _, SubGoal)
|
|
),
|
|
collect_used_modules_in_promise_goal(SubGoal,
|
|
!UsedModuleNames, !FoundUnqual)
|
|
;
|
|
Goal = try_expr(_, _, SubGoal, ThenGoal, MaybeElseGoal, Catches,
|
|
MaybeCatchAny),
|
|
collect_used_modules_in_promise_goal(SubGoal,
|
|
!UsedModuleNames, !FoundUnqual),
|
|
collect_used_modules_in_promise_goal(ThenGoal,
|
|
!UsedModuleNames, !FoundUnqual),
|
|
(
|
|
MaybeElseGoal = no
|
|
;
|
|
MaybeElseGoal = yes(ElseGoal),
|
|
collect_used_modules_in_promise_goal(ElseGoal,
|
|
!UsedModuleNames, !FoundUnqual)
|
|
),
|
|
list.foldl2(collect_used_modules_in_promise_catch, Catches,
|
|
!UsedModuleNames, !FoundUnqual),
|
|
(
|
|
MaybeCatchAny = no
|
|
;
|
|
MaybeCatchAny = yes(catch_any_expr(_, CatchAnyGoal)),
|
|
collect_used_modules_in_promise_goal(CatchAnyGoal,
|
|
!UsedModuleNames, !FoundUnqual)
|
|
)
|
|
;
|
|
Goal = atomic_expr(_, _, _, _, MainGoal, OrElseGoals),
|
|
collect_used_modules_in_promise_goal(MainGoal,
|
|
!UsedModuleNames, !FoundUnqual),
|
|
collect_used_modules_in_promise_goals(OrElseGoals,
|
|
!UsedModuleNames, !FoundUnqual)
|
|
;
|
|
Goal = if_then_else_expr(_, _, _, CondGoal, ThenGoal, ElseGoal),
|
|
collect_used_modules_in_promise_goal(CondGoal,
|
|
!UsedModuleNames, !FoundUnqual),
|
|
collect_used_modules_in_promise_goal(ThenGoal,
|
|
!UsedModuleNames, !FoundUnqual),
|
|
collect_used_modules_in_promise_goal(ElseGoal,
|
|
!UsedModuleNames, !FoundUnqual)
|
|
;
|
|
Goal = event_expr(_, _Name, ArgTerms0),
|
|
list.map(term.coerce, ArgTerms0, ArgTerms),
|
|
collect_used_modules_in_terms(ArgTerms, !UsedModuleNames, !FoundUnqual)
|
|
;
|
|
Goal = call_expr(_, SymName, ArgTerms0, _Purity),
|
|
(
|
|
SymName = qualified(ModuleName, _),
|
|
set_tree234.insert(ModuleName, !UsedModuleNames)
|
|
;
|
|
SymName = unqualified(_),
|
|
!:FoundUnqual = yes
|
|
),
|
|
list.map(term.coerce, ArgTerms0, ArgTerms),
|
|
collect_used_modules_in_terms(ArgTerms, !UsedModuleNames, !FoundUnqual)
|
|
;
|
|
Goal = unify_expr(_, LHS0, RHS0, _Purity),
|
|
term.coerce(LHS0, LHS),
|
|
term.coerce(RHS0, RHS),
|
|
collect_used_modules_in_term(LHS, !UsedModuleNames, !FoundUnqual),
|
|
collect_used_modules_in_term(RHS, !UsedModuleNames, !FoundUnqual)
|
|
).
|
|
|
|
% Performs collect_used_modules_in_promise_goal on a list of goals.
|
|
%
|
|
:- pred collect_used_modules_in_promise_goals(list(goal)::in,
|
|
set_tree234(module_name)::in, set_tree234(module_name)::out,
|
|
bool::in, bool::out) is det.
|
|
|
|
collect_used_modules_in_promise_goals([], !UsedModuleNames, !FoundUnqual).
|
|
collect_used_modules_in_promise_goals([Goal | Goals],
|
|
!UsedModuleNames, !FoundUnqual) :-
|
|
collect_used_modules_in_promise_goal(Goal,
|
|
!UsedModuleNames, !FoundUnqual),
|
|
collect_used_modules_in_promise_goals(Goals,
|
|
!UsedModuleNames, !FoundUnqual).
|
|
|
|
:- pred collect_used_modules_in_promise_catch(catch_expr::in,
|
|
set_tree234(module_name)::in, set_tree234(module_name)::out,
|
|
bool::in, bool::out) is det.
|
|
|
|
collect_used_modules_in_promise_catch(CatchExpr,
|
|
!UsedModuleNames, !FoundUnqual) :-
|
|
CatchExpr = catch_expr(Pattern0, Goal),
|
|
term.coerce(Pattern0, Pattern),
|
|
collect_used_modules_in_term(Pattern, !UsedModuleNames, !FoundUnqual),
|
|
collect_used_modules_in_promise_goal(Goal, !UsedModuleNames, !FoundUnqual).
|
|
|
|
% Add all the module names in qualified sym_names in Term to
|
|
% !UsedModuleNames, and set !FoundUnqual to true if any of the sym_names
|
|
% in Term is unqualified.
|
|
%
|
|
:- pred collect_used_modules_in_term(term::in,
|
|
set_tree234(module_name)::in, set_tree234(module_name)::out,
|
|
bool::in, bool::out) is det.
|
|
|
|
collect_used_modules_in_term(Term, !UsedModuleNames, !FoundUnqual) :-
|
|
( if try_parse_sym_name_and_args(Term, SymName, ArgTerms) then
|
|
(
|
|
SymName = qualified(ModuleName, _),
|
|
set_tree234.insert(ModuleName, !UsedModuleNames)
|
|
;
|
|
SymName = unqualified(_),
|
|
!:FoundUnqual = yes
|
|
),
|
|
collect_used_modules_in_terms(ArgTerms, !UsedModuleNames, !FoundUnqual)
|
|
else
|
|
true
|
|
).
|
|
|
|
:- pred collect_used_modules_in_terms(list(term)::in,
|
|
set_tree234(module_name)::in, set_tree234(module_name)::out,
|
|
bool::in, bool::out) is det.
|
|
|
|
collect_used_modules_in_terms([], !UsedModuleNames, !FoundUnqual).
|
|
collect_used_modules_in_terms([Term | Terms],
|
|
!UsedModuleNames, !FoundUnqual) :-
|
|
collect_used_modules_in_term(Term, !UsedModuleNames, !FoundUnqual),
|
|
collect_used_modules_in_terms(Terms, !UsedModuleNames, !FoundUnqual).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
:- end_module parse_tree.module_qual.collect_mq_info.
|
|
%---------------------------------------------------------------------------%
|