diff options
Diffstat (limited to 'gcc/m2/gm2-lang.cc')
-rw-r--r-- | gcc/m2/gm2-lang.cc | 336 |
1 files changed, 261 insertions, 75 deletions
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 (); |