diff: bug fix for name mangling of nested modules

Fergus Henderson fjh at cs.mu.OZ.AU
Fri Mar 6 13:29:43 AEDT 1998


Estimated hours taken: 1

Fix a bug where `mkinit' was not mangling nested module names properly.
This bug meant that nested modules didn't work in grades which required
initialization functions, e.g. the profiling grades.

compiler/llds_out.m:
	Use the mangled module name rather than the mangled file name
	to compute the init function names, because nested module
	names get mangled with the module names separated by `__',
	whereas mangled file names use the ugly `f_<numbers>' ASCII escapes
	to encode names containing `.'.

util/mkinit.c:
	Handle nested module names: convert `.' to `__' when computing
	the init function name from the file name.
	(Note: it is still not using the full name mangling algorithm
	here, so this will still fail if the module name contains special
	characters.)

	Also change the layout of curly braces in a few places,
	to match our C coding guidelines.

cvs diff  compiler/llds_out.m util/mkinit.c
Index: compiler/llds_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/llds_out.m,v
retrieving revision 1.73
diff -u -r1.73 llds_out.m
--- llds_out.m	1998/03/03 17:34:55	1.73
+++ llds_out.m	1998/03/06 02:03:33
@@ -132,12 +132,12 @@
 output_c_file(C_File) -->
 	globals__io_lookup_bool_option(split_c_files, SplitFiles),
 	( { SplitFiles = yes } ->
-		{ C_File = c_file(ModuleName, C_HeaderInfo, Modules) },
-		{ module_name_to_file_name(ModuleName, BaseName) },
-		{ string__append(BaseName, ".dir", ObjDirName) },
+		{ C_File = c_file(ModuleName, C_HeaderInfo, C_Modules) },
+		{ module_name_to_file_name(ModuleName, BaseFileName) },
+		{ string__append(BaseFileName, ".dir", ObjDirName) },
 		make_directory(ObjDirName),
-		output_c_file_init(BaseName, Modules),
-		output_c_file_list(Modules, 1, ModuleName, C_HeaderInfo)
+		output_c_file_init(ModuleName, C_Modules),
+		output_c_file_list(C_Modules, 1, ModuleName, C_HeaderInfo)
 	;
 		output_single_c_file(C_File, no)
 	).
@@ -161,31 +161,31 @@
 	{ Num1 is Num + 1 },
 	output_c_file_list(Modules, Num1, ModuleName, C_HeaderLines).
 
-:- pred output_c_file_init(string, list(c_module), io__state, io__state).
+:- pred output_c_file_init(module_name, list(c_module), io__state, io__state).
 :- mode output_c_file_init(in, in, di, uo) is det.
 
