Created
January 10, 2023 10:49
-
-
Save iains/23321b1eb98f537e39d73efbee9504e7 to your computer and use it in GitHub Desktop.
gm2 patch v3.1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 0123fb126ce7817222aecb9545a3f26e6fc297b2 Mon Sep 17 00:00:00 2001 | |
From: Iain Sandoe <iain@sandoe.co.uk> | |
Date: Tue, 10 Jan 2023 09:10:25 +0000 | |
Subject: [PATCH] modula-2, driver: Try to fix up specs and command line v3.1 | |
Signed-off-by: Iain Sandoe <iain@sandoe.co.uk> | |
gcc/ChangeLog: | |
* gcc.cc (fe_add_spec_function): | |
(lookup_spec_function): | |
(get_multilib_dir): | |
* gcc.h (get_multilib_dir): | |
(fe_add_spec_function): | |
gcc/m2/ChangeLog: | |
* gm2spec.cc (enum stdcxxlib_kind): | |
(build_archive_path): | |
(concat_option): | |
(add_default_combination): | |
(add_default_archives): | |
(add_default_libs): | |
(build_include_path): | |
(add_default_includes): | |
(library_installed): | |
(defined): | |
(check_valid_library): | |
(check_valid_list): | |
(convert_abbreviations): | |
(m2include_spec_fn): | |
(m2_register_spec_functions): | |
(lang_specific_driver): | |
* lang-specs.h (M2CPP): | |
(M2DEFAULT_DIALECT_INCLUDE): | |
(M2DEFAULT_INCLUDE): | |
--- | |
gcc/gcc.cc | 37 ++++++++ | |
gcc/gcc.h | 3 + | |
gcc/m2/gm2spec.cc | 211 +++++++++++++++++++++----------------------- | |
gcc/m2/lang-specs.h | 27 ++++-- | |
4 files changed, 161 insertions(+), 117 deletions(-) | |
diff --git a/gcc/gcc.cc b/gcc/gcc.cc | |
index d629ca5e424..6a4db8e797e 100644 | |
--- a/gcc/gcc.cc | |
+++ b/gcc/gcc.cc | |
@@ -1774,6 +1774,10 @@ static const struct spec_function static_spec_functions[] = | |
}; | |
static int processing_spec_function; | |
+ | |
+/* Front end registered spec functions */ | |
+static vec<const struct spec_function *> lang_spec_functions; | |
+ | |
/* Add appropriate libgcc specs to OBSTACK, taking into account | |
various permutations of -shared-libgcc, -shared, and such. */ | |
@@ -6813,17 +6817,42 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) | |
return 0; | |
} | |
+/* Allow the front end to register a spec function. */ | |
+ | |
+void fe_add_spec_function (const char *name, | |
+ const char *(*func) (int, const char **)) | |
+{ | |
+ const struct spec_function *f = lookup_spec_function (name); | |
+ struct spec_function *fl = | |
+ (struct spec_function *) xmalloc (sizeof (struct spec_function)); | |
+ | |
+ if (f != NULL) | |
+ fatal_error (input_location, "spec function (%s) already registered", | |
+ name); | |
+ | |
+ fl->name = name; | |
+ fl->func = func; | |
+ lang_spec_functions.safe_push (fl); | |
+} | |
+ | |
+ | |
/* Look up a spec function. */ | |
static const struct spec_function * | |
lookup_spec_function (const char *name) | |
{ | |
const struct spec_function *sf; | |
+ unsigned ix; | |
for (sf = static_spec_functions; sf->name != NULL; sf++) | |
if (strcmp (sf->name, name) == 0) | |
return sf; | |
+ /* Now check for any language registered spec functions. */ | |
+ FOR_EACH_VEC_ELT (lang_spec_functions, ix, sf) | |
+ if (strcmp (sf->name, name) == 0) | |
+ return sf; | |
+ | |
return NULL; | |
} | |
@@ -9559,6 +9588,14 @@ default_arg (const char *p, int len) | |
return 0; | |
} | |
+/* Return the value of multilib_dir. */ | |
+ | |
+const char * | |
+get_multilib_dir (void) | |
+{ | |
+ return multilib_dir; | |
+} | |
+ | |
/* Work out the subdirectory to use based on the options. The format of | |
multilib_select is a list of elements. Each element is a subdirectory | |
name followed by a list of options followed by a semicolon. The format | |
diff --git a/gcc/gcc.h b/gcc/gcc.h | |
index 19a61b373ee..456afb44d61 100644 | |
--- a/gcc/gcc.h | |
+++ b/gcc/gcc.h | |
@@ -73,6 +73,9 @@ struct spec_function | |
extern int do_spec (const char *); | |
extern void record_temp_file (const char *, int, int); | |
extern void set_input (const char *); | |
+extern const char *get_multilib_dir (void); | |
+extern void fe_add_spec_function (const char *name, | |
+ const char *(*func) (int, const char **)); | |
/* Spec files linked with gcc.cc must provide definitions for these. */ | |
diff --git a/gcc/m2/gm2spec.cc b/gcc/m2/gm2spec.cc | |
index 583723da416..09ad34a919e 100644 | |
--- a/gcc/m2/gm2spec.cc | |
+++ b/gcc/m2/gm2spec.cc | |
@@ -103,6 +103,7 @@ enum stdcxxlib_kind | |
}; | |
#define DEFAULT_DIALECT "pim" | |
+ | |
#undef DEBUG_ARG | |
typedef enum { iso, pim, min, logitech, pimcoroutine, maxlib } libs; | |
@@ -139,7 +140,6 @@ static bool seen_uselist = false; | |
static bool uselist = false; | |
static bool gen_module_list = true; // Default uses -fgen-module-list=-. | |
static const char *gen_module_filename = "-"; | |
-static const char *multilib_dir = NULL; | |
/* The original argument list and related info is copied here. */ | |
static unsigned int gm2_xargc; | |
static const struct cl_decoded_option *gm2_x_decoded_options; | |
@@ -148,6 +148,8 @@ static void append_arg (const struct cl_decoded_option *); | |
/* The new argument list will be built here. */ | |
static unsigned int gm2_newargc; | |
static struct cl_decoded_option *gm2_new_decoded_options; | |
+static const char *full_libraries = NULL; | |
+static const char *libraries = NULL; /* Abbreviated libraries. */ | |
/* Return whether strings S1 and S2 are both NULL or both the same | |
@@ -241,6 +243,7 @@ build_archive_path (const char *libpath, const char *library) | |
{ | |
int machine_length = 0; | |
char dir_sep[2]; | |
+ const char *multilib_dir = get_multilib_dir (); | |
dir_sep[0] = DIR_SEPARATOR; | |
dir_sep[1] = (char)0; | |
@@ -281,53 +284,73 @@ safe_strdup (const char *s) | |
return NULL; | |
} | |
+static char * | |
+concat_option (char *dest, const char *pre, const char *path, const char *post) | |
+{ | |
+ if (dest == NULL) | |
+ { | |
+ dest = (char *) xmalloc (strlen (pre) + strlen (path) + strlen (post) + 1); | |
+ strcpy (dest, pre); | |
+ strcat (dest, path); | |
+ strcat (dest, post); | |
+ return dest; | |
+ } | |
+ else | |
+ { | |
+ char *result = (char *) xmalloc (strlen (dest) + strlen (pre) | |
+ + strlen (path) + strlen (post) + 1 + 1); | |
+ strcpy (result, dest); | |
+ strcat (result, " "); | |
+ strcat (result, pre); | |
+ strcat (result, path); | |
+ strcat (result, post); | |
+ free (dest); | |
+ return result; | |
+ } | |
+} | |
+ | |
/* add_default_combination adds the correct link path and then the | |
library name. */ | |
-static bool | |
-add_default_combination (const char *libpath, const char *library) | |
+static char * | |
+add_default_combination (char *dest, const char *libpath, const char *library) | |
{ | |
if (library != NULL) | |
- { | |
- append_option (OPT_L, build_archive_path (libpath, library), 1); | |
- append_option (OPT_l, safe_strdup (library), 1); | |
- return true; | |
- } | |
- return false; | |
+ dest = concat_option (dest, "%x{-l", safe_strdup (library), "}"); | |
+ return dest; | |
} | |
-/* add_default_archives adds the default archives to the end of the | |
- current command line. */ | |
+/* add_default_libs adds the -l option which is derived from the | |
+ libraries. */ | |
static int | |
-add_default_archives (const char *libpath, const char *libraries) | |
+add_default_libs (const char *libraries) | |
{ | |
const char *l = libraries; | |
const char *e; | |
char *libname; | |
unsigned int libcount = 0; | |
- do | |
+ while ((l != NULL) && (l[0] != (char)0)) | |
{ | |
e = index (l, ','); | |
if (e == NULL) | |
{ | |
libname = xstrdup (l); | |
l = NULL; | |
- if (add_default_combination (libpath, libname)) | |
- libcount++; | |
+ append_option (OPT_l, safe_strdup (libname), 1); | |
+ libcount++; | |
free (libname); | |
} | |
else | |
{ | |
libname = xstrndup (l, e - l); | |
l = e + 1; | |
- if (add_default_combination (libpath, libname)) | |
- libcount++; | |
+ append_option (OPT_l, safe_strdup (libname), 1); | |
+ libcount++; | |
free (libname); | |
} | |
} | |
- while ((l != NULL) && (l[0] != (char)0)); | |
return libcount; | |
} | |
@@ -340,6 +363,7 @@ build_include_path (const char *libpath, const char *library) | |
char dir_sep[2]; | |
char *gm2libs; | |
unsigned int machine_length = 0; | |
+ const char *multilib_dir = get_multilib_dir (); | |
dir_sep[0] = DIR_SEPARATOR; | |
dir_sep[1] = (char)0; | |
@@ -382,15 +406,16 @@ add_include (const char *libpath, const char *library) | |
/* add_default_includes add the appropriate default include paths | |
depending upon the style of libraries chosen. */ | |
-static void | |
+static const char * | |
add_default_includes (const char *libpath, const char *libraries) | |
{ | |
+ char *result = NULL; | |
const char *l = libraries; | |
const char *e; | |
const char *c; | |
const char *path; | |
- do | |
+ while ((l != NULL) && (l[0] != (char)0)) | |
{ | |
e = index (l, ','); | |
if (e == NULL) | |
@@ -404,80 +429,12 @@ add_default_includes (const char *libpath, const char *libraries) | |
l = e + 1; | |
} | |
path = add_include (libpath, c); | |
- append_option (OPT_I, path, 1); | |
+ if (path != NULL) | |
+ result = concat_option (result, "-I", path, ""); | |
} | |
- while ((l != NULL) && (l[0] != (char)0)); | |
-} | |
- | |
-/* library_installed returns true if directory library is found under | |
- libpath. */ | |
- | |
-static bool | |
-library_installed (const char *libpath, const char *library) | |
-{ | |
-#if defined(HAVE_OPENDIR) && defined(HAVE_DIRENT_H) | |
- const char *complete = build_archive_path (libpath, library); | |
- DIR *directory = opendir (complete); | |
- | |
- if (directory == NULL || (errno == ENOENT)) | |
- return false; | |
- /* Directory exists and therefore the library also exists. */ | |
- closedir (directory); | |
- return true; | |
-#else | |
- return false; | |
-#endif | |
-} | |
- | |
-/* check_valid check to see that the library is valid. | |
- It check the library against the default library set in gm2 and | |
- also against any additional libraries installed in the prefix tree. */ | |
- | |
-static bool | |
-check_valid_library (const char *libpath, const char *library) | |
-{ | |
- /* Firstly check against the default libraries (which might not be | |
- installed yet). */ | |
- for (int i = 0; i < maxlib; i++) | |
- if (strcmp (library, library_name[i]) == 0) | |
- return true; | |
- /* Secondly check whether it is installed (a third party library). */ | |
- return library_installed (libpath, library); | |
-} | |
- | |
-/* check_valid_list check to see that the libraries specified are valid. | |
- It checks against the default library set in gm2 and also against | |
- any additional libraries installed in the libpath tree. */ | |
- | |
-static bool | |
-check_valid_list (const char *libpath, const char *libraries) | |
-{ | |
- const char *start = libraries; | |
- const char *end; | |
- const char *copy; | |
- | |
- do | |
- { | |
- end = index (start, ','); | |
- if (end == NULL) | |
- { | |
- copy = xstrdup (start); | |
- start = NULL; | |
- } | |
- else | |
- { | |
- copy = xstrndup (start, end - start); | |
- start = end + 1; | |
- } | |
- if (! check_valid_library (libpath, copy)) | |
- { | |
- error ("library specified %sq is either not installed or does not exist", | |
- copy); | |
- return false; | |
- } | |
- } | |
- while ((start != NULL) && (start[0] != (char)0)); | |
- return true; | |
+ if (result == NULL) | |
+ return ""; | |
+ return result; | |
} | |
/* add_word returns a new string which has the contents of lib | |
@@ -535,7 +492,8 @@ convert_abbreviations (const char *libraries) | |
} | |
else | |
{ | |
- full_libraries = convert_abbreviation (full_libraries, xstrndup (start, end - start)); | |
+ full_libraries = convert_abbreviation (full_libraries, | |
+ xstrndup (start, end - start)); | |
start = end + 1; | |
} | |
} | |
@@ -543,6 +501,31 @@ convert_abbreviations (const char *libraries) | |
return full_libraries; | |
} | |
+/* m2include_spec_fn is called by the lang-specs.h to set the include paths | |
+ which maybe target dependent. */ | |
+ | |
+static const char * | |
+m2include_spec_fn (int argc, const char *argv[]) | |
+{ | |
+ if (argc == 1) | |
+ full_libraries = convert_abbreviations (argv[0]); | |
+ else if (argc == 2 && (strcmp (argv[0], "-") == 0)) | |
+ { | |
+ if (strncmp (argv[1], "flibs=", strlen ("flibs=")) == 0) | |
+ full_libraries = convert_abbreviations (&argv[1][strlen ("flibs=")]); | |
+ } | |
+ return add_default_includes (LIBSUBDIR, full_libraries); | |
+} | |
+ | |
+/* m2_register_spec_functions register the Modula-2 associated spec | |
+ functions. */ | |
+ | |
+void | |
+m2_register_spec_functions (void) | |
+{ | |
+ fe_add_spec_function ("m2include", m2include_spec_fn); | |
+} | |
+ | |
void | |
lang_specific_driver (struct cl_decoded_option **in_decoded_options, | |
@@ -572,9 +555,7 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options, | |
/* Which c++ runtime library to link. */ | |
stdcxxlib_kind which_library = USE_LIBSTDCXX; | |
- const char *libraries = NULL; | |
const char *dialect = DEFAULT_DIALECT; | |
- const char *libpath = LIBSUBDIR; | |
/* An array used to flag each argument that needs a bit set for | |
LANGSPEC, MATHLIB, or WITHLIBC. */ | |
@@ -632,6 +613,7 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options, | |
fprintf (stderr, "\n"); | |
#endif | |
+ m2_register_spec_functions (); | |
gm2_xargc = argc; | |
gm2_x_decoded_options = decoded_options; | |
gm2_newargc = 0; | |
@@ -673,12 +655,15 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options, | |
case OPT_flibs_: | |
libraries = xstrdup (arg); | |
allow_libraries = decoded_options[i].value; | |
+ args[i] |= SKIPOPT; /* We will add the option if it is needed. */ | |
break; | |
case OPT_fmod_: | |
seen_module_extension = true; | |
+ args[i] |= SKIPOPT; /* We will add the option if it is needed. */ | |
break; | |
case OPT_fpthread: | |
need_pthread = decoded_options[i].value; | |
+ args[i] |= SKIPOPT; /* We will add the option if it is needed. */ | |
break; | |
case OPT_fm2_plugin: | |
need_plugin = decoded_options[i].value; | |
@@ -687,6 +672,7 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options, | |
error ("plugin support is disabled; configure with " | |
"%<--enable-plugin%>"); | |
#endif | |
+ args[i] |= SKIPOPT; /* We will add the option if it is needed. */ | |
break; | |
case OPT_fscaffold_dynamic: | |
seen_scaffold_dynamic = true; | |
@@ -701,10 +687,12 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options, | |
gen_module_list = decoded_options[i].value; | |
if (gen_module_list) | |
gen_module_filename = decoded_options[i].arg; | |
+ args[i] |= SKIPOPT; /* We will add the option if it is needed. */ | |
break; | |
case OPT_fuse_list_: | |
seen_uselist = true; | |
uselist = decoded_options[i].value; | |
+ args[i] |= SKIPOPT; /* We will add the option if it is needed. */ | |
break; | |
case OPT_nostdlib: | |
@@ -794,11 +782,7 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options, | |
break; | |
default: | |
- if ((decoded_options[i].orig_option_with_args_text != NULL) | |
- && (strncmp (decoded_options[i].orig_option_with_args_text, | |
- "-m", 2) == 0)) | |
- multilib_dir = xstrdup (decoded_options[i].orig_option_with_args_text | |
- + 2); | |
+ break; | |
} | |
} | |
if (language != NULL && (strcmp (language, "modula-2") != 0)) | |
@@ -855,9 +839,13 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options, | |
#endif | |
} | |
- /* We now add in extra arguments to facilitate a successful | |
- compile or link. For example include paths for dialect of Modula-2, | |
- library paths and default scaffold linking options. */ | |
+ /* We now add in extra arguments to facilitate a successful link. | |
+ Note that the libraries are added to the end of the link here | |
+ and also placed earlier into the link by lang-specs.h. Possibly | |
+ this is needed because the m2pim,m2iso libraries are cross linked | |
+ (--fixme-- combine all the m2 libraries into a single archive). | |
+ | |
+ We also add default scaffold linking options. */ | |
/* If we have not seen either uselist or gen_module_list and we need | |
to link then we turn on -fgen_module_list=- as the default. */ | |
@@ -867,20 +855,19 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options, | |
if (allow_libraries) | |
{ | |
/* If the libraries have not been specified by the user but the | |
- dialect has been specified then select the appropriate libraries. */ | |
+ dialect has been specified then select the appropriate | |
+ libraries. */ | |
if (libraries == NULL) | |
{ | |
if (strcmp (dialect, "iso") == 0) | |
- libraries = xstrdup ("m2iso,m2pim"); | |
+ libraries = xstrdup ("m2iso,m2cor,m2pim,m2log"); | |
else | |
/* Default to pim libraries if none specified. */ | |
- libraries = xstrdup ("m2pim,m2log,m2iso"); | |
+ libraries = xstrdup ("m2pim,m2iso,m2cor,m2log"); | |
} | |
libraries = convert_abbreviations (libraries); | |
- if (! check_valid_list (libpath, libraries)) | |
- return; | |
- add_default_includes (libpath, libraries); | |
} | |
+ | |
if ((! seen_x_flag) && seen_module_extension) | |
append_option (OPT_x, "modula-2", 1); | |
@@ -894,7 +881,8 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options, | |
append_option (OPT_Wl_, LD_STATIC_OPTION, 1); | |
#endif | |
if (allow_libraries) | |
- add_default_archives (libpath, libraries); | |
+ (void)add_default_libs (libraries); | |
+ | |
#ifdef HAVE_LD_STATIC_DYNAMIC | |
if (allow_libraries && !shared_libgm2) | |
append_option (OPT_Wl_, LD_DYNAMIC_OPTION, 1); | |
@@ -962,6 +950,7 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options, | |
*in_added_libraries = added_libraries; | |
} | |
+ | |
/* Called before linking. Returns 0 on success and -1 on failure. */ | |
int | |
lang_specific_pre_link (void) /* Not used for M2. */ | |
diff --git a/gcc/m2/lang-specs.h b/gcc/m2/lang-specs.h | |
index 706064fc8db..6186d8b8ab0 100644 | |
--- a/gcc/m2/lang-specs.h | |
+++ b/gcc/m2/lang-specs.h | |
@@ -1,5 +1,5 @@ | |
/* Definitions for specs for GNU Modula-2. | |
- Copyright (C) 2001-2022 Free Software Foundation, Inc. | |
+ Copyright (C) 2001-2023 Free Software Foundation, Inc. | |
Contributed by Gaius Mulley. | |
This file is part of GCC. | |
@@ -24,15 +24,30 @@ along with GCC; see the file COPYING3. If not see | |
/* Pass the preprocessor options on the command line together with | |
the exec prefix. */ | |
-#define M2CPP "%{fcpp:-fcpp-begin " \ | |
- " -E -lang-asm -traditional-cpp " \ | |
- " %(cpp_unique_options) -fcpp-end}" | |
+#define M2CPP \ | |
+ "%{fcpp:-fcpp-begin " \ | |
+ " -E -lang-asm -traditional-cpp " \ | |
+ " %(cpp_unique_options) -fcpp-end} " | |
+ | |
+/* The include paths might contain the multilib_dir depending upon target. | |
+ m2include is in effect a callback to allow the driver to create the | |
+ path with a resolved multilib_dir. */ | |
+ | |
+#define M2DEFAULT_DIALECT_INCLUDE \ | |
+ "%{fpim*:%:m2include(pim,iso,cor,log)} \ | |
+ %{fiso:%:m2include(iso,cor,pim,log)} \ | |
+ %{!fiso:%{!fpim*:%:m2include(pim,iso,cor,log)}} " | |
+ | |
+#define M2DEFAULT_INCLUDE \ | |
+ "%{!fno-libs*:%{!flibs*:" M2DEFAULT_DIALECT_INCLUDE "}}" \ | |
+ "%{flibs*:%:m2include(%{flibs*})} " | |
{".mod", "@modula-2", 0, 0, 0}, | |
{"@modula-2", | |
- "cc1gm2 " M2CPP | |
- " %(cc1_options) %{B*} %{c*} %{f*} %{+e*} %{I*} " | |
+ "cc1gm2 " | |
+ " %(cc1_options) %{B*} %{c*} %{+e*} %{I*} " | |
" %{MD} %{MMD} %{M} %{MM} %{MA} %{MT*} %{MF*} %V" | |
" %{save-temps*}" | |
+ M2CPP M2DEFAULT_INCLUDE | |
" %i %{!fsyntax-only:%(invoke_as)}", | |
0, 0, 0}, | |
-- | |
2.37.1 (Apple Git-137.1) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment