[m-rev.] diff: prelim support for pragma oisu

Zoltan Somogyi zs at unimelb.edu.au
Mon Sep 10 23:50:30 AEST 2012


Add preliminary support for a new pragma that will be needed to implement
order-independent state update (oisu). The pragma will look like this:

:- pragma oisu(global_data/0, [
	creators([global_data_init/3]),
	mutators([global_data_add_new_proc_var/4,
		global_data_add_new_proc_layout/4,
		...]),
	destructors([])
]).

compiler/prog_item.m:
	Add a representation for oisu pragmas.

	Change the representation of some existing pragmas to represent
	type_ctors as a unit.

	Give the representation of an existing pragma a less ambiguous name.

compiler/prog_data.m:
	Make a type tighter.

compiler/make_hlds_error.m:
	Give some predicates that generate error messages the ability
	to keep some parts of error messages atomic (i.e. unbreakable
	at white space).

compiler/prog_io_pragma.m:
	Add code for parsing oisu pragmas.

	Treat type_ctors in pragmas as unit, not as a name/arity pair.

compiler/add_pragma.m:
compiler/make_hlds_passes.m:
	Make_hlds_passes.m adds items to the HLDS in three passes (this is
	due to dependencies between items). Pragmas are handled in passes
	2 and 3. One pass used to decide what to do for pragmas in
	make_hlds_passes.m, the other pass made that same decision
	in add_pragma.m. We now make the decision in add_pragma.m
	in BOTH passes. This allows add_pragma.m to export many fewer
	predicates, and reduces the coupling between the two modules.

compiler/add_pragma.m:
compiler/prog_data.m:
	Move a generally-useful function from add_pragma.m to prog_data.m.

compiler/add_pragma.m:
	Add preliminary code for handling oisu pragmas to the HLDS. (Since
	the HLDS has not yet been updated to handle oisu pragmas, we don't
	yet update the HLDS when we handle oisu pragmas.)

	Simplify some code.

compiler/prog_io_util.m:
	Rename a predicate to avoid an ambiguity.

compiler/add_clause.m:
compiler/add_pred.m:
compiler/equiv_type.m:
compiler/goal_expr_to_goal.m:
compiler/intermod.m:
compiler/mercury_to_mercury.m:
compiler/module_imports.m:
compiler/module_qual.m:
compiler/modules.m:
compiler/prog_io_mutable.m:
compiler/prog_io_type_defn.m:
compiler/recompilation.check.m:
compiler/recompilation.version.m:
	Conform to the changes above.

Zoltan.

cvs diff: Diffing .
Index: add_clause.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/add_clause.m,v
retrieving revision 1.72
diff -u -b -r1.72 add_clause.m
--- add_clause.m	7 Sep 2012 11:42:01 -0000	1.72
+++ add_clause.m	10 Sep 2012 13:06:48 -0000
@@ -128,8 +128,8 @@
             ;
                 preds_add_implicit_report_error(ModuleName, PredOrFunc,
                     PredName, Arity, Status, no, Context,
-                    origin_user(PredName), "clause", PredId, !ModuleInfo,
-                    !Specs)
+                    origin_user(PredName), [words("clause")], PredId,
+                    !ModuleInfo, !Specs)
             )
         ),
         % Lookup the pred_info for this pred, add the clause to the
Index: add_pragma.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/add_pragma.m,v
retrieving revision 1.130
diff -u -b -r1.130 add_pragma.m
--- add_pragma.m	7 Sep 2012 11:42:01 -0000	1.130
+++ add_pragma.m	10 Sep 2012 13:06:50 -0000
@@ -13,85 +13,22 @@
 :- import_module hlds.hlds_pred.
 :- import_module hlds.make_hlds.make_hlds_passes.
 :- import_module hlds.make_hlds.qual_info.
-:- import_module libs.globals.
 :- import_module parse_tree.error_util.
-:- import_module parse_tree.prog_data.
 :- import_module parse_tree.prog_item.
 
 :- import_module list.
-:- import_module maybe.
-:- import_module term.
 
 %-----------------------------------------------------------------------------%
 
-:- pred add_pragma(item_pragma_info::in,
+:- pred add_pass_2_pragma(item_pragma_info::in,
     item_status::in, item_status::out, module_info::in, module_info::out,
     list(error_spec)::in, list(error_spec)::out) is det.
 
-:- pred add_pragma_foreign_export(item_origin::in,
-    pragma_info_foreign_export::in, prog_context::in,
-    module_info::in, module_info::out,
-    list(error_spec)::in, list(error_spec)::out) is det.
-
-:- pred add_pragma_reserve_tag(type_ctor::in, import_status::in,
-    prog_context::in, module_info::in, module_info::out,
-    list(error_spec)::in, list(error_spec)::out) is det.
-
-:- pred add_pragma_foreign_export_enum(pragma_info_foreign_export_enum::in,
-    import_status::in, prog_context::in, module_info::in, module_info::out,
-    list(error_spec)::in, list(error_spec)::out) is det.
-
-:- pred add_pragma_foreign_enum(pragma_info_foreign_enum::in,
-    import_status::in, prog_context::in, module_info::in, module_info::out,
-    list(error_spec)::in, list(error_spec)::out) is det.
-
-:- pred add_pragma_type_spec(pragma_info_type_spec::in, term.context::in,
-    module_info::in, module_info::out, qual_info::in, qual_info::out,
-    list(error_spec)::in, list(error_spec)::out) is det.
-
-:- pred add_pragma_termination_info(pragma_info_termination_info::in,
-    prog_context::in, module_info::in, module_info::out,
-    list(error_spec)::in, list(error_spec)::out) is det.
-
-:- pred add_pragma_termination2_info(pragma_info_termination2_info::in,
-    prog_context::in, module_info::in, module_info::out,
-    list(error_spec)::in, list(error_spec)::out) is det.
-
-:- pred add_pragma_structure_sharing(pragma_info_structure_sharing::in,
-    prog_context::in, module_info::in, module_info::out,
-    list(error_spec)::in, list(error_spec)::out) is det.
-
-:- pred add_pragma_structure_reuse(pragma_info_structure_reuse::in,
-    prog_context::in, module_info::in, module_info::out,
-    list(error_spec)::in, list(error_spec)::out) is det.
-
-    % ZZZ 1
-:- pred module_add_pragma_foreign_proc(pragma_info_foreign_proc::in,
-    import_status::in, prog_context::in, maybe(int)::in,
-    module_info::in, module_info::out, qual_info::in, qual_info::out,
-    list(error_spec)::in, list(error_spec)::out) is det.
-
-:- pred module_add_pragma_tabled(pragma_info_tabled::in, prog_context::in,
+:- pred add_pass_3_pragma(item_pragma_info::in,
     import_status::in, import_status::out, module_info::in, module_info::out,
     qual_info::in, qual_info::out,
     list(error_spec)::in, list(error_spec)::out) is det.
 
-    % module_add_pragma_fact_table(FTInfo, Status, Context,
-    %   !ModuleInfo, !Info):
-    %
-    % Add a `pragma fact_table' declaration to the HLDS. This predicate calls
-    % the fact table compiler (fact_table_compile_facts) to create a separate
-    % `.o' file for the fact_table and then creates separate pieces of
-    % `pragma c_code' to access the table in each mode of the fact table
-    % predicate.
-    %
-:- pred module_add_pragma_fact_table(pragma_info_fact_table::in,
-    import_status::in, prog_context::in, module_info::in, module_info::out,
-    qual_info::in, qual_info::out,
-    list(error_spec)::in, list(error_spec)::out) is det.
-
-:- func lookup_current_backend(globals) = backend.
-
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
@@ -130,6 +67,7 @@
 :- import_module parse_tree.mercury_to_mercury.
 :- import_module parse_tree.modules.
 :- import_module parse_tree.prog_ctgc.
+:- import_module parse_tree.prog_data.
 :- import_module parse_tree.prog_foreign.
 :- import_module parse_tree.prog_mode.
 :- import_module parse_tree.prog_out.
@@ -150,16 +88,18 @@
 :- import_module io.
 :- import_module list.
 :- import_module map.
+:- import_module maybe.
 :- import_module multi_map.
 :- import_module pair.
 :- import_module require.
 :- import_module set.
 :- import_module string.
+:- import_module term.
 :- import_module varset.
 
 %-----------------------------------------------------------------------------%
 
-add_pragma(ItemPragma, !Status, !ModuleInfo, !Specs) :-
+add_pass_2_pragma(ItemPragma, !Status, !ModuleInfo, !Specs) :-
     ItemPragma = item_pragma_info(Origin, Pragma, Context, _SeqNum),
     % Check for invalid pragmas in the `interface' section.
     !.Status = item_status(ImportStatus, _),
@@ -180,35 +120,18 @@
         Allowed = yes
     ),
     (
-        % Ignore `pragma source_file' declarations - they're dealt
-        % with elsewhere.
-        Pragma = pragma_source_file(_)
+        Pragma = pragma_foreign_decl(FDInfo),
+        FDInfo = pragma_info_foreign_decl(Lang, IsLocal, C_Header),
+        module_add_foreign_decl(Lang, IsLocal, C_Header, Context, !ModuleInfo)
     ;
         Pragma = pragma_foreign_code(FCInfo),
         FCInfo = pragma_info_foreign_code(Lang, Body_Code),
         module_add_foreign_body_code(Lang, Body_Code, Context, !ModuleInfo)
     ;
-        Pragma = pragma_foreign_decl(FDInfo),
-        FDInfo = pragma_info_foreign_decl(Lang, IsLocal, C_Header),
-        module_add_foreign_decl(Lang, IsLocal, C_Header, Context, !ModuleInfo)
-    ;
         Pragma = pragma_foreign_import_module(FIMInfo),
         FIMInfo = pragma_info_foreign_import_module(Lang, Import),
         module_add_foreign_import_module(Lang, Import, Context, !ModuleInfo)
     ;
-        % Handle pragma foreign procs later on (when we process clauses).
-        Pragma = pragma_foreign_proc(_)
-    ;
-        % Handle pragma foreign_export_enum (after we have added all the
-        % types).
-        Pragma = pragma_foreign_export_enum(_)
-    ;
-        % Likewise for pragma foreign_enum.
-        Pragma = pragma_foreign_enum(_)
-    ;
-        % Handle pragma tabled decls later on (when we process clauses).
-        Pragma = pragma_tabled(_)
-    ;
         Pragma = pragma_inline(PredNameArity),
         PredNameArity = pred_name_arity(Name, Arity),
         add_pred_marker("inline", Name, Arity, ImportStatus, Context,
@@ -221,20 +144,6 @@
             marker_user_marked_no_inline, [marker_user_marked_inline],
             !ModuleInfo, !Specs)
     ;
-        Pragma = pragma_obsolete(PredNameArity),
-        PredNameArity = pred_name_arity(Name, Arity),
-        add_pred_marker("obsolete", Name, Arity, ImportStatus,
-            Context, marker_obsolete, [], !ModuleInfo, !Specs)
-    ;
-        Pragma = pragma_no_detism_warning(PredNameArity),
-        PredNameArity = pred_name_arity(Name, Arity),
-        add_pred_marker("no_determinism_warning", Name, Arity, ImportStatus,
-            Context, marker_no_detism_warning, [], !ModuleInfo, !Specs)
-    ;
-        % Handle pragma foreign_export decls later on, after default
-        % function modes have been added.
-        Pragma = pragma_foreign_export(_)
-    ;
         % Used for inter-module unused argument elimination.
         % This can only appear in .opt files.
         Pragma = pragma_unused_args(UnusedArgsInfo),
@@ -281,27 +190,15 @@
                 !ModuleInfo, !Specs)
         )
     ;
-        % Handle pragma type_spec decls later on (when we process clauses).
-        Pragma = pragma_type_spec(_)
-    ;
-        % Handle pragma fact_table decls later on (when we process clauses
-        % -- since these decls take the place of clauses).
-        Pragma = pragma_fact_table(_)
-    ;
-        % Handle pragma reserve_tag decls later on (when we process clauses
-        % -- they need to be handled after the type definitions
-        % have been added).
-        Pragma = pragma_reserve_tag(_)
-    ;
-        Pragma = pragma_promise_pure(PredNameArity),
+        Pragma = pragma_obsolete(PredNameArity),
         PredNameArity = pred_name_arity(Name, Arity),
-        add_pred_marker("promise_pure", Name, Arity, ImportStatus,
-            Context, marker_promised_pure, [], !ModuleInfo, !Specs)
+        add_pred_marker("obsolete", Name, Arity, ImportStatus,
+            Context, marker_obsolete, [], !ModuleInfo, !Specs)
     ;
-        Pragma = pragma_promise_semipure(PredNameArity),
+        Pragma = pragma_no_detism_warning(PredNameArity),
         PredNameArity = pred_name_arity(Name, Arity),
-        add_pred_marker("promise_semipure", Name, Arity, ImportStatus,
-            Context, marker_promised_semipure, [], !ModuleInfo, !Specs)
+        add_pred_marker("no_determinism_warning", Name, Arity, ImportStatus,
+            Context, marker_no_detism_warning, [], !ModuleInfo, !Specs)
     ;
         Pragma = pragma_promise_eqv_clauses(PredNameArity),
         PredNameArity = pred_name_arity(Name, Arity),
@@ -309,13 +206,15 @@
             ImportStatus, Context, marker_promised_equivalent_clauses, [],
             !ModuleInfo, !Specs)
     ;
-        % Handle pragma termination_info decls later on, in pass 3 --
-        % we need to add function default modes before handling
-        % these pragmas
-        Pragma = pragma_termination_info(_)
+        Pragma = pragma_promise_pure(PredNameArity),
+        PredNameArity = pred_name_arity(Name, Arity),
+        add_pred_marker("promise_pure", Name, Arity, ImportStatus,
+            Context, marker_promised_pure, [], !ModuleInfo, !Specs)
     ;
-        % As for termination_info pragmas
-        Pragma = pragma_termination2_info(_)
+        Pragma = pragma_promise_semipure(PredNameArity),
+        PredNameArity = pred_name_arity(Name, Arity),
+        add_pred_marker("promise_semipure", Name, Arity, ImportStatus,
+            Context, marker_promised_semipure, [], !ModuleInfo, !Specs)
     ;
         Pragma = pragma_terminates(PredNameArity),
         PredNameArity = pred_name_arity(Name, Arity),
@@ -337,10 +236,6 @@
             [marker_terminates, marker_does_not_terminate],
             !ModuleInfo, !Specs)
     ;
-        Pragma = pragma_structure_sharing(_)
-    ;
-        Pragma = pragma_structure_reuse(_)
-    ;
         Pragma = pragma_mode_check_clauses(PredNameArity),
         PredNameArity = pred_name_arity(Name, Arity),
         add_pred_marker("mode_check_clauses", Name, Arity, ImportStatus,
@@ -359,19 +254,149 @@
         RFSInfo = pragma_info_require_feature_set(FeatureSet),
         check_required_feature_set(FeatureSet, ImportStatus, Context,
             !ModuleInfo, !Specs)
+    ;
+        % Ignore `pragma source_file' declarations in pass 2;
+        % they have already been handled while reading in the items.
+        Pragma = pragma_source_file(_)
+    ;
+        % Ignore these pragmas in pass 2; we will handle them in pass 3,
+        % when we process clauses.
+        ( Pragma = pragma_foreign_proc(_)
+        ; Pragma = pragma_type_spec(_)
+        ; Pragma = pragma_tabled(_)
+        ; Pragma = pragma_fact_table(_)
+        )
+    ;
+        % Ignore these pragmas in pass 2; we will handle them in pass 3,
+        % after we have added all the types.
+        ( Pragma = pragma_foreign_export_enum(_)
+        ; Pragma = pragma_foreign_enum(_)
+        ; Pragma = pragma_reserve_tag(_)
+        ; Pragma = pragma_oisu(_)
+        )
+    ;
+        % Ignore these pragmas in pass 2; we will handle them in pass 3,
+        % after default function modes have been added.
+        ( Pragma = pragma_foreign_proc_export(_)
+        ; Pragma = pragma_termination_info(_)
+        ; Pragma = pragma_termination2_info(_)
+        )
+    ;
+        % Ignore these pragmas in pass 2; we will handle them in pass 3.
+        % XXX Document the reason why we handle them then.
+        ( Pragma = pragma_structure_sharing(_)
+        ; Pragma = pragma_structure_reuse(_)
+        )
     ).
 
-add_pragma_foreign_export(Origin, FEInfo, Context, !ModuleInfo, !Specs) :-
-    FEInfo = pragma_info_foreign_export(Lang, PrednameModesPF, ExportedName),
+%-----------------------------------------------------------------------------%
+
+add_pass_3_pragma(ItemPragma, !Status, !ModuleInfo, !QualInfo, !Specs) :-
+    ItemPragma = item_pragma_info(Origin, Pragma, Context, SeqNum),
+    (
+        Pragma = pragma_foreign_proc(FPInfo),
+        add_pragma_foreign_proc(FPInfo, !.Status, Context, yes(SeqNum),
+            !ModuleInfo, !Specs)
+    ;
+        Pragma = pragma_foreign_proc_export(FEInfo),
+        add_pragma_foreign_proc_export(Origin, FEInfo, Context,
+            !ModuleInfo, !Specs)
+    ;
+        Pragma = pragma_foreign_export_enum(FEEInfo),
+        add_pragma_foreign_export_enum(FEEInfo, !.Status, Context,
+            !ModuleInfo, !Specs)
+    ;
+        Pragma = pragma_foreign_enum(FEInfo),
+        add_pragma_foreign_enum(FEInfo, !.Status, Context, !ModuleInfo, !Specs)
+    ;
+        Pragma = pragma_type_spec(TypeSpecInfo),
+        add_pragma_type_spec(TypeSpecInfo, Context,
+            !ModuleInfo, !QualInfo, !Specs)
+    ;
+        Pragma = pragma_tabled(TabledInfo),
+        module_info_get_globals(!.ModuleInfo, Globals),
+        globals.lookup_bool_option(Globals, type_layout, TypeLayout),
+        (
+            TypeLayout = yes,
+            module_add_pragma_tabled(TabledInfo, Context, !Status,
+                !ModuleInfo, !QualInfo, !Specs)
+        ;
+            TypeLayout = no,
+            TabledInfo = pragma_info_tabled(EvalMethod, _, _, _),
+            Pieces = [words("Error:"),
+                quote(":- pragma " ++ eval_method_to_string(EvalMethod)),
+                words("declaration requires type_ctor_layout structures."),
+                words("Don't use --no-type-layout to disable them."), nl],
+            Msg = simple_msg(Context, [always(Pieces)]),
+            Spec = error_spec(severity_error, phase_parse_tree_to_hlds, [Msg]),
+            !:Specs = [Spec | !.Specs]
+        )
+    ;
+        Pragma = pragma_fact_table(FTInfo),
+        add_pragma_fact_table(FTInfo, !.Status, Context, !ModuleInfo, !Specs)
+    ;
+        Pragma = pragma_reserve_tag(TypeCtor),
+        add_pragma_reserve_tag(TypeCtor, !.Status, Context,
+            !ModuleInfo, !Specs)
+    ;
+        Pragma = pragma_oisu(OISUInfo),
+        add_pragma_oisu(OISUInfo, !.Status, Context, !ModuleInfo, !Specs)
+    ;
+        Pragma = pragma_termination_info(TermInfo),
+        add_pragma_termination_info(TermInfo, Context, !ModuleInfo, !Specs)
+    ;
+        Pragma = pragma_termination2_info(Term2Info),
+        add_pragma_termination2_info(Term2Info, Context, !ModuleInfo, !Specs)
+    ;
+        Pragma = pragma_structure_sharing(SharingInfo),
+        add_pragma_structure_sharing(SharingInfo, Context, !ModuleInfo, !Specs)
+    ;
+        Pragma = pragma_structure_reuse(ReuseInfo),
+        add_pragma_structure_reuse(ReuseInfo, Context, !ModuleInfo, !Specs)
+    ;
+        % Ignore these kinds of pragmas in pass 3, since they have
+        % already been handled earlier, in pass 2, or even earlier.
+        ( Pragma = pragma_foreign_decl(_)
+        ; Pragma = pragma_foreign_code(_)
+        ; Pragma = pragma_foreign_import_module(_)
+        ; Pragma = pragma_inline(_)
+        ; Pragma = pragma_no_inline(_)
+        ; Pragma = pragma_unused_args(_)
+        ; Pragma = pragma_exceptions(_)
+        ; Pragma = pragma_trailing_info(_)
+        ; Pragma = pragma_mm_tabling_info(_)
+        ; Pragma = pragma_obsolete(_)
+        ; Pragma = pragma_no_detism_warning(_)
+        ; Pragma = pragma_source_file(_)
+        ; Pragma = pragma_promise_eqv_clauses(_)
+        ; Pragma = pragma_promise_pure(_)
+        ; Pragma = pragma_promise_semipure(_)
+        ; Pragma = pragma_terminates(_)
+        ; Pragma = pragma_does_not_terminate(_)
+        ; Pragma = pragma_check_termination(_)
+        ; Pragma = pragma_mode_check_clauses(_)
+        ; Pragma = pragma_require_feature_set(_)
+        )
+    ).
+
+%-----------------------------------------------------------------------------%
+
+:- pred add_pragma_foreign_proc_export(item_origin::in,
+    pragma_info_foreign_proc_export::in, prog_context::in,
+    module_info::in, module_info::out,
+    list(error_spec)::in, list(error_spec)::out) is det.
+
+add_pragma_foreign_proc_export(Origin, FPEInfo, Context, !ModuleInfo,
+        !Specs) :-
+    FPEInfo = pragma_info_foreign_proc_export(Lang, PrednameModesPF,
+        ExportedName),
     PrednameModesPF = pred_name_modes_pf(Name, Modes, PredOrFunc), 
     module_info_get_predicate_table(!.ModuleInfo, PredTable),
     list.length(Modes, Arity),
     (
         predicate_table_search_pf_sym_arity(PredTable,
             may_be_partially_qualified, PredOrFunc, Name, Arity, PredIds),
-        ( PredIds = [_]
-        ; PredIds = [_, _ | _]
-        )
+        PredIds = [_ | _]
     ->
         (
             PredIds = [PredId],
@@ -379,22 +404,18 @@
                 PredId, Modes, ExportedName, Context, !ModuleInfo, !Specs)
         ;
             PredIds = [_, _ | _],
-            StartPieces = [
-                words("error: ambiguous"), p_or_f(PredOrFunc),
+            StartPieces = [words("error: ambiguous"), p_or_f(PredOrFunc),
                 words("name in"), quote("pragma foreign_export"),
                 words("declaration."), nl,
-                words("The possible matches are:"), nl_indent_delta(1)
-            ],
+                words("The possible matches are:"), nl_indent_delta(1)],
             PredIdPiecesList = list.map(
                 describe_one_pred_name(!.ModuleInfo, should_module_qualify),
                 PredIds),
             PredIdPieces = component_list_to_line_pieces(PredIdPiecesList,
                 [suffix(".")]),
             MainPieces = StartPieces ++ PredIdPieces,
-            VerbosePieces = [
-                words("An explicit module qualifier may"),
-                words("be necessary.")
-            ],
+            VerbosePieces = [words("An explicit module qualifier"),
+                words("may be necessary.")],
             Msg = simple_msg(Context,
                 [always(MainPieces), verbose_only(VerbosePieces)]),
             Spec = error_spec(severity_error, phase_parse_tree_to_hlds, [Msg]),
@@ -404,7 +425,8 @@
         (
             Origin = user,
             undefined_pred_or_func_error(Name, Arity, Context,
-                "`:- pragma foreign_export' declaration", !Specs)
+                [quote(":- pragma foreign_export"), words("declaration")],
+                !Specs)
         ;
             Origin = compiler(Details),
             (
@@ -454,8 +476,7 @@
                 fixed("`:- pragma foreign_export' declaration"),
                 words("for a procedure that has"),
                 words("a declared determinism of"),
-                fixed(determinism_to_string(Detism) ++ ".")
-            ],
+                fixed(determinism_to_string(Detism) ++ "."), nl],
             Msg = simple_msg(Context, [always(Pieces)]),
             Spec = error_spec(severity_error, phase_parse_tree_to_hlds,
                 [Msg]),
@@ -484,7 +505,8 @@
         (
             Origin = user,
             undefined_mode_error(Name, Arity, Context,
-                "`:- pragma foreign_export' declaration", !Specs)
+                [quote(":- pragma foreign_export"), words("declaration")],
+                !Specs)
         ;
             Origin = compiler(Details),
             (
@@ -506,13 +528,13 @@
 
 %-----------------------------------------------------------------------------%
 
+:- pred add_pragma_reserve_tag(type_ctor::in, import_status::in,
+    prog_context::in, module_info::in, module_info::out,
+    list(error_spec)::in, list(error_spec)::out) is det.
+
 add_pragma_reserve_tag(TypeCtor, PragmaStatus, Context, !ModuleInfo, !Specs) :-
     TypeCtor = type_ctor(TypeName, TypeArity),
     module_info_get_type_table(!.ModuleInfo, TypeTable0),
-    ContextPieces = [
-        words("In"), quote("pragma reserve_tag"), words("declaration for"),
-        sym_name_and_arity(TypeName / TypeArity), suffix(":"), nl
-    ],
     ( search_type_ctor_defn(TypeTable0, TypeCtor, TypeDefn0) ->
         hlds_data.get_type_defn_body(TypeDefn0, TypeBody0),
         hlds_data.get_type_defn_status(TypeDefn0, TypeStatus),
@@ -527,11 +549,9 @@
             )
         ->
             MaybeSeverity = yes(severity_error),
-            ErrorPieces = [
-                words("error:"), quote("pragma reserve_tag"),
+            ErrorPieces = [words("error:"), quote("pragma reserve_tag"),
                 words("declaration must have"),
-                words("the same visibility as the type definition.")
-            ]
+                words("the same visibility as the type definition.")]
         ;
             (
                 TypeBody0 = hlds_du_type(Body, _CtorTags0, _CheaperTagTest,
@@ -544,11 +564,9 @@
                     TypeStatus \= status_opt_imported
                 ->
                     MaybeSeverity = yes(severity_warning),
-                    ErrorPieces = [
-                        words("warning: multiple"),
+                    ErrorPieces = [words("warning: multiple"),
                         quote("pragma reserved_tag"),
-                        words("declarations for the same type.")
-                    ]
+                        words("declarations for the same type."), nl]
                 ;
                     MaybeSeverity = no,
                     ErrorPieces = []
@@ -574,18 +592,15 @@
                 ; TypeBody0 = hlds_abstract_type(_)
                 ),
                 MaybeSeverity = yes(severity_error),
-                ErrorPieces = [
-                    words("error:"), sym_name_and_arity(TypeName / TypeArity),
-                    words("is not a discriminated union type."), nl
-                ]
+                ErrorPieces = [words("error:"),
+                    sym_name_and_arity(TypeName / TypeArity),
+                    words("is not a discriminated union type."), nl]
             )
         )
     ;
         MaybeSeverity = yes(severity_error),
-        ErrorPieces = [
-            words("error: undefined type"),
-            sym_name_and_arity(TypeName / TypeArity), suffix("."), nl
-        ]
+        ErrorPieces = [words("error: undefined type"),
+            sym_name_and_arity(TypeName / TypeArity), suffix("."), nl]
     ),
     (
         ErrorPieces = []
@@ -597,6 +612,9 @@
             MaybeSeverity = no,
             unexpected($module, $pred, "no severity")
         ),
