Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iains/23321b1eb98f537e39d73efbee9504e7 to your computer and use it in GitHub Desktop.
Save iains/23321b1eb98f537e39d73efbee9504e7 to your computer and use it in GitHub Desktop.
gm2 patch v3.1
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