[m-rev.] for post-commit review: local foreign_decl's

Zoltan Somogyi zs at cs.mu.OZ.AU
Wed Jun 9 17:54:40 AEST 2004


For review by Fergus, if he has the time.

Zoltan.

Add a mechanism that allows foreign_decl pieces of code to remain local
to the module. This is needed by the robdd module, which I want to add
to the library.

doc/reference_manual.texi:
	Document the new mechanism, which is an optional field in foreign_decl
	pragmas.

compiler/foreign.m:
	Add a flag to foreign_decls that says whether they are local to
	their defining module, or exported to other modules.

compiler/prog_data.m:
	Add a field to the foreign_decl item to hold this flag.

compiler/prog_io_pragm.m:
	Parse the optional field in foreign_decl pragmas that specifies this
	flag.

compiler/mercury_to_mercury.m:
	Print the field in foreign_decl items.

compiler/make_hlds.m:
	Transmit the field from the item to the HLDS.

compiler/mercury_compile.m:
	When generating the list of foreign_decls to put at the start of a C
	file, do not enclose the local declarations in the usual guards.
	These guards are defined by the header file, but having seen the header
	file doesn't guarantee any more that we have seen all the foreign_decls
	of the module we are compiling.

compiler/export.m:
compiler/mlds_to_c.m:
	When generating header files, only include a foreign_decl
	if it is not marked as local.

compiler/mlds_to_java.m:
compiler/mlds_to_managed.m:
	Ignore the local/exported distinction for foreign_decls for now. 
	Implementing it for these languages may be nontrivial, and we don't
	yet need the capability.

compiler/hlds_module.m:
compiler/llds_out.m:
compiler/recompilation.version.m:
compiler/module_qual.m:
compiler/modules.m:
	Conform to the changes above.

cvs diff: Diffing .
cvs diff: Diffing analysis
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/export.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/export.m,v
retrieving revision 1.77
diff -u -b -r1.77 export.m
--- compiler/export.m	5 Apr 2004 05:06:47 -0000	1.77
+++ compiler/export.m	31 May 2004 06:39:30 -0000
@@ -1,4 +1,4 @@
-%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%)
 % Copyright (C) 1996-2004 The University of Melbourne.
 % This file may only be copied under the terms of the GNU General
 % Public License - see the file COPYING in the Mercury distribution.
@@ -654,7 +654,8 @@
 			"#ifndef ", decl_guard(ModuleName), "\n",
 			"#define ", decl_guard(ModuleName), "\n"],
 			!IO),
-		list__foldl(output_foreign_decl, ForeignDecls, !IO),
+		list__foldl(output_foreign_decl(yes(foreign_decl_is_exported)),
+			ForeignDecls, !IO),
 		io__write_string("\n#endif\n", !IO),
 
 		export__produce_header_file_2(C_ExportDecls, !IO),
@@ -701,18 +702,28 @@
 	),
 	export__produce_header_file_2(ExportedProcs).
 
-:- pred output_foreign_decl(foreign_decl_code::in, io::di, io::uo) is det.
+:- pred output_foreign_decl(maybe(foreign_decl_is_local)::in,
+	foreign_decl_code::in, io::di, io::uo) is det.
 