+        ContextPieces = [words("In"), quote("pragma reserve_tag"),
+            words("declaration for"), sym_name_and_arity(TypeName / TypeArity),
+            suffix(":"), nl],
         Msg = simple_msg(Context, [always(ContextPieces ++ ErrorPieces)]),
         Spec = error_spec(Severity, phase_parse_tree_to_hlds, [Msg]),
         !:Specs = [Spec | !.Specs]
@@ -604,17 +622,19 @@
 
 %-----------------------------------------------------------------------------%
 
+:- pred add_pragma_foreign_export_enum(pragma_info_foreign_export_enum::in,
+    import_status::in, prog_context::in, module_info::in, module_info::out,
+    list(error_spec)::in, list(error_spec)::out) is det.
+
 add_pragma_foreign_export_enum(FEEInfo, _ImportStatus, Context,
         !ModuleInfo, !Specs) :-
-    FEEInfo = pragma_info_foreign_export_enum(Lang, TypeName, TypeArity,
+    FEEInfo = pragma_info_foreign_export_enum(Lang, TypeCtor,
         Attributes, Overrides),
     TypeCtor = type_ctor(TypeName, TypeArity),
     module_info_get_type_table(!.ModuleInfo, TypeTable),
-    ContextPieces = [
-        words("In"), fixed("`pragma foreign_export_enum'"),
+    ContextPieces = [words("In"), quote("pragma foreign_export_enum"),
         words("declaration for"),
-        sym_name_and_arity(TypeName / TypeArity), suffix(":"), nl
-    ],
+        sym_name_and_arity(TypeName / TypeArity), suffix(":"), nl],
     (
         % Emit an error message for foreign_export_enum pragmas for the
         % builtin atomic types.
@@ -626,12 +646,9 @@
         )
     ->
         MaybeSeverity = yes(severity_error),
-        ErrorPieces = [
-            words("error: "),
+        ErrorPieces = [words("error: "),
             sym_name_and_arity(TypeName / TypeArity),
-            words("is an atomic type"),
-            suffix(".")
-        ]
+            words("is an atomic type"), suffix("."), nl]
     ;
         ( search_type_ctor_defn(TypeTable, TypeCtor, TypeDefn) ->
             get_type_defn_body(TypeDefn, TypeBody),
@@ -642,12 +659,9 @@
                 ; TypeBody = hlds_foreign_type(_)
                 ),
                 MaybeSeverity = yes(severity_error),
-                ErrorPieces = [
-                    words("error: "),
+                ErrorPieces = [words("error: "),
                     sym_name_and_arity(TypeName / TypeArity),
-                    words("is not an enumeration type"),
-                    suffix(".")
-                ]
+                    words("is not an enumeration type"), suffix("."), nl]
             ;
                 % XXX How should we handle IsForeignType here?
                 TypeBody = hlds_du_type(Ctors, _TagValues, _CheaperTagTest,
@@ -671,8 +685,9 @@
                     (
                         MaybeOverridesMap = yes(OverridesMap),
                         build_export_enum_name_map(ContextPieces, Lang,
-                            TypeName, TypeArity, Context, Prefix, MakeUpperCase,
-                            OverridesMap, Ctors, MaybeMapping, !Specs),
+                            TypeName, TypeArity, Context, Prefix,
+                            MakeUpperCase, OverridesMap, Ctors, MaybeMapping,
+                            !Specs),
                         (
                             MaybeMapping = yes(Mapping),
                             ExportedEnum = exported_enum_info(Lang, Context,
@@ -697,18 +712,16 @@
                     MaybeSeverity = yes(severity_error),
                     % XXX Maybe we should add a verbose error message that
                     % identifies the non-zero arity constructors.
-                    ErrorPieces = [
-                        words("error: "),
+                    ErrorPieces = [words("error: "),
                         sym_name_and_arity(TypeName / TypeArity),
                         words("is not an enumeration type."),
                         words("It has one or more non-zero arity"),
-                        words("constructors.")
-                    ]
+                        words("constructors."), nl]
                 )
             )
         ;
-            % This case corresponds to an undefined type.  We do not
-            % issue an error message for it here since module qualification
+            % This case corresponds to an undefined type. We do not issue
+            % an error message for it here since module qualification
             % will have already done so.
             MaybeSeverity = no,
             ErrorPieces = []
@@ -766,24 +779,22 @@
     ;
         MaybeOverridesMap = no,
         % XXX we should report exactly why it is not a bijective.
-        ErrorPieces = [
-            words("error: "),
+        ErrorPieces = [words("error: "),
             words("the user-specified mapping between Mercury and"),
-            words("foreign names does not form a bijection.")
-        ],
+            words("foreign names does not form a bijection.")],
         Msg = simple_msg(Context, [always(ContextPieces ++ ErrorPieces)]),
         Spec = error_spec(severity_error, phase_parse_tree_to_hlds, [Msg]),
         !:Specs = [Spec | !.Specs]
     ).
 
-:- pred build_export_enum_name_map(format_components::in,
-    foreign_language::in, sym_name::in, arity::in, prog_context::in,
-    string::in, uppercase_export_enum::in, map(sym_name, string)::in,
+:- pred build_export_enum_name_map(format_components::in, foreign_language::in,
+    sym_name::in, arity::in, prog_context::in, string::in,
+    uppercase_export_enum::in, map(sym_name, string)::in,
     list(constructor)::in, maybe(map(sym_name, string))::out,
     list(error_spec)::in, list(error_spec)::out) is det.
 
-build_export_enum_name_map(ContextPieces, Lang, TypeName, TypeArity,
-        Context, Prefix, MakeUpperCase, Overrides0, Ctors, MaybeMapping, !Specs) :-
+build_export_enum_name_map(ContextPieces, Lang, TypeName, TypeArity, Context,
+        Prefix, MakeUpperCase, Overrides0, Ctors, MaybeMapping, !Specs) :-
     (
         TypeName = qualified(TypeModuleQual, _)
     ;
@@ -796,33 +807,28 @@
     list.foldl3(
         add_ctor_to_name_map(Lang, Prefix, MakeUpperCase, TypeModuleQual),
         Ctors, Overrides0, Overrides, map.init, NameMap, [], BadCtors),
-    %
-    % Check for any remaining user-specified renamings that didn't
-    % match the constructors of the type and report and error
-    % for them.
-    %
+
+    % Check for any remaining user-specified renamings that didn't match
+    % the constructors of the type and report and error for them.
+
     ( not map.is_empty(Overrides) ->
-       InvalidRenamingPieces = [
-            words("user-specified foreign names for constructors"),
-            words("that do not match match any of the constructors of"),
-            sym_name_and_arity(TypeName / TypeArity), suffix(".")
-        ],
+       InvalidRenamingPieces = [words("user-specified foreign names"),
+            words("for constructors that do not match match"),
+            words("any of the constructors of"),
+            sym_name_and_arity(TypeName / TypeArity), suffix("."), nl],
         InvalidRenamings = map.keys(Overrides),
         InvalidRenamingComponents =
             list.map((func(S) = [sym_name(S)]), InvalidRenamings),
         InvalidRenamingList = component_list_to_line_pieces(
             InvalidRenamingComponents, [nl]),
-        InvalidRenamingVerbosePieces = [
-            words("The following"),
+        InvalidRenamingVerbosePieces = [words("The following"),
             words(choose_number(InvalidRenamings,
                 "constructor does", "constructors do")),
-            words("not match"), suffix(":"), nl_indent_delta(2)
-        ] ++ InvalidRenamingList,
+            words("not match"), suffix(":"), nl_indent_delta(2)]
+            ++ InvalidRenamingList,
         InvalidRenamingMsg = simple_msg(Context,
-            [
-                always(ContextPieces ++ InvalidRenamingPieces),
-                verbose_only(InvalidRenamingVerbosePieces)
-            ]),
+            [always(ContextPieces ++ InvalidRenamingPieces),
+                verbose_only(InvalidRenamingVerbosePieces)]),
         InvalidRenamingSpec = error_spec(severity_error,
             phase_parse_tree_to_hlds, [InvalidRenamingMsg]),
         list.cons(InvalidRenamingSpec, !Specs),
@@ -861,17 +867,13 @@
                 SortedBadCtors),
             BadCtorsList = component_list_to_line_pieces(
                 BadCtorComponents, [nl]),
-            BadCtorsVerboseErrorPieces = [
-                words("The following"),
-                words(choose_number(BadCtors, "constructor",
-                    "constructors")),
-                words("cannot be converted:"), nl_indent_delta(2)
-            ] ++ BadCtorsList,
+            BadCtorsVerboseErrorPieces = [words("The following"),
+                words(choose_number(BadCtors, "constructor", "constructors")),
+                words("cannot be converted:"), nl_indent_delta(2)]
+                ++ BadCtorsList,
             BadCtorsMsg = simple_msg(Context,
-                [
-                    always(ContextPieces ++ BadCtorsErrorPieces),
-                    verbose_only(BadCtorsVerboseErrorPieces)
-                ]),
+                [always(ContextPieces ++ BadCtorsErrorPieces),
+                    verbose_only(BadCtorsVerboseErrorPieces)]),
             BadCtorsSpec = error_spec(severity_error,
                 phase_parse_tree_to_hlds, [BadCtorsMsg]),
             list.cons(BadCtorsSpec, !Specs),
@@ -894,10 +896,9 @@
     ;
         MaybeNameMap = no,
         % XXX we should report exactly why it is not bijective.
-        ErrorPieces = [
-            words("error: the mapping between Mercury and foreign names"),
-            words("does not form a bijection.")
-        ],
+        ErrorPieces = [words("error:"),
+            words("the mapping between Mercury and foreign names"),
+            words("does not form a bijection."), nl],
         Msg = simple_msg(Context, [always(ContextPieces ++ ErrorPieces)]),
         Spec = error_spec(severity_error, phase_parse_tree_to_hlds, [Msg]),
         !:Specs = [Spec | !.Specs]
@@ -919,7 +920,7 @@
         % All of the constructor sym_names should be module qualified by now.
         % We unqualify them before inserting them into the mapping since
         % the code in export.m expects that to be done.
-        %
+
         CtorSymName = qualified(_, _),
         UnqualCtorName = unqualify_name(CtorSymName),
         UnqualSymName = unqualified(UnqualCtorName)
@@ -927,9 +928,8 @@
         CtorSymName = unqualified(_),
         unexpected($module, $pred, "unqualified constructor name")
     ),
-    %
+
     % If the user specified a name for this constructor then use that.
