diff: bug fix for pragma export includes

David Glen JEFFERY dgj at cs.mu.oz.au
Mon Jul 28 16:10:58 AEST 1997


Hi all,

Could someone please review this?

=====================

Estimated hours taken: 2

Change the place in which the "#include" for a module's ".h" file is placed
when a procedure has been exported. Previously, the #include appeared just
before the definitions of the C functions for the exports. This change puts
the include at the top of the generated C file.

This has the consequence that the exported function can be used from 
pragma c_code declarations without explicitly including the .h file.

compiler/llds_out.m:
	Don't bother outputting the include line when are outputing the 
	exported functions.
compiler/mercury_compile.m:
	When we generate the pragma exports, add a "#include" to the
	c_header_info. This always gets put at the top of the generated file.

tests/hard_coded/export_test.*:
	A test for this bug fix.

compiler/llds_out.m:
compiler/mercury_compile.m:

Index: compiler/llds_out.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/llds_out.m,v
retrieving revision 1.52
diff -u -r1.52 llds_out.m
--- llds_out.m	1997/07/27 15:00:53	1.52
+++ llds_out.m	1997/07/28 04:37:05
@@ -445,22 +445,8 @@
 	io__write_string(C_Code),
 	io__write_string("\n").
 
-output_c_module(c_export(PragmaExports), DeclSet, DeclSet, BaseName) -->
-	(
-		{ PragmaExports = [_|_] }
-	->
-		globals__io_lookup_bool_option(split_c_files, SplitFiles),
-		( { SplitFiles = yes } ->
-			io__write_strings(
-				["#include ""../", BaseName, ".h""\n"])
-		;
-			io__write_strings(["#include """, BaseName, ".h""\n"])
-		),
-		output_exported_c_functions(PragmaExports)
-	;
-		% Don't spit out a #include if there are no pragma exports
-		[]	
-	).
+output_c_module(c_export(PragmaExports), DeclSet, DeclSet, _BaseName) -->
+	output_exported_c_functions(PragmaExports).
 
 	% output_c_header_include_lines reverses the list of c header lines
 	% and passes them to output_c_header_include_lines_2 which outputs them.
Index: compiler/mercury_compile.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/mercury_compile.m,v
retrieving revision 1.49
diff -u -r1.49 mercury_compile.m
--- mercury_compile.m	1997/07/27 15:00:58	1.49
+++ mercury_compile.m	1997/07/28 05:09:45
@@ -1429,7 +1429,7 @@
 	{ module_info_name(HLDS, Name) },
 	{ string__append(Name, "_module", ModName) },
 	globals__io_lookup_int_option(procs_per_c_function, ProcsPerFunc),
-	{ module_info_get_c_header(HLDS, C_HeaderCode) },
+	{ module_info_get_c_header(HLDS, C_HeaderCode0) },
 	{ module_info_get_c_body_code(HLDS, C_BodyCode0) },
 	{ get_c_body_code(C_BodyCode0, C_BodyCode) },
 	( { ProcsPerFunc = 0 } ->
@@ -1442,9 +1442,44 @@
 			ProcModules) }
 	),
 	{ export__get_pragma_exported_procs(HLDS, PragmaExports) },
+	maybe_add_header_file_include(PragmaExports, Name, C_HeaderCode0,
+		C_HeaderCode),
 	{ list__condense([C_BodyCode, BaseTypeData, CommonDataModules,
 		ProcModules, [c_export(PragmaExports)]], ModuleList) },
 	{ list__length(ModuleList, NumChunks) }.
+
+:- pred maybe_add_header_file_include(list(c_export), string,
+	c_header_info, c_header_info, io__state, io__state).
+:- mode maybe_add_header_file_include(in, in, in, out, di, uo) is det.
+
+maybe_add_header_file_include(PragmaExports, BaseName, 
+		C_HeaderCode0, C_HeaderCode) -->
+	(
+		{ PragmaExports = [] },
+		{ C_HeaderCode = C_HeaderCode0 }
+	;
+		{ PragmaExports = [_|_] },
+                globals__io_lookup_bool_option(split_c_files, SplitFiles),
+                { 
+			SplitFiles = yes,
+                        string__append_list(
+                                ["#include ""../", BaseName, ".h""\n"],
+				Include0)
+                ;
+			SplitFiles = no,
+                        string__append_list(
+				["#include """, BaseName, ".h""\n"],
+				Include0)
+                },
+
+		{ term__context_init(Context) },
+		{ Include = Include0 - Context },
+
+			% We put the new include at the end since the list is
+			% stored in reverse, and we want this include to come
+			% first.
+		{ list__append(C_HeaderCode0, [Include], C_HeaderCode) }
+	).
 
 :- pred get_c_body_code(c_body_info, list(c_module)).
 :- mode get_c_body_code(in, out) is det.


Index: Mmake
===================================================================
RCS file: /home/staff/zs/imp/tests/hard_coded/Mmake,v
retrieving revision 1.54
diff -u -r1.54 Mmake
--- Mmake	1997/07/23 15:29:02	1.54
+++ Mmake	1997/07/28 05:23:44
@@ -23,6 +23,7 @@
 	elim_special_pred \
 	error_func \
 	expand \
+	export_test \
 	float_map \
 	float_reg \
 	float_rounding_bug \

New File: export_test.exp
===================================================================
42

New File: export_test.m
===================================================================
%
% test case for calling an exported Mercury proc from pragma c_code.
%
% author: dgj
:- module export_test.

:- interface.

:- import_module int, io.

:- pred main(io__state::di, io__state::uo) is det.

:- pred foo(int::in, int::out) is det.

:- pred bar(int::in, int::out) is det.

:- implementation.

main -->
	{ bar(41, X) },
	io__write(X),
	io__write_char('\n').

foo(X, X+1).

:- pragma export(foo(in, out), "foo").

:- pragma c_code(bar(X::in, Y::out),
"
	foo(X, &Y);
").



=====================


love and cuddles,
dgj
-- 
David Jeffery (dgj at cs.mu.oz.au)     |  Kids, you tried your best and 
MEngSc student,                     |  you failed miserably. The lesson
Department of Computer Science      |  is, never try.
University of Melbourne, Australia  |           -- Homer Simpson



More information about the developers mailing list