aboutsummaryrefslogtreecommitdiff
path: root/gcc/m2
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/m2')
-rw-r--r--gcc/m2/ChangeLog40
-rw-r--r--gcc/m2/gm2-compiler/PathName.mod21
-rw-r--r--gcc/m2/gm2-lang.cc336
-rw-r--r--gcc/m2/gm2spec.cc31
-rw-r--r--gcc/m2/lang.opt10
5 files changed, 358 insertions, 80 deletions
diff --git a/gcc/m2/ChangeLog b/gcc/m2/ChangeLog
index ad10605..f63381d 100644
--- a/gcc/m2/ChangeLog
+++ b/gcc/m2/ChangeLog
@@ -1,3 +1,43 @@
+2025-08-29 Gaius Mulley <gaiusmod2@gmail.com>
+
+ PR modula2/121709
+ * gm2-lang.cc (concat_component): New function.
+ (find_cpp_entry): Ditto.
+ (lookup_cpp_default): Ditto.
+ (add_default_include_paths): Rewrite.
+ (m2_pathname_root): Remove.
+
+2025-08-28 Gaius Mulley <gaiusmod2@gmail.com>
+
+ PR modula2/121629
+ * gm2-compiler/PathName.mod: Add copyright notice.
+ * gm2-lang.cc (named_path): Add field lib_root.
+ (push_back_Ipath): Set lib_root false.
+ (push_back_lib_root): New function.
+ (get_dir_sep_size): Ditto.
+ (add_path_component): Ditto.
+ (add_one_import_path): Ditto.
+ (add_non_dialect_specific_path): Ditto.
+ (foreach_lib_gen_import_path): Ditto.
+ (get_module_source_dir): Ditto.
+ (add_default_include_paths): Ditto.
+ (assign_flibs): Ditto.
+ (m2_pathname_root): Ditto.
+ (add_m2_import_paths): Remove function.
+ (gm2_langhook_post_options): Call assign_flibs.
+ Check np.lib_root and call foreach_lib_gen_import_path.
+ Replace call to add_m2_import_paths with a call to
+ add_default_include_paths.
+ (gm2_langhook_handle_option): Add case OPT_fm2_pathname_rootI_.
+ * gm2spec.cc (named_path): Add field lib_root.
+ (push_back_Ipath): Set lib_root false.
+ (push_back_lib_root): New function.
+ (add_m2_I_path): Add OPT_fm2_pathname_rootI_ option
+ if np.lib_root.
+ (lang_specific_driver): Add case OPT_fm2_pathname_root_.
+ * lang.opt (fm2-pathname-root=): New option.
+ (fm2-pathname-rootI=): Ditto.
+
2025-08-01 Gaius Mulley <gaiusmod2@gmail.com>
PR modula2/121354
diff --git a/gcc/m2/gm2-compiler/PathName.mod b/gcc/m2/gm2-compiler/PathName.mod
index 6fc7612..0ba9024 100644
--- a/gcc/m2/gm2-compiler/PathName.mod
+++ b/gcc/m2/gm2-compiler/PathName.mod
@@ -1,3 +1,24 @@
+(* M2PathName.mod maintain a dictionary of named paths.
+
+Copyright (C) 2023-2025 Free Software Foundation, Inc.
+Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
+
+This file is part of GNU Modula-2.
+
+GNU Modula-2 is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GNU Modula-2 is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Modula-2; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. *)
+
IMPLEMENTATION MODULE PathName ;
FROM Storage IMPORT ALLOCATE, DEALLOCATE ;
diff --git a/gcc/m2/gm2-lang.cc b/gcc/m2/gm2-lang.cc
index 31a2e46..cc074d5 100644
--- a/gcc/m2/gm2-lang.cc
+++ b/gcc/m2/gm2-lang.cc
@@ -40,6 +40,7 @@ along with GCC; see the file COPYING3. If not see
#include "m2-tree.h"
#include "convert.h"
#include "rtegraph.h"
+#include "cppdefault.h"
static void write_globals (void);
@@ -51,6 +52,7 @@ static bool iso = false;
typedef struct named_path_s {
std::vector<const char*>path;
const char *name;
+ bool lib_root;
} named_path;
@@ -59,6 +61,7 @@ static bool allow_libraries = true;
static const char *flibs = nullptr;
static const char *iprefix = nullptr;
static const char *imultilib = nullptr;
+static const char *target_system_root = nullptr;
static std::vector<named_path>Ipaths;
static std::vector<const char*>isystem;
static std::vector<const char*>iquote;
@@ -372,6 +375,7 @@ push_back_Ipath (const char *arg)
named_path np;
np.path.push_back (arg);
np.name = xstrdup (M2Options_GetM2PathName ());
+ np.lib_root = false;
Ipaths.push_back (np);
}
else
@@ -384,11 +388,254 @@ push_back_Ipath (const char *arg)
named_path np;
np.path.push_back (arg);
np.name = xstrdup (M2Options_GetM2PathName ());
+ np.lib_root = false;
Ipaths.push_back (np);
}
}
}
+/* push_back_lib_root pushes a lib_root onto the Ipaths vector.
+ The ordering of the -fm2_add_lib_root=, -I and named paths
+ must be preserved. */
+
+static void
+push_back_lib_root (const char *arg)
+{
+ named_path np;
+ np.name = arg;
+ np.lib_root = true;
+ Ipaths.push_back (np);
+}
+
+/* get_dir_sep_size return the length of the DIR_SEPARATOR string. */
+
+static size_t
+get_dir_sep_size (void)
+{
+ const char dir_sep[] = {DIR_SEPARATOR, (char)0};
+ size_t dir_sep_size = strlen (dir_sep);
+ return dir_sep_size;
+}
+
+/* add_path_component strcats src into dest and adds a directory seperator
+ if necessary. */
+
+static void
+add_path_component (char *dest, const char *src)
+{
+ size_t len = strlen (dest);
+ const char dir_sep[] = {DIR_SEPARATOR, (char)0};
+ size_t dir_sep_size = strlen (dir_sep);
+
+ if (len > 0)
+ {
+ /* Only add a seperator if dest is not empty and does not end
+ with a seperator. */
+ if (len >= dir_sep_size
+ && (strcmp (&dest[len-dir_sep_size], dir_sep) != 0))
+ strcat (dest, dir_sep);
+ }
+ strcat (dest, src);
+}
+
+/* This prefixes LIBNAME with the current compiler prefix (if it has been
+ relocated) or the LIBSUBDIR, if not. */
+
+static void
+add_one_import_path (const char *libpath, const char *libname)
+{
+ size_t dir_sep_size = get_dir_sep_size ();
+ size_t mlib_len = 0;
+
+ if (imultilib)
+ {
+ mlib_len = strlen (imultilib);
+ mlib_len += dir_sep_size;
+ }
+
+ char *lib = (char *)alloca (strlen (libpath) + dir_sep_size
+ + strlen ("m2") + dir_sep_size
+ + strlen (libname) + 1
+ + mlib_len + 1);
+ strcpy (lib, libpath);
+ if (imultilib)
+ add_path_component (lib, imultilib);
+ add_path_component (lib, "m2");
+ add_path_component (lib, libname);
+ M2Options_SetM2PathName (libname);
+ M2Options_SetSearchPath (lib);
+}
+
+/* add_non_dialect_specific_path add non dialect specific includes
+ given a base libpath. */
+
+static void
+add_non_dialect_specific_path (const char *libpath)
+{
+ char *incpath = (char *)alloca (strlen (libpath)
+ + strlen ("m2")
+ + get_dir_sep_size ()
+ + 1);
+ strcpy (incpath, libpath);
+ add_path_component (incpath, "m2");
+ M2Options_SetM2PathName (""); /* No pathname for non dialect specific libs. */
+ M2Options_SetSearchPath (incpath);
+}
+
+/* For each comma-separated standard library name in LIBLIST, add the
+ corresponding include path. */
+
+static void
+foreach_lib_gen_import_path (const char *liblist, const char *libpath)
+{
+ while (*liblist != 0 && *liblist != '-')
+ {
+ const char *comma = strstr (liblist, ",");
+ size_t len;
+ if (comma)
+ len = comma - liblist;
+ else
+ len = strlen (liblist);
+ char *libname = (char *) alloca (len+1);
+ strncpy (libname, liblist, len);
+ libname[len] = 0;
+ add_one_import_path (libpath, libname);
+ liblist += len;
+ if (*liblist == ',')
+ liblist++;
+ }
+ add_non_dialect_specific_path (libpath);
+}
+
+/* get_module_source_dir return the libpath/{multilib/} as a malloc'd
+ string. */
+
+static const char *
+get_module_source_dir (void)
+{
+ const char *libpath = iprefix ? iprefix : LIBSUBDIR;
+ const char dir_sep[] = {DIR_SEPARATOR, (char)0};
+ size_t dir_sep_size = strlen (dir_sep);
+ unsigned int mlib_len = 0;
+
+ if (imultilib)
+ {
+ mlib_len = strlen (imultilib);
+ mlib_len += strlen (dir_sep);
+ }
+ char *lib = (char *) xmalloc (strlen (libpath)
+ + dir_sep_size
+ + mlib_len + 1);
+ strcpy (lib, libpath);
+ /* iprefix has a trailing dir separator, LIBSUBDIR does not. */
+ if (!iprefix)
+ strcat (lib, dir_sep);
+
+ if (imultilib)
+ {
+ strcat (lib, imultilib);
+ strcat (lib, dir_sep);
+ }
+ return lib;
+}
+
+/* concat_component returns a string containing the path left/right.
+ Pre-requisite, left and right are null terminated strings. The contents of
+ left and right are held on the heap. Post-requisite, left and right are
+ freed and a new combined string is malloced. */
+
+static char *
+concat_component (char *left, char *right)
+{
+ size_t len = strlen (left)
+ + strlen (right)
+ + get_dir_sep_size ()
+ + 1;
+ char *new_str = (char *) xmalloc (len);
+ strcpy (new_str, left);
+ add_path_component (new_str, right);
+ free (left);
+ free (right);
+ return new_str;
+}
+
+/* find_cpp_entry return the element of the cpp_include_defaults array
+ whose fname matches name. */
+
+static const struct default_include *
+find_cpp_entry (const char *name)
+{
+ const struct default_include *p;
+
+ for (p = cpp_include_defaults; p->fname; p++)
+ if (strcmp (p->fname, name) == 0)
+ return p;
+ return NULL;
+}
+
+/* lookup_cpp_default lookup the entry in cppdefault then add the directory to
+ the m2 search path. It also honours sysroot, imultilib and imultiarch. */
+
+static void
+lookup_cpp_default (const char *sysroot, const char *flibs, const char *name)
+{
+ const struct default_include *p = find_cpp_entry (name);
+
+ if (p != NULL)
+ {
+ char *full_str = xstrdup (p->fname);
+
+ /* Should this directory start with the sysroot? */
+ if (sysroot && p->add_sysroot)
+ full_str = concat_component (xstrdup (sysroot), full_str);
+ /* Should we append the imultilib component? */
+ if (p->multilib == 1 && imultilib)
+ full_str = concat_component (full_str, xstrdup (imultilib));
+ /* Or append the imultiarch component? */
+ else if (p->multilib == 2 && imultiarch)
+ full_str = concat_component (full_str, xstrdup (imultiarch));
+ else
+ full_str = xstrdup (p->fname);
+ foreach_lib_gen_import_path (flibs, full_str);
+ free (full_str);
+ }
+}
+
+/* add_default_include_paths add include paths for site wide definition modules
+ and also gcc version specific definition modules. */
+
+static void
+add_default_include_paths (const char *flibs)
+{
+ /* Follow the order found in cppdefaults.cc. */
+#ifdef LOCAL_INCLUDE_DIR
+ lookup_cpp_default (target_system_root, flibs, LOCAL_INCLUDE_DIR);
+#endif
+#ifdef PREFIX_INCLUDE_DIR
+ lookup_cpp_default (target_system_root, flibs, PREFIX_INCLUDE_DIR);
+#endif
+ /* Add the gcc version specific include path. */
+ foreach_lib_gen_import_path (flibs, get_module_source_dir ());
+#ifdef NATIVE_SYSTEM_HEADER_DIR
+ lookup_cpp_default (target_system_root, flibs, NATIVE_SYSTEM_HEADER_DIR);
+#endif
+}
+
+/* assign_flibs assign flibs to a default providing that allow_libraries
+ is true and flibs has not been set. */
+
+static void
+assign_flibs (void)
+{
+ if (allow_libraries && (flibs == NULL))
+ {
+ if (iso)
+ flibs = "m2iso,m2cor,m2pim,m2log";
+ else
+ flibs = "m2pim,m2iso,m2cor,m2log";
+ }
+}
+
/* Handle gm2 specific options. Return 0 if we didn't do anything. */
bool
@@ -435,6 +682,9 @@ gm2_langhook_handle_option (
case OPT_fpositive_mod_floor_div:
M2Options_SetPositiveModFloor (value);
return 1;
+ case OPT_fm2_pathname_rootI_:
+ push_back_lib_root (arg);
+ return 1;
case OPT_flibs_:
allow_libraries = value;
flibs = arg;
@@ -659,7 +909,7 @@ gm2_langhook_handle_option (
return 1;
break;
case OPT_isysroot:
- /* Otherwise, ignored, at least for now. */
+ target_system_root = arg;
return 1;
break;
case OPT_fm2_whole_program:
@@ -710,66 +960,6 @@ gm2_langhook_handle_option (
return 0;
}
-/* This prefixes LIBNAME with the current compiler prefix (if it has been
- relocated) or the LIBSUBDIR, if not. */
-static void
-add_one_import_path (const char *libname)
-{
- const char *libpath = iprefix ? iprefix : LIBSUBDIR;
- const char dir_sep[] = {DIR_SEPARATOR, (char)0};
- size_t dir_sep_size = strlen (dir_sep);
- unsigned int mlib_len = 0;
-
- if (imultilib)
- {
- mlib_len = strlen (imultilib);
- mlib_len += strlen (dir_sep);
- }
-
- char *lib = (char *)alloca (strlen (libpath) + dir_sep_size
- + strlen ("m2") + dir_sep_size
- + strlen (libname) + 1
- + mlib_len + 1);
- strcpy (lib, libpath);
- /* iprefix has a trailing dir separator, LIBSUBDIR does not. */
- if (!iprefix)
- strcat (lib, dir_sep);
-
- if (imultilib)
- {
- strcat (lib, imultilib);
- strcat (lib, dir_sep);
- }
- strcat (lib, "m2");
- strcat (lib, dir_sep);
- strcat (lib, libname);
- M2Options_SetM2PathName (libname);
- M2Options_SetSearchPath (lib);
-}
-
-/* For each comma-separated standard library name in LIBLIST, add the
- corresponding include path. */
-static void
-add_m2_import_paths (const char *liblist)
-{
- while (*liblist != 0 && *liblist != '-')
- {
- const char *comma = strstr (liblist, ",");
- size_t len;
- if (comma)
- len = comma - liblist;
- else
- len = strlen (liblist);
- char *libname = (char *) alloca (len+1);
- strncpy (libname, liblist, len);
- libname[len] = 0;
- add_one_import_path (libname);
- liblist += len;
- if (*liblist == ',')
- liblist++;
- }
-}
-
/* Run after parsing options. */
static bool
@@ -784,16 +974,7 @@ gm2_langhook_post_options (const char **pfilename)
/* Add the include paths as per the libraries specified.
NOTE: This assumes that the driver has validated the input and makes
no attempt to be defensive of nonsense input in flibs=. */
- if (allow_libraries)
- {
- if (!flibs)
- {
- if (iso)
- flibs = "m2iso,m2cor,m2pim,m2log";
- else
- flibs = "m2pim,m2iso,m2cor,m2log";
- }
- }
+ assign_flibs ();
/* Add search paths.
We are not handling all of the cases yet (e.g idirafter).
@@ -807,9 +988,14 @@ gm2_langhook_post_options (const char **pfilename)
iquote.clear();
for (auto np : Ipaths)
{
- M2Options_SetM2PathName (np.name);
- for (auto *s : np.path)
- M2Options_SetSearchPath (s);
+ if (np.lib_root)
+ foreach_lib_gen_import_path (flibs, np.name);
+ else
+ {
+ M2Options_SetM2PathName (np.name);
+ for (auto *s : np.path)
+ M2Options_SetSearchPath (s);
+ }
}
Ipaths.clear();
for (auto *s : isystem)
@@ -818,7 +1004,7 @@ gm2_langhook_post_options (const char **pfilename)
/* FIXME: this is not a good way to suppress the addition of the import
paths. */
if (allow_libraries)
- add_m2_import_paths (flibs);
+ add_default_include_paths (flibs);
/* Returning false means that the backend should be used. */
return M2Options_GetPPOnly ();
diff --git a/gcc/m2/gm2spec.cc b/gcc/m2/gm2spec.cc
index 868e5c5..18d9ce7 100644
--- a/gcc/m2/gm2spec.cc
+++ b/gcc/m2/gm2spec.cc
@@ -158,10 +158,12 @@ static const char *m2_path_name = "";
typedef struct named_path_s {
std::vector<const char*>path;
const char *name;
+ bool lib_root;
} named_path;
static std::vector<named_path>Ipaths;
+/* push_back_Ipath pushes a named path to the Ipaths global variable. */
static void
push_back_Ipath (const char *arg)
@@ -171,6 +173,7 @@ push_back_Ipath (const char *arg)
named_path np;
np.path.push_back (arg);
np.name = m2_path_name;
+ np.lib_root = false;
Ipaths.push_back (np);
}
else
@@ -183,11 +186,25 @@ push_back_Ipath (const char *arg)
named_path np;
np.path.push_back (arg);
np.name = m2_path_name;
+ np.lib_root = false;
Ipaths.push_back (np);
}
}
}
+/* push_back_lib_root pushes a lib_root onto the Ipaths vector.
+ The ordering of the -fm2_add_lib_root=, -I and named paths
+ must be preserved. */
+
+static void
+push_back_lib_root (const char *arg)
+{
+ named_path np;
+ np.name = arg;
+ np.lib_root = true;
+ Ipaths.push_back (np);
+}
+
/* Return whether strings S1 and S2 are both NULL or both the same
string. */
@@ -379,15 +396,18 @@ convert_abbreviations (const char *libraries)
return full_libraries;
}
-/* add_m2_I_path appends -fm2-pathname and -fm2-pathnameI options to
- the command line which are contructed in the saved Ipaths. */
+/* add_m2_I_path appends -fm2-pathname, -fm2-pathnameI and -fm2-add-lib-root
+ options to the command line which are contructed in the saved Ipaths.
+ The order of these options must be maintained. */
static void
add_m2_I_path (void)
{
for (auto np : Ipaths)
{
- if (strcmp (np.name, "") == 0)
+ if (np.lib_root)
+ append_option (OPT_fm2_pathname_rootI_, safe_strdup (np.name), 1);
+ else if (strcmp (np.name, "") == 0)
append_option (OPT_fm2_pathname_, safe_strdup ("-"), 1);
else
append_option (OPT_fm2_pathname_, safe_strdup (np.name), 1);
@@ -576,6 +596,10 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
args[i] |= SKIPOPT; /* We will add the option if it is needed. */
m2_path_name = decoded_options[i].arg;
break;
+ case OPT_fm2_pathname_root_:
+ args[i] |= SKIPOPT; /* We will add the option if it is needed. */
+ push_back_lib_root (decoded_options[i].arg);
+ break;
case OPT__help:
case OPT__help_:
/* Let gcc.cc handle this, as it has a really
@@ -739,7 +763,6 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
"-fgen-module-list=", "-fuse-list=");
}
-
/* There's no point adding -shared-libgcc if we don't have a shared
libgcc. */
#ifndef ENABLE_SHARED_LIBGCC
diff --git a/gcc/m2/lang.opt b/gcc/m2/lang.opt
index 48c2380..2aea4cc 100644
--- a/gcc/m2/lang.opt
+++ b/gcc/m2/lang.opt
@@ -172,7 +172,15 @@ specify the module mangled prefix name for all modules in the following include
fm2-pathnameI
Modula-2 Joined
-; For internal use only: used by the driver to copy the user facing -I option
+; For internal use only: used by the driver to copy the user facing -I option in order
+
+fm2-pathname-root=
+Modula-2 Joined
+add include paths for all the library names in -flibs= to this directory root
+
+fm2-pathname-rootI=
+Modula-2 Joined
+; For internal use only: used by the driver to copy the user facing -I option in order
fm2-plugin
Modula-2