-    %
     ( map.remove(UnqualSymName, UserForeignName, !Overrides) ->
         ForeignNameTail = UserForeignName
     ;
@@ -966,16 +966,17 @@
 
 %-----------------------------------------------------------------------------%
 
+:- pred add_pragma_foreign_enum(pragma_info_foreign_enum::in,
+    import_status::in, prog_context::in, module_info::in, module_info::out,
+    list(error_spec)::in, list(error_spec)::out) is det.
+
 add_pragma_foreign_enum(FEInfo, ImportStatus, Context, !ModuleInfo, !Specs) :-
-    FEInfo = pragma_info_foreign_enum(Lang, TypeName, TypeArity,
-        ForeignTagValues),
+    FEInfo = pragma_info_foreign_enum(Lang, TypeCtor, ForeignTagValues),
     TypeCtor = type_ctor(TypeName, TypeArity),
     module_info_get_type_table(!.ModuleInfo, TypeTable0),
-    ContextPieces = [
-        words("In"), fixed("`pragma foreign_enum'"),
+    ContextPieces = [words("In"), quote("pragma foreign_enum"),
         words("declaration for"),
-        sym_name_and_arity(TypeName / TypeArity), suffix(":"), nl
-    ],
+        sym_name_and_arity(TypeName / TypeArity), suffix(":"), nl],
     (
         % Emit an error message for foreign_enum pragmas for the
         % builtin atomic types.
@@ -1009,7 +1010,7 @@
                 DuTypeKind0, MaybeUserEq, MaybeDirectArgCtors,
                 ReservedTag, ReservedAddr, IsForeignType),
             % Work out what language's foreign_enum pragma we should be
-            % looking at for the the current compilation target language.
+            % looking at for the current compilation target language.
             module_info_get_globals(!.ModuleInfo, Globals),
             globals.get_target(Globals, TargetLanguage),
             LangForForeignEnums =
@@ -1064,7 +1065,7 @@
                         )
                     ;
                         % If there are no matching foreign_enum pragmas for
-                        % this target language then don't do anything.
+                        % this target language, then don't do anything.
                         true
                     ),
                     MaybeSeverity = no,
@@ -1159,8 +1160,7 @@
     ).
 
     % The constructor names we get from the parse tree may be unqualified
-    % but the ones we match against in the HLDS are not.  Module qualify
-    % them.
+    % but the ones we match against in the HLDS are not. Module qualify them.
     %
     % XXX module_qual.m should really be doing this rather than add_pragma.m.
     %
@@ -1236,17 +1236,12 @@
     DoOrDoes = choose_number(UnmappedCtors,
         "constructor does not have a foreign value",
         "constructors do not have foreign values"),
-    VerboseErrorPieces = [
-        words("The following"), words(DoOrDoes),
-        nl_indent_delta(2)
-    ] ++ CtorList,
+    VerboseErrorPieces = [words("The following"), words(DoOrDoes),
+        nl_indent_delta(2)] ++ CtorList,
     Msg = simple_msg(Context,
-        [
-            always(ContextPieces ++ ErrorPieces),
-            verbose_only(VerboseErrorPieces)
-        ]),
-    Spec = error_spec(severity_error, phase_parse_tree_to_hlds,
-        [Msg]),
+        [always(ContextPieces ++ ErrorPieces),
+            verbose_only(VerboseErrorPieces)]),
+    Spec = error_spec(severity_error, phase_parse_tree_to_hlds, [Msg]),
     list.cons(Spec, !Specs).
 
 :- pred add_foreign_enum_bijection_error(prog_context::in,
@@ -1254,11 +1249,9 @@
     is det.
 
 add_foreign_enum_bijection_error(Context, ContextPieces, !Specs) :-
-    ErrorPieces = [
-        words("error: "),
+    ErrorPieces = [words("error: "),
         words("the mapping between Mercury enumeration values and"),
-        words("foreign values does not form a bijection.")
-    ],
+        words("foreign values does not form a bijection."), nl],
     Msg = simple_msg(Context, [always(ContextPieces ++ ErrorPieces)]),
     Spec = error_spec(severity_error, phase_parse_tree_to_hlds, [Msg]),
     list.cons(Spec, !Specs).
@@ -1269,12 +1262,10 @@
 
 add_foreign_enum_pragma_in_interface_error(Context, TypeName, TypeArity,
         !Specs) :-
-    ErrorPieces = [
-        words("Error: "),
+    ErrorPieces = [words("Error: "),
         words("`pragma foreign_enum' declaration for"),
         sym_name_and_arity(TypeName / TypeArity),
-        words("in module interface.")
-    ],
+        words("in module interface."), nl ],
     Msg = simple_msg(Context, [always(ErrorPieces)]),
     Spec = error_spec(severity_error, phase_parse_tree_to_hlds, [Msg]),
     list.cons(Spec, !Specs).
@@ -1398,6 +1389,10 @@
 
 %-----------------------------------------------------------------------------%
 
+:- pred add_pragma_type_spec(pragma_info_type_spec::in, term.context::in,
+    module_info::in, module_info::out, qual_info::in, qual_info::out,
+    list(error_spec)::in, list(error_spec)::out) is det.
+
 add_pragma_type_spec(TSInfo, Context, !ModuleInfo, !QualInfo, !Specs) :-
     TSInfo = pragma_info_type_spec(SymName, _, Arity, MaybePredOrFunc,
         _, _, _, _),
@@ -1419,7 +1414,7 @@
             !ModuleInfo, !QualInfo, !Specs)
     ;
         undefined_pred_or_func_error(SymName, Arity, Context,
-            "`:- pragma type_spec' declaration", !Specs)
+            [quote(":- pragma type_spec"), words("declaration")], !Specs)
     ).
 
 :- pred add_pragma_type_spec_2(pragma_info_type_spec::in,
@@ -1455,10 +1450,10 @@
             % the interface procedures for local predicates to check the
             % type-class correctness of the requested specializations.
             %
-            % If we're doing smart recompilation we need to record the pragmas
-            % even if we aren't doing type specialization to avoid problems
-            % with differing output for the recompilation tests in debugging
-            % grades.
+            % If we are doing smart recompilation, we need to record the
+            % pragmas even if we aren't doing type specialization, to avoid
+            % problems with differing output for the recompilation tests
+            % in debugging grades.
 
             ( DoTypeSpec = yes
             ; \+ pred_info_is_imported(PredInfo0)
@@ -1709,12 +1704,12 @@
 :- pred find_duplicate_list_elements(list(T)::in, list(T)::out) is det.
 
 find_duplicate_list_elements([], []).
-find_duplicate_list_elements([H | T], Vars) :-
-    find_duplicate_list_elements(T, Vars0),
+find_duplicate_list_elements([H | T], DupVars) :-
+    find_duplicate_list_elements(T, DupVars0),
     ( list.member(H, T) ->
-        Vars = [H | Vars0]
+        DupVars = [H | DupVars0]
     ;
-        Vars = Vars0
+        DupVars = DupVars0
     ).
 
 :- pred report_subst_existq_tvars(pred_info::in, prog_context::in,
@@ -1786,8 +1781,8 @@
     Arity = pred_info_orig_arity(PredInfo),
     PredOrFunc = pred_info_is_pred_or_func(PredInfo),
     SimpleCallId = simple_call_id(PredOrFunc, qualified(Module, Name), Arity),
-    Pieces = [words("In `:- pragma type_spec' declaration for"),
-        simple_call(SimpleCallId), suffix(":"), nl].
+    Pieces = [words("In"), quote(":- pragma type_spec"),
+        words("declaration for"), simple_call(SimpleCallId), suffix(":"), nl].
 
 :- func report_variables(list(tvar), tvarset) = list(format_component).
 
@@ -1820,7 +1815,7 @@
         ;
             module_info_incr_errors(!ModuleInfo),
             undefined_mode_error(SymName, Arity, Context,
-                "`:- pragma type_spec' declaration", !Specs),
+                [quote(":- pragma type_spec"), words("declaration")], !Specs),
             MaybeProcIds = no
         )
     ;
@@ -1838,6 +1833,10 @@
 
 %-----------------------------------------------------------------------------%
 
+:- pred add_pragma_termination2_info(pragma_info_termination2_info::in,
+    prog_context::in, module_info::in, module_info::out,
+    list(error_spec)::in, list(error_spec)::out) is det.
+
 add_pragma_termination2_info(Term2Info, Context, !ModuleInfo, !Specs) :-
     Term2Info = pragma_info_termination2_info(PredModesPF,
         MaybePragmaSuccessArgSizeInfo, MaybePragmaFailureArgSizeInfo,
@@ -1909,6 +1908,10 @@
 
 %-----------------------------------------------------------------------------%
 
+:- pred add_pragma_structure_sharing(pragma_info_structure_sharing::in,
+    prog_context::in, module_info::in, module_info::out,
+    list(error_spec)::in, list(error_spec)::out) is det.
+
 add_pragma_structure_sharing(SharingInfo, Context, !ModuleInfo, !Specs):-
     SharingInfo = pragma_info_structure_sharing(PredNameModesPF,
         HeadVars, Types, MaybeSharingDomain),
@@ -1970,6 +1973,12 @@
         )
     ).
 
+%-----------------------------------------------------------------------------%
+
+:- pred add_pragma_structure_reuse(pragma_info_structure_reuse::in,
+    prog_context::in, module_info::in, module_info::out,
+    list(error_spec)::in, list(error_spec)::out) is det.
+
 add_pragma_structure_reuse(ReuseInfo, Context, !ModuleInfo, !Specs):-
     ReuseInfo = pragma_info_structure_reuse(PredNameModesPF, HeadVars,
         Types, MaybeReuseDomain),
@@ -2034,6 +2043,10 @@
 
 %-----------------------------------------------------------------------------%
 
+:- pred add_pragma_termination_info(pragma_info_termination_info::in,
+    prog_context::in, module_info::in, module_info::out,
+    list(error_spec)::in, list(error_spec)::out) is det.
+
 add_pragma_termination_info(TermInfo, Context, !ModuleInfo, !Specs) :-
     TermInfo = pragma_info_termination_info(PredModesPF,
         MaybePragmaArgSizeInfo, MaybePragmaTerminationInfo),
@@ -2097,8 +2110,13 @@
 
 %-----------------------------------------------------------------------------%
 
-module_add_pragma_foreign_proc(FPInfo, Status, Context, MaybeItemNumber,
-        !ModuleInfo, !QualInfo, !Specs) :-
+:- pred add_pragma_foreign_proc(pragma_info_foreign_proc::in,
+    import_status::in, prog_context::in, maybe(int)::in,
+    module_info::in, module_info::out,
+    list(error_spec)::in, list(error_spec)::out) is det.
+
+add_pragma_foreign_proc(FPInfo, Status, Context, MaybeItemNumber,
+        !ModuleInfo, !Specs) :-
     FPInfo = pragma_info_foreign_proc(Attributes0, PredName, PredOrFunc,
         PVars, ProgVarSet, _InstVarset, PragmaImpl),
 
@@ -2142,8 +2160,8 @@
     globals.get_backend_foreign_languages(Globals, BackendForeignLangs),
 
     % Lookup the pred declaration in the predicate table.
-    % (If it's not there, print an error message and insert
-    % a dummy declaration for the predicate.)
+    % If it is not there, print an error message and insert
+    % a dummy declaration for the predicate.
     module_info_get_predicate_table(!.ModuleInfo, PredTable0),
     (
         predicate_table_search_pf_sym_arity(PredTable0, is_fully_qualified,
@@ -2153,8 +2171,8 @@
     ;
         preds_add_implicit_report_error(ModuleName, PredOrFunc,
             PredName, Arity, Status, no, Context, origin_user(PredName),
-            "`:- pragma foreign_proc' declaration",
-            PredId, !ModuleInfo, !Specs)
+            [quote(":- pragma foreign_proc"), words("declaration")], PredId,
+            !ModuleInfo, !Specs)
     ),
 
     % Lookup the pred_info for this pred, add the pragma to the proc_info
@@ -2260,6 +2278,11 @@
 
 %-----------------------------------------------------------------------------%
 
+:- pred module_add_pragma_tabled(pragma_info_tabled::in, prog_context::in,
+    import_status::in, import_status::out, module_info::in, module_info::out,
+    qual_info::in, qual_info::out,
+    list(error_spec)::in, list(error_spec)::out) is det.
+
 module_add_pragma_tabled(TabledInfo, Context, !Status, !ModuleInfo,
         !QualInfo, !Specs) :-
     TabledInfo = pragma_info_tabled(EvalMethod, PredNameArityMPF,
@@ -2272,8 +2295,8 @@
         PredOrFunc = PredOrFunc0,
 
         % Lookup the pred declaration in the predicate table.
-        % (If it is not there, print an error message and insert
-        % a dummy declaration for the predicate.)
+        % If it is not there, print an error message and insert
+        % a dummy declaration for the predicate.
         (
             predicate_table_search_pf_sym_arity(PredicateTable0,
                 is_fully_qualified, PredOrFunc, PredName, Arity, PredIds0)
@@ -2281,11 +2304,11 @@
             PredIds = PredIds0
         ;
             module_info_get_name(!.ModuleInfo, ModuleName),
-            string.format("`:- pragma %s' declaration", [s(EvalMethodStr)],
-                Message1),
+            DescPieces = [quote(":- pragma " ++ EvalMethodStr),
+                words("declaration")],
             preds_add_implicit_report_error(ModuleName, PredOrFunc, PredName,
-                Arity, !.Status, no, Context, origin_user(PredName), Message1,
-                PredId, !ModuleInfo, !Specs),
+                Arity, !.Status, no, Context, origin_user(PredName),
+                DescPieces, PredId, !ModuleInfo, !Specs),
             PredIds = [PredId]
         )
     ;
@@ -2297,11 +2320,11 @@
             PredIds = PredIds0
         ;
             module_info_get_name(!.ModuleInfo, ModuleName),
-            string.format("`:- pragma %s' declaration", [s(EvalMethodStr)],
-                Message1),
+            DescPieces = [quote(":- pragma " ++ EvalMethodStr),
+                words("declaration")],
             preds_add_implicit_report_error(ModuleName, pf_predicate, PredName,
-                Arity, !.Status, no, Context, origin_user(PredName), Message1,
-                PredId, !ModuleInfo, !Specs),
+                Arity, !.Status, no, Context, origin_user(PredName),
+                DescPieces, PredId, !ModuleInfo, !Specs),
             PredIds = [PredId]
         )
     ),
@@ -2309,7 +2332,12 @@
         MaybeAttributes = yes(Attributes),
         Statistics = Attributes ^ table_attr_statistics,
         AllowReset = Attributes ^ table_attr_allow_reset,