-export__output_foreign_decl(foreign_decl_code(Lang, Code, Context)) -->
-	( { Lang = c } ->
-		{ term__context_file(Context, File) },
-		{ term__context_line(Context, Line) },
-		c_util__set_line_num(File, Line),
-		io__write_string(Code),
-		io__nl,
-		c_util__reset_line_num
+output_foreign_decl(MaybeDesiredIsLocal, DeclCode, !IO) :-
+	DeclCode = foreign_decl_code(Lang, IsLocal, Code, Context),
+	(
+		Lang = c,
+		(
+			MaybeDesiredIsLocal = no
+		;
+			MaybeDesiredIsLocal = yes(DesiredIsLocal),
+			DesiredIsLocal = IsLocal
+		)
+	->
+		term__context_file(Context, File),
+		term__context_line(Context, Line),
+		c_util__set_line_num(File, Line, !IO),
+		io__write_string(Code, !IO),
+		io__nl(!IO),
+		c_util__reset_line_num(!IO)
 	;
-		[]
+		true
 	).
 
 %-----------------------------------------------------------------------------%
Index: compiler/foreign.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/foreign.m,v
retrieving revision 1.37
diff -u -b -r1.37 foreign.m
--- compiler/foreign.m	12 May 2004 14:24:18 -0000	1.37
+++ compiler/foreign.m	24 May 2004 08:50:00 -0000
@@ -33,13 +33,27 @@
 :- type foreign_body_info   ==	list(foreign_body_code).
 		% in reverse order
 
-:- type foreign_decl_code	--->
-		foreign_decl_code(foreign_language, string, prog_context).
-:- type foreign_import_module	--->
-		foreign_import_module(foreign_language, module_name,
-			prog_context).
-:- type foreign_body_code	--->
-		foreign_body_code(foreign_language, string, prog_context).
+:- type foreign_decl_code
+	--->	foreign_decl_code(
+			foreign_language,
+			foreign_decl_is_local,
+			string,
+			prog_context
+		).
+
+:- type foreign_import_module
+	--->	foreign_import_module(
+			foreign_language,
+			module_name,
+			prog_context
+		).
+
+:- type foreign_body_code
+	--->	foreign_body_code(
+			foreign_language,
+			string,
+			prog_context
+		).
 
 :- type foreign_export_defns == list(foreign_export).
 :- type foreign_export_decls
@@ -287,7 +301,7 @@
 prefer_foreign_language(_Globals, java, _Lang1, _Lang2) = no.
 
 foreign__filter_decls(WantedLang, Decls0, LangDecls, NotLangDecls) :-
-	list__filter((pred(foreign_decl_code(Lang, _, _)::in) is semidet :-
+	list__filter((pred(foreign_decl_code(Lang, _, _, _)::in) is semidet :-
 			WantedLang = Lang),
 		Decls0, LangDecls, NotLangDecls).
 
Index: compiler/hlds_module.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_module.m,v
retrieving revision 1.99
diff -u -b -r1.99 hlds_module.m
--- compiler/hlds_module.m	7 Jun 2004 09:06:42 -0000	1.99
+++ compiler/hlds_module.m	7 Jun 2004 09:22:20 -0000
@@ -272,8 +272,9 @@
 :- pred module_info_set_foreign_import_module(foreign_import_module_info::in,
 	module_info::in, module_info::out) is det.
 
-:- pred module_add_foreign_decl(foreign_language::in, string::in,
-	prog_context::in, module_info::in, module_info::out) is det.
+:- pred module_add_foreign_decl(foreign_language::in,
+	foreign_decl_is_local::in, string::in, prog_context::in,
+	module_info::in, module_info::out) is det.
 
 :- pred module_add_foreign_body_code(foreign_language::in, string::in,
 	prog_context::in, module_info::in, module_info::out) is det.
@@ -907,12 +908,12 @@
 	AllImports = (IndirectImports `set__union` DirectImports)
 			`set__union` set__list_to_set(Parents).
 
-module_add_foreign_decl(Lang, ForeignDecl, Context, !Module) :-
+module_add_foreign_decl(Lang, IsLocal, ForeignDecl, Context, !Module) :-
 	module_info_get_foreign_decl(!.Module, ForeignDeclIndex0),
 		% store the decls in reverse order and reverse them later
 		% for efficiency
-	ForeignDeclIndex = [foreign_decl_code(Lang, ForeignDecl, Context) |
-		ForeignDeclIndex0],
+	ForeignDeclIndex = [foreign_decl_code(Lang, IsLocal, ForeignDecl,
+		Context) | ForeignDeclIndex0],
 	module_info_set_foreign_decl(ForeignDeclIndex, !Module).
 
 module_add_foreign_body_code(Lang, Foreign_Body_Code, Context, !Module) :-
Index: compiler/llds_out.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/llds_out.m,v
retrieving revision 1.234
diff -u -b -r1.234 llds_out.m
--- compiler/llds_out.m	7 Jun 2004 09:06:49 -0000	1.234
+++ compiler/llds_out.m	7 Jun 2004 09:22:20 -0000
@@ -1081,22 +1081,17 @@
 			"foreign code other than C")
 	).
 
-	% output_foreign_header_include_lines reverses the list of c
-	% header lines and passes them to
-	% output_c_header_include_lines_2 which outputs them.  The list
-	% must be reversed since they are inserted in reverse order.
 :- pred output_foreign_header_include_lines(list(foreign_decl_code)::in,
 	io::di, io::uo) is det.
 
-output_foreign_header_include_lines(Headers, !IO) :-
-	list__reverse(Headers, RevHeaders),
-	list__foldl(output_foreign_header_include_lines_2, RevHeaders, !IO).
+output_foreign_header_include_lines(Decls, !IO) :-
+	list__foldl(output_foreign_header_include_line, Decls, !IO).
 
-:- pred output_foreign_header_include_lines_2(foreign_decl_code::in,
+:- pred output_foreign_header_include_line(foreign_decl_code::in,
 	io::di, io::uo) is det.
 
-output_foreign_header_include_lines_2(Decl, !IO) :-
-	Decl = foreign_decl_code(Lang, Code, Context),
+output_foreign_header_include_line(Decl, !IO) :-
+	Decl = foreign_decl_code(Lang, _IsLocal, Code, Context),
 	( Lang = c ->
 		globals__io_lookup_bool_option(auto_comments, PrintComments,
 			!IO),
Index: compiler/make_hlds.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/make_hlds.m,v
retrieving revision 1.470
diff -u -b -r1.470 make_hlds.m
--- compiler/make_hlds.m	7 Jun 2004 09:06:51 -0000	1.470
+++ compiler/make_hlds.m	7 Jun 2004 09:22:20 -0000
@@ -475,8 +475,9 @@
 		module_add_foreign_body_code(Lang, Body_Code, Context,
 			!Module)
 	;
-		Pragma  = foreign_decl(Lang, C_Header),
-		module_add_foreign_decl(Lang, C_Header, Context, !Module)
+		Pragma  = foreign_decl(Lang, IsLocal, C_Header),
+		module_add_foreign_decl(Lang, IsLocal, C_Header, Context,
+			!Module)
 	;
 		Pragma  = foreign_import_module(Lang, Import),
 		module_add_foreign_import_module(Lang, Import, Context,
@@ -8624,8 +8625,8 @@
 
 				% create foreign_decls to declare
 				% extern variables
-			module_add_foreign_decl(c, C_HeaderCode, Context,
-				!Module),
+			module_add_foreign_decl(c, foreign_decl_is_local,
+				C_HeaderCode, Context, !Module),
 
 			module_add_fact_table_file(FileName, !Module),
 
Index: compiler/mercury_compile.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mercury_compile.m,v
retrieving revision 1.309
diff -u -b -r1.309 mercury_compile.m
--- compiler/mercury_compile.m	7 Jun 2004 09:06:54 -0000	1.309
+++ compiler/mercury_compile.m	7 Jun 2004 09:22:21 -0000
@@ -3815,10 +3815,18 @@
 			ChunkedModules)
 	),
 	list__map_foldl(make_foreign_import_header_code, C_Includes,
-		C_HeaderCode1, !IO),
+		C_IncludeHeaderCode, !IO),
 
+	% The lists are reversed because insertions into them are at the front.
+	% We don't want to put C_LocalHeaderCode between Start and End, because
+	% C_IncludeHeaderCode may include our own header file, which defines
+	% the module's guard macro, which in turn #ifdefs out the stuff between
+	% Start and End.
+	list__filter(foreign_decl_code_is_local, list__reverse(C_HeaderCode0),
+		C_LocalHeaderCode, C_ExportedHeaderCode),
 	make_decl_guards(ModuleSymName, Start, End),
-	C_HeaderCode = [End | C_HeaderCode0] ++ [Start | C_HeaderCode1],
+	C_HeaderCode = list__reverse(C_IncludeHeaderCode) ++
+		C_LocalHeaderCode ++ [Start | C_ExportedHeaderCode] ++ [End],
 
 	CFile = c_file(ModuleSymName, C_HeaderCode, C_BodyCode,
 		C_ExportDefns, GlobalVars, AllData, ChunkedModules),
@@ -3830,6 +3838,11 @@
 	ComponentCount = UserCCodeCount + ExportCount
 		+ CompGenVarCount + CompGenDataCount + CompGenCodeCount.
 
+:- pred foreign_decl_code_is_local(foreign_decl_code::in) is semidet.
+
+foreign_decl_code_is_local(Decl) :-
+	Decl = foreign_decl_code(_, foreign_decl_is_local, _, _).
+
 :- pred make_decl_guards(sym_name::in, foreign_decl_code::out,
 	foreign_decl_code::out) is det.
 
@@ -3837,8 +3850,10 @@
 	Define = decl_guard(ModuleName),
 	Start = "#ifndef " ++ Define ++ "\n#define " ++ Define ++ "\n",
 	End = "\n#endif",
-	StartGuard = foreign_decl_code(c, Start, term__context_init),
-	EndGuard = foreign_decl_code(c, End, term__context_init).
+	StartGuard = foreign_decl_code(c, foreign_decl_is_exported, Start,
+		term__context_init),
+	EndGuard = foreign_decl_code(c, foreign_decl_is_exported, End,
+		term__context_init).
 
 :- pred make_foreign_import_header_code(foreign_import_module::in,
 	foreign_decl_code::out, io::di, io::uo) is det.
@@ -3852,7 +3867,8 @@
 		string__append_list(
 			["#include """, HeaderFileName, """\n"],
 			IncludeString),
-		Include = foreign_decl_code(c, IncludeString, Context)
+		Include = foreign_decl_code(c, foreign_decl_is_exported,
+			IncludeString, Context)
 	;
 		Lang = csharp,
 		error("sorry. :- import_module not yet implemented: " ++
Index: compiler/mercury_to_mercury.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mercury_to_mercury.m,v
retrieving revision 1.241
diff -u -b -r1.241 mercury_to_mercury.m
--- compiler/mercury_to_mercury.m	20 May 2004 22:03:07 -0000	1.241
+++ compiler/mercury_to_mercury.m	24 May 2004 08:10:47 -0000
@@ -174,12 +174,12 @@
 :- mode mercury_output_index_spec(in, di, uo) is det.
 
 	% Output the given foreign_decl declaration
-:- pred mercury_output_pragma_foreign_decl(foreign_language, string,
-		io__state, io__state).
-:- mode mercury_output_pragma_foreign_decl(in, in, di, uo) is det.
+:- pred mercury_output_pragma_foreign_decl(foreign_language::in,
+	foreign_decl_is_local::in, string::in,
+	io::di, io::uo) is det.
 
-:- func mercury_pragma_foreign_decl_to_string(foreign_language, string)
-	= string.
+:- func mercury_pragma_foreign_decl_to_string(foreign_language,
+	foreign_decl_is_local, string) = string.
 
 :- pred mercury_output_pragma_foreign_import_module(foreign_language,
 		module_name, io__state, io__state).
@@ -554,8 +554,9 @@
 		{ Pragma = source_file(SourceFile) },
 		mercury_output_pragma_source_file(SourceFile)
 	;
-		{ Pragma = foreign_decl(Lang, ForeignHeaderString) },
-		mercury_output_pragma_foreign_decl(Lang, ForeignHeaderString)
+		{ Pragma = foreign_decl(Lang, IsLocal, ForeignHeaderString) },
+		mercury_output_pragma_foreign_decl(Lang, IsLocal,
+			ForeignHeaderString)
 	;
 		{ Pragma = foreign_import_module(Lang, ModuleName) },
 		mercury_output_pragma_foreign_import_module(Lang, ModuleName)
@@ -2765,22 +2766,32 @@
 
 %-----------------------------------------------------------------------------%
 
-mercury_output_pragma_foreign_decl(Lang, ForeignDeclString) -->
-	mercury_format_pragma_foreign_decl(Lang, ForeignDeclString).
+mercury_output_pragma_foreign_decl(Lang, IsLocal, ForeignDeclString) -->
+	mercury_format_pragma_foreign_decl(Lang, IsLocal, ForeignDeclString).
 
-mercury_pragma_foreign_decl_to_string(Lang, ForeignDeclString) = String :-
-	mercury_format_pragma_foreign_decl(Lang, ForeignDeclString,
+mercury_pragma_foreign_decl_to_string(Lang, IsLocal, ForeignDeclString)
+		= String :-
+	mercury_format_pragma_foreign_decl(Lang, IsLocal, ForeignDeclString,
 		"", String).
 
-:- pred mercury_format_pragma_foreign_decl(foreign_language::in, string::in,
-	U::di, U::uo) is det <= output(U).
+:- pred mercury_format_pragma_foreign_decl(foreign_language::in,
+	foreign_decl_is_local::in, string::in, U::di, U::uo) is det
+	<= output(U).
 
-mercury_format_pragma_foreign_decl(Lang, ForeignDeclString) -->
-	add_string(":- pragma foreign_decl("),
-	mercury_format_foreign_language_string(Lang),
-	add_string(", "),
-	mercury_format_foreign_code_string(ForeignDeclString),
-	add_string(").\n").
+mercury_format_pragma_foreign_decl(Lang, IsLocal, ForeignDeclString, !U) :-
+	add_string(":- pragma foreign_decl(", !U),
+	mercury_format_foreign_language_string(Lang, !U),
+	add_string(", ", !U),
+	(
+		IsLocal = foreign_decl_is_local,
+		add_string("local", !U)
+	;
+		IsLocal = foreign_decl_is_exported,
+		add_string("exported", !U)
+	),
+	add_string(", ", !U),
+	mercury_format_foreign_code_string(ForeignDeclString, !U),
+	add_string(").\n", !U).
 
 mercury_output_foreign_language_string(Lang) -->
 	mercury_format_foreign_language_string(Lang).
Index: compiler/mlds_to_c.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mlds_to_c.m,v
retrieving revision 1.162
diff -u -b -r1.162 mlds_to_c.m
--- compiler/mlds_to_c.m	23 Mar 2004 10:52:09 -0000	1.162
+++ compiler/mlds_to_c.m	31 May 2004 06:50:15 -0000
@@ -601,26 +601,46 @@
 	DeclGuard = decl_guard(SymName),
 	io__write_strings(["#ifndef ", DeclGuard,
 		"\n#define ", DeclGuard, "\n"], !IO),
-	io__write_list(HeaderCode, "\n", mlds_output_c_hdr_decl(Indent), !IO),
+	io__write_list(HeaderCode, "\n",
+		mlds_output_c_hdr_decl(Indent, yes(foreign_decl_is_exported)),
+		!IO),
 	io__write_string("\n#endif\n", !IO).
 
-:- pred mlds_output_c_hdr_decl(indent::in, foreign_decl_code::in,
-	io::di, io::uo) is det.
+:- pred mlds_output_c_hdr_decl(indent::in, maybe(foreign_decl_is_local)::in,
+	foreign_decl_code::in, io::di, io::uo) is det.
 
-mlds_output_c_hdr_decl(_Indent, foreign_decl_code(Lang, Code, Context), !IO) :-
-		% only output C code in the C header file.
+mlds_output_c_hdr_decl(_Indent, MaybeDesiredIsLocal, DeclCode, !IO) :-
+	DeclCode = foreign_decl_code(Lang, IsLocal, Code, Context),
+	% Only output C code in the C header file.
 	( Lang = c ->
-		mlds_to_c__output_context(mlds__make_context(Context), !IO),
+		( 
+			(
+				MaybeDesiredIsLocal = no
+			;
+				MaybeDesiredIsLocal = yes(DesiredIsLocal),
+				IsLocal = DesiredIsLocal
+			)
+		->
+			mlds_to_c__output_context(mlds__make_context(Context),
+				!IO),
 		io__write_string(Code, !IO)
 	;
+			true
+		)
+	;
 		sorry(this_file, "foreign code other than C")
 	).
 
 :- pred mlds_output_c_decls(indent::in, mlds__foreign_code::in,
 	io::di, io::uo) is det.
 
-% all of the declarations go in the header file or as c_code
-mlds_output_c_decls(_, _, !IO).
+mlds_output_c_decls(Indent, ForeignCode, !IO) :-
+	ForeignCode = mlds__foreign_code(RevHeaderCode, _RevImports,
+		_RevBodyCode, _ExportDefns),
+	HeaderCode = list__reverse(RevHeaderCode),
+	io__write_list(HeaderCode, "\n",
+		mlds_output_c_hdr_decl(Indent, yes(foreign_decl_is_local)),
+		!IO).
 
 :- pred mlds_output_c_defns(mlds_module_name::in, indent::in,
 	mlds__foreign_code::in, io::di, io::uo) is det.
Index: compiler/mlds_to_java.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mlds_to_java.m,v
retrieving revision 1.58
diff -u -b -r1.58 mlds_to_java.m
--- compiler/mlds_to_java.m	29 Apr 2004 08:43:58 -0000	1.58
+++ compiler/mlds_to_java.m	24 May 2004 08:26:18 -0000
@@ -443,11 +443,11 @@
 % Code for working with Java `foreign_code'.
 %
 
-:- pred output_java_decl(indent::in, foreign_decl_code::in, io::di,
-	io::uo) is det.
+:- pred output_java_decl(indent::in, foreign_decl_code::in, io::di, io::uo)
+	is det.
 
-output_java_decl(Indent, foreign_decl_code(Lang, Code, Context), !IO) :-
-	% only output Java code
+output_java_decl(Indent, DeclCode, !IO) :-
+	DeclCode = foreign_decl_code(Lang, _IsLocal, Code, Context),
 	( Lang = java ->
 		indent_line(make_context(Context), Indent, !IO),
 		io__write_string(Code, !IO),
Index: compiler/mlds_to_managed.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mlds_to_managed.m,v
retrieving revision 1.11
diff -u -b -r1.11 mlds_to_managed.m
--- compiler/mlds_to_managed.m	19 Mar 2004 10:19:24 -0000	1.11
+++ compiler/mlds_to_managed.m	24 May 2004 08:27:11 -0000
@@ -276,7 +276,8 @@
 
 	{ HeaderCode = list__reverse(RevHeaderCode) },
 	io__write_list(HeaderCode, "\n", 
-		(pred(foreign_decl_code(CodeLang, Code, Context)::in,
+		% XXX Ignoring _IsLocal may not be the right thing to do.
+		(pred(foreign_decl_code(CodeLang, _IsLocal, Code, Context)::in,
 				di, uo) is det -->
 			output_context(Lang, Context),
 			( { CodeLang = Lang } ->
Index: compiler/module_qual.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/module_qual.m,v
retrieving revision 1.90
diff -u -b -r1.90 module_qual.m
--- compiler/module_qual.m	12 May 2004 14:24:30 -0000	1.90
+++ compiler/module_qual.m	24 May 2004 08:20:24 -0000
@@ -984,7 +984,7 @@
 	mq_info::in, mq_info::out, io__state::di, io__state::uo) is det.
 
 qualify_pragma(X at source_file(_), X, Info, Info) --> [].
-qualify_pragma(X at foreign_decl(_, _), X, Info, Info) --> [].
+qualify_pragma(X at foreign_decl(_, _, _), X, Info, Info) --> [].
 qualify_pragma(X at foreign_code(_, _), X, Info, Info) --> [].
 qualify_pragma(X at foreign_import_module(_, _), X, Info, Info) --> [].
 qualify_pragma(X, Y, Info0, Info) -->
Index: compiler/modules.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/modules.m,v
retrieving revision 1.301
diff -u -b -r1.301 modules.m
--- compiler/modules.m	7 Jun 2004 09:06:58 -0000	1.301
+++ compiler/modules.m	7 Jun 2004 09:22:22 -0000
@@ -1660,7 +1660,7 @@
 % but if we do allow it, we should put it in the generated
 % header file, which currently we don't.
 
-pragma_allowed_in_interface(foreign_decl(_, _), no).
+pragma_allowed_in_interface(foreign_decl(_, _, _), no).
 pragma_allowed_in_interface(foreign_import_module(_, _), yes).
 pragma_allowed_in_interface(foreign_code(_, _), no).
 pragma_allowed_in_interface(foreign_proc(_, _, _, _, _, _), no).
@@ -6927,7 +6927,7 @@
 item_needs_foreign_imports(Item @ type_defn(_, _, _, _, _), Lang) :-
 	Item ^ td_ctor_defn = foreign_type(ForeignType, _, _),
 	Lang = foreign_type_language(ForeignType).
-item_needs_foreign_imports(pragma(foreign_decl(Lang, _)), Lang).
+item_needs_foreign_imports(pragma(foreign_decl(Lang, _, _)), Lang).
 item_needs_foreign_imports(pragma(foreign_code(Lang, _)), Lang).
 item_needs_foreign_imports(pragma(foreign_proc(Attrs, _, _, _, _, _)),
 		foreign_language(Attrs)).
Index: compiler/proc_label.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/proc_label.m,v
retrieving revision 1.4
diff -u -b -r1.4 proc_label.m
--- compiler/proc_label.m	19 May 2004 03:59:33 -0000	1.4
+++ compiler/proc_label.m	9 Jun 2004 05:23:28 -0000
@@ -34,7 +34,7 @@
 	% from `.opt' files, the defining module's name may need to be added
 	% as a qualifier to the label.
 
-:- type proc_label
+:.- type proc_label
 	--->	proc(
 			module_name,	% defining module
 			pred_or_func,
Index: compiler/prog_data.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/prog_data.m,v
retrieving revision 1.108
diff -u -b -r1.108 prog_data.m
--- compiler/prog_data.m	12 May 2004 14:24:33 -0000	1.108
+++ compiler/prog_data.m	24 May 2004 08:01:40 -0000
@@ -227,6 +227,10 @@
 % Pragmas
 %
 
+:- type foreign_decl_is_local
+	--->	foreign_decl_is_local
+	;	foreign_decl_is_exported.
+
 :- type pragma_type
 	%
 	% Foreign language interfacing pragmas
@@ -235,6 +239,7 @@
 			% header code.
 	--->	foreign_decl(
 			decl_lang	:: foreign_language,
+			decl_is_local	:: foreign_decl_is_local,
 			decl_decl	:: string
 		)
 
Index: compiler/prog_io_pragma.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/prog_io_pragma.m,v
retrieving revision 1.66
diff -u -b -r1.66 prog_io_pragma.m
--- compiler/prog_io_pragma.m	12 May 2004 14:24:34 -0000	1.66
+++ compiler/prog_io_pragma.m	24 May 2004 08:48:35 -0000
@@ -261,6 +261,23 @@
 			"declaration", ErrorTerm)
 	).
 
+:- pred parse_foreign_decl_is_local(term::in, foreign_decl_is_local::out)
+	is semidet.
+
+parse_foreign_decl_is_local(term__functor(Functor, [], _), IsLocal) :-
+	(
+		Functor = term__string(String)
+	;
+		Functor = term__atom(String)
+	),
+	(
+		String = "local",
+		IsLocal = foreign_decl_is_local
+	;
+		String = "exported",
+		IsLocal = foreign_decl_is_exported
+	).
+
 :- pred parse_foreign_language(term, foreign_language).
 :- mode parse_foreign_language(in, out) is semidet.
 
@@ -427,17 +444,24 @@
 	string__format("invalid `:- pragma %s' declaration ", [s(Pragma)],
 		InvalidDeclStr),
 	( 
-		PragmaTerms = [Lang, HeaderTerm]
+		(
+			PragmaTerms = [LangTerm, HeaderTerm],
+			IsLocal = foreign_decl_is_exported
+		;
+			PragmaTerms = [LangTerm, IsLocalTerm, HeaderTerm],
+			parse_foreign_decl_is_local(IsLocalTerm, IsLocal)
+		)
 	->
 		( 
-			parse_foreign_language(Lang, ForeignLanguage)
+			parse_foreign_language(LangTerm, ForeignLanguage)
 		->
 			(
 				HeaderTerm = term__functor(term__string(
 					HeaderCode), [], _)
 			->
-				Result = ok(pragma(foreign_decl(
-					ForeignLanguage, HeaderCode)))
+				DeclCode = foreign_decl(ForeignLanguage,
+					IsLocal, HeaderCode),
+				Result = ok(pragma(DeclCode))
 			;
 				ErrMsg = "-- expected string for foreign declaration code",
 				Result = error(string__append(InvalidDeclStr,
@@ -446,7 +470,7 @@
 		;
 			ErrMsg = "-- invalid language parameter",
 			Result = error(string__append(InvalidDeclStr, ErrMsg), 
-				Lang)
+				LangTerm)
 		)
 	;
 		string__format("invalid `:- pragma %s' declaration ",
Index: compiler/recompilation.version.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/recompilation.version.m,v
retrieving revision 1.8
diff -u -b -r1.8 recompilation.version.m
--- compiler/recompilation.version.m	12 May 2004 14:24:35 -0000	1.8
+++ compiler/recompilation.version.m	24 May 2004 08:21:19 -0000
@@ -561,7 +561,7 @@
 :- pred is_pred_pragma(pragma_type::in,
 		maybe(maybe_pred_or_func_id)::out) is det.
 
-is_pred_pragma(foreign_decl(_, _), no).
+is_pred_pragma(foreign_decl(_, _, _), no).
 is_pred_pragma(foreign_import_module(_, _), no).
 is_pred_pragma(foreign_code(_, _), no).
 is_pred_pragma(foreign_proc(_, Name, PredOrFunc, Args, _, _),
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
Index: doc/reference_manual.texi
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/doc/reference_manual.texi,v
retrieving revision 1.293
diff -u -b -r1.293 reference_manual.texi
--- doc/reference_manual.texi	12 May 2004 14:19:06 -0000	1.293
+++ doc/reference_manual.texi	31 May 2004 07:05:51 -0000
@@ -5788,8 +5788,8 @@
 @section Adding foreign declarations
 
 Foreign language declarations (such as type declarations, header file
-inclusions or macro definitions) can included in the Mercury source file as
-part of a @samp{foreign_decl} declaration of the form
+inclusions or macro definitions) can be included in the Mercury source file
+as part of a @samp{foreign_decl} declaration of the form
 
 @example
 :- pragma foreign_decl("@var{Lang}", @var{DeclCode}).
@@ -5806,6 +5806,27 @@
 visible in @samp{pragma foreign_code}, @samp{pragma foreign_type},
 and @samp{pragma foreign_proc} declarations that specify the same foreign
 language and occur in the same Mercury module.
+
+By default, the contents of @samp{pragma foreign_decl} declarations
+are also visible in the same kinds of declarations in other modules
+that import the module containing the @samp{pragma foreign_decl} declaration.
+This is because they may be required to make sense of
+types defined using @samp{pragma foreign_type} and/or
+predicates defined using @samp{pragma foreign_code}
+in the containing module,
+and these may be visible in other modules,
+especially in the presence of intermodule optimization,
+
+If you do not want the contents of a @samp{pragma foreign_decl} declaration
+to be visible in foreign language code in other modules,
+you can use the following variant of the declaration:
+
+ at example
+:- pragma foreign_decl("@var{Lang}", local, @var{DeclCode}).
+ at end example
+
+Note: currently only the C backends support this variant
+of the @samp{pragma foreign_decl} declaration.
 
 To make the declarations for Mercury predicates or functions
 exported to a foreign language using a @samp{pragma export}
cvs diff: Diffing extras
cvs diff: Diffing extras/aditi
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/concurrency
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/mercury_glut
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/stream
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/mmc_make
cvs diff: Diffing tests/mmc_make/lib
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
cvs diff: Diffing util
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list