Files
mercury/tests/hard_coded/intermod_may_export_body2.m
Peter Wang e9dafb3ec6 Add foreign_proc attributes may_export_body/may_not_export_body.
Add an attribute may_not_export_body to prevent a foreign_proc from
being opt-exported. Also add may_export_body for completeness.

compiler/prog_data_foreign.m:
    Add type to represent those attributes.

    Add a field for that attribute to pragma_foreign_proc_attributes,
    plus getters and setters.

compiler/parse_pragma_foreign.m:
    Parse may_export_body and may_not_export_body attributes on
    foreign_proc declarations.

    Detect conflicting attributes.

compiler/parse_tree_out_pragma.m:
    Write out may_export_body and may_not_export_body attributes.

compiler/intermod.m:
    Do not write a foreign_proc with may_not_export_body to .opt files.

compiler/simplify_proc.m:
    Report an error if a foreign_proc with may_export_body is
    also marked with pragma no_inline.

compiler/add_mutable_aux_preds.m:
    Mark auxiliary predicates for mutables with may_not_export_body
    instead of may_not_duplicate. This allows calls to those predicates
    to be inlined.

doc/reference_manual.texi:
    Document the new attributes.

tests/hard_coded/Mercury.options:
tests/hard_coded/Mmakefile:
tests/hard_coded/intermod_may_export_body.exp:
tests/hard_coded/intermod_may_export_body.m:
tests/hard_coded/intermod_may_export_body2.m:
tests/invalid/Mmakefile:
tests/invalid/test_may_export_body.err_exp:
tests/invalid/test_may_export_body.m:
    Add test cases.

vim/syntax/mercury.vim:
    Update vim syntax file.

NEWS:
    Announce addition.
2021-04-20 11:05:29 +10:00

60 lines
1.5 KiB
Mathematica

%---------------------------------------------------------------------------%
% vim: ts=4 sw=4 et ft=mercury
%---------------------------------------------------------------------------%
:- module intermod_may_export_body2.
:- interface.
:- pred plus(int::in, int::in, int::out) is det.
:- pred cannot_export_plus(int::in, int::in, int::out) is det.
:- implementation.
plus(X, Y, Z) :-
% This call should be inlined.
cannot_export_plus(X, Y, Z).
%---------------------------------------------------------------------------%
:- pragma foreign_decl("C", local, "
typedef MR_Integer MyInt;
").
:- pragma foreign_decl("C#", local, "
using System.Collections; // for ArrayList
").
:- pragma foreign_decl("Java", local, "
import java.util.ArrayList;
").
:- pragma inline(cannot_export_plus/3).
:- pragma foreign_proc("C",
cannot_export_plus(X::in, Y::in, Z::out),
[will_not_call_mercury, promise_pure, may_not_export_body],
"
// Refers to local type MyInt.
Z = (MyInt) (X + Y);
").
:- pragma foreign_proc("C#",
cannot_export_plus(X::in, Y::in, Z::out),
[will_not_call_mercury, promise_pure, may_not_export_body],
"
// Uses ArrayList without namespace prefix.
ArrayList arr = new ArrayList();
arr.Add(X + Y);
Z = (int) arr[0];
").
:- pragma foreign_proc("Java",
cannot_export_plus(X::in, Y::in, Z::out),
[will_not_call_mercury, promise_pure, may_not_export_body],
"
// Uses ArrayList without package prefix.
ArrayList<Integer> arr = new ArrayList();
arr.add(X + Y);
Z = arr.get(0);
").