-        ( PredIds = [_, _ | _] ->
+        (
+            ( PredIds = []
+            ; PredIds = [_]
+            )
+        ;
+            PredIds = [_, _ | _],
             (
                 Statistics = table_gather_statistics,
                 StatsPieces = [words("Error: cannot request statistics"),
@@ -2338,8 +2366,6 @@
             ;
                 AllowReset = table_dont_allow_reset
             )
-        ;
-            true
         )
     ;
         MaybeAttributes = no
@@ -2963,19 +2989,41 @@
 
 %---------------------------------------------------------------------------%
 
-module_add_pragma_fact_table(FTInfo, Status, Context,
-        !ModuleInfo, !QualInfo, !Specs) :-
+:- pred add_pragma_oisu(pragma_info_oisu::in, import_status::in,
+    prog_context::in, module_info::in, module_info::out,
+    list(error_spec)::in, list(error_spec)::out) is det.
+
+add_pragma_oisu(_OISUInfo, _Status, _Context, !ModuleInfo, !Specs).
+    % XXX incomplete
+    % OISUInfo = pragma_info_oisu(TypeCtor, Creators, Mutators, Destructors).
+
+%---------------------------------------------------------------------------%
+
+    % add_pragma_fact_table(FTInfo, Status, Context,
+    %   !ModuleInfo, !Info):
+    %
+    % Add a `pragma fact_table' declaration to the HLDS. This predicate calls
+    % the fact table compiler (fact_table_compile_facts) to create a separate
+    % `.o' file for the fact_table and then creates separate pieces of
+    % `pragma c_code' to access the table in each mode of the fact table
+    % predicate.
+    %
+:- pred add_pragma_fact_table(pragma_info_fact_table::in,
+    import_status::in, prog_context::in, module_info::in, module_info::out,
+    list(error_spec)::in, list(error_spec)::out) is det.
+
+add_pragma_fact_table(FTInfo, Status, Context, !ModuleInfo, !Specs) :-
     FTInfo = pragma_info_fact_table(PredArity, FileName), 
     PredArity = pred_name_arity(Pred, Arity),
     module_info_get_predicate_table(!.ModuleInfo, PredicateTable),
     (
         predicate_table_search_sym_arity(PredicateTable, is_fully_qualified,
-            Pred, Arity, PredIDs0),
-        PredIDs0 = [PredID | PredIDs1]
+            Pred, Arity, PredIds0),
+        PredIds0 = [PredId | PredIds1]
     ->
         (
-            PredIDs1 = [],      % only one predicate found
-            module_info_pred_info(!.ModuleInfo, PredID, PredInfo0),
+            PredIds1 = [],      % only one predicate found
+            module_info_pred_info(!.ModuleInfo, PredId, PredInfo0),
 
             % Compile the fact table into a separate .o file.
             % We should be able to dispense with the impure shenanigans
@@ -2986,15 +3034,15 @@
                     semipure private_builtin.trace_get_io_state(!:IO),
                     fact_table_compile_facts(Pred, Arity, FileName,
                         PredInfo0, PredInfo, Context, !.ModuleInfo,
-                        C_HeaderCode, PrimaryProcID, !IO),
+                        C_HeaderCode, PrimaryProcId, !IO),
                     impure private_builtin.trace_set_io_state(!.IO)
                 )
             ),
 
-            module_info_set_pred_info(PredID, PredInfo, !ModuleInfo),
+            module_info_set_pred_info(PredId, PredInfo, !ModuleInfo),
             pred_info_get_procedures(PredInfo, ProcTable),
             pred_info_get_arg_types(PredInfo, ArgTypes),
-            ProcIDs = pred_info_procids(PredInfo),
+            ProcIds = pred_info_procids(PredInfo),
             PredOrFunc = pred_info_is_pred_or_func(PredInfo),
             adjust_func_arity(PredOrFunc, Arity, NumArgs),
 
@@ -3005,12 +3053,12 @@
             module_add_fact_table_file(FileName, !ModuleInfo),
 
             % Create foreign_procs to access the table in each mode.
-            module_add_fact_table_procedures(ProcIDs, PrimaryProcID,
+            add_fact_table_procedures(ProcIds, PrimaryProcId,
                 ProcTable, Pred, PredOrFunc, NumArgs, ArgTypes, Status,
-                Context, !ModuleInfo, !QualInfo, !Specs)
+                Context, !ModuleInfo, !Specs)
         ;
-            PredIDs1 = [_ | _],     % >1 predicate found
-            Pieces = [words("In pragma fact_table for"),
+            PredIds1 = [_ | _],     % >1 predicate found
+            Pieces = [words("In"), quote("pragma fact_table"), words("for"),
                 sym_name_and_arity(Pred/Arity), suffix(":"), nl,
                 words("error: ambiguous predicate/function name."), nl],
             Msg = simple_msg(Context, [always(Pieces)]),
@@ -3019,7 +3067,7 @@
         )
     ;
         undefined_pred_or_func_error(Pred, Arity, Context,
-            "`:- pragma fact_table' declaration", !Specs)
+            [quote(":- pragma fact_table"), words("declaration")], !Specs)
     ).
 
     % Add a `pragma c_code' for each mode of the fact table lookup to the
@@ -3027,34 +3075,31 @@
     % `pragma fact_table's are represented in the HLDS by a
     % `pragma c_code' for each mode of the predicate.
     %
-:- pred module_add_fact_table_procedures(list(proc_id)::in, proc_id::in,
+:- pred add_fact_table_procedures(list(proc_id)::in, proc_id::in,
     proc_table::in, sym_name::in, pred_or_func::in, arity::in,
     list(mer_type)::in, import_status::in, prog_context::in,
-    module_info::in, module_info::out, qual_info::in, qual_info::out,
+    module_info::in, module_info::out,
     list(error_spec)::in, list(error_spec)::out) is det.
 
-module_add_fact_table_procedures([],_,_,_,_,_,_,_,_, !ModuleInfo, !QualInfo,
-        !Specs).
-module_add_fact_table_procedures([ProcID | ProcIDs], PrimaryProcID, ProcTable,
+add_fact_table_procedures([],_,_,_,_,_,_,_,_, !ModuleInfo, !Specs).
+add_fact_table_procedures([ProcId | ProcIds], PrimaryProcId, ProcTable,
         SymName, PredOrFunc, Arity, ArgTypes, Status, Context,
-        !ModuleInfo, !QualInfo, !Specs) :-
-    module_add_fact_table_proc(ProcID, PrimaryProcID, ProcTable, SymName,
+        !ModuleInfo, !Specs) :-
+    add_fact_table_proc(ProcId, PrimaryProcId, ProcTable, SymName,
         PredOrFunc, Arity, ArgTypes, Status, Context,
-        !ModuleInfo, !QualInfo, !Specs),
-    module_add_fact_table_procedures(ProcIDs, PrimaryProcID, ProcTable,
+        !ModuleInfo, !Specs),
+    add_fact_table_procedures(ProcIds, PrimaryProcId, ProcTable,
         SymName, PredOrFunc, Arity, ArgTypes, Status, Context,
-        !ModuleInfo, !QualInfo, !Specs).
+        !ModuleInfo, !Specs).
 
-:- pred module_add_fact_table_proc(proc_id::in, proc_id::in, proc_table::in,
+:- pred add_fact_table_proc(proc_id::in, proc_id::in, proc_table::in,
     sym_name::in, pred_or_func::in, arity::in, list(mer_type)::in,
     import_status::in, prog_context::in, module_info::in, module_info::out,
-    qual_info::in, qual_info::out,
     list(error_spec)::in, list(error_spec)::out) is det.
 
-module_add_fact_table_proc(ProcID, PrimaryProcID, ProcTable, SymName,
-        PredOrFunc, Arity, ArgTypes, Status, Context, !ModuleInfo, !QualInfo,
-        !Specs) :-
-    map.lookup(ProcTable, ProcID, ProcInfo),
+add_fact_table_proc(ProcId, PrimaryProcId, ProcTable, SymName,
+        PredOrFunc, Arity, ArgTypes, Status, Context, !ModuleInfo, !Specs) :-
+    map.lookup(ProcTable, ProcId, ProcInfo),
     varset.init(ProgVarSet0),
     varset.new_vars(Arity, Vars, ProgVarSet0, ProgVarSet),
     proc_info_get_argmodes(ProcInfo, Modes),
@@ -3066,8 +3111,8 @@
     some [!IO] (
         promise_pure (
             semipure private_builtin.trace_get_io_state(!:IO),
-            fact_table_generate_c_code(SymName, PragmaVars, ProcID,
-                PrimaryProcID, ProcInfo, ArgTypes, !.ModuleInfo,
+            fact_table_generate_c_code(SymName, PragmaVars, ProcId,
+                PrimaryProcId, ProcInfo, ArgTypes, !.ModuleInfo,
                 C_ProcCode, C_ExtraCode, !IO),
             impure private_builtin.trace_set_io_state(!.IO)
         )
@@ -3082,8 +3127,8 @@
     MaybeItemNumber = no,
     FCInfo = pragma_info_foreign_proc(Attrs, SymName, PredOrFunc, PragmaVars,
         ProgVarSet, InstVarSet, fc_impl_ordinary(C_ProcCode, no)),
-    module_add_pragma_foreign_proc(FCInfo, Status, Context, MaybeItemNumber,
-        !ModuleInfo, !QualInfo, !Specs),
+    add_pragma_foreign_proc(FCInfo, Status, Context, MaybeItemNumber,
+        !ModuleInfo, !Specs),
     ( C_ExtraCode = "" ->
         true
     ;
@@ -3217,8 +3262,9 @@
         MultipleArgs = [_ | _],
         adjust_func_arity(PredOrFunc, OrigArity, Arity),
         SimpleCallId = simple_call_id(PredOrFunc, PredName, OrigArity),
-        Pieces1 = [words("In `:- pragma foreign_proc' declaration for"),
-            simple_call(SimpleCallId), suffix(":"), nl],
+        Pieces1 = [words("In"), quote(":- pragma foreign_proc"),
+            words("declaration for"), simple_call(SimpleCallId),
+            suffix(":"), nl],
         (
             MultipleArgs = [MultipleArg],
             Pieces2 = [words("error: variable"),
@@ -3239,10 +3285,10 @@
         goal_info_init(GoalInfo0),
         goal_info_set_context(Context, GoalInfo0, GoalInfo1),
 
-        % Check that the purity of a predicate/function declaration agrees with
-        % the (promised) purity of the foreign proc.  We do not perform this
-        % check there is a promise_{pure,semipure} pragma for the
-        % predicate/function since in that case they will differ anyway.
+        % Check that the purity of a predicate/function declaration agrees
+        % with the (promised) purity of the foreign proc. We do not perform
+        % this check if there is a promise_{pure,semipure} pragma for the
+        % predicate/function, since in that case they will differ anyway.
         (
             ( check_marker(Markers, marker_promised_pure)
             ; check_marker(Markers, marker_promised_semipure)
@@ -3349,16 +3395,6 @@
         )
     ).
 
-lookup_current_backend(Globals) = CurrentBackend :-
-    globals.lookup_bool_option(Globals, highlevel_code, HighLevel),
-    (
-        HighLevel = yes,
-        CurrentBackend = high_level_backend
-    ;
-        HighLevel= no,
-        CurrentBackend = low_level_backend
-    ).
-
 :- type overridden_by_old_foreign_proc
     --->    overridden_by_old_foreign_proc
     ;       not_overridden_by_old_foreign_proc.
Index: add_pred.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/add_pred.m,v
retrieving revision 1.50
diff -u -b -r1.50 add_pred.m
--- add_pred.m	2 Jul 2012 01:16:32 -0000	1.50
+++ add_pred.m	10 Sep 2012 13:06:50 -0000
@@ -59,7 +59,7 @@
     %
 :- pred preds_add_implicit_report_error(module_name::in, pred_or_func::in,
     sym_name::in, arity::in, import_status::in, bool::in, prog_context::in,
-    pred_origin::in, string::in, pred_id::out,
+    pred_origin::in, list(format_component)::in, pred_id::out,
     module_info::in, module_info::out,
     list(error_spec)::in, list(error_spec)::out) is det.
 
@@ -419,7 +419,7 @@
     ;
         preds_add_implicit_report_error(ModuleName, PredOrFunc, PredName,
             Arity, Status, IsClassMethod, MContext, origin_user(PredName),
-            "mode declaration", PredId, !ModuleInfo, !Specs)
+            [words("mode declaration")], PredId, !ModuleInfo, !Specs)
     ),
     module_info_get_predicate_table(!.ModuleInfo, PredicateTable1),
     predicate_table_get_preds(PredicateTable1, Preds0),
@@ -476,11 +476,11 @@
         !PredInfo, ProcId).
 
 preds_add_implicit_report_error(ModuleName, PredOrFunc, PredName, Arity,
-        Status, IsClassMethod, Context, Origin, Description, PredId,
+        Status, IsClassMethod, Context, Origin, DescPieces, PredId,
         !ModuleInfo, !Specs) :-
     module_info_get_globals(!.ModuleInfo, Globals),
     maybe_undefined_pred_error(Globals, PredName, Arity, PredOrFunc,
-        Status, IsClassMethod, Context, Description, !Specs),
+        Status, IsClassMethod, Context, DescPieces, !Specs),
     (
         PredOrFunc = pf_function,
         adjust_func_arity(pf_function, FuncArity, Arity),
Index: equiv_type.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/equiv_type.m,v
retrieving revision 1.98
diff -u -b -r1.98 equiv_type.m
--- equiv_type.m	5 Sep 2012 06:18:13 -0000	1.98
+++ equiv_type.m	10 Sep 2012 13:06:51 -0000
@@ -641,7 +641,7 @@
         ; Pragma0 = pragma_foreign_code(_)
         ; Pragma0 = pragma_foreign_decl(_)
         ; Pragma0 = pragma_foreign_enum(_)
-        ; Pragma0 = pragma_foreign_export(_)
+        ; Pragma0 = pragma_foreign_proc_export(_)
         ; Pragma0 = pragma_foreign_export_enum(_)
         ; Pragma0 = pragma_foreign_import_module(_)
         ; Pragma0 = pragma_inline(_)
@@ -658,6 +658,7 @@
         ; Pragma0 = pragma_source_file(_)
         ; Pragma0 = pragma_structure_reuse(_)
         ; Pragma0 = pragma_structure_sharing(_)
+        ; Pragma0 = pragma_oisu(_)
         ; Pragma0 = pragma_tabled(_)
         ; Pragma0 = pragma_terminates(_)
         ; Pragma0 = pragma_termination2_info(_)
@@ -793,14 +794,14 @@
     ;
         TypeDefn0 = parse_tree_solver_type(SolverDetails0, MaybeUserEqComp),
         SolverDetails0 = solver_type_details(RepresentationType0, InitPred,
-            GroundInst, AnyInst, MutableItems0),
+            GroundInst, AnyInst, MutableInfos0),
         replace_in_type_location_2(Location, EqvMap, [TypeCtor],
             RepresentationType0, RepresentationType,
             _, ContainsCirc, !VarSet, !EquivTypeInfo, !UsedModules),
         replace_in_constraint_store(Location, EqvMap, EqvInstMap,
-            MutableItems0, MutableItems, !EquivTypeInfo, !UsedModules),
+            MutableInfos0, MutableInfos, !EquivTypeInfo, !UsedModules),
         SolverDetails = solver_type_details(RepresentationType, InitPred,
-            GroundInst, AnyInst, MutableItems),
+            GroundInst, AnyInst, MutableInfos),
         TypeDefn = parse_tree_solver_type(SolverDetails, MaybeUserEqComp)
     ;
         ( TypeDefn0 = parse_tree_abstract_type(_)
@@ -811,22 +812,19 @@
     ).
 
 :- pred replace_in_constraint_store(eqv_type_location::in,
-    eqv_map::in, eqv_inst_map::in, list(item)::in, list(item)::out,
+    eqv_map::in, eqv_inst_map::in,
+    list(item_mutable_info)::in, list(item_mutable_info)::out,
     equiv_type_info::in, equiv_type_info::out,
     used_modules::in, used_modules::out) is det.
 
 replace_in_constraint_store(_, _, _, [], [], !EquivTypeInfo, !UsedModules).
 replace_in_constraint_store(Location, EqvMap, EqvInstMap,
-        [CStore0 | CStores0], [CStore | CStores], !EquivTypeInfo, !UsedModules) :-
-    ( if CStore0 = item_mutable(ItemMutableInfo0) then
+        [MutableInfo0 | MutableInfos0], [MutableInfo | MutableInfos],
+        !EquivTypeInfo, !UsedModules) :-
         replace_in_mutable_defn(Location, EqvMap, EqvInstMap,
-            ItemMutableInfo0, ItemMutableInfo, !EquivTypeInfo, !UsedModules),
-        CStore = item_mutable(ItemMutableInfo)
-      else
-        unexpected($module, $pred, "item is not a mutable")
-    ),
+        MutableInfo0, MutableInfo, !EquivTypeInfo, !UsedModules),
     replace_in_constraint_store(Location, EqvMap, EqvInstMap,
-        CStores0, CStores, !EquivTypeInfo, !UsedModules).
+        MutableInfos0, MutableInfos, !EquivTypeInfo, !UsedModules).
 
 %-----------------------------------------------------------------------------%
 
Index: goal_expr_to_goal.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/goal_expr_to_goal.m,v
retrieving revision 1.7
diff -u -b -r1.7 goal_expr_to_goal.m
--- goal_expr_to_goal.m	23 Apr 2012 03:34:47 -0000	1.7
+++ goal_expr_to_goal.m	10 Sep 2012 13:06:52 -0000
@@ -58,7 +58,6 @@
 :- import_module hlds.hlds_pred.
 :- import_module hlds.hlds_pred.
 :- import_module hlds.hlds_rtti.
-:- import_module hlds.make_hlds.add_pragma.
 :- import_module hlds.make_hlds.add_pred.
 :- import_module hlds.make_hlds.field_access.
 :- import_module hlds.make_hlds.make_hlds_warn.
Index: intermod.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/intermod.m,v
retrieving revision 1.274
diff -u -b -r1.274 intermod.m
--- intermod.m	5 Sep 2012 06:18:14 -0000	1.274
+++ intermod.m	10 Sep 2012 13:06:53 -0000
@@ -1368,7 +1368,7 @@
     hlds_data.get_type_defn_tparams(TypeDefn, Args),
     hlds_data.get_type_defn_body(TypeDefn, Body),
     hlds_data.get_type_defn_context(TypeDefn, Context),
-    TypeCtor = type_ctor(Name, Arity),
+    TypeCtor = type_ctor(Name, _Arity),
     (
         Body = hlds_du_type(Ctors, _, _, _, MaybeUserEqComp,
             MaybeDirectArgCtors,
@@ -1486,7 +1486,7 @@
     ->
         map.foldl(gather_foreign_enum_value_pair, ConsTagVals, [],
             ForeignEnumVals),
-        FEInfo = pragma_info_foreign_enum(Lang, Name, Arity, ForeignEnumVals),
+        FEInfo = pragma_info_foreign_enum(Lang, TypeCtor, ForeignEnumVals),
         ForeignPragma = pragma_foreign_enum(FEInfo),
         ForeignItemPragma = item_pragma_info(user, ForeignPragma, Context, -1),
         ForeignItem = item_pragma(ForeignItemPragma),
Index: make_hlds_error.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/make_hlds_error.m,v
retrieving revision 1.14
diff -u -b -r1.14 make_hlds_error.m
--- make_hlds_error.m	16 Jul 2008 03:30:27 -0000	1.14
+++ make_hlds_error.m	10 Sep 2012 13:06:53 -0000
@@ -34,18 +34,21 @@
     list(error_spec)::in, list(error_spec)::out) is det.
 
 :- pred undefined_pred_or_func_error(sym_name::in, int::in, prog_context::in,
-    string::in, list(error_spec)::in, list(error_spec)::out) is det.
+    list(format_component)::in,
+    list(error_spec)::in, list(error_spec)::out) is det.
 
     % Similar to undeclared_mode_error, but gives less information.
     % XXX perhaps we should get rid of this, and change the callers to
     % instead call undeclared_mode_error.
     %
 :- pred undefined_mode_error(sym_name::in, int::in, prog_context::in,
-    string::in, list(error_spec)::in, list(error_spec)::out) is det.
+    list(format_component)::in,
+    list(error_spec)::in, list(error_spec)::out) is det.
 
 :- pred maybe_undefined_pred_error(globals::in, sym_name::in, int::in,
     pred_or_func::in, import_status::in, bool::in, prog_context::in,
-    string::in, list(error_spec)::in, list(error_spec)::out) is det.
+    list(format_component)::in,
+    list(error_spec)::in, list(error_spec)::out) is det.
 
     % Emit an error if something is exported.  (Used to check for
     % when things shouldn't be exported.)
@@ -102,18 +105,18 @@
         !:Specs = [Spec | !.Specs]
     ).
 
-undefined_pred_or_func_error(Name, Arity, Context, Description, !Specs) :-
+undefined_pred_or_func_error(Name, Arity, Context, DescPieces, !Specs) :-
     % This used to say `preceding' instead of `corresponding.'
     % Which is more correct?