-output_c_file_init(BaseName, Modules) -->
-	{ string__format("%s.dir/%s_%03d", [s(BaseName), s(BaseName), i(0)],
-		NewName) },
-	{ string__append(NewName, ".c", FileName) },
+output_c_file_init(ModuleName, C_Modules) -->
+	{ module_name_to_file_name(ModuleName, BaseFileName) },
+	{ string__format("%s.dir/%s_%03d.c",
+		[s(BaseFileName), s(BaseFileName), i(0)], FileName) },
 	io__tell(FileName, Result),
 	(
 		{ Result = ok }
 	->
 		{ library__version(Version) },
 		io__write_strings(
-			["/*\n** Automatically generated from `", BaseName,
+			["/*\n** Automatically generated from `", BaseFileName,
 			".m' by the Mercury compiler,\n** version ", Version,
 			".\n** Do not edit.\n*/\n"]),
 		io__write_string("/*\n"),
 		io__write_string("INIT "),
-		output_init_name(BaseName),
+		output_init_name(ModuleName),
 		io__write_string("\n"),
 		io__write_string("ENDINIT\n"),
 		io__write_string("*/\n\n"),
 		io__write_string("#include ""mercury_imp.h""\n"),
 		io__write_string("\n"),
-		output_c_module_init_list(BaseName, Modules),
+		output_c_module_init_list(ModuleName, C_Modules),
 		io__told
 	;
 		io__progname_base("llds.m", ProgName),
@@ -202,12 +202,13 @@
 
 output_single_c_file(c_file(ModuleName, C_HeaderLines, Modules), SplitFiles) 
 		-->
-	{ module_name_to_file_name(ModuleName, BaseName) },
+	{ module_name_to_file_name(ModuleName, BaseFileName) },
 	( { SplitFiles = yes(Num) } ->
-		{ string__format("%s.dir/%s_%03d.c", [s(BaseName), s(BaseName), 
-			i(Num)], FileName) }
+		{ string__format("%s.dir/%s_%03d.c",
+			[s(BaseFileName), s(BaseFileName), i(Num)],
+			FileName) }
 	;
-		{ string__append(BaseName, ".c", FileName) }
+		{ string__append(BaseFileName, ".c", FileName) }
 	),
 	io__tell(FileName, Result),
 	(
@@ -215,7 +216,7 @@
 	->
 		{ library__version(Version) },
 		io__write_strings(
-			["/*\n** Automatically generated from `", BaseName,
+			["/*\n** Automatically generated from `", BaseFileName,
 			".m' by the Mercury compiler,\n** version ", Version,
 			".\n** Do not edit.\n*/\n"]),
 		( { SplitFiles = yes(_) } ->
@@ -223,7 +224,7 @@
 		;
 			io__write_string("/*\n"),
 			io__write_string("INIT "),
-			output_init_name(BaseName),
+			output_init_name(ModuleName),
 			io__write_string("\n"),
 			io__write_string("ENDINIT\n"),
 			io__write_string("*/\n\n")
@@ -239,7 +240,7 @@
 			[]
 		;
 			io__write_string("\n"),
-			output_c_module_init_list(BaseName, Modules)
+			output_c_module_init_list(ModuleName, Modules)
 		),
 		io__told
 	;
@@ -252,10 +253,11 @@
 		io__set_exit_status(1)
 	).
 
-:- pred output_c_module_init_list(string, list(c_module), io__state, io__state).
+:- pred output_c_module_init_list(module_name, list(c_module),
+					io__state, io__state).
 :- mode output_c_module_init_list(in, in, di, uo) is det.
 
-output_c_module_init_list(BaseName, Modules) -->
+output_c_module_init_list(ModuleName, Modules) -->
 
 		% Output initialization functions, bunched into groups
 		% of 40.
@@ -265,20 +267,20 @@
 	io__write_string("\t|| defined(DEBUG_LABELS) || !defined(SPEED) \\\n"),
 	io__write_string("\t|| defined(NATIVE_GC) \n\n"),
 	io__write_string("static void "),
-	output_bunch_name(BaseName, 0),
+	output_bunch_name(ModuleName, 0),
 	io__write_string("(void)\n"),
 	io__write_string("{\n"),
-	output_c_module_init_list_2(Modules, BaseName, 0, 40, 0, InitFuncs),
+	output_c_module_init_list_2(Modules, ModuleName, 0, 40, 0, InitFuncs),
 	io__write_string("}\n\n#endif\n\n"),
 
 		% Output code to call each of the init functions created
 		% above.
 	io__write_string("void "),
-	output_init_name(BaseName),
+	output_init_name(ModuleName),
 	io__write_string("(void);"),
 	io__write_string("/* suppress gcc -Wmissing-decls warning */\n"),
 	io__write_string("void "),
-	output_init_name(BaseName),
+	output_init_name(ModuleName),
 	io__write_string("(void)\n"),
 	io__write_string("{\n"),
 	io__write_string("#if (defined(USE_GCC_NONLOCAL_GOTOS) && "),
@@ -289,7 +291,7 @@
 	io__write_string("\tstatic bool done = FALSE;\n"),
 	io__write_string("\tif (!done) {\n"),
 	io__write_string("\t\tdone = TRUE;\n"),
-	output_c_module_init_list_3(0, BaseName, InitFuncs),
+	output_c_module_init_list_3(0, ModuleName, InitFuncs),
 	io__write_string("\t}\n"),
 	io__write_string("#endif\n"),
 	output_c_data_init_list(Modules),
@@ -300,8 +302,8 @@
 	io__write_string(
 		"static const void *const MR_grade = &MR_GRADE_VAR;\n").
 
-:- pred output_c_module_init_list_2(list(c_module), string, int, int, int, int,
-	io__state, io__state).
+:- pred output_c_module_init_list_2(list(c_module), module_name, int, int, int,
+		int, io__state, io__state).
 :- mode output_c_module_init_list_2(in, in, in, in, in, out, di, uo) is det.
 
 output_c_module_init_list_2([], _, _, _, InitFunc, InitFunc) --> [].
@@ -311,13 +313,13 @@
 	output_c_module_init_list_2(Ms, A, B, C, D, E).
 output_c_module_init_list_2([c_code(_, _) | Ms], A, B, C, D, E) -->
 	output_c_module_init_list_2(Ms, A, B, C, D, E).
-output_c_module_init_list_2([c_module(ModuleName, _) | Ms], BaseName,
+output_c_module_init_list_2([c_module(C_ModuleName, _) | Ms], ModuleName,
 		Calls0, MaxCalls, InitFunc0, InitFunc) -->
 	( { Calls0 > MaxCalls } ->
 		io__write_string("}\n\n"),
 		{ InitFunc1 is InitFunc0 + 1 },
 		io__write_string("static void "),
-		output_bunch_name(BaseName, InitFunc1),
+		output_bunch_name(ModuleName, InitFunc1),
 		io__write_string("(void)\n"),
 		io__write_string("{\n"),
 		{ Calls1 = 1 }
@@ -328,33 +330,34 @@
 	globals__io_lookup_bool_option(split_c_files, SplitFiles),
 	( { SplitFiles = yes } ->
 		io__write_string("\t{ extern ModuleFunc "),
-		io__write_string(ModuleName),
+		io__write_string(C_ModuleName),
 		io__write_string(";\n"),
 		io__write_string("\t  "),
-		io__write_string(ModuleName),
+		io__write_string(C_ModuleName),
 		io__write_string("(); }\n")
 	;
 		io__write_string("\t"),
-		io__write_string(ModuleName),
+		io__write_string(C_ModuleName),
 		io__write_string("();\n")
 	),
-	output_c_module_init_list_2(Ms, BaseName,
+	output_c_module_init_list_2(Ms, ModuleName,
 		Calls1, MaxCalls, InitFunc1, InitFunc).
 
 	% Output calls to all the bunched initialization functions.
 
-:- pred output_c_module_init_list_3(int, string, int, io__state, io__state).
+:- pred output_c_module_init_list_3(int, module_name, int,
+				io__state, io__state).
 :- mode output_c_module_init_list_3(in, in, in, di, uo) is det.
 
-output_c_module_init_list_3(InitFunc0, BaseName, MaxInitFunc) -->
+output_c_module_init_list_3(InitFunc0, ModuleName, MaxInitFunc) -->
 	( { InitFunc0 > MaxInitFunc } ->
 		[]
 	;
 		io__write_string("\t\t"),
-		output_bunch_name(BaseName, InitFunc0),
+		output_bunch_name(ModuleName, InitFunc0),
 		io__write_string("();\n"),
 		{ InitFunc1 is InitFunc0 + 1},
-		output_c_module_init_list_3(InitFunc1, BaseName, MaxInitFunc)
+		output_c_module_init_list_3(InitFunc1, ModuleName, MaxInitFunc)
 	).
 
 
@@ -371,15 +374,15 @@
 	output_c_data_init_list(Ms).
 output_c_data_init_list([c_module(_, _) | Ms]) -->
 	output_c_data_init_list(Ms).
-output_c_data_init_list([c_data(BaseName, DataName, _, _, _) | Ms])  -->
+output_c_data_init_list([c_data(ModuleName, DataName, _, _, _) | Ms])  -->
 	(
 		{ DataName = base_type(info, TypeName, Arity) }
 	->
 		io__write_string("\tMR_INIT_BASE_TYPE_INFO(\n\t\t"),
-		output_data_addr(BaseName, DataName),
+		output_data_addr(ModuleName, DataName),
 		io__write_string(",\n\t\t"),
-		{ llds_out__sym_name_mangle(BaseName, BaseNameString) },
-		{ string__append(BaseNameString, "__", UnderscoresModule) },
+		{ llds_out__sym_name_mangle(ModuleName, ModuleNameString) },
+		{ string__append(ModuleNameString, "__", UnderscoresModule) },
 		( 
 			{ string__append(UnderscoresModule, _, TypeName) } 
 		->
@@ -397,33 +400,25 @@
 	),
 	output_c_data_init_list(Ms).
 
-:- pred output_init_name(string, io__state, io__state).
+:- pred output_init_name(module_name, io__state, io__state).
 :- mode output_init_name(in, di, uo) is det.
 
-output_init_name(BaseName0) -->
+output_init_name(ModuleName) -->
 	io__write_string("mercury__"),
-	{ llds_out__name_mangle(BaseName0, BaseName) },
-	io__write_string(BaseName),
+	{ llds_out__sym_name_mangle(ModuleName, MangledModuleName) },
+	io__write_string(MangledModuleName),
 	io__write_string("__init").
 
-:- pred output_bunch_name(string, int, io__state, io__state).
+:- pred output_bunch_name(module_name, int, io__state, io__state).
 :- mode output_bunch_name(in, in, di, uo) is det.
 
-output_bunch_name(BaseName0, Number) -->
+output_bunch_name(ModuleName, Number) -->
 	io__write_string("mercury__"),
-	{ llds_out__name_mangle(BaseName0, BaseName) },
-	io__write_string(BaseName),
+	{ llds_out__sym_name_mangle(ModuleName, MangledModuleName) },
+	io__write_string(MangledModuleName),
 	io__write_string("_bunch_"),
 	io__write_int(Number).
 
-:- pred output_module_name(module_name, io__state, io__state).
-:- mode output_module_name(in, di, uo) is det.
-
-output_module_name(ModuleName0) -->
-	io__write_string("mercury__"),
-	{ llds_out__sym_name_mangle(ModuleName0, ModuleName) },
-	io__write_string(ModuleName).
-
 :- pred output_c_module_list(list(c_module), decl_set, io__state, io__state).
 :- mode output_c_module_list(in, in, di, uo) is det.
 
@@ -451,10 +446,10 @@
 	output_c_procedure_list(Procedures, PrintComments, EmitCLoops),
 	io__write_string("END_MODULE\n").
 
-output_c_module(c_data(BaseName, VarName, ExportedFromModule, ArgVals, _Refs),
-		DeclSet0, DeclSet) -->
+output_c_module(c_data(ModuleName, VarName, ExportedFromModule, ArgVals,
+		_Refs), DeclSet0, DeclSet) -->
 	io__write_string("\n"),
-	{ DataAddr = data_addr(data_addr(BaseName, VarName)) },
+	{ DataAddr = data_addr(data_addr(ModuleName, VarName)) },
 	output_cons_arg_decls(ArgVals, "", "", 0, _, DeclSet0, DeclSet1),
 		% The code for data local to a Mercury module
 		% should normally be visible only within the C file
@@ -2016,7 +2011,7 @@
 	io__state, io__state).
 :- mode output_data_addr_decls(in, in, in, in, out, di, uo) is det.
 
-output_data_addr_decls(data_addr(BaseName, VarName),
+output_data_addr_decls(data_addr(ModuleName, VarName),
 		FirstIndent, LaterIndent, N0, N) -->
 	output_indent(FirstIndent, LaterIndent, N0),
 	{ N is N0 + 1 },
@@ -2034,11 +2029,11 @@
 		io__write_string("const ")
 	),
 	io__write_string("struct "),
-	output_data_addr(BaseName, VarName), 
+	output_data_addr(ModuleName, VarName), 
 	io__write_string("_struct\n"),
 	io__write_string(LaterIndent),
 	io__write_string("\t"),
-	output_data_addr(BaseName, VarName), 
+	output_data_addr(ModuleName, VarName), 
 	io__write_string(";\n").
 
 %-----------------------------------------------------------------------------%
@@ -2251,18 +2246,18 @@
 :- pred output_data_addr(module_name, data_name, io__state, io__state).
 :- mode output_data_addr(in, in, di, uo) is det.
 
-output_data_addr(BaseName0, VarName) -->
-	{ llds_out__sym_name_mangle(BaseName0, BaseName) },
+output_data_addr(ModuleName, VarName) -->
+	{ llds_out__sym_name_mangle(ModuleName, MangledModuleName) },
 	io__write_string("mercury_data_"),
 	(
 		{ VarName = common(N) },
-		io__write_string(BaseName),
+		io__write_string(MangledModuleName),
 		io__write_string("__common_"),
 		{ string__int_to_string(N, NStr) },
 		io__write_string(NStr)
 	;
 		{ VarName = base_type(BaseData, TypeName0, TypeArity) },
-		io__write_string(BaseName),
+		io__write_string(MangledModuleName),
 		{ llds_out__make_base_type_name(BaseData, TypeName0, TypeArity,
 			Str) },
 		io__write_string("__"),
@@ -2877,11 +2872,11 @@
 	io__write_string("FALSE").
 output_rval_const(code_addr_const(CodeAddress)) -->
 	output_code_addr(CodeAddress).
-output_rval_const(data_addr_const(data_addr(BaseName, VarName))) -->
+output_rval_const(data_addr_const(data_addr(ModuleName, VarName))) -->
 	% data addresses are all assumed to be of type `Word *';
 	% we need to cast them here to avoid type errors
 	io__write_string("(const Word *) &"),
-	output_data_addr(BaseName, VarName).
+	output_data_addr(ModuleName, VarName).
 output_rval_const(label_entry(Label)) -->
 	io__write_string("ENTRY("),
 	output_label(Label),
@@ -3216,20 +3211,21 @@
 %-----------------------------------------------------------------------------%
 
 llds_out__make_base_typeclass_info_name(class_id(ClassSym, ClassArity),
-		TypeNames0, Str) :-
+		TypeNames, Str) :-
 	(
 		ClassSym = unqualified(_),
 		error("llds_out__make_base_typeclass_info_name: unqualified name")
 	;
-		ClassSym = qualified(ModuleName0, ClassName0),
-		llds_out__sym_name_mangle(ModuleName0, ModuleName),
-		llds_out__name_mangle(ClassName0, ClassName),
-		llds_out__qualify_name(ModuleName, ClassName, ClassString)
-	),
-	string__int_to_string(ClassArity, A_str),
-	llds_out__name_mangle(TypeNames0, TypeNames),
-	string__append_list(["base_typeclass_info_", ClassString, "_", A_str,
-		"__", TypeNames], Str).
+		ClassSym = qualified(ModuleName, ClassName),
+		llds_out__sym_name_mangle(ModuleName, MangledModuleName),
+		llds_out__name_mangle(ClassName, MangledClassName),
+		llds_out__qualify_name(MangledModuleName, MangledClassName,
+			MangledClassString)
+	),
+	string__int_to_string(ClassArity, ArityString),
+	llds_out__name_mangle(TypeNames, MangledTypeNames),
+	string__append_list(["base_typeclass_info_", MangledClassString,
+		"_", ArityString, "__", MangledTypeNames], Str).
 
 %-----------------------------------------------------------------------------%
 
Index: util/mkinit.c
===================================================================
RCS file: /home/mercury1/repository/mercury/util/mkinit.c,v
retrieving revision 1.26
diff -u -r1.26 mkinit.c
--- mkinit.c	1998/02/03 08:20:12	1.26
+++ mkinit.c	1998/03/06 02:10:40
@@ -189,6 +189,7 @@
 static	void output_main_init_function(void);
 static	void output_main(void);
 static	void process_file(char *filename);
+static	void process_m_file(char *filename);
 static	void process_init_file(const char *filename);
 static	void output_init_function(const char *func_name);
 static	int getline(FILE *file, char *line, int line_max);
@@ -208,7 +209,8 @@
 extern char *sys_errlist[];
 
 char *
-strerror(int errnum) {
+strerror(int errnum)
+{
 	if (errnum >= 0 && errnum < sys_nerr && sys_errlist[errnum] != NULL) {
 		return sys_errlist[errnum];
 	} else {
@@ -234,8 +236,7 @@
 	output_main_init_function();
 	output_main();
 
-	if (num_errors > 0)
-	{
+	if (num_errors > 0) {
 		fputs("/* Force syntax error, since there were */\n", stdout);
 		fputs("/* errors in the generation of this file */\n", stdout);
 		fputs("#error \"You need to remake this file\"\n", stdout);
@@ -251,10 +252,8 @@
 parse_options(int argc, char *argv[])
 {
 	int	c;
-	while ((c = getopt(argc, argv, "c:w:l")) != EOF)
-	{
-		switch (c)
-		{
+	while ((c = getopt(argc, argv, "c:w:l")) != EOF) {
+		switch (c) {
 		case 'c':
 			if (sscanf(optarg, "%d", &maxcalls) != 1)
 				usage();
@@ -295,8 +294,7 @@
 
 	fputs(header1, stdout);
 
-	for (filenum = 0; filenum < num_files; filenum++)
-	{
+	for (filenum = 0; filenum < num_files; filenum++) {
 		fputs("** ", stdout);
 		fputs(files[filenum], stdout);
 		putc('\n', stdout);
@@ -315,8 +313,7 @@
 	fputs("static void init_modules_0(void)\n", stdout);
 	fputs("{\n", stdout);
 
-	for (filenum = 0; filenum < num_files; filenum++)
-	{
+	for (filenum = 0; filenum < num_files; filenum++) {
 		process_file(files[filenum]);
 	}
 
@@ -334,8 +331,9 @@
 
 	fputs(if_need_to_init, stdout);
 
-	for (i = 0; i <= num_modules; i++)
+	for (i = 0; i <= num_modules; i++) {
 		printf("\tinit_modules_%d();\n", i);
+	}
 	fputs("#endif\n", stdout);
 
 	fputs("}\n", stdout);
@@ -353,16 +351,14 @@
 /*---------------------------------------------------------------------------*/
 
 static void 
-process_file(char *filename) {
+process_file(char *filename)
+{
 	int len = strlen(filename);
-	if (strcmp(filename + len - 2, ".m") == 0) {
-		char func_name[1000];
-		filename[len - 2] = '\0';	 /* remove trailing ".m" */
-		sprintf(func_name, "mercury__%s__init", filename);
-		output_init_function(func_name);
-	} else if (strcmp(filename + len - 5, ".init") == 0) {
+	if (len >= 2 && strcmp(filename + len - 2, ".m") == 0) {
+		process_m_file(filename);
+	} else if (len >= 5 && strcmp(filename + len - 5, ".init") == 0) {
 		process_init_file(filename);
-	} else if (strcmp(filename + len - 2, ".c") == 0) {
+	} else if (len >= 2 && strcmp(filename + len - 2, ".c") == 0) {
 		process_init_file(filename);
 	} else {
 		fprintf(stderr,
@@ -372,8 +368,37 @@
 	}
 }
 
+static void
+process_m_file(char *filename)
+{
+	char func_name[1000];
+
+	char *dot;
+
+	/* remove the trailing ".m" */
+	filename[strlen(filename) - 2] = '\0';	
+
+	/*
+	** The func name is "mercury__<modulename>__init",
+	** where <modulename> is the base filename with all
+	** `.'s replaced with `__'.
+	*/
+	strcpy(func_name, "mercury");
+	while ((dot = strchr(filename, '.')) != NULL) {
+		strcat(func_name, "__");
+		strncat(func_name, filename, dot - filename);
+		filename = dot + 1;
+	}
+	strcat(func_name, "__");
+	strcat(func_name, filename);
+	strcat(func_name, "__init");
+
+	output_init_function(func_name);
+}
+
 static void 
-process_init_file(const char *filename) {
+process_init_file(const char *filename)
+{
 	const char * const	init_str = "INIT ";
 	const char * const	endinit_str = "ENDINIT ";
 	const int		init_strlen = strlen(init_str);

-- 
Fergus Henderson <fjh at cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3         |     -- the last words of T. S. Garp.



More information about the developers mailing list