[m-rev.] for review: fix foreign_decls in the LLDS grades
Peter Ross
petdr at cs.mu.OZ.AU
Wed Jul 31 22:42:11 AEST 2002
Hi,
For Simon or Fergus to review.
===================================================================
Estimated hours taken: 2
Branches: main
Record foreign_decls in the .mh file in the LLDS grades. This allows
these declarations to be reused in different modules by just adding a
foreign_import_module declaration, rather than duplicating the
declarations using intermodule optimization.
compiler/export.m:
Output the foreign_decls in the .mh file.
A .mh file is now created if there is a pragma export or any
foreign_decls in the module.
compiler/foreign.m:
Change the type foreign_export_decls so that it records the foreign
decls.
Add the utility predicate decl_guard which is used to get the name
used to protect foreign decls..
compiler/intermod.m:
Don't add pragma foreign_code to .opt files until the limitation
with foreign_import_module documented in
intermod__write_intermod_info_2 is fixed.
No longer output the foreign_decls in the .opt files instead replace
it with a foreign_import_module to obtain the decls, currently this
is disable until the limitation with foreign_import_module
documented in intermod__write_intermod_info_2 is fixed.
compiler/mercury_compile.m:
Guard the declarations output in the C file with decl_guard. We
output this second copy because it uses the line numbers of the
source file for the declarations allowing one to debug problems more
easily.
compiler/mlds_to_c.m:
Guard the declaration output in the .mih file with decl_guard.
Index: compiler/export.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/export.m,v
retrieving revision 1.61
diff -u -r1.61 export.m
--- compiler/export.m 24 Jul 2002 16:05:08 -0000 1.61
+++ compiler/export.m 31 Jul 2002 12:00:19 -0000
@@ -69,6 +69,7 @@
:- import_module backend_libs__foreign.
:- import_module parse_tree__modules.
:- import_module hlds__hlds_pred, check_hlds__type_util.
+:- import_module hlds__error_util.
:- import_module backend_libs__code_model.
:- import_module ll_backend__code_gen, ll_backend__code_util.
:- import_module ll_backend__llds_out, ll_backend__arg_info.
@@ -80,13 +81,24 @@
%-----------------------------------------------------------------------------%
-export__get_foreign_export_decls(HLDS, C_ExportDecls) :-
+export__get_foreign_export_decls(HLDS, ForeignExportDecls) :-
module_info_get_predicate_table(HLDS, PredicateTable),
predicate_table_get_preds(PredicateTable, Preds),
+
+ ( module_info_contains_foreign_type(HLDS) ->
+ module_info_get_foreign_decl(HLDS, ForeignDecls),
+ MaybeForeignDecls = yes(ForeignDecls)
+ ;
+ MaybeForeignDecls = no
+ ),
+
module_info_get_pragma_exported_procs(HLDS, ExportedProcs),
module_info_globals(HLDS, Globals),
export__get_foreign_export_decls_2(Preds, ExportedProcs, Globals,
- HLDS, C_ExportDecls).
+ HLDS, C_ExportDecls),
+
+ ForeignExportDecls = foreign_export_decls(MaybeForeignDecls,
+ C_ExportDecls).
:- pred export__get_foreign_export_decls_2(pred_table,
list(pragma_exported_proc), globals,
@@ -597,31 +609,38 @@
% Should this predicate go in llds_out.m?
-export__produce_header_file([], _) --> [].
-export__produce_header_file(C_ExportDecls, ModuleName) -->
- { C_ExportDecls = [_|_] },
- export__produce_header_file(C_ExportDecls, ModuleName, ".mh"),
-
- % XXX We still need to produce the `.h' file for bootstrapping.
- % The C files in the trace directory refer to std_util.h and io.h.
- globals__io_lookup_bool_option(highlevel_code, HighLevelCode),
- {
- HighLevelCode = yes,
- ModuleName = unqualified(StdLibModule),
- mercury_std_library_module(StdLibModule)
- ->
- HeaderModuleName = qualified(unqualified("mercury"),
- StdLibModule)
- ;
- HeaderModuleName = ModuleName
- },
- export__produce_header_file(C_ExportDecls, HeaderModuleName, ".h").
+export__produce_header_file(ForeignExportDecls, ModuleName) -->
+ ( { ForeignExportDecls = foreign_export_decls(no, []) } ->
+ []
+ ;
+ export__produce_header_file(ForeignExportDecls,
+ ModuleName, ".mh"),
+
+ % XXX We still need to produce the `.h' file for
+ % bootstrapping. The C files in the trace directory refer to
+ % std_util.h and io.h.
+ globals__io_lookup_bool_option(highlevel_code, HighLevelCode),
+ {
+ HighLevelCode = yes,
+ ModuleName = unqualified(StdLibModule),
+ mercury_std_library_module(StdLibModule)
+ ->
+ HeaderModuleName = qualified(unqualified("mercury"),
+ StdLibModule)
+ ;
+ HeaderModuleName = ModuleName
+ },
+ export__produce_header_file(ForeignExportDecls,
+ HeaderModuleName, ".h")
+ ).
-:- pred export__produce_header_file(foreign_export_decls, module_name, string,
- io__state, io__state).
+:- pred export__produce_header_file(foreign_export_decls,
+ module_name, string, io__state, io__state).
:- mode export__produce_header_file(in, in, in, di, uo) is det.
-export__produce_header_file(C_ExportDecls, ModuleName, HeaderExt) -->
+export__produce_header_file(ForeignExportDecls, ModuleName, HeaderExt) -->
+ { ForeignExportDecls = foreign_export_decls(MaybeForeignDecls,
+ C_ExportDecls) },
module_name_to_file_name(ModuleName, HeaderExt, yes, FileName),
io__open_output(FileName, Result),
(
@@ -656,6 +675,16 @@
"#include ""mercury_deep_profiling.h""\n",
"#endif\n",
"\n"]),
+
+ ( { MaybeForeignDecls = yes(ForeignDecls) } ->
+ io__write_strings(["#ifndef ", decl_guard(ModuleName),
+ "\n#define ", decl_guard(ModuleName), "\n"]),
+ list__foldl(output_foreign_decl, ForeignDecls),
+ io__write_string("#endif\n")
+ ;
+ []
+ ),
+
export__produce_header_file_2(C_ExportDecls),
io__write_strings([
"\n",
@@ -676,7 +705,7 @@
io__set_exit_status(1)
).
-:- pred export__produce_header_file_2(foreign_export_decls,
+:- pred export__produce_header_file_2(list(foreign_export_decl),
io__state, io__state).
:- mode export__produce_header_file_2(in, di, uo) is det.
export__produce_header_file_2([]) --> [].
@@ -693,8 +722,24 @@
io__write_string(ArgDecls),
io__write_string(");\n")
;
- { error("export__produce_header_file_2: foreign languages other than C unimplemented") }
+ { sorry(this_file,
+ "foreign languages other than C unimplemented") }
),
export__produce_header_file_2(ExportedProcs).
+
+:- pred output_foreign_decl(foreign_decl_code::in, io::di, io::uo) is det.
+
+export__output_foreign_decl(foreign_decl_code(Lang, Code, _Context)) -->
+ ( { Lang = c } ->
+ io__write_string(Code),
+ io__nl
+ ;
+ []
+ ).
+
+%-----------------------------------------------------------------------------%
+
+:- func this_file = string.
+this_file = "export.m".
%-----------------------------------------------------------------------------%
Index: compiler/foreign.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/foreign.m,v
retrieving revision 1.21
diff -u -r1.21 foreign.m
--- compiler/foreign.m 24 Jul 2002 16:05:08 -0000 1.21
+++ compiler/foreign.m 31 Jul 2002 11:49:34 -0000
@@ -21,7 +21,7 @@
:- import_module parse_tree__prog_data, libs__globals.
:- import_module hlds__hlds_module, hlds__hlds_pred.
-:- import_module bool, list, string, term.
+:- import_module bool, list, std_util, string, term.
:- type foreign_decl_info == list(foreign_decl_code).
% in reverse order
@@ -39,7 +39,16 @@
foreign_body_code(foreign_language, string, prog_context).
:- type foreign_export_defns == list(foreign_export).
-:- type foreign_export_decls == list(foreign_export_decl).
+:- type foreign_export_decls
+ ---> foreign_export_decls(
+ % The foreign decls needed for use by
+ % the foreign exports, if any.
+ % Currently this will be filled out if
+ % there is a foreign_type declared in
+ % the module.
+ maybe(foreign_decl_info),
+ list(foreign_export_decl)
+ ).
:- type foreign_export_decl
---> foreign_export_decl(
@@ -184,6 +193,10 @@
:- mode foreign_language_module_name(in, in) = out is semidet.
:- mode foreign_language_module_name(in, in(lang_gen_ext_file)) = out is det.
+ % The name of the #define which can be used to guard declarations with
+ % to prevent entities being declared twice.
+:- func decl_guard(sym_name) = string.
+
:- implementation.
:- import_module list, map, assoc_list, std_util, string, varset, int, term.
@@ -677,6 +690,14 @@
).
to_type_string(il, mercury(_Type)) = _ :-
sorry(this_file, "to_type_string for il").
+
+%-----------------------------------------------------------------------------%
+
+:- import_module ll_backend__llds_out.
+
+decl_guard(ModuleName) = UppercaseModuleName ++ "_DECL_GUARD" :-
+ llds_out__sym_name_mangle(ModuleName, MangledModuleName),
+ string__to_upper(MangledModuleName, UppercaseModuleName).
%-----------------------------------------------------------------------------%
Index: compiler/intermod.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/intermod.m,v
retrieving revision 1.123
diff -u -r1.123 intermod.m
--- compiler/intermod.m 22 Jul 2002 06:29:34 -0000 1.123
+++ compiler/intermod.m 31 Jul 2002 10:06:02 -0000
@@ -320,6 +320,12 @@
pred_info_clauses_info(PredInfo, ClauseInfo),
clauses_info_clauses(ClauseInfo, Clauses),
+ % XXX until mmake can handle the extra dependencies introduced
+ % in intermod__write_intermod_info_2 we cannot use
+ % foreign_procs because they might depend on foreign decls
+ % which are in the header file.
+ \+ pred_info_pragma_goal_type(PredInfo),
+
pred_info_procids(PredInfo, [ProcId | _ProcIds]),
pred_info_procedures(PredInfo, Procs),
map__lookup(Procs, ProcId, ProcInfo),
@@ -1104,15 +1110,15 @@
globals__io_set_option(dump_hlds_options, string("")),
( { WriteHeader = yes } ->
{ module_info_get_foreign_decl(ModuleInfo, RevForeignDecls) },
+ { module_info_get_pragma_exported_procs(ModuleInfo,
+ PragmaExportedProcs) },
{ module_info_get_foreign_import_module(ModuleInfo,
RevForeignImports) },
- { module_info_get_pragma_exported_procs(ModuleInfo,
- PragmaExportedProcs) },
- { ForeignDecls = list__reverse(RevForeignDecls) },
{ ForeignImports0 = list__reverse(RevForeignImports) },
%
- % If this module contains `:- pragma export' declarations,
+ % If this module contains `:- pragma export' or
+ % `:- pragma foreign_decl' declarations,
% they may be referred to by the C code we are writing
% to the `.opt' file, so write the implicit
% `:- pragma foreign_import_module("C", ModuleName).'
@@ -1123,9 +1129,15 @@
% the standard library fails (mmake attempts to build
% tree234.o before std_util.h is built).
%
- { semidet_fail, PragmaExportedProcs \= [] ->
- % XXX Currently we only handle procedures
- % exported to C.
+ % XXX Currently we only handle procedures
+ % exported to C.
+ {
+ % Check that the import could contain anything.
+ ( PragmaExportedProcs \= []
+ ; RevForeignDecls \= []
+ ),
+ semidet_fail
+ ->
module_info_name(ModuleInfo, ModuleName),
ForeignImportThisModule = foreign_import_module(c,
ModuleName, term__context_init),
@@ -1134,19 +1146,14 @@
;
ForeignImports = ForeignImports0
},
+
list__foldl(
(pred(ForeignImport::in, di, uo) is det -->
{ ForeignImport = foreign_import_module(Lang,
Import, _) },
mercury_output_pragma_foreign_import_module(Lang,
Import)
- ), ForeignImports),
-
- list__foldl(
- (pred(ForeignDecl::in, di, uo) is det -->
- { ForeignDecl = foreign_decl_code(Lang, Header, _) },
- mercury_output_pragma_foreign_decl(Lang, Header)
- ), ForeignDecls)
+ ), ForeignImports)
;
[]
),
Index: compiler/mercury_compile.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/mercury_compile.m,v
retrieving revision 1.263
diff -u -r1.263 mercury_compile.m
--- compiler/mercury_compile.m 30 Jul 2002 08:25:07 -0000 1.263
+++ compiler/mercury_compile.m 31 Jul 2002 11:49:34 -0000
@@ -3181,7 +3181,8 @@
% If this module contains `:- pragma export' declarations,
% add a "#include <module>.h" declaration.
% XXX pragma export is only supported for C.
- ( UseForeignLanguage = c, Foreign_ExportDecls \= [] ->
+ Foreign_ExportDecls = foreign_export_decls(_, ExportDecls),
+ ( UseForeignLanguage = c, ExportDecls \= [] ->
% We put the new include at the end since the list is
% stored in reverse, and we want this include to come
% first.
@@ -3251,8 +3252,8 @@
{ list__condense([CommonableData, NonCommonStaticData, ClosureLayouts,
TypeCtorTables, TypeClassInfos, PossiblyDynamicLayouts],
AllData) },
- mercury_compile__construct_c_file(C_InterfaceInfo, Procs1, GlobalVars,
- AllData, CFile, NumChunks),
+ mercury_compile__construct_c_file(HLDS, C_InterfaceInfo,
+ Procs1, GlobalVars, AllData, CFile, NumChunks),
mercury_compile__output_llds(ModuleName, CFile, LayoutLabels,
MaybeRLFile, Verbose, Stats),
@@ -3276,13 +3277,14 @@
% Split the code up into bite-size chunks for the C compiler.
-:- pred mercury_compile__construct_c_file(foreign_interface_info,
+:- pred mercury_compile__construct_c_file(module_info, foreign_interface_info,
list(c_procedure), list(comp_gen_c_var), list(comp_gen_c_data),
c_file, int, io__state, io__state).
-:- mode mercury_compile__construct_c_file(in, in, in, in, out, out, di, uo)
+:- mode mercury_compile__construct_c_file(in, in, in, in, in, out, out, di, uo)
is det.
-mercury_compile__construct_c_file(C_InterfaceInfo, Procedures, GlobalVars,
+mercury_compile__construct_c_file(_Module,
+ C_InterfaceInfo, Procedures, GlobalVars,
AllData, CFile, ComponentCount) -->
{ C_InterfaceInfo = foreign_interface_info(ModuleSymName,
C_HeaderCode0, C_Includes, C_BodyCode0,
@@ -3303,7 +3305,10 @@
),
list__map_foldl(make_foreign_import_header_code, C_Includes,
C_HeaderCode1),
- { C_HeaderCode = C_HeaderCode0 ++ C_HeaderCode1 },
+
+ { make_decl_guards(ModuleSymName, Start, End) },
+ { C_HeaderCode = [End | C_HeaderCode0] ++ [Start | C_HeaderCode1] },
+
{ CFile = c_file(ModuleSymName, C_HeaderCode, C_BodyCode,
C_ExportDefns, GlobalVars, AllData, ChunkedModules) },
{ list__length(C_BodyCode, UserCCodeCount) },
@@ -3313,6 +3318,16 @@
{ list__length(ChunkedModules, CompGenCodeCount) },
{ ComponentCount is UserCCodeCount + ExportCount
+ CompGenVarCount + CompGenDataCount + CompGenCodeCount }.
+
+:- pred make_decl_guards(sym_name::in,
+ foreign_decl_code::out, foreign_decl_code::out) is det.
+
+make_decl_guards(ModuleName, StartGuard, EndGuard) :-
+ Define = decl_guard(ModuleName),
+ Start = "#ifndef " ++ Define ++ "\n#define " ++ Define ++ "\n",
+ End = "#endif",
+ StartGuard = foreign_decl_code(c, Start, term__context_init),
+ EndGuard = foreign_decl_code(c, End, term__context_init).
:- pred make_foreign_import_header_code(foreign_import_module,
foreign_decl_code, io__state, io__state).
Index: compiler/mlds_to_c.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/mlds_to_c.m,v
retrieving revision 1.134
diff -u -r1.134 mlds_to_c.m
--- compiler/mlds_to_c.m 23 Jul 2002 16:35:36 -0000 1.134
+++ compiler/mlds_to_c.m 31 Jul 2002 11:58:50 -0000
@@ -547,11 +547,15 @@
io__state, io__state).
:- mode mlds_output_c_hdr_decls(in, in, in, di, uo) is det.
-mlds_output_c_hdr_decls(_ModuleName, Indent, ForeignCode) -->
+mlds_output_c_hdr_decls(ModuleName, Indent, ForeignCode) -->
{ ForeignCode = mlds__foreign_code(RevHeaderCode, _RevImports,
_RevBodyCode, _ExportDefns) },
{ HeaderCode = list__reverse(RevHeaderCode) },
- io__write_list(HeaderCode, "\n", mlds_output_c_hdr_decl(Indent)).
+ { DeclGuard = decl_guard(mlds_module_name_to_sym_name(ModuleName)) },
+ io__write_strings(["#ifndef ", DeclGuard,
+ "\n#define ", DeclGuard, "\n"]),
+ io__write_list(HeaderCode, "\n", mlds_output_c_hdr_decl(Indent)),
+ io__write_string("#endif\n").
:- pred mlds_output_c_hdr_decl(indent,
foreign_decl_code, io__state, io__state).
----
Peter Ross
PhD Student University of Melbourne
http://www.cs.mu.oz.au/~petdr/
--------------------------------------------------------------------------
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