-    Pieces = [words("Error:"), words(Description), words("for"),
+    Pieces = [words("Error:") | DescPieces] ++ [words("for"),
         sym_name_and_arity(Name / Arity),
         words("without corresponding `pred' or `func' declaration.")],
     Msg = simple_msg(Context, [always(Pieces)]),
     Spec = error_spec(severity_error, phase_parse_tree_to_hlds, [Msg]),
     !:Specs = [Spec | !.Specs].
 
-undefined_mode_error(Name, Arity, Context, Description, !Specs) :-
-    Pieces = [words("Error:"), words(Description), words("for"),
+undefined_mode_error(Name, Arity, Context, DescPieces, !Specs) :-
+    Pieces = [words("Error:") | DescPieces] ++ [words("for"),
         sym_name_and_arity(Name / Arity),
         words("specifies non-existent mode.")],
     Msg = simple_msg(Context, [always(Pieces)]),
@@ -167,15 +170,15 @@
     [words(":- mode"), words(mode_decl_to_string(ProcId, PredInfo)),
     suffix(".")].
 
+maybe_undefined_pred_error(Globals, Name, Arity, PredOrFunc, Status,
+        IsClassMethod, Context, DescPieces, !Specs) :-
     % This is not considered an unconditional error anymore:
     % if there is no `:- pred' or `:- func' declaration,
     % and the declaration is local, and not a type class method,
     % and the `--infer-types' option was specified,
     % then we just add an implicit declaration for that predicate or
     % function, marking it as one whose type will be inferred.
-    %
-maybe_undefined_pred_error(Globals, Name, Arity, PredOrFunc, Status,
-        IsClassMethod, Context, Description, !Specs) :-
+
     DefinedInThisModule = status_defined_in_this_module(Status),
     IsExported = status_is_exported(Status),
     globals.lookup_bool_option(Globals, infer_types, InferTypes),
@@ -187,7 +190,7 @@
     ->
         true
     ;
-        Pieces = [words("Error:"), words(Description), words("for"),
+        Pieces = [words("Error:") | DescPieces] ++ [words("for"),
             simple_call(simple_call_id(PredOrFunc, Name, Arity)), nl,
             words("without preceding"), quote(pred_or_func_to_str(PredOrFunc)),
             words("declaration."), nl],
Index: make_hlds_passes.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/make_hlds_passes.m,v
retrieving revision 1.121
diff -u -b -r1.121 make_hlds_passes.m
--- make_hlds_passes.m	5 Sep 2012 06:18:14 -0000	1.121
+++ make_hlds_passes.m	10 Sep 2012 13:06:55 -0000
@@ -412,9 +412,9 @@
     count_words(PackedArgs, 0, PackedLength),
     expect(PackedLength =< UnpackedLength, $module, $pred,
         "packed length exceeds unpacked length"),
-    % Boehm GC will round up allocations (at least) to the next even
-    % number of words.  There is no point saving a single word if that
-    % word will be allocated anyway.
+    % Boehm GC will round up allocations (at least) to the next even number
+    % of words. There is no point saving a single word if that word will be
+    % allocated anyway.
     ( round_to_even(PackedLength) < round_to_even(UnpackedLength) ->
         Worthwhile = yes
     ;
@@ -618,7 +618,7 @@
         add_solver_type_decl_items(TVarSet, SymName, TypeParams,
             SolverTypeDetails, Context, !Status, !ModuleInfo, !Specs),
         MutableItems = SolverTypeDetails ^ std_mutable_items,
-        add_solver_type_mutable_items_pass_1(MutableItems, !Status,
+        add_solver_type_mutable_items_pass_1(MutableItems, !.Status,
             !ModuleInfo, !Specs)
     ;
         true
@@ -635,8 +635,8 @@
     init_markers(Markers0),
 
     % If this predicate was added as a result of the mutable transformation
-    % then mark this predicate as a mutable access pred.  We do this
-    % so that we can tell optimizations, like inlining, to treat it specially.
+    % then mark this predicate as a mutable access pred. We do this so that
+    % we can tell optimizations, like inlining, to treat it specially.
     (
         Origin = compiler(Reason),
         (
@@ -898,15 +898,16 @@
         DefinedThisModule = no
     ).
 
-:- pred add_solver_type_mutable_items_pass_1(list(item)::in,
-    item_status::in, item_status::out, module_info::in, module_info::out,
+:- pred add_solver_type_mutable_items_pass_1(list(item_mutable_info)::in,
+    item_status::in, module_info::in, module_info::out,
     list(error_spec)::in, list(error_spec)::out) is det.
 
-add_solver_type_mutable_items_pass_1([], !Status, !ModuleInfo, !Specs).
-add_solver_type_mutable_items_pass_1([Item | Items], !Status,
+add_solver_type_mutable_items_pass_1([], _, !ModuleInfo, !Specs).
+add_solver_type_mutable_items_pass_1([MutableInfo | MutableInfos], Status,
         !ModuleInfo, !Specs) :-
-    add_item_decl_pass_1(Item, _, !Status, !ModuleInfo, !Specs),
-    add_solver_type_mutable_items_pass_1(Items, !Status, !ModuleInfo, !Specs).
+    add_pass_1_mutable(MutableInfo, Status, !ModuleInfo, !Specs),
+    add_solver_type_mutable_items_pass_1(MutableInfos, Status,
+        !ModuleInfo, !Specs).
 
 :- pred add_module_specifiers(list(module_specifier)::in, import_status::in,
     module_info::in, module_info::out) is det.
@@ -948,7 +949,7 @@
         add_pass_2_pred_decl(ItemPredDecl, !.Status, !ModuleInfo, !Specs)
     ;
         Item = item_pragma(ItemPragma),
-        add_pragma(ItemPragma, !Status, !ModuleInfo, !Specs)
+        add_pass_2_pragma(ItemPragma, !Status, !ModuleInfo, !Specs)
     ;
         Item = item_instance(ItemInstance),
         add_pass_2_instance(ItemInstance, !.Status, !ModuleInfo, !Specs)
@@ -986,7 +987,7 @@
         Status, !ModuleInfo, !Specs),
     ( TypeDefn = parse_tree_solver_type(SolverTypeDetails, _MaybeUserEqComp) ->
         MutableItems = SolverTypeDetails ^ std_mutable_items,
-        add_solver_type_mutable_items_pass_2(MutableItems, Status, _,
+        add_solver_type_mutable_items_pass_2(MutableItems, Status,
             !ModuleInfo, !Specs)
     ;
         true
@@ -1166,7 +1167,7 @@
                 IOSetPromisePureItemPragma = item_pragma_info(
                     compiler(mutable_decl), IOSetPromisePurePragma, Context,
                     -1),
-                add_pragma(IOSetPromisePureItemPragma, Status, _,
+                add_pass_2_pragma(IOSetPromisePureItemPragma, Status, _,
                     !ModuleInfo, !Specs)
             ;
                 IOStateInterface = no
@@ -1212,15 +1213,16 @@
         DefinedThisModule = no
     ).
 
-:- pred add_solver_type_mutable_items_pass_2(list(item)::in,
-    item_status::in, item_status::out, module_info::in, module_info::out,
+:- pred add_solver_type_mutable_items_pass_2(list(item_mutable_info)::in,
+    item_status::in, module_info::in, module_info::out,
     list(error_spec)::in, list(error_spec)::out) is det.
 
-add_solver_type_mutable_items_pass_2([], !Status, !ModuleInfo, !Specs).
-add_solver_type_mutable_items_pass_2([Item | Items], !Status, !ModuleInfo,
-        !Specs) :-
-    add_item_decl_pass_2(Item, !Status, !ModuleInfo, !Specs),
-    add_solver_type_mutable_items_pass_2(Items, !Status, !ModuleInfo, !Specs).
+add_solver_type_mutable_items_pass_2([], _, !ModuleInfo, !Specs).
+add_solver_type_mutable_items_pass_2([MutableInfo | MutableInfos], Status,
+        !ModuleInfo, !Specs) :-
+    add_pass_2_mutable(MutableInfo, Status, !ModuleInfo, !Specs),
+    add_solver_type_mutable_items_pass_2(MutableInfos, Status,
+        !ModuleInfo, !Specs).
 
     % Check to see if there is a valid foreign_name attribute for this backend.
     % If so, use it as the name of the global variable in the target code,
@@ -1434,99 +1436,6 @@
         true
     ).
 
-:- pred add_pass_3_pragma(item_pragma_info::in,
-    import_status::in, import_status::out, module_info::in, module_info::out,
-    qual_info::in, qual_info::out,
-    list(error_spec)::in, list(error_spec)::out) is det.
-
-add_pass_3_pragma(ItemPragma, !Status, !ModuleInfo, !QualInfo, !Specs) :-
-    ItemPragma = item_pragma_info(Origin, Pragma, Context, SeqNum),
-    (
-        Pragma = pragma_foreign_proc(FPInfo),
-        module_add_pragma_foreign_proc(FPInfo, !.Status, Context,
-            yes(SeqNum), !ModuleInfo, !QualInfo, !Specs)
-    ;
-        Pragma = pragma_fact_table(FTInfo),
-        module_add_pragma_fact_table(FTInfo, !.Status, Context,
-            !ModuleInfo, !QualInfo, !Specs)
-    ;
-        Pragma = pragma_tabled(TabledInfo),
-        module_info_get_globals(!.ModuleInfo, Globals),
-        globals.lookup_bool_option(Globals, type_layout, TypeLayout),
-        (
-            TypeLayout = yes,
-            module_add_pragma_tabled(TabledInfo, Context, !Status,
-                !ModuleInfo, !QualInfo, !Specs)
-        ;
-            TypeLayout = no,
-            TabledInfo = pragma_info_tabled(EvalMethod, _, _, _),
-            Pieces = [words("Error:"),
-                quote(":- pragma " ++ eval_method_to_string(EvalMethod)),
-                words("declaration requires type_ctor_layout structures."),
-                words("Don't use --no-type-layout to disable them."),
-                nl],
-            Msg = simple_msg(Context, [always(Pieces)]),
-            Spec = error_spec(severity_error, phase_parse_tree_to_hlds, [Msg]),
-            !:Specs = [Spec | !.Specs]
-        )
-    ;
-        Pragma = pragma_type_spec(TypeSpecInfo),
-        add_pragma_type_spec(TypeSpecInfo, Context,
-            !ModuleInfo, !QualInfo, !Specs)
-    ;
-        Pragma = pragma_termination_info(TermInfo),
-        add_pragma_termination_info(TermInfo, Context, !ModuleInfo, !Specs)
-    ;
-        Pragma = pragma_termination2_info(Term2Info),
-        add_pragma_termination2_info(Term2Info, Context, !ModuleInfo, !Specs)
-    ;
-        Pragma = pragma_structure_sharing(SharingInfo),
-        add_pragma_structure_sharing(SharingInfo, Context, !ModuleInfo, !Specs)
-    ;
-        Pragma = pragma_structure_reuse(ReuseInfo),
-        add_pragma_structure_reuse(ReuseInfo, Context, !ModuleInfo, !Specs)
-    ;
-        Pragma = pragma_reserve_tag(TypeCtor),
-        add_pragma_reserve_tag(TypeCtor, !.Status, Context,
-            !ModuleInfo, !Specs)
-    ;
-        Pragma = pragma_foreign_export_enum(FEEInfo),
-        add_pragma_foreign_export_enum(FEEInfo, !.Status, Context,
-            !ModuleInfo, !Specs)
-    ;
-        Pragma = pragma_foreign_enum(FEInfo),
-        add_pragma_foreign_enum(FEInfo, !.Status, Context, !ModuleInfo, !Specs)
-    ;
-        Pragma = pragma_foreign_export(FEInfo),
-        add_pragma_foreign_export(Origin, FEInfo, Context, !ModuleInfo, !Specs)
-    ;
-        % Don't worry about any pragma declarations other than the
-        % clause-like pragmas (c_code, tabling and fact_table),
-        % foreign_type and the termination_info pragma here,
-        % since they've already been handled earlier, in pass 2.
-        ( Pragma = pragma_check_termination(_)
-        ; Pragma = pragma_does_not_terminate(_)
-        ; Pragma = pragma_exceptions(_)
-        ; Pragma = pragma_foreign_code(_)
-        ; Pragma = pragma_foreign_decl(_)
-        ; Pragma = pragma_foreign_import_module(_)
-        ; Pragma = pragma_inline(_)
-        ; Pragma = pragma_mm_tabling_info(_)
-        ; Pragma = pragma_mode_check_clauses(_)
-        ; Pragma = pragma_no_inline(_)
-        ; Pragma = pragma_obsolete(_)
-        ; Pragma = pragma_no_detism_warning(_)
-        ; Pragma = pragma_promise_eqv_clauses(_)
-        ; Pragma = pragma_promise_pure(_)
-        ; Pragma = pragma_promise_semipure(_)
-        ; Pragma = pragma_source_file(_)
-        ; Pragma = pragma_terminates(_)
-        ; Pragma = pragma_trailing_info(_)
-        ; Pragma = pragma_unused_args(_)
-        ; Pragma = pragma_require_feature_set(_)
-        )
-    ).
-
 :- pred add_pass_3_promise(item_promise_info::in,
     import_status::in, module_info::in, module_info::out,
     qual_info::in, qual_info::out,
@@ -1607,9 +1516,9 @@
                     !ModuleInfo),
                 PredNameModesPF = pred_name_modes_pf(SymName, 
                     [di_mode, uo_mode], pf_predicate),
-                FEInfo = pragma_info_foreign_export(ExportLang,
+                FPEInfo = pragma_info_foreign_proc_export(ExportLang,
                     PredNameModesPF, CName),
-                ExportPragma = pragma_foreign_export(FEInfo),
+                ExportPragma = pragma_foreign_proc_export(FPEInfo),
                 ExportItemPragma = item_pragma_info(compiler(initialise_decl),
                     ExportPragma, Context, -1),
                 ExportItem = item_pragma(ExportItemPragma),
@@ -1632,9 +1541,9 @@
                     !ModuleInfo),
                 PredNameModesPF = pred_name_modes_pf(SymName, 
                     [], pf_predicate),
-                FEInfo = pragma_info_foreign_export(ExportLang,
+                FPEInfo = pragma_info_foreign_proc_export(ExportLang,
                     PredNameModesPF, CName),
-                ExportPragma = pragma_foreign_export(FEInfo),
+                ExportPragma = pragma_foreign_proc_export(FPEInfo),
                 ExportItemPragma = item_pragma_info(compiler(initialise_decl),
                     ExportPragma, Context, -1),
                 ExportItem = item_pragma(ExportItemPragma),
@@ -1705,9 +1614,9 @@
             MaybeExportLang = yes(ExportLang),
             module_info_new_user_init_pred(SymName, Arity, CName, !ModuleInfo),
             PredNameModesPF = pred_name_modes_pf(SymName, [], pf_predicate),
-            FEInfo = pragma_info_foreign_export(ExportLang, PredNameModesPF,
-                CName),
-            ExportPragma = pragma_foreign_export(FEInfo),
+            FPEInfo = pragma_info_foreign_proc_export(ExportLang,
+                PredNameModesPF, CName),
+            ExportPragma = pragma_foreign_proc_export(FPEInfo),
             ExportItemPragma = item_pragma_info(compiler(mutable_decl),
                 ExportPragma, Context, -1),
             ExportItem = item_pragma(ExportItemPragma),
@@ -1784,9 +1693,9 @@
                     !ModuleInfo),
                 PredNameModesPF = pred_name_modes_pf(SymName,
                     [di_mode, uo_mode], pf_predicate),
-                FEInfo = pragma_info_foreign_export(ExportLang,
+                FPEInfo = pragma_info_foreign_proc_export(ExportLang,
                     PredNameModesPF, CName),
-                ExportPragma = pragma_foreign_export(FEInfo),
+                ExportPragma = pragma_foreign_proc_export(FPEInfo),
                 ExportItemPragma = item_pragma_info(compiler(finalise_decl),
                     ExportPragma, Context, -1),
                 ExportItem = item_pragma(ExportItemPragma),
@@ -1809,9 +1718,9 @@
                     !ModuleInfo),
                 PredNameModesPF = pred_name_modes_pf(SymName,
                     [], pf_predicate),
-                FEInfo = pragma_info_foreign_export(ExportLang,
+                FPEInfo = pragma_info_foreign_proc_export(ExportLang,
                     PredNameModesPF, CName),
-                ExportPragma = pragma_foreign_export(FEInfo),
+                ExportPragma = pragma_foreign_proc_export(FPEInfo),
                 ExportItemPragma = item_pragma_info(compiler(finalise_decl),
                     ExportPragma, Context, -1),
                 ExportItem = item_pragma(ExportItemPragma),
@@ -1986,7 +1895,7 @@
 
 %-----------------------------------------------------------------------------%
 %
-% C mutables
+% C mutables.
 %
 
     % Add the foreign_decl and foreign_code items that declare/define
@@ -2013,8 +1922,7 @@
     add_item_decl_pass_2(ForeignDefn, ItemStatus0, _, !ModuleInfo, !Specs).
 
     % Create the C foreign_decl for the mutable.
-    % The bool argument says whether the mutable is a constant mutable
-    % or not.
+    % The bool argument says whether the mutable is a constant mutable or not.
     %
 :- pred get_c_mutable_global_foreign_decl(module_info::in, mer_type::in,
     string::in, bool::in, mutable_thread_local::in, prog_context::in,
@@ -3135,17 +3043,17 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred add_solver_type_mutable_items_clauses(list(item)::in,
+:- pred add_solver_type_mutable_items_clauses(list(item_mutable_info)::in,
     import_status::in, import_status::out,
     module_info::in, module_info::out, qual_info::in, qual_info::out,
     list(error_spec)::in, list(error_spec)::out) is det.
 
 add_solver_type_mutable_items_clauses([], !Status,
         !ModuleInfo, !QualInfo, !Specs).
-add_solver_type_mutable_items_clauses([Item | Items], !Status,
+add_solver_type_mutable_items_clauses([MutableInfo | MutableInfos], !Status,
         !ModuleInfo, !QualInfo, !Specs) :-
-    add_item_pass_3(Item, !Status, !ModuleInfo, !QualInfo, !Specs),
-    add_solver_type_mutable_items_clauses(Items, !Status,
+    add_pass_3_mutable(MutableInfo, !.Status, !ModuleInfo, !QualInfo, !Specs),
+    add_solver_type_mutable_items_clauses(MutableInfos, !Status,
         !ModuleInfo, !QualInfo, !Specs).
 
 %-----------------------------------------------------------------------------%
@@ -3222,10 +3130,8 @@
         set.insert_list(PredIds, StratPredIds0, StratPredIds),
         module_info_set_stratified_preds(StratPredIds, !ModuleInfo)
     ;
-        string.append_list(["`:- pragma ", PragmaName, "' declaration"],
-            Description),
-        undefined_pred_or_func_error(Name, Arity, Context, Description,
-            !Specs)
+        DescPieces = [quote(":- pragma " ++ PragmaName), words("declaration")],
+        undefined_pred_or_func_error(Name, Arity, Context, DescPieces, !Specs)
     ).
 
 %-----------------------------------------------------------------------------%
@@ -3268,8 +3174,8 @@
         module_info_set_predicate_table(PredTable, !ModuleInfo)
     ;
         PredIds = [],
-        Description = "`:- pragma " ++ PragmaName ++ "' declaration",
-        undefined_pred_or_func_error(Name, Arity, Context, Description, !Specs)
+        DescPieces = [quote(":- pragma " ++ PragmaName), words("declaration")],
+        undefined_pred_or_func_error(Name, Arity, Context, DescPieces, !Specs)
     ).
 
 :- pred get_matching_pred_ids(module_info::in, sym_name::in, arity::in,
@@ -3298,7 +3204,7 @@
         module_mark_preds_as_external(PredIdList, !ModuleInfo)
     ;
         undefined_pred_or_func_error(PredName, Arity, Context,
-            "`:- external' declaration", !Specs)
+            [quote(":- external"), words("declaration")], !Specs)
     ).
 
 :- pred module_mark_preds_as_external(list(pred_id)::in,
@@ -3356,8 +3262,8 @@
         WrongStatus0 = no
     ),
     map.det_update(PredId, PredInfo, !PredTable),
-    pragma_add_marker(PredIds, UpdatePredInfo, Status,
-        MustBeExported, !PredTable, WrongStatus1),
+    pragma_add_marker(PredIds, UpdatePredInfo, Status, MustBeExported,
+        !PredTable, WrongStatus1),
     bool.or(WrongStatus0, WrongStatus1, WrongStatus).
 
 :- pred add_marker_pred_info(marker::in, pred_info::in, pred_info::out) is det.
Index: mercury_to_mercury.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mercury_to_mercury.m,v
retrieving revision 1.362
diff -u -b -r1.362 mercury_to_mercury.m
--- mercury_to_mercury.m	5 Sep 2012 06:18:14 -0000	1.362
+++ mercury_to_mercury.m	10 Sep 2012 13:06:57 -0000
@@ -704,8 +704,8 @@
         Pragma = pragma_foreign_proc(FPInfo),
         mercury_output_pragma_foreign_proc(FPInfo, !IO)
     ;
-        Pragma = pragma_foreign_export(FEInfo),
-        mercury_format_pragma_foreign_export(FEInfo, !IO)
+        Pragma = pragma_foreign_proc_export(FPEInfo),
+        mercury_format_pragma_foreign_proc_export(FPEInfo, !IO)
     ;
         Pragma = pragma_foreign_export_enum(FEEInfo),
         mercury_format_pragma_foreign_export_enum(FEEInfo, !IO)
