diff options
Diffstat (limited to 'gcc/m2')
-rw-r--r-- | gcc/m2/ChangeLog | 40 | ||||
-rw-r--r-- | gcc/m2/gm2-compiler/PathName.mod | 21 | ||||
-rw-r--r-- | gcc/m2/gm2-lang.cc | 336 | ||||
-rw-r--r-- | gcc/m2/gm2spec.cc | 31 | ||||
-rw-r--r-- | gcc/m2/lang.opt | 10 |
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 |