Files
mercury/compiler/prog_mutable.m
Julien Fischer 9ec3ae8d08 Fix the problems with mutable declarations and sub-modules by making
Estimated hours taken: 11
Branches: main

Fix the problems with mutable declarations and sub-modules by making
sure that the relevant information is written out in the private interface
files.

Fix a bug where mutable variables were not being initialised with their
declared intial value.  The problem was that the compiler was optimizing away
the body of the automatically generated predicate that was setting the initial
value.  We now make such predicates impure to prevent this.

In order to support the above, accept `:- intialise' declarations that specify
impure predicates, provided that the declaration in question was generated by the
compiler.  It is still an error for the user to specify such declarations.

Fix some other problems with mutable declarations.

compiler/modules.m:
	Do not write `:- mutable' declarations out to private interface
	files, instead write out the predicate and mode declarations for
	the access predicates.

	Remove some old XXX comments about mutables that are no longer
	relevant.

compiler/make_hlds_passes.m:
	Don't add the export pragmas for initialise declarations during pass
	2.  For some reason we were doing this during pass 2 and again during
	pass 3.

	Make the intialise predicates for mutable variables impure in order to
	prevent the compiler from optimizing them away

	Fix origin fields that were being set incorrectly during the mutable
	transformation.

compiler/prog_mutable.m:
	New module.  Shift some code from make_hlds_passes to here, since
	modules.m also needs access to it.

compiler/parse_tree.m:
	Include the new module.

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

tests/hard_coded/sub-modules/Mmakefile:
tests/hard_coded/sub-modules/mutable_parent.m:
tests/hard_coded/sub-modules/mutable_child.m:
tests/hard_coded/sub-modules/mutable_grandchild.m:
tests/hard_coded/sub-modules/mutable_parent.exp:
	Test case for mutables and sub-modules.

tests/hard_coded/not_in_interface.m:
tests/hard_coded/not_in_interface.err_exp:
	Test for ordering problems between mutable and initialise
	declarations when emitting errors about items that should
	not occur in module interfaces. This can happen if the
	item's origin field is incorrectly set.
2005-09-15 07:38:47 +00:00

99 lines
3.4 KiB
Mathematica

%-----------------------------------------------------------------------------%
% Copyright (C) 2005 The University of Melbourne.
% This file may only be copied under the terms of the GNU General
% Public License - see the file COPYING in the Mercury distribution.
%-----------------------------------------------------------------------------%
%
% Main authors: rafe, juliensf
%
% Utility predicates for dealing with mutable declarations.
%
%-----------------------------------------------------------------------------%
:- module parse_tree.prog_mutable.
:- interface.
:- import_module mdbcomp.prim_data.
:- import_module parse_tree.prog_data.
:- import_module string.
%-----------------------------------------------------------------------------%
:- func prog_mutable.get_pred_decl(module_name, string, (type), (inst))
= item.
:- func prog_mutable.set_pred_decl(module_name, string, (type), (inst))
= item.
:- func prog_mutable.init_pred_decl(module_name, string) = item.
% XXX We should probably mangle Name for safety...
%
:- func mutable_get_pred_sym_name(sym_name, string) = sym_name.
:- func mutable_set_pred_sym_name(sym_name, string) = sym_name.
:- func mutable_init_pred_sym_name(sym_name, string) = sym_name.
:- func mutable_c_var_name(string) = string.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
:- implementation.
:- import_module parse_tree.prog_mode.
:- import_module list.
:- import_module std_util.
:- import_module varset.
%-----------------------------------------------------------------------------%
get_pred_decl(ModuleName, Name, Type, Inst) = GetPredDecl :-
VarSet = varset__init,
InstVarSet = varset__init,
ExistQVars = [],
Constraints = constraints([], []),
GetPredDecl = pred_or_func(VarSet, InstVarSet, ExistQVars, predicate,
mutable_get_pred_sym_name(ModuleName, Name),
[type_and_mode(Type, out_mode(Inst))],
no /* with_type */, no /* with_inst */, yes(det),
true /* condition */, (semipure), Constraints).
set_pred_decl(ModuleName, Name, Type, Inst) = SetPredDecl :-
VarSet = varset__init,
InstVarSet = varset__init,
ExistQVars = [],
Constraints = constraints([], []),
SetPredDecl = pred_or_func(VarSet, InstVarSet, ExistQVars, predicate,
mutable_set_pred_sym_name(ModuleName, Name),
[type_and_mode(Type, in_mode(Inst))],
no /* with_type */, no /* with_inst */, yes(det),
true /* condition */, (impure), Constraints).
init_pred_decl(ModuleName, Name) = InitPredDecl :-
VarSet = varset__init,
InstVarSet = varset__init,
ExistQVars = [],
Constraints = constraints([], []),
InitPredDecl = pred_or_func(VarSet, InstVarSet, ExistQVars,
predicate, mutable_init_pred_sym_name(ModuleName, Name),
[], no /* with_type */, no /* with_inst */, yes(det),
true /* condition */, (impure), Constraints).
mutable_get_pred_sym_name(ModuleName, Name) =
qualified(ModuleName, "get_" ++ Name).
mutable_set_pred_sym_name(ModuleName, Name) =
qualified(ModuleName, "set_" ++ Name).
mutable_init_pred_sym_name(ModuleName, Name) =
qualified(ModuleName, "initialise_mutable_" ++ Name).
mutable_c_var_name(Name) = "mutable_variable_" ++ Name.
%-----------------------------------------------------------------------------%
:- end_module prog_mutable.
%-----------------------------------------------------------------------------%