@@ -723,6 +723,9 @@
         mercury_output_pragma_decl(Pred, Arity, pf_predicate,
             "no_determinism_warning", no, !IO)
     ;
+        Pragma = pragma_oisu(OISUInfo),
+        mercury_output_pragma_oisu(OISUInfo, !IO)
+    ;
         Pragma = pragma_tabled(TabledInfo),
         mercury_output_pragma_tabled(TabledInfo, !IO)
     ;
@@ -1929,7 +1932,7 @@
 
 mercury_output_solver_type_details(Info, TVarSet, Details, !IO) :-
     Details = solver_type_details(RepresentationType, HowToInit, GroundInst,
-        AnyInst, MutableItems),
+        AnyInst, MutableInfos),
     io.write_string("representation is ", !IO),
     mercury_output_type(TVarSet, no, RepresentationType, !IO),
     (
@@ -1945,12 +1948,12 @@
     io.write_string(",\n\t\tany is ", !IO),
     mercury_output_inst(AnyInst, EmptyInstVarSet, !IO),
     (
-        MutableItems = []
+        MutableInfos = []
     ;
-        MutableItems = [_ | _],
+        MutableInfos = [_ | _],
         io.write_string(",\n\t\tconstraint_store is [\n\t\t\t", !IO),
-        io.write_list(MutableItems, ",\n\t\t\t", mercury_output_item(Info),
-            !IO),
+        io.write_list(MutableInfos, ",\n\t\t\t",
+            mercury_output_item_mutable(Info), !IO),
         io.write_string("\n\t\t]", !IO)
     ).
 
@@ -3781,11 +3784,12 @@
     pragma_info_foreign_export_enum::in, U::di, U::uo) is det <= output(U).
 
 mercury_format_pragma_foreign_export_enum(FEEInfo, !U) :-
-    FEEInfo = pragma_info_foreign_export_enum(Lang, TypeName, TypeArity,
+    FEEInfo = pragma_info_foreign_export_enum(Lang, TypeCtor,
         Attributes, Overrides),
     add_string(":- pragma foreign_export_enum(", !U),
     mercury_format_foreign_language_string(Lang, !U),
     add_string(", ", !U),
+    TypeCtor = type_ctor(TypeName, TypeArity),
     mercury_format_bracketed_sym_name_ngt(TypeName, next_to_graphic_token, !U),
     add_string("/", !U),
     add_int(TypeArity, !U),
@@ -3838,10 +3842,11 @@
     U::di, U::uo) is det <= output(U).
 
 mercury_format_pragma_foreign_enum(FEInfo, !U) :-
-    FEInfo = pragma_info_foreign_enum(Lang, TypeName, TypeArity, Values),
+    FEInfo = pragma_info_foreign_enum(Lang, TypeCtor, Values),
     add_string(":- pragma foreign_enum(", !U),
     mercury_format_foreign_language_string(Lang, !U),
     add_string(", ", !U),
+    TypeCtor = type_ctor(TypeName, TypeArity),
     mercury_format_bracketed_sym_name_ngt(TypeName, next_to_graphic_token, !U),
     add_string("/", !U),
     add_int(TypeArity, !U),
@@ -3851,11 +3856,12 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred mercury_format_pragma_foreign_export(pragma_info_foreign_export::in,
-    U::di, U::uo) is det <= output(U).
+:- pred mercury_format_pragma_foreign_proc_export(
+    pragma_info_foreign_proc_export::in, U::di, U::uo) is det <= output(U).
 
-mercury_format_pragma_foreign_export(FEInfo, !U) :-
-    FEInfo = pragma_info_foreign_export(Lang, PredNameModesPF, ExportName),
+mercury_format_pragma_foreign_proc_export(FPEInfo, !U) :-
+    FPEInfo = pragma_info_foreign_proc_export(Lang, PredNameModesPF,
+        ExportName),
     PredNameModesPF = pred_name_modes_pf(Name, ModeList, PredOrFunc), 
     varset.init(Varset), % The varset isn't really used.
     InstInfo = simple_inst_info(Varset),
@@ -3882,6 +3888,71 @@
 
 %-----------------------------------------------------------------------------%
 
+:- pred mercury_output_pragma_oisu(pragma_info_oisu::in,
+    io::di, io::uo) is det.
+
+mercury_output_pragma_oisu(OISUInfo, !IO) :-
+    mercury_format_pragma_oisu(OISUInfo, !IO).
+
+:- pred mercury_format_pragma_oisu(pragma_info_oisu::in,
+    U::di, U::uo) is det <= output(U).
+
+mercury_format_pragma_oisu(OISUInfo, !U) :-
+    OISUInfo = pragma_info_oisu(TypeCtor, CreatorPreds, MutatorPreds,
+        DestructorPreds),
+    add_string(":- pragma oisu(", !U),
+    TypeCtor = type_ctor(TypeName, TypeArity),
+    add_string(":- pragma reserve_tag(", !U),
+    mercury_format_bracketed_sym_name_ngt(TypeName, next_to_graphic_token, !U),
+    add_string("/", !U),
+    add_int(TypeArity, !U),
+    add_string(",\n", !U),
+    add_string("\tcreators([\n", !U),
+    mercury_format_pred_name_arity_list(CreatorPreds, !U),
+    add_string("\t]),\n", !U),
+    add_string("\tmutators([\n", !U),
+    mercury_format_pred_name_arity_list(MutatorPreds, !U),
+    add_string("\t]),\n", !U),
+    add_string("\tdestructors([\n", !U),
+    mercury_format_pred_name_arity_list(DestructorPreds, !U),
+    add_string("\t]).\n", !U),
+    add_string(").\n", !U).
+
+:- pred mercury_format_pred_name_arity_list(list(pred_name_arity)::in,
+    U::di, U::uo) is det <= output(U).
+
+mercury_format_pred_name_arity_list([], !U).
+mercury_format_pred_name_arity_list([PredNameArity | PredNameArities], !U) :-
+    mercury_format_pred_name_arity_list_lag(PredNameArity, PredNameArities,
+        !U).
+
+:- pred mercury_format_pred_name_arity_list_lag(pred_name_arity::in,
+    list(pred_name_arity)::in, U::di, U::uo) is det <= output(U).
+
+mercury_format_pred_name_arity_list_lag(PredNameArity, PredNameArities, !U) :-
+    add_string("\t\t", !U),
+    mercury_format_pred_name_arity(PredNameArity, !U),
+    (
+        PredNameArities = [],
+        add_string("\n", !U)
+    ;
+        PredNameArities = [HeadPredNameArity | TailPredNameArities],
+        add_string(",\n", !U),
+        mercury_format_pred_name_arity_list_lag(HeadPredNameArity,
+            TailPredNameArities, !U)
+    ).
+
+:- pred mercury_format_pred_name_arity(pred_name_arity::in, U::di, U::uo)
+    is det <= output(U).
+
+mercury_format_pred_name_arity(PredNameArity, !U) :-
+    PredNameArity = pred_name_arity(PredName, Arity),
+    mercury_format_bracketed_sym_name_ngt(PredName, next_to_graphic_token, !U),
+    add_string("/", !U),
+    add_int(Arity, !U).
+
+%-----------------------------------------------------------------------------%
+
 :- pred mercury_output_pragma_tabled(pragma_info_tabled::in,
     io::di, io::uo) is det.
 
Index: module_qual.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/module_qual.m,v
retrieving revision 1.194
diff -u -b -r1.194 module_qual.m
--- module_qual.m	5 Sep 2012 06:18:14 -0000	1.194
+++ module_qual.m	10 Sep 2012 13:06:58 -0000
@@ -9,8 +9,8 @@
 % File: module_qual.m.
 % Main authors: stayl, fjh.
 %
-% Module qualifies types, insts and modes within declaration items.  The
-% head of all declarations should be module qualified in prog_io.m.
+% Module qualifies types, insts and modes within declaration items.
+% The head of all declarations should be module qualified in prog_io.m.
 % This module qualifies the bodies of the declarations.  Checks for
 % undefined types, insts and modes.  Uses two passes over the item list,
 % one to collect all type, mode and inst ids and a second to do the
@@ -1039,21 +1039,16 @@
     SolverTypeDetails  = solver_type_details(RepnType, InitPred,
         GroundInst, AnyInst, MutableItems).
 
-:- pred qualify_constraint_stores(list(item)::in, list(item)::out,
+:- pred qualify_constraint_stores(
+    list(item_mutable_info)::in, list(item_mutable_info)::out,
     mq_info::in, mq_info::out,
     list(error_spec)::in, list(error_spec)::out) is det.
 
 qualify_constraint_stores([], [], !Info, !Specs).
-qualify_constraint_stores([CStore0 | CStores0], [CStore | CStores],
+qualify_constraint_stores([Mutable0 | Mutables0], [Mutable | Mutables],
         !Info, !Specs) :-
-    ( if CStore0 = item_mutable(ItemMutableInfo0) then
-        do_module_qualify_mutable(ItemMutableInfo0, ItemMutableInfo,
-            !Info, !Specs), 
-        CStore = item_mutable(ItemMutableInfo)
-      else
-        unexpected($module, $pred, "item is not a mutable")
-    ),
-    qualify_constraint_stores(CStores0, CStores, !Info, !Specs).
+    do_module_qualify_mutable(Mutable0, Mutable, !Info, !Specs),
+    qualify_constraint_stores(Mutables0, Mutables, !Info, !Specs).
 
 :- pred qualify_constructors(list(constructor)::in, list(constructor)::out,
     mq_info::in, mq_info::out,
@@ -1399,7 +1394,6 @@
         ; Pragma0 = pragma_trailing_info(_)
         ; Pragma0 = pragma_mm_tabling_info(_)
         ; Pragma0 = pragma_fact_table(_)
-        ; Pragma0 = pragma_reserve_tag(_)
         ; Pragma0 = pragma_promise_pure(_)
         ; Pragma0 = pragma_promise_semipure(_)
         ; Pragma0 = pragma_promise_eqv_clauses(_)
@@ -1411,22 +1405,25 @@
         ),
         Pragma = Pragma0
     ;
+        Pragma0 = pragma_reserve_tag(_TypeCtor0),
+        % XXX We should be module qualifying TypeCtor0 here,
+        % not in add_pragma.m. However, the code in add_pragma.m
+        % does generate better error messages than qualify_type_ctor does;
+        % this implies we should fix qualify_type_ctor.
+        Pragma = Pragma0
+    ;
         Pragma0 = pragma_foreign_export_enum(FEEInfo0),
-        FEEInfo0 = pragma_info_foreign_export_enum(Lang, TypeName0, TypeArity0,
+        FEEInfo0 = pragma_info_foreign_export_enum(Lang, TypeCtor0,
             Attributes, Overrides),
-        qualify_type_ctor(type_ctor(TypeName0, TypeArity0),
-            type_ctor(TypeName, TypeArity), !Info, !Specs),
-        FEEInfo = pragma_info_foreign_export_enum(Lang, TypeName, TypeArity,
+        qualify_type_ctor(TypeCtor0, TypeCtor, !Info, !Specs),
+        FEEInfo = pragma_info_foreign_export_enum(Lang, TypeCtor,
             Attributes, Overrides),
         Pragma = pragma_foreign_export_enum(FEEInfo)
     ;
         Pragma0 = pragma_foreign_enum(FEInfo0),
-        FEInfo0 = pragma_info_foreign_enum(Lang, TypeName0, TypeArity0,
-            Values),
-        qualify_type_ctor(type_ctor(TypeName0, TypeArity0),
-            type_ctor(TypeName, TypeArity), !Info, !Specs),
-        FEInfo = pragma_info_foreign_enum(Lang, TypeName, TypeArity,
-            Values),
+        FEInfo0 = pragma_info_foreign_enum(Lang, TypeCtor0, Values),
+        qualify_type_ctor(TypeCtor0, TypeCtor, !Info, !Specs),
+        FEInfo = pragma_info_foreign_enum(Lang, TypeCtor, Values),
         Pragma = pragma_foreign_enum(FEInfo)
     ;
         Pragma0 = pragma_foreign_proc(FPInfo0),
@@ -1440,6 +1437,15 @@
             Vars, Varset, InstVarset, Impl),
         Pragma = pragma_foreign_proc(FPInfo)
     ;
+        Pragma0 = pragma_oisu(OISUInfo0),
+        OISUInfo0 = pragma_info_oisu(TypeCtor0, CreatorPreds,
+            MutatorPreds, DestructorPreds),
+        % XXX Preds
+        qualify_type_ctor(TypeCtor0, TypeCtor, !Info, !Specs),
+        OISUInfo = pragma_info_oisu(TypeCtor, CreatorPreds,
+            MutatorPreds, DestructorPreds),
+        Pragma = pragma_oisu(OISUInfo)
+    ;
         Pragma0 = pragma_tabled(TabledInfo0),
         TabledInfo0 = pragma_info_tabled(EvalMethod, PredNameArityPF,
             MModes0, Attrs),
@@ -1455,13 +1461,15 @@
             MModes, Attrs),
         Pragma = pragma_tabled(TabledInfo)
     ;
-        Pragma0 = pragma_foreign_export(FEInfo0),
-        FEInfo0 = pragma_info_foreign_export(Lang, PredNameModesPF0, CFunc),
+        Pragma0 = pragma_foreign_proc_export(FPEInfo0),
+        FPEInfo0 = pragma_info_foreign_proc_export(Lang, PredNameModesPF0,
+            CFunc),
         PredNameModesPF0 = pred_name_modes_pf(Name, Modes0, PredOrFunc),
         qualify_mode_list(Modes0, Modes, !Info, !Specs),
         PredNameModesPF = pred_name_modes_pf(Name, Modes, PredOrFunc),
-        FEInfo = pragma_info_foreign_export(Lang, PredNameModesPF, CFunc),
-        Pragma = pragma_foreign_export(FEInfo)
+        FPEInfo = pragma_info_foreign_proc_export(Lang, PredNameModesPF,
+            CFunc),
+        Pragma = pragma_foreign_proc_export(FPEInfo)
     ;
         Pragma0 = pragma_type_spec(TypeSpecInfo0),
         TypeSpecInfo0 = pragma_info_type_spec(A, B, C, D, MaybeModes0,
@@ -1640,26 +1648,27 @@
 
 :- pred add_module_qualifier(sym_name::in, sym_name::in, sym_name::out) is det.
 
-add_module_qualifier(Module, unqualified(SymName), qualified(Module, SymName)).
-add_module_qualifier(DefaultModule, qualified(SymModule, SymName),
-        qualified(Module, SymName)) :-
+add_module_qualifier(DefaultModule, SymName0, SymName) :-
+    (
+        SymName0 = unqualified(Name),
+        SymName = qualified(DefaultModule, Name)
+    ;
+        SymName0 = qualified(SymModule, SubSymName),
     ( match_sym_name(SymModule, DefaultModule) ->
-        Module = DefaultModule
+            SymName = qualified(DefaultModule, SubSymName)
     ;
-        % This case is an error.  The user must have written something
-        % like
+            % This case is an error. The user must have written something like
         %   :- instance foo.bar(some_type) where [
         %       pred(baz.p/1) is q
         %   ].
-        % where the module qualifier on the pred or func in the
-        % instance (`baz.') does not match the qualifier for the
-        % class name (`foo.').
+            % where the module qualifier on the pred or func in the instance
+            % (baz) does not match the qualifier for the class name (foo).
         %
         % We don't report the error here, we just leave the original
         % module qualifier intact so that the error can be reported
         % later on.
-
-        Module = SymModule
+            SymName = SymName0
+        )
     ).
 
     % Find the unique match in the current name space for a given mq_id
@@ -1809,10 +1818,9 @@
         sym_name_and_arity(id_to_sym_name_and_arity(Id)),
         suffix("."), nl],
     (
-        %
-        % If it is a qualified symbol, then check whether the module
-        % specified has been imported.
-        %
+        % If it is a qualified symbol, then check whether the specified module
+        % has been imported.
+
         Id = mq_id(qualified(ModuleName, _), _Arity),
         mq_info_get_imported_modules(Info, ImportedModules),
         \+ set.member(ModuleName, ImportedModules),
Index: modules.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/modules.m,v
retrieving revision 1.472
diff -u -b -r1.472 modules.m
--- modules.m	5 Sep 2012 06:18:14 -0000	1.472
+++ modules.m	10 Sep 2012 13:07:00 -0000
@@ -1481,12 +1481,11 @@
         Item = item_pragma(ItemPragma),
         ItemPragma = item_pragma_info(_, Pragma, _, _),
         Pragma = pragma_foreign_enum(FEInfo),
-        FEInfo = pragma_info_foreign_enum(_Lang, TypeName, TypeArity, _Values)
+        FEInfo = pragma_info_foreign_enum(_Lang, TypeCtor, _Values)
     ->
         % We only add a pragma foreign_enum pragma to the interface file
         % if it corresponds to a type _definition_ in the interface of the
         % module.
-        TypeCtor = type_ctor(TypeName, TypeArity),
         map.search(TypeDefnMap, TypeCtor, Defns),
         Defns \= [parse_tree_abstract_type(_) - _]
     ;
@@ -1666,13 +1665,14 @@
     (
         ( Pragma = pragma_foreign_code(_)
         ; Pragma = pragma_foreign_decl(_)
-        ; Pragma = pragma_foreign_export(_)
+        ; Pragma = pragma_foreign_proc_export(_)
         ; Pragma = pragma_foreign_export_enum(_)
         ; Pragma = pragma_foreign_proc(_)
         ; Pragma = pragma_inline(_)
         ; Pragma = pragma_no_detism_warning(_)
         ; Pragma = pragma_no_inline(_)
         ; Pragma = pragma_fact_table(_)
+        ; Pragma = pragma_oisu(_)
         ; Pragma = pragma_tabled(_)
         ; Pragma = pragma_promise_pure(_)
         ; Pragma = pragma_promise_semipure(_)
@@ -3867,10 +3867,10 @@
                 FCInfo = pragma_info_foreign_code(Lang, _)
             ;
                 Pragma = pragma_foreign_enum(FEInfo),
-                FEInfo = pragma_info_foreign_enum(Lang, _, _, _)
+                FEInfo = pragma_info_foreign_enum(Lang, _, _)
             ;
-                Pragma = pragma_foreign_export(FEInfo),
-                FEInfo = pragma_info_foreign_export(Lang, _, _)
+                Pragma = pragma_foreign_proc_export(FPEInfo),
+                FPEInfo = pragma_info_foreign_proc_export(Lang, _, _)
             ),
             Langs = [Lang]
         ;
@@ -3890,6 +3890,7 @@
             ; Pragma = pragma_obsolete(_)
             ; Pragma = pragma_no_detism_warning(_)
             ; Pragma = pragma_source_file(_)
+            ; Pragma = pragma_oisu(_)
             ; Pragma = pragma_tabled(_)
             ; Pragma = pragma_fact_table(_)
             ; Pragma = pragma_reserve_tag(_)
@@ -3976,7 +3977,7 @@
             ( Pragma = pragma_foreign_decl(_)
             ; Pragma = pragma_foreign_code(_)
             ; Pragma = pragma_foreign_proc(_)
-            ; Pragma = pragma_foreign_export(_)
+            ; Pragma = pragma_foreign_proc_export(_)
             ; Pragma = pragma_foreign_export_enum(_)
             ; Pragma = pragma_type_spec(_)
             ; Pragma = pragma_inline(_)
@@ -3988,6 +3989,7 @@
             ; Pragma = pragma_obsolete(_)
             ; Pragma = pragma_no_detism_warning(_)
             ; Pragma = pragma_source_file(_)
+            ; Pragma = pragma_oisu(_)
             ; Pragma = pragma_tabled(_)
             ; Pragma = pragma_fact_table(_)
             ; Pragma = pragma_reserve_tag(_)
@@ -4403,7 +4405,7 @@
         ; Pragma = pragma_exceptions(_)
         ; Pragma = pragma_trailing_info(_)
         ; Pragma = pragma_mm_tabling_info(_)
-        ; Pragma = pragma_foreign_export(_)
+        ; Pragma = pragma_foreign_proc_export(_)
         ; Pragma = pragma_foreign_export_enum(_)
         ; Pragma = pragma_foreign_enum(_)
         ; Pragma = pragma_inline(_)
@@ -4415,6 +4417,7 @@
         ; Pragma = pragma_promise_semipure(_)
         ; Pragma = pragma_promise_eqv_clauses(_)
         ; Pragma = pragma_reserve_tag(_)
+        ; Pragma = pragma_oisu(_)
         ; Pragma = pragma_tabled(_)
         ; Pragma = pragma_terminates(_)
         ; Pragma = pragma_termination_info(_)
@@ -4511,11 +4514,11 @@
 
 :- func chunkable_pragma_type(pragma_type) = bool.
 
-chunkable_pragma_type(Pragma) = Reorderable :-
+chunkable_pragma_type(Pragma) = Chunkable :-
     (
         ( Pragma = pragma_check_termination(_)
         ; Pragma = pragma_does_not_terminate(_)
-        ; Pragma = pragma_foreign_export(_)
+        ; Pragma = pragma_foreign_proc_export(_)
         ; Pragma = pragma_foreign_export_enum(_)
         ; Pragma = pragma_foreign_enum(_)
         ; Pragma = pragma_inline(_)
@@ -4527,6 +4530,7 @@
         ; Pragma = pragma_promise_semipure(_)
         ; Pragma = pragma_promise_eqv_clauses(_)
         ; Pragma = pragma_reserve_tag(_)
+        ; Pragma = pragma_oisu(_)
         ; Pragma = pragma_tabled(_)
         ; Pragma = pragma_terminates(_)
         ; Pragma = pragma_termination_info(_)
@@ -4538,7 +4542,7 @@
         ; Pragma = pragma_unused_args(_)
         ; Pragma = pragma_require_feature_set(_)
         ),
-        Reorderable = yes
+        Chunkable = yes
     ;
         ( Pragma = pragma_exceptions(_)
         ; Pragma = pragma_fact_table(_)
@@ -4549,7 +4553,7 @@
         ; Pragma = pragma_source_file(_)
         ; Pragma = pragma_termination2_info(_)
         ),
-        Reorderable = no
+        Chunkable = no
     ).
 
     % Given a list of items for which symname_ordered succeeds, we need to keep
Index: prog_data.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/prog_data.m,v
retrieving revision 1.245
diff -u -b -r1.245 prog_data.m
--- prog_data.m	2 Jul 2012 01:16:36 -0000	1.245
+++ prog_data.m	10 Sep 2012 13:07:01 -0000
@@ -43,6 +43,7 @@
 
 :- implementation.
 
+:- import_module libs.options.
 :- import_module require.
 :- import_module string.
 
@@ -1827,7 +1828,7 @@
                 std_init_pred           :: solver_type_init,
                 std_ground_inst         :: mer_inst,
                 std_any_inst            :: mer_inst,
-                std_mutable_items       :: list(item)
+                std_mutable_items       :: list(item_mutable_info)
             ).
 
     % An init_pred specifies the name of an impure user-defined predicate
@@ -2534,6 +2535,8 @@
 :- pred add_all_modules(item_visibility::in, sym_name::in,
     used_modules::in, used_modules::out) is det.
 
+:- func lookup_current_backend(globals) = backend.
+
 :- implementation.
 
 used_modules_init = used_modules(set.init, set.init).
@@ -2560,6 +2563,16 @@
     set.insert(Module, ImplUsedModules0, ImplUsedModules),
     !UsedModules ^ impl_used_modules := ImplUsedModules.
 
+lookup_current_backend(Globals) = CurrentBackend :-
+    globals.lookup_bool_option(Globals, highlevel_code, HighLevel),
+    (
+        HighLevel = yes,
+        CurrentBackend = high_level_backend
+    ;
+        HighLevel= no,
+        CurrentBackend = low_level_backend
+    ).
+
 %-----------------------------------------------------------------------------%
 %
 % Event specifications.
Index: prog_io_mutable.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/prog_io_mutable.m,v
retrieving revision 1.3
diff -u -b -r1.3 prog_io_mutable.m
--- prog_io_mutable.m	23 May 2011 05:08:10 -0000	1.3
+++ prog_io_mutable.m	10 Sep 2012 13:07:01 -0000
@@ -33,6 +33,9 @@
 :- pred parse_mutable_decl(module_name::in, varset::in, list(term)::in,
     prog_context::in, int::in, maybe1(item)::out) is semidet.
 
+:- pred parse_mutable_decl_info(module_name::in, varset::in, list(term)::in,
+    prog_context::in, int::in, maybe1(item_mutable_info)::out) is semidet.
+
 %-----------------------------------------------------------------------------e
 
 :- implementation.
@@ -121,7 +124,19 @@
         )
     ).
 
-parse_mutable_decl(_ModuleName, VarSet, Terms, Context, SeqNum, MaybeItem) :-
+parse_mutable_decl(ModuleName, VarSet, Terms, Context, SeqNum, MaybeItem) :-
+    parse_mutable_decl_info(ModuleName, VarSet, Terms, Context, SeqNum,
+        MaybeMutableInfo),
+    (
+        MaybeMutableInfo = ok1(MutableInfo),
+        MaybeItem = ok1(item_mutable(MutableInfo))
+    ;
+        MaybeMutableInfo = error1(Specs),
+        MaybeItem = error1(Specs)
+    ).
+
+parse_mutable_decl_info(_ModuleName, VarSet, Terms, Context, SeqNum,
+        MaybeMutableInfo) :-
     Terms = [NameTerm, TypeTerm, ValueTerm, InstTerm | OptMutAttrsTerm],
     parse_mutable_name(NameTerm, MaybeName),
     parse_mutable_type(VarSet, TypeTerm, MaybeType),
@@ -149,14 +164,13 @@
         % references to it.  Ignoring the varset may lead to later compiler
         % passes attempting to reuse this variable when fresh variables are
         % allocated.
-        ItemMutable = item_mutable_info(Name, Type, Value, Inst, MutAttrs,
+        MutableInfo = item_mutable_info(Name, Type, Value, Inst, MutAttrs,
             ProgVarSet, Context, SeqNum),
-        Item = item_mutable(ItemMutable),
-        MaybeItem = ok1(Item)
+        MaybeMutableInfo = ok1(MutableInfo)
     ;
         Specs = get_any_errors1(MaybeName) ++ get_any_errors1(MaybeType) ++
             get_any_errors1(MaybeInst) ++ get_any_errors1(MaybeMutAttrs),
-        MaybeItem = error1(Specs)
+        MaybeMutableInfo = error1(Specs)
     ).
 
 :- pred parse_mutable_name(term::in, maybe1(string)::out) is det.
Index: prog_io_pragma.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/prog_io_pragma.m,v
retrieving revision 1.152
diff -u -b -r1.152 prog_io_pragma.m
--- prog_io_pragma.m	7 Sep 2012 11:42:01 -0000	1.152
+++ prog_io_pragma.m	10 Sep 2012 13:07:03 -0000
@@ -257,6 +257,10 @@
             "type", MakePragma, PragmaTerms, ErrorTerm,
             VarSet, Context, SeqNum, MaybeItem)
     ;
+        PragmaName = "ousi",
+        parse_oisu_pragma(ModuleName, PragmaTerms, ErrorTerm,
+            VarSet, Context, SeqNum, MaybeItem)
+    ;
         (
             PragmaName = "memo",
             EvalMethod = eval_memo
@@ -459,10 +463,10 @@
             MaybeOverridesTerm = yes(OverridesTerm)
         )
     ->
-        ( parse_foreign_language(LangTerm, ForeignLanguage) ->
-            parse_export_enum_type(MercuryTypeTerm, MaybeType),
+        ( parse_foreign_language(LangTerm, ForeignLang) ->
+            parse_export_enum_type_ctor(MercuryTypeTerm, MaybeTypeCtor),
             (
-                MaybeType = ok2(Name, Arity),
+                MaybeTypeCtor = ok1(TypeCtor),
                 maybe_parse_export_enum_attributes(VarSet, MaybeAttributesTerm,
                     MaybeAttributes),
                 (
@@ -471,10 +475,8 @@
                         MaybeOverridesTerm, MaybeOverrides),
                     (
                         MaybeOverrides = ok1(Overrides),
-                        FEEInfo = pragma_info_foreign_export_enum(
-                            ForeignLanguage, Name, Arity, Attributes,
-                            Overrides
-                        ),
+                        FEEInfo = pragma_info_foreign_export_enum(ForeignLang,
+                            TypeCtor, Attributes, Overrides),
                         Pragma = pragma_foreign_export_enum(FEEInfo),
                         ItemPragma = item_pragma_info(user, Pragma,
                             Context, SeqNum),
@@ -489,7 +491,7 @@
                     MaybeItem = error1(Specs)
                 )
             ;
-                MaybeType = error2(Specs),
+                MaybeTypeCtor = error1(Specs),
                 MaybeItem = error1(Specs)
             )
         ;
@@ -509,17 +511,17 @@
         MaybeItem = error1([Spec])
     ).
 
-:- pred parse_export_enum_type(term::in, maybe2(sym_name, arity)::out) is det.
+:- pred parse_export_enum_type_ctor(term::in, maybe1(type_ctor)::out) is det.
 
-parse_export_enum_type(TypeTerm, MaybeNameAndArity) :-
-    ( parse_name_and_arity(TypeTerm, Name, Arity) ->
-        MaybeNameAndArity = ok2(Name, Arity)
+parse_export_enum_type_ctor(TypeTerm, MaybeTypeCtor) :-
+    ( parse_name_and_arity_unqualified(TypeTerm, Name, Arity) ->
+        MaybeTypeCtor = ok1(type_ctor(Name, Arity))
     ;
         Pieces = [words("Error: expected name/arity for type in"),
             quote(":- pragma foreign_export_enum"), words("declaration."), nl],
         Spec = error_spec(severity_error, phase_term_to_parse_tree,
             [simple_msg(get_term_context(TypeTerm), [always(Pieces)])]),
-        MaybeNameAndArity = error2([Spec])
+        MaybeTypeCtor = error1([Spec])
     ).
 
 :- pred maybe_parse_export_enum_overrides(varset::in, maybe(term)::in,
@@ -672,10 +674,10 @@
 parse_pragma_foreign_enum(PragmaTerms, ErrorTerm, VarSet, Context, SeqNum,
         MaybeItem) :-
     ( PragmaTerms = [LangTerm, MercuryTypeTerm, ValuesTerm] ->
-        ( parse_foreign_language(LangTerm, ForeignLanguage) ->
-            parse_export_enum_type(MercuryTypeTerm, MaybeType),
+        ( parse_foreign_language(LangTerm, ForeignLang) ->
+            parse_export_enum_type_ctor(MercuryTypeTerm, MaybeTypeCtor),
             (
-                MaybeType = ok2(TypeName, TypeArity),
+                MaybeTypeCtor = ok1(TypeCtor),
                 UnrecognizedPieces =
                     [words("Error: expected a valid mapping element."), nl],
                 PairPieces = [words("In foreign_enum constructor name:")],
@@ -684,8 +686,8 @@
                     UnrecognizedPieces, MaybeValues),
                 (
                     MaybeValues = ok1(Values),
-                    FEInfo = pragma_info_foreign_enum(ForeignLanguage,
-                        TypeName, TypeArity, Values),
+                    FEInfo = pragma_info_foreign_enum(ForeignLang, TypeCtor,
+                        Values),
                     Pragma = pragma_foreign_enum(FEInfo),
                     ItemPragma = item_pragma_info(user, Pragma, Context,
                         SeqNum),
@@ -696,7 +698,7 @@
                     MaybeItem = error1(Specs)
                 )
             ;
-                MaybeType = error2(Specs),
+                MaybeTypeCtor = error1(Specs),
                 MaybeItem = error1(Specs)
             )
         ;
@@ -737,9 +739,9 @@
                 ( parse_foreign_language(LangTerm, ForeignLanguage) ->
                     PredNameModesPF = pred_name_modes_pf(PredName, Modes,
                         PredOrFunc),
-                    FEInfo = pragma_info_foreign_export(ForeignLanguage,
+                    FPEInfo = pragma_info_foreign_proc_export(ForeignLanguage,
                         PredNameModesPF, Function),
-                    Pragma = pragma_foreign_export(FEInfo),
+                    Pragma = pragma_foreign_proc_export(FPEInfo),
                     ItemPragma = item_pragma_info(user, Pragma, Context,
                         SeqNum),
                     Item = item_pragma(ItemPragma),
@@ -1794,7 +1796,8 @@
         MaybeItem = error1(Specs)
     ).
 
-    % This parses a pragma that refers to symbol name / arity.
+    % Parse the sole argument of a pragma that should contain
+    % a symbol name / arity pair.
     %
 :- pred parse_name_arity_pragma(module_name::in, string::in, string::in,
     pred(sym_name, int, pragma_type)::(pred(in, in, out) is det),
@@ -1803,12 +1806,12 @@
 
 parse_name_arity_pragma(ModuleName, PragmaName, NameKind, MakePragma,
         PragmaTerms, ErrorTerm, VarSet, Context, SeqNum, MaybeItem) :-
-    ( PragmaTerms = [PredAndArityTerm] ->
+    ( PragmaTerms = [NameAndArityTerm] ->
         parse_simple_name_and_arity(ModuleName, PragmaName, NameKind,
-            PredAndArityTerm, PredAndArityTerm, VarSet, MaybeNameAndArity),
+            NameAndArityTerm, NameAndArityTerm, VarSet, MaybeNameAndArity),
         (
-            MaybeNameAndArity = ok2(PredName, Arity),
-            MakePragma(PredName, Arity, Pragma),
+            MaybeNameAndArity = ok2(Name, Arity),
+            MakePragma(Name, Arity, Pragma),
             ItemPragma = item_pragma_info(user, Pragma, Context, SeqNum),
             Item = item_pragma(ItemPragma),
             MaybeItem = ok1(Item)
@@ -2360,6 +2363,153 @@
         MaybePragmaVars = error1([Spec])
     ).
 
+:- pred parse_oisu_pragma(module_name::in, list(term)::in, term::in,
+    varset::in, prog_context::in, int::in, maybe1(item)::out) is det.
+
+parse_oisu_pragma(ModuleName, PragmaTerms, ErrorTerm, VarSet, Context, SeqNum,
+        MaybeItem) :-
+    (
+        PragmaTerms = [TypeCtorTerm, CreatorsTerm, MutatorsTerm | OtherTerms],
+        (
+            OtherTerms = [],
+            MaybeDestructorsTerm = no
+        ;
+            OtherTerms = [DestructorsTerm],
+            MaybeDestructorsTerm = yes(DestructorsTerm)
+        )
+    ->
+        ( parse_name_and_arity(ModuleName, TypeCtorTerm, Name, Arity) ->
+            MaybeTypeCtor = ok1(type_ctor(Name, Arity))
+        ;
+            TypeCtorTermStr = describe_error_term(VarSet, TypeCtorTerm),
+            Pieces = [words("Error: expected"),
+                words("predicate name/arity for first argument of"),
+                quote(":- pragma oisu"), words("declaration, not"),
+                quote(TypeCtorTermStr), suffix("."), nl],
+            TypeCtorSpec = error_spec(severity_error, phase_term_to_parse_tree,
+                [simple_msg(get_term_context(ErrorTerm), [always(Pieces)])]),
+            MaybeTypeCtor = error1([TypeCtorSpec])
+        ),
+        parse_oisu_preds_term(ModuleName, VarSet, "second", "creators",
+            CreatorsTerm, MaybeCreatorsNamesArities),
+        parse_oisu_preds_term(ModuleName, VarSet, "third", "mutators",
+            MutatorsTerm, MaybeMutatorsNamesArities),
+        (
+            MaybeDestructorsTerm = yes(DestructorsTerm2),
+            parse_oisu_preds_term(ModuleName, VarSet, "third", "mutators",
+                DestructorsTerm2, MaybeDestructorsNamesArities)
+        ;
+            MaybeDestructorsTerm = no,
+            MaybeDestructorsNamesArities = ok1([])
+        ),
+        (
+            MaybeTypeCtor = ok1(TypeCtor),
+            MaybeCreatorsNamesArities = ok1(CreatorsNamesArities),
+            MaybeMutatorsNamesArities = ok1(MutatorsNamesArities),
+            MaybeDestructorsNamesArities = ok1(DestructorsNamesArities)
+        ->
+            OISUInfo = pragma_info_oisu(TypeCtor, CreatorsNamesArities,
+                MutatorsNamesArities, DestructorsNamesArities),
+            Pragma = pragma_oisu(OISUInfo),
+            ItemPragma = item_pragma_info(user, Pragma, Context, SeqNum),
+            Item = item_pragma(ItemPragma),
+            MaybeItem = ok1(Item)
+        ;
+            Specs = get_any_errors1(MaybeTypeCtor) ++
+                get_any_errors1(MaybeCreatorsNamesArities) ++
+                get_any_errors1(MaybeMutatorsNamesArities) ++
+                get_any_errors1(MaybeDestructorsNamesArities),
+            MaybeItem = error1(Specs)
+        )
+    ;
+        Pieces = [words("Error: wrong number of arguments in"),
+            quote(":- pragma oisu"), words("declaration."), nl],
+        Spec = error_spec(severity_error, phase_term_to_parse_tree,
+            [simple_msg(get_term_context(ErrorTerm), [always(Pieces)])]),
+        MaybeItem = error1([Spec])
+   ).
+
+:- pred parse_oisu_preds_term(module_name::in, varset::in, string::in,
+    string::in, term::in, maybe1(list(pred_name_arity))::out) is det.
+
+parse_oisu_preds_term(ModuleName, VarSet, ArgNum, ExpectedFunctor, Term,
+        MaybeNamesArities) :-
+    (
+        Term = term.functor(term.atom(Functor), Args, _),
+        Functor = ExpectedFunctor,
+        Args = [Arg]
+    ->
+        parse_name_and_arity_list(ModuleName, VarSet, ExpectedFunctor,
+            Arg, MaybeNamesArities)
+    ;
+        Pieces = [words("Error:"), words(ArgNum), words("argument of"),
+            quote(":- pragma oisu"), words("declaration"),
+            words("should have the form"),
+            quote(ExpectedFunctor ++ "([pred1/arity1, ..., predn/arityn])"),
+            suffix("."), nl],
+        Spec = error_spec(severity_error, phase_term_to_parse_tree,
+            [simple_msg(get_term_context(Term), [always(Pieces)])]),
+        MaybeNamesArities = error1([Spec])
+    ).
+
+:- pred parse_name_and_arity_list(module_name::in, varset::in, string::in,
+    term::in, maybe1(list(pred_name_arity))::out) is det.
+
+parse_name_and_arity_list(ModuleName, VarSet, Wrapper, Term,
+        MaybeNamesArities) :-
+    (
+        Term = term.functor(Functor, Args, _),
+        (
+            Functor = term.atom("[]"),
+            Args = []
+        ->
+            MaybeNamesArities = ok1([])
+        ;
+            Functor = term.atom("[|]"),
+            Args = [Arg1, Arg2]
+        ->
+            ( parse_name_and_arity(ModuleName, Arg1, Arg1Name, Arg1Arity) ->
+                MaybeHeadNameArity = ok1(pred_name_arity(Arg1Name, Arg1Arity))
+            ;
+                Arg1Str = describe_error_term(VarSet, Arg1),
+                Pieces = [words("Error: expected predname/arity,"),
+                    words("not"), quote(Arg1Str), suffix("."), nl],
+                Spec = error_spec(severity_error, phase_term_to_parse_tree,
+                    [simple_msg(get_term_context(Arg1), [always(Pieces)])]),
+                MaybeHeadNameArity = error1([Spec])
+            ),
+            parse_name_and_arity_list(ModuleName, VarSet, Wrapper, Arg2,
+                MaybeTailNamesArities),
+            (
+                MaybeHeadNameArity = ok1(HeadNameArity),
+                MaybeTailNamesArities = ok1(TailNamesArities)
+            ->
+                MaybeNamesArities = ok1([HeadNameArity | TailNamesArities])
+            ;
+                HeadSpecs = get_any_errors1(MaybeHeadNameArity),
+                TailSpecs = get_any_errors1(MaybeTailNamesArities),
+                MaybeNamesArities = error1(HeadSpecs ++ TailSpecs)
+            )
+        ;
+            TermStr = describe_error_term(VarSet, Term),
+            Pieces = [words("Error: expected a list as the argument of"),
+                words(Wrapper), suffix(","),
+                words("not"), quote(TermStr), suffix("."), nl],
+            Spec = error_spec(severity_error, phase_term_to_parse_tree,
+                [simple_msg(get_term_context(Term), [always(Pieces)])]),
+            MaybeNamesArities = error1([Spec])
+        )
+    ;
+        Term = term.variable(_, _),
+        TermStr = describe_error_term(VarSet, Term),
+        Pieces = [words("Error: expected a list as the argument of"),
+            words(Wrapper), suffix(","),
+            words("not"), quote(TermStr), suffix("."), nl],
+        Spec = error_spec(severity_error, phase_term_to_parse_tree,
+            [simple_msg(get_term_context(Term), [always(Pieces)])]),
+        MaybeNamesArities = error1([Spec])
+    ).
+
 :- pred parse_tabling_pragma(module_name::in, string::in, eval_method::in,
     list(term)::in, term::in, varset::in, prog_context::in, int::in,
     maybe1(item)::out) is det.
@@ -2385,10 +2535,10 @@
                 MaybeModes),
             (
                 MaybeAttrs = no,
-                PredNameArityMPF = pred_name_arity_mpf(PredName,
-                    Arity, MaybePredOrFunc),
-                TabledInfo = pragma_info_tabled(EvalMethod,
-                    PredNameArityMPF, MaybeModes, no),
+                PredNameArityMPF = pred_name_arity_mpf(PredName, Arity,
+                    MaybePredOrFunc),
+                TabledInfo = pragma_info_tabled(EvalMethod, PredNameArityMPF,
+                    MaybeModes, no),
                 Pragma = pragma_tabled(TabledInfo),
                 ItemPragma = item_pragma_info(user, Pragma, Context, SeqNum),
                 Item = item_pragma(ItemPragma),
@@ -2398,8 +2548,7 @@
                 UnrecognizedPieces =
                     [words("Error: expected tabling attribute."), nl],
                 convert_maybe_list("tabling attributes", yes(VarSet),
-                    AttrsListTerm,
-                    parse_tabling_attribute(VarSet, EvalMethod),
+                    AttrsListTerm, parse_tabling_attribute(VarSet, EvalMethod),
                     UnrecognizedPieces, MaybeAttributeList),
                 (
                     MaybeAttributeList = ok1(AttributeList),
@@ -2482,8 +2631,7 @@
         (
             !.Attributes ^ table_attr_statistics = table_dont_gather_statistics
         ->
-            !Attributes ^ table_attr_statistics
-                := table_gather_statistics,
+            !Attributes ^ table_attr_statistics := table_gather_statistics,
             update_tabling_attributes(TermSingleAttrs, !.Attributes,
                 MaybeAttributes)
         ;
@@ -2496,8 +2644,7 @@
     ;
         SingleAttr = attr_allow_reset,
         ( !.Attributes ^ table_attr_allow_reset = table_dont_allow_reset ->
-            !Attributes ^ table_attr_allow_reset
-                := table_allow_reset,
+            !Attributes ^ table_attr_allow_reset := table_allow_reset,
             update_tabling_attributes(TermSingleAttrs, !.Attributes,
                 MaybeAttributes)
         ;
Index: prog_io_type_defn.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/prog_io_type_defn.m,v
retrieving revision 1.7
diff -u -b -r1.7 prog_io_type_defn.m
--- prog_io_type_defn.m	5 Jul 2011 03:34:33 -0000	1.7
+++ prog_io_type_defn.m	10 Sep 2012 13:07:03 -0000
@@ -987,7 +987,8 @@
     ContextPieces = [],
     parse_type(Term, VarSet, ContextPieces, MaybeType).
 
-:- func parse_where_mutable_is(module_name, term) = maybe1(list(item)).
+:- func parse_where_mutable_is(module_name, term) =
+    maybe1(list(item_mutable_info)).
 
 parse_where_mutable_is(ModuleName, Term) = MaybeItems :-
     ( Term = term.functor(term.atom("mutable"), _, _) ->
@@ -1009,22 +1010,22 @@
         MaybeItems = error1([Spec])
     ).
 
-:- pred parse_mutable_decl_term(module_name::in, term::in, maybe1(item)::out)
-    is det.
+:- pred parse_mutable_decl_term(module_name::in, term::in,
+    maybe1(item_mutable_info)::out) is det.
 
-parse_mutable_decl_term(ModuleName, Term, MaybeItem) :-
+parse_mutable_decl_term(ModuleName, Term, MaybeMutableInfo) :-
     (
         Term = term.functor(term.atom("mutable"), Args, Context),
         varset.init(VarSet),
-        parse_mutable_decl(ModuleName, VarSet, Args, Context, -1,
-            MaybeItemPrime)
+        parse_mutable_decl_info(ModuleName, VarSet, Args, Context, -1,
+            MaybeMutableInfoPrime)
     ->
-        MaybeItem = MaybeItemPrime
+        MaybeMutableInfo = MaybeMutableInfoPrime
     ;
         Pieces = [words("Error: expected a mutable declaration."), nl],
         Spec = error_spec(severity_error, phase_term_to_parse_tree,
             [simple_msg(get_term_context(Term), [always(Pieces)])]),
-        MaybeItem = error1([Spec])
+        MaybeMutableInfo = error1([Spec])
     ).
 
 :- func parse_where_direct_arg_is(module_name, varset, term) =
@@ -1071,7 +1072,7 @@
 :- func make_maybe_where_details(is_solver_type, maybe1(maybe(unit)),
     maybe1(maybe(mer_type)), maybe1(maybe(init_pred)),
     maybe1(maybe(mer_inst)), maybe1(maybe(mer_inst)),
-    maybe1(maybe(list(item))),
+    maybe1(maybe(list(item_mutable_info))),
     maybe1(maybe(equality_pred)), maybe1(maybe(comparison_pred)),
     maybe1(maybe(list(sym_name_and_arity))),
     maybe1(maybe(unit)), term)
@@ -1116,7 +1117,8 @@
 
 :- func make_maybe_where_details_2(is_solver_type, maybe(unit),
     maybe(mer_type), maybe(init_pred), maybe(mer_inst), maybe(mer_inst),
-    maybe(list(item)), maybe(equality_pred), maybe(comparison_pred),
+    maybe(list(item_mutable_info)),
+    maybe(equality_pred), maybe(comparison_pred),
     maybe(list(sym_name_and_arity)), maybe(unit), term)
     = maybe3(maybe(solver_type_details), maybe(unify_compare),
         maybe(list(sym_name_and_arity))).
@@ -1170,7 +1172,7 @@
                 AnyIs            = MaybeAnyInst,
                 EqualityIs       = MaybeEqPred,
                 ComparisonIs     = MaybeCmpPred,
-                CStoreIs         = MaybeMutableItems
+                CStoreIs         = MaybeMutableInfos
             ->
                 (
                     MaybeGroundInst = yes(GroundInst)
@@ -1185,10 +1187,10 @@
                     AnyInst = ground_inst
                 ),
                 (
-                    MaybeMutableItems = yes(MutableItems)
+                    MaybeMutableInfos = yes(MutableInfos)
                 ;
-                    MaybeMutableItems = no,
-                    MutableItems = []
+                    MaybeMutableInfos = no,
+                    MutableInfos = []
                 ),
                 (
                     MaybeInitialisation = yes(InitPred),
@@ -1198,7 +1200,7 @@
                     HowToInit = solver_init_explicit
                 ),
                 SolverTypeDetails = solver_type_details(
-                    RepnType, HowToInit, GroundInst, AnyInst, MutableItems),
+                    RepnType, HowToInit, GroundInst, AnyInst, MutableInfos),
                 MaybeSolverTypeDetails = yes(SolverTypeDetails),
                 (
                     MaybeEqPred = no,
Index: prog_io_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/prog_io_util.m,v
retrieving revision 1.75
diff -u -b -r1.75 prog_io_util.m
--- prog_io_util.m	23 Apr 2012 03:34:49 -0000	1.75
+++ prog_io_util.m	10 Sep 2012 13:07:04 -0000
@@ -108,8 +108,8 @@
 :- pred parse_name_and_arity(module_name::in, term(T)::in,
     sym_name::out, arity::out) is semidet.
 
-:- pred parse_name_and_arity(term(T)::in, sym_name::out, arity::out)
-    is semidet.
+:- pred parse_name_and_arity_unqualified(term(T)::in,
+    sym_name::out, arity::out) is semidet.
 
 :- pred parse_pred_or_func_name_and_arity(term(T)::in,
     pred_or_func::out, sym_name::out, arity::out) is semidet.
@@ -263,7 +263,7 @@
         PredNameTerm, SymName),
     ArityTerm = term.functor(term.integer(Arity), [], _).
 
-parse_name_and_arity(PredAndArityTerm, SymName, Arity) :-
+parse_name_and_arity_unqualified(PredAndArityTerm, SymName, Arity) :-
     parse_name_and_arity(unqualified(""),
         PredAndArityTerm, SymName, Arity).
 
Index: prog_item.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/prog_item.m,v
retrieving revision 1.47
diff -u -b -r1.47 prog_item.m
--- prog_item.m	5 Sep 2012 06:18:15 -0000	1.47
+++ prog_item.m	10 Sep 2012 13:07:05 -0000
@@ -455,7 +455,7 @@
     ;       pragma_foreign_code(pragma_info_foreign_code)
     ;       pragma_foreign_proc(pragma_info_foreign_proc)
     ;       pragma_foreign_import_module(pragma_info_foreign_import_module)
-    ;       pragma_foreign_export(pragma_info_foreign_export)
+    ;       pragma_foreign_proc_export(pragma_info_foreign_proc_export)
     ;       pragma_foreign_export_enum(pragma_info_foreign_export_enum)
     ;       pragma_foreign_enum(pragma_info_foreign_enum)
     ;       pragma_type_spec(pragma_info_type_spec)
@@ -471,6 +471,7 @@
     ;       pragma_tabled(pragma_info_tabled)
     ;       pragma_fact_table(pragma_info_fact_table)
     ;       pragma_reserve_tag(type_ctor)
+    ;       pragma_oisu(pragma_info_oisu)
     ;       pragma_promise_eqv_clauses(pred_name_arity)
     ;       pragma_promise_pure(pred_name_arity)
     ;       pragma_promise_semipure(pred_name_arity)
@@ -525,8 +526,8 @@
                 imp_module              :: module_name
             ).
 
-:- type pragma_info_foreign_export
-    --->    pragma_info_foreign_export(
+:- type pragma_info_foreign_proc_export
+    --->    pragma_info_foreign_proc_export(
                 % Predname, Predicate/function, Modes, foreign function name.
                 exp_language            :: foreign_language,
                 exp_pred_id             :: pred_name_modes_pf,
@@ -536,8 +537,7 @@
 :- type pragma_info_foreign_export_enum
     --->    pragma_info_foreign_export_enum(
                 export_enum_language   :: foreign_language,
-                export_enum_type_name  :: sym_name,
-                export_enum_type_arity :: arity,
+                export_enum_type_ctor  :: type_ctor,
                 export_enum_attributes :: export_enum_attributes,
                 export_enum_overrides  :: assoc_list(sym_name, string)
             ).
@@ -545,8 +545,7 @@
 :- type pragma_info_foreign_enum
     --->    pragma_info_foreign_enum(
                 foreign_enum_language   :: foreign_language,
-                foreign_enum_type_name  :: sym_name,
-                foreign_enum_type_arity :: arity,
+                foreign_enum_type_ctor  :: type_ctor,
                 foreign_enum_values     :: assoc_list(sym_name, string)
             ).
 
@@ -627,7 +626,13 @@
                 fact_table_filename     :: string
             ).
 
-    % Purity pragmas.
+:- type pragma_info_oisu
+    --->    pragma_info_oisu(
+                oisu_type_ctor          :: type_ctor,
+                oisu_creator_preds      :: list(pred_name_arity),
+                oisu_transformer_preds  :: list(pred_name_arity),
+                oisu_destroyer_preds    :: list(pred_name_arity)
+            ).
 
     % Termination analysis pragmas.
 
@@ -1146,8 +1151,8 @@
         % punts it on to mlds_to_c.m, thus generating C code for it,
         % rather than assembler code. So we need to treat `pragma export'
         % like the other pragmas for foreign code.
-        Pragma = pragma_foreign_export(FEInfo),
-        FEInfo = pragma_info_foreign_export(Lang, _, _),
+        Pragma = pragma_foreign_proc_export(FPEInfo),
+        FPEInfo = pragma_info_foreign_proc_export(Lang, _, _),
         ( list.member(Lang, BackendLangs) ->
             !Info ^ used_foreign_languages :=
                 set.insert(!.Info ^ used_foreign_languages, Lang),
@@ -1210,6 +1215,7 @@
         ; Pragma = pragma_source_file(_)
         ; Pragma = pragma_structure_reuse(_)
         ; Pragma = pragma_structure_sharing(_)
+        ; Pragma = pragma_oisu(_)
         ; Pragma = pragma_tabled(_)
         ; Pragma = pragma_terminates(_)
         ; Pragma = pragma_termination2_info(_)
Index: recompilation.check.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/recompilation.check.m,v
retrieving revision 1.56
diff -u -b -r1.56 recompilation.check.m
--- recompilation.check.m	5 Jul 2011 03:34:33 -0000	1.56
+++ recompilation.check.m	10 Sep 2012 13:07:05 -0000
@@ -353,7 +353,7 @@
 :- pred parse_name_and_arity_to_used(term::in, item_name::out) is semidet.
 
 parse_name_and_arity_to_used(Term, UsedClass) :-
-    parse_name_and_arity(Term, ClassName, ClassArity),
+    parse_name_and_arity_unqualified(Term, ClassName, ClassArity),
     UsedClass = item_name(ClassName, ClassArity).
 
 %-----------------------------------------------------------------------------%
@@ -438,7 +438,7 @@
 parse_simple_item(Info, Term, !Set) :-
     (
         Term = term.functor(term.atom("-"), [NameArityTerm, MatchesTerm], _),
-        parse_name_and_arity(NameArityTerm, SymName, Arity)
+        parse_name_and_arity_unqualified(NameArityTerm, SymName, Arity)
     ->
         Name = unqualify_name(SymName),
         conjunction_to_list(MatchesTerm, MatchTermList),
@@ -553,14 +553,16 @@
             Arity)
     ;
         Term = term.functor(term.atom("ctor"), [NameArityTerm], _),
-        parse_name_and_arity(NameArityTerm, TypeName, TypeArity)
+        parse_name_and_arity_unqualified(NameArityTerm, TypeName, TypeArity)
     ->
         Ctor = resolved_functor_constructor(item_name(TypeName, TypeArity))
     ;
         Term = term.functor(term.atom("field"),
             [TypeNameArityTerm, ConsNameArityTerm], _),
-        parse_name_and_arity(TypeNameArityTerm, TypeName, TypeArity),
-        parse_name_and_arity(ConsNameArityTerm, ConsName, ConsArity)
+        parse_name_and_arity_unqualified(TypeNameArityTerm,
+            TypeName, TypeArity),
+        parse_name_and_arity_unqualified(ConsNameArityTerm,
+            ConsName, ConsArity)
     ->
         Ctor = resolved_functor_field(item_name(TypeName, TypeArity),
             item_name(ConsName, ConsArity))
Index: recompilation.version.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/recompilation.version.m,v
retrieving revision 1.83
diff -u -b -r1.83 recompilation.version.m
--- recompilation.version.m	5 Sep 2012 06:18:15 -0000	1.83
+++ recompilation.version.m	10 Sep 2012 13:07:06 -0000
@@ -616,6 +616,7 @@
         ; PragmaType = pragma_foreign_enum(_)
         ; PragmaType = pragma_source_file(_)
         ; PragmaType = pragma_reserve_tag(_)
+        ; PragmaType = pragma_oisu(_)               % XXX
         ; PragmaType = pragma_require_feature_set(_)
         ),
         MaybePredOrFuncId = no
@@ -672,8 +673,8 @@
         MaybePredOrFuncId = yes(yes(PredOrFunc) - Name / Arity)
     ;
         (
-            PragmaType = pragma_foreign_export(FEInfo),
-            FEInfo = pragma_info_foreign_export(_, PredNameModesPF, _)
+            PragmaType = pragma_foreign_proc_export(FPEInfo),
+            FPEInfo = pragma_info_foreign_proc_export(_, PredNameModesPF, _)
         ;
             PragmaType = pragma_termination_info(TermInfo),
             TermInfo = pragma_info_termination_info(PredNameModesPF, _, _)
cvs diff: Diffing notes
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list