LCOV - code coverage report
Current view: top level - gcc/m2 - gm2spec.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 77.3 % 392 303
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 14 14
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* gm2spec.cc specific flags and argument handling within GNU Modula-2.
       2              : 
       3              : Copyright (C) 2007-2026 Free Software Foundation, Inc.
       4              : Contributed by Gaius Mulley <gaius@glam.ac.uk>.
       5              : 
       6              : This file is part of GNU Modula-2.
       7              : 
       8              : GNU Modula-2 is free software; you can redistribute it and/or modify
       9              : it under the terms of the GNU General Public License as published by
      10              : the Free Software Foundation; either version 3, or (at your option)
      11              : any later version.
      12              : 
      13              : GNU Modula-2 is distributed in the hope that it will be useful, but
      14              : WITHOUT ANY WARRANTY; without even the implied warranty of
      15              : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16              : General Public License for more details.
      17              : 
      18              : You should have received a copy of the GNU General Public License
      19              : along with GNU Modula-2; see the file COPYING3.  If not see
      20              : <http://www.gnu.org/licenses/>.  */
      21              : 
      22              : #include "config.h"
      23              : #define INCLUDE_STRING
      24              : #define INCLUDE_VECTOR
      25              : #include "system.h"
      26              : #include "coretypes.h"
      27              : #include "tm.h"
      28              : #include "xregex.h"
      29              : #include "obstack.h"
      30              : #include "intl.h"
      31              : #include "prefix.h"
      32              : #include "opt-suggestions.h"
      33              : #include "gcc.h"
      34              : #include "opts.h"
      35              : #include "vec.h"
      36              : 
      37              : #include "m2/gm2config.h"
      38              : 
      39              : #ifdef HAVE_DIRENT_H
      40              : #include <dirent.h>
      41              : #else
      42              : #ifdef HAVE_SYS_NDIR_H
      43              : #include <sys/ndir.h>
      44              : #endif
      45              : #ifdef HAVE_SYS_DIR_H
      46              : #include <sys/dir.h>
      47              : #endif
      48              : #ifdef HAVE_NDIR_H
      49              : #include <ndir.h>
      50              : #endif
      51              : #endif
      52              : 
      53              : /* This bit is set if the arguments is a M2 source file.  */
      54              : #define M2SOURCE        (1<<1)
      55              : /* This bit is set if we saw a `-xfoo' language specification.  */
      56              : #define LANGSPEC        (1<<2)
      57              : /* This bit is set if they did `-lm' or `-lmath'.  */
      58              : #define MATHLIB         (1<<3)
      59              : /* This bit is set if they did `-lc'.  */
      60              : #define WITHLIBC        (1<<4)
      61              : /* Skip this option.  */
      62              : #define SKIPOPT         (1<<5)
      63              : 
      64              : #ifndef MATH_LIBRARY
      65              : #define MATH_LIBRARY "m"
      66              : #endif
      67              : #ifndef MATH_LIBRARY_PROFILE
      68              : #define MATH_LIBRARY_PROFILE MATH_LIBRARY
      69              : #endif
      70              : 
      71              : #ifndef LIBSTDCXX
      72              : #define LIBSTDCXX "stdc++"
      73              : #endif
      74              : #ifndef LIBSTDCXX_PROFILE
      75              : #define LIBSTDCXX_PROFILE LIBSTDCXX
      76              : #endif
      77              : #ifndef LIBSTDCXX_STATIC
      78              : #define LIBSTDCXX_STATIC NULL
      79              : #endif
      80              : 
      81              : #ifndef LIBCXX
      82              : #define LIBCXX "c++"
      83              : #endif
      84              : #ifndef LIBCXX_PROFILE
      85              : #define LIBCXX_PROFILE LIBCXX
      86              : #endif
      87              : #ifndef LIBCXX_STATIC
      88              : #define LIBCXX_STATIC NULL
      89              : #endif
      90              : 
      91              : #ifndef LIBCXXABI
      92              : #define LIBCXXABI "c++abi"
      93              : #endif
      94              : #ifndef LIBCXXABI_PROFILE
      95              : #define LIBCXXABI_PROFILE LIBCXXABI
      96              : #endif
      97              : #ifndef LIBCXXABI_STATIC
      98              : #define LIBCXXABI_STATIC NULL
      99              : #endif
     100              : 
     101              : /* The values used here must match those of the stdlib_kind enumeration
     102              :    in c.opt.  */
     103              : enum stdcxxlib_kind
     104              : {
     105              :   USE_LIBSTDCXX = 1,
     106              :   USE_LIBCXX = 2
     107              : };
     108              : 
     109              : #define DEFAULT_DIALECT "pim"
     110              : 
     111              : #undef DEBUG_ARG
     112              : 
     113              : typedef enum { iso, pim, min, logitech, pimcoroutine, maxlib } libs;
     114              : 
     115              : /* These are the library names which are installed as part of gm2 and reflect
     116              :    -flibs=name.  The -flibs= option provides the user with a short cut to add
     117              :    libraries without having to know the include and link path.  */
     118              : 
     119              : static const char *library_name[maxlib]
     120              :     = { "m2iso", "m2pim", "m2min", "m2log", "m2cor" };
     121              : 
     122              : /* They match the installed archive name for example libm2iso.a,
     123              :    libm2pim.a, libm2min.a, libm2log.a and libm2cor.a.  They also match a
     124              :    subdirectory name where the definition modules are kept.  The driver
     125              :    checks the argument to -flibs= for an entry in library_name or
     126              :    alternatively the existance of the subdirectory (to allow for third
     127              :    party libraries to coexist).  */
     128              : 
     129              : static const char *library_abbrev[maxlib]
     130              :     = { "iso", "pim", "min", "log", "cor" };
     131              : 
     132              : /* Users may specifiy -flibs=pim,iso etc which are mapped onto
     133              :    -flibs=m2pim,m2iso respectively.  This provides a match between
     134              :    the dialect of Modula-2 and the library set.  */
     135              : 
     136              : static bool seen_scaffold_static = false;
     137              : static bool seen_scaffold_dynamic = false;
     138              : static bool seen_scaffold_main = false;
     139              : static bool scaffold_static = false;
     140              : static bool scaffold_dynamic = true; // Default uses -fscaffold-dynamic.
     141              : static bool scaffold_main = false;
     142              : static bool seen_gen_module_list = false;
     143              : static bool seen_uselist = false;
     144              : static bool uselist = false;
     145              : static bool gen_module_list = true;  // Default uses -fgen-module-list=-.
     146              : static const char *gen_module_filename = "-";
     147              : /* The original argument list and related info is copied here.  */
     148              : static unsigned int gm2_xargc;
     149              : static const struct cl_decoded_option *gm2_x_decoded_options;
     150              : static void append_arg (const struct cl_decoded_option *);
     151              : 
     152              : /* The new argument list will be built here.  */
     153              : static unsigned int gm2_newargc;
     154              : static struct cl_decoded_option *gm2_new_decoded_options;
     155              : static const char *libraries = NULL;  /* Abbreviated libraries.  */
     156              : static const char *m2_path_name = "";
     157              : 
     158       361506 : typedef struct named_path_s {
     159              :   std::vector<const char*>path;
     160              :   const char *name;
     161              :   bool lib_root;
     162              : } named_path;
     163              : 
     164              : static std::vector<named_path>Ipaths;
     165              : 
     166              : /* push_back_Ipath pushes a named path to the Ipaths global variable.  */
     167              : 
     168              : static void
     169       123189 : push_back_Ipath (const char *arg)
     170              : {
     171       123189 :   if (Ipaths.empty ())
     172              :     {
     173        19310 :       named_path np;
     174        19310 :       np.path.push_back (arg);
     175        19310 :       np.name = m2_path_name;
     176        19310 :       np.lib_root = false;
     177        19310 :       Ipaths.push_back (np);
     178        19310 :     }
     179              :   else
     180              :     {
     181       103879 :       if (strcmp (Ipaths.back ().name,
     182              :                   m2_path_name) == 0)
     183        36585 :         Ipaths.back ().path.push_back (arg);
     184              :       else
     185              :         {
     186        67294 :           named_path np;
     187        67294 :           np.path.push_back (arg);
     188        67294 :           np.name = m2_path_name;
     189        67294 :           np.lib_root = false;
     190        67294 :           Ipaths.push_back (np);
     191        67294 :         }
     192              :     }
     193       123189 : }
     194              : 
     195              : /* push_back_lib_root pushes a lib_root onto the Ipaths vector.
     196              :    The ordering of the -fm2_add_lib_root=, -I and named paths
     197              :    must be preserved.  */
     198              : 
     199              : static void
     200           24 : push_back_lib_root (const char *arg)
     201              : {
     202           24 :   named_path np;
     203           24 :   np.name = arg;
     204           24 :   np.lib_root = true;
     205           24 :   Ipaths.push_back (np);
     206           24 : }
     207              : 
     208              : /* Return whether strings S1 and S2 are both NULL or both the same
     209              :    string.  */
     210              : 
     211              : static bool
     212       503358 : strings_same (const char *s1, const char *s2)
     213              : {
     214       503358 :   return s1 == s2 || (s1 != NULL && s2 != NULL && strcmp (s1, s2) == 0);
     215              : }
     216              : 
     217              : bool
     218       101049 : options_same (const struct cl_decoded_option *opt1,
     219              :               const struct cl_decoded_option *opt2)
     220              : {
     221       101049 :   return (opt1->opt_index == opt2->opt_index
     222        83893 :           && strings_same (opt1->arg, opt2->arg)
     223        83893 :           && strings_same (opt1->orig_option_with_args_text,
     224        83893 :                            opt2->orig_option_with_args_text)
     225        83893 :           && strings_same (opt1->canonical_option[0],
     226        83893 :                            opt2->canonical_option[0])
     227        83893 :           && strings_same (opt1->canonical_option[1],
     228        83893 :                            opt2->canonical_option[1])
     229        83893 :           && strings_same (opt1->canonical_option[2],
     230        83893 :                            opt2->canonical_option[2])
     231        83893 :           && strings_same (opt1->canonical_option[3],
     232        83893 :                            opt2->canonical_option[3])
     233        83893 :           && (opt1->canonical_option_num_elements
     234        83893 :               == opt2->canonical_option_num_elements)
     235        83893 :           && opt1->value == opt2->value
     236       184942 :           && opt1->errors == opt2->errors);
     237              : }
     238              : 
     239              : /* Append another argument to the list being built.  */
     240              : 
     241              : static void
     242       651644 : append_arg (const struct cl_decoded_option *arg)
     243              : {
     244       651644 :   static unsigned int newargsize;
     245              : 
     246       651644 :   if (gm2_new_decoded_options == gm2_x_decoded_options
     247       103203 :       && gm2_newargc < gm2_xargc
     248       752693 :       && options_same (arg, &gm2_x_decoded_options[gm2_newargc]))
     249              :     {
     250        83893 :       ++gm2_newargc;
     251        83893 :       return;                   /* Nothing new here.  */
     252              :     }
     253              : 
     254       567751 :   if (gm2_new_decoded_options == gm2_x_decoded_options)
     255              :     {                           /* Make new arglist.  */
     256        19310 :       unsigned int i;
     257              : 
     258        19310 :       newargsize = (gm2_xargc << 2) + 20; /* This should handle all.  */
     259        19310 :       gm2_new_decoded_options = XNEWVEC (struct cl_decoded_option, newargsize);
     260              : 
     261              :       /* Copy what has been done so far.  */
     262       103203 :       for (i = 0; i < gm2_newargc; ++i)
     263        83893 :         gm2_new_decoded_options[i] = gm2_x_decoded_options[i];
     264              :     }
     265              : 
     266       567751 :   if (gm2_newargc == newargsize)
     267            0 :     fatal_error (input_location, "overflowed output argument list for %qs",
     268            0 :                  arg->orig_option_with_args_text);
     269              : 
     270       567751 :   gm2_new_decoded_options[gm2_newargc++] = *arg;
     271              : }
     272              : 
     273              : /* Append an option described by OPT_INDEX, ARG and VALUE to the list
     274              :    being built.  */
     275              : 
     276              : static void
     277       333320 : append_option (size_t opt_index, const char *arg, int value)
     278              : {
     279       333320 :   struct cl_decoded_option decoded;
     280              : 
     281       333320 :   generate_option (opt_index, arg, value, CL_DRIVER, &decoded);
     282       333320 :   append_arg (&decoded);
     283       333320 : }
     284              : 
     285              : /* safe_strdup safely duplicates a string.  */
     286              : 
     287              : static char *
     288       218385 : safe_strdup (const char *s)
     289              : {
     290            0 :   if (s != NULL)
     291       123213 :     return xstrdup (s);
     292              :   return NULL;
     293              : }
     294              : 
     295              : /* add_default_libs adds the -l option which is derived from the
     296              :    libraries.  */
     297              : 
     298              : static int
     299         2142 : add_default_libs (const char *libraries)
     300              : {
     301         2142 :   const char *l = libraries;
     302         2142 :   const char *e;
     303         2142 :   char *libname;
     304         2142 :   unsigned int libcount = 0;
     305              : 
     306         8568 :   while ((l != NULL) && (l[0] != (char)0))
     307              :     {
     308         8568 :       e = index (l, ',');
     309         8568 :       if (e == NULL)
     310              :         {
     311         2142 :           libname = xstrdup (l);
     312         2142 :           l = NULL;
     313         2142 :           append_option (OPT_l, safe_strdup (libname), 1);
     314         2142 :           libcount++;
     315         2142 :           free (libname);
     316              :         }
     317              :       else
     318              :         {
     319         6426 :           libname = xstrndup (l, e - l);
     320         6426 :           l = e + 1;
     321         6426 :           append_option (OPT_l, safe_strdup (libname), 1);
     322         6426 :           libcount++;
     323         6426 :           free (libname);
     324              :         }
     325              :     }
     326         2142 :   return libcount;
     327              : }
     328              : 
     329              : /* add_word returns a new string which has the contents of lib
     330              :    appended to list.  If list is NULL then lib is duplicated and
     331              :    returned otherwise the list is appended by "," and the contents of
     332              :    lib.  */
     333              : 
     334              : static const char *
     335        11200 : add_word (const char *list, const char *lib)
     336              : {
     337        11200 :   char *copy;
     338        11200 :   if (list == NULL)
     339         2800 :     return xstrdup (lib);
     340         8400 :   copy = (char *) xmalloc (strlen (list) + strlen (lib) + 1 + 1);
     341         8400 :   strcpy (copy, list);
     342         8400 :   strcat (copy, ",");
     343         8400 :   strcat (copy, lib);
     344         8400 :   return copy;
     345              : }
     346              : 
     347              : /* convert_abbreviation checks abbreviation against known library
     348              :    abbreviations.  If an abbreviation is found it converts the element
     349              :    to the full library name, otherwise the user supplied name is added
     350              :    to the full_libraries list.  A new string is returned.  */
     351              : 
     352              : static const char *
     353        11200 : convert_abbreviation (const char *full_libraries, const char *abbreviation)
     354              : {
     355        67200 :   for (int i = 0; i < maxlib; i++)
     356        56000 :     if (strcmp (abbreviation, library_abbrev[i]) == 0)
     357            0 :       return add_word (full_libraries, library_name[i]);
     358              :   /* Perhaps the user typed in the whole lib name rather than an abbrev.  */
     359        33600 :   for (int i = 0; i < maxlib; i++)
     360        33600 :     if (strcmp (abbreviation, library_name[i]) == 0)
     361        11200 :       return add_word (full_libraries, abbreviation);
     362              :   /* Not found, probably a user typo.  */
     363            0 :   error ("%qs is not a valid Modula-2 system library name or abbreviation",
     364              :          abbreviation);
     365            0 :   return full_libraries;
     366              : }
     367              : 
     368              : /* convert_abbreviations checks each element in the library list to
     369              :    see if an a known library abbreviation was used.  If found it
     370              :    converts the element to the full library name, otherwise the
     371              :    element is copied into the list.  A new string is returned.  */
     372              : 
     373              : static const char *
     374         2800 : convert_abbreviations (const char *libraries)
     375              : {
     376         2800 :   const char *start = libraries;
     377         2800 :   const char *end;
     378         2800 :   const char *full_libraries = NULL;
     379              : 
     380        11200 :   do
     381              :     {
     382        11200 :       end = index (start, ',');
     383        11200 :       if (end == NULL)
     384              :         {
     385         2800 :           full_libraries = convert_abbreviation (full_libraries, start);
     386         2800 :           start = NULL;
     387              :         }
     388              :       else
     389              :         {
     390         8400 :           full_libraries = convert_abbreviation (full_libraries,
     391         8400 :                                                  xstrndup (start, end - start));
     392         8400 :           start = end + 1;
     393              :         }
     394              :     }
     395        11200 :   while ((start != NULL) && (start[0] != (char)0));
     396         2800 :   return full_libraries;
     397              : }
     398              : 
     399              : /* add_m2_I_path appends -fm2-pathname, -fm2-pathnameI and -fm2-add-lib-root
     400              :    options to the command line which are contructed in the saved Ipaths.
     401              :    The order of these options must be maintained.  */
     402              : 
     403              : static void
     404        19310 : add_m2_I_path (void)
     405              : {
     406       105938 :   for (auto np : Ipaths)
     407              :     {
     408        86628 :       if (np.lib_root)
     409           48 :         append_option (OPT_fm2_pathname_rootI_, safe_strdup (np.name), 1);
     410        86604 :       else if (strcmp (np.name, "") == 0)
     411         2176 :         append_option (OPT_fm2_pathname_, safe_strdup ("-"), 1);
     412              :       else
     413        84428 :         append_option (OPT_fm2_pathname_, safe_strdup (np.name), 1);
     414       209817 :       for (auto *s : np.path)
     415       246378 :         append_option (OPT_fm2_pathnameI, safe_strdup (s), 1);
     416        86628 :     }
     417        19310 :   Ipaths.clear();
     418        19310 : }
     419              : 
     420              : 
     421              : void
     422        19310 : lang_specific_driver (struct cl_decoded_option **in_decoded_options,
     423              :                       unsigned int *in_decoded_options_count,
     424              :                       int *in_added_libraries)
     425              : {
     426        19310 :   unsigned int argc = *in_decoded_options_count;
     427        19310 :   struct cl_decoded_option *decoded_options = *in_decoded_options;
     428        19310 :   unsigned int i;
     429              : 
     430              :   /* True if we saw a `-xfoo' language specification on the command
     431              :      line.  This function will add a -xmodula-2 if the user has not
     432              :      already placed one onto the command line.  */
     433        19310 :   bool seen_x_flag = false;
     434        19310 :   const char *language = NULL;
     435              : 
     436              :   /* If nonzero, the user gave us the `-p' or `-pg' flag.  */
     437        19310 :   int saw_profile_flag = 0;
     438              : 
     439              :   /* What action to take for the c++ runtime library:
     440              :     -1  means we should not link it in.
     441              :      0  means we should link it if it is needed.
     442              :      1  means it is needed and should be linked in.
     443              :      2  means it is needed but should be linked statically.  */
     444        19310 :   int library = 0;
     445              : 
     446              :   /* Which c++ runtime library to link.  */
     447        19310 :   stdcxxlib_kind which_library = USE_LIBSTDCXX;
     448              : 
     449        19310 :   const char *dialect = DEFAULT_DIALECT;
     450              : 
     451              :   /* An array used to flag each argument that needs a bit set for
     452              :      LANGSPEC, MATHLIB, or WITHLIBC.  */
     453        19310 :   int *args;
     454              : 
     455              :   /* Have we seen -fmod=?  */
     456        19310 :   char *module_extension = NULL;
     457              : 
     458              :   /* Should the driver perform a link?  */
     459        19310 :   bool linking = true;
     460              : 
     461              :   /* Should the driver link the shared gm2 libs?  */
     462        19310 :   bool shared_libgm2 = true;
     463              : 
     464              :   /* "-lm" or "-lmath" if it appears on the command line.  */
     465        19310 :   const struct cl_decoded_option *saw_math = NULL;
     466              : 
     467              :   /* "-lc" if it appears on the command line.  */
     468        19310 :   const struct cl_decoded_option *saw_libc = NULL;
     469              : 
     470              :   /* By default, we throw on the math library if we have one.  */
     471        19310 :   int need_math = (MATH_LIBRARY[0] != '\0');
     472              : 
     473              :   /* 1 if we should add -lpthread to the command-line.
     474              :      FIXME: the default should be a configuration choice.  */
     475        19310 :   int need_pthread = 1;
     476              : 
     477              :   /* True if we saw -static.  */
     478        19310 :   int static_link = 0;
     479              : 
     480              :   /* True if we should add -shared-libgcc to the command-line.  */
     481        19310 :   int shared_libgcc = 1;
     482              : 
     483              :   /* Have we seen the -v flag?  */
     484        19310 :   bool verbose = false;
     485              : 
     486              :   /* Have we seen the -fm2-pathname flag?  */
     487        19310 :   bool seen_pathname = false;
     488              : 
     489              :   /* The number of libraries added in.  */
     490        19310 :   int added_libraries;
     491              : 
     492              :   /* True if we should add -fplugin=m2rte to the command-line.  */
     493        19310 :   bool need_plugin = false;
     494              : 
     495              :   /* True if we should set up include paths and library paths.  */
     496        19310 :   bool allow_libraries = true;
     497              : 
     498              : #if defined(DEBUG_ARG)
     499              :   printf ("argc = %d\n", argc);
     500              :   fprintf (stderr, "Incoming:");
     501              :   for (i = 0; i < argc; i++)
     502              :     fprintf (stderr, " %s", decoded_options[i].orig_option_with_args_text);
     503              :   fprintf (stderr, "\n");
     504              : #endif
     505              : 
     506              :   // add_spec_function ("m2I", add_m2_I_path);
     507        19310 :   gm2_xargc = argc;
     508        19310 :   gm2_x_decoded_options = decoded_options;
     509        19310 :   gm2_newargc = 0;
     510        19310 :   gm2_new_decoded_options = decoded_options;
     511        19310 :   added_libraries = *in_added_libraries;
     512        19310 :   args = XCNEWVEC (int, argc);
     513              : 
     514              :   /* First pass through arglist.
     515              : 
     516              :      If -nostdlib or a "turn-off-linking" option is anywhere in the
     517              :      command line, don't do any library-option processing (except
     518              :      relating to -x).  */
     519              : 
     520       561896 :   for (i = 1; i < argc; i++)
     521              :     {
     522       542586 :       const char *arg = decoded_options[i].arg;
     523       542586 :       args[i] = 0;
     524              : #if defined(DEBUG_ARG)
     525              :       printf ("1st pass: %s\n",
     526              :               decoded_options[i].orig_option_with_args_text);
     527              : #endif
     528       542586 :       switch (decoded_options[i].opt_index)
     529              :         {
     530              :         case OPT_fiso:
     531       542586 :           dialect = "iso";
     532              :           break;
     533          158 :         case OPT_fpim2:
     534          158 :           dialect = "pim2";
     535          158 :           break;
     536           30 :         case OPT_fpim3:
     537           30 :           dialect = "pim3";
     538           30 :           break;
     539          184 :         case OPT_fpim4:
     540          184 :           dialect = "pim4";
     541          184 :           break;
     542        11563 :         case OPT_fpim:
     543        11563 :           dialect = "pim";
     544        11563 :           break;
     545        19187 :         case OPT_flibs_:
     546        19187 :           libraries = xstrdup (arg);
     547        19187 :           allow_libraries = decoded_options[i].value;
     548        19187 :           args[i] |= SKIPOPT; /* We will add the option if it is needed.  */
     549        19187 :           break;
     550            6 :         case OPT_fmod_:
     551            6 :           module_extension = xstrdup (arg);
     552              : #if defined(DEBUG_ARG)
     553              :           printf ("seen -fmod=%s\n", module_extension);
     554              : #endif
     555            6 :           break;
     556            0 :         case OPT_fpthread:
     557            0 :           need_pthread = decoded_options[i].value;
     558            0 :           args[i] |= SKIPOPT; /* We will add the option if it is needed.  */
     559            0 :           break;
     560          491 :         case OPT_fm2_plugin:
     561          491 :           need_plugin = decoded_options[i].value;
     562              : #ifndef ENABLE_PLUGIN
     563              :           if (need_plugin)
     564              :             error ("plugin support is disabled; configure with "
     565              :                    "%<--enable-plugin%>");
     566              : #endif
     567          491 :           args[i] |= SKIPOPT; /* We will add the option if it is needed.  */
     568          491 :           break;
     569           62 :         case OPT_fscaffold_dynamic:
     570           62 :           seen_scaffold_dynamic = true;
     571           62 :           scaffold_dynamic = decoded_options[i].value;
     572           62 :           args[i] |= SKIPOPT; /* We will add the option if it is needed.  */
     573           62 :           break;
     574           22 :         case OPT_fscaffold_static:
     575           22 :           seen_scaffold_static = true;
     576           22 :           scaffold_static = decoded_options[i].value;
     577           22 :           args[i] |= SKIPOPT; /* We will add the option if it is needed.  */
     578           22 :           break;
     579           84 :         case OPT_fscaffold_main:
     580           84 :           seen_scaffold_main = true;
     581           84 :           scaffold_main = decoded_options[i].value;
     582           84 :           args[i] |= SKIPOPT; /* We will add the option if it is needed.  */
     583           84 :           break;
     584            0 :         case OPT_fgen_module_list_:
     585            0 :           seen_gen_module_list = true;
     586            0 :           gen_module_list = decoded_options[i].value;
     587            0 :           if (gen_module_list)
     588            0 :             gen_module_filename = decoded_options[i].arg;
     589              :           break;
     590            0 :         case OPT_fuse_list_:
     591            0 :           seen_uselist = true;
     592            0 :           uselist = decoded_options[i].value;
     593            0 :           break;
     594       102689 :         case OPT_fm2_pathname_:
     595       102689 :           seen_pathname = true;
     596       102689 :           args[i] |= SKIPOPT; /* We will add the option if it is needed.  */
     597       102689 :           m2_path_name = decoded_options[i].arg;
     598       102689 :           break;
     599           24 :         case OPT_fm2_pathname_root_:
     600           24 :           args[i] |= SKIPOPT; /* We will add the option if it is needed.  */
     601           24 :           push_back_lib_root (decoded_options[i].arg);
     602           24 :           break;
     603            0 :         case OPT__help:
     604            0 :         case OPT__help_:
     605              :           /* Let gcc.cc handle this, as it has a really
     606              :              cool facility for handling --help and --verbose --help.  */
     607            0 :           *in_added_libraries = 0;
     608            0 :           return;
     609       121013 :         case OPT_I:
     610       121013 :           args[i] |= SKIPOPT; /* We will add the option if it is needed.  */
     611       121013 :           push_back_Ipath (decoded_options[i].arg);
     612       121013 :           break;
     613            0 :         case OPT_nostdlib:
     614            0 :         case OPT_nostdlib__:
     615            0 :         case OPT_nodefaultlibs:
     616            0 :           library = -1;
     617            0 :           break;
     618              : 
     619         2678 :         case OPT_l:
     620         2678 :           if (strcmp (arg, MATH_LIBRARY) == 0)
     621              :             {
     622         2678 :               args[i] |= MATHLIB;
     623         2678 :               need_math = 0;
     624              :             }
     625            0 :           else if (strcmp (arg, "c") == 0)
     626            0 :             args[i] |= WITHLIBC;
     627              :           else
     628              :             /* Unrecognized libraries (e.g. -lfoo) may require libstdc++.  */
     629            0 :             library = (library == 0) ? 1 : library;
     630              :           break;
     631              : 
     632            0 :         case OPT_pg:
     633            0 :         case OPT_p:
     634            0 :           saw_profile_flag++;
     635            0 :           break;
     636              : 
     637            0 :         case OPT_x:
     638            0 :           seen_x_flag = true;
     639            0 :           language = arg;
     640            0 :           break;
     641              : 
     642            0 :         case OPT_v:
     643            0 :           verbose = true;
     644            0 :           break;
     645              : 
     646            0 :         case OPT_Xlinker:
     647            0 :         case OPT_Wl_:
     648              :           /* Arguments that go directly to the linker might be .o files,
     649              :              or something, and so might cause libstdc++ to be needed.  */
     650            0 :           if (library == 0)
     651       542586 :             library = 1;
     652              :           break;
     653              : 
     654        12389 :         case OPT_c:
     655        12389 :         case OPT_r:
     656        12389 :         case OPT_S:
     657        12389 :         case OPT_E:
     658        12389 :         case OPT_M:
     659        12389 :         case OPT_MM:
     660        12389 :         case OPT_fsyntax_only:
     661              :           /* Don't specify libraries if we won't link, since that would
     662              :              cause a warning.  */
     663        12389 :           linking = false;
     664        12389 :           library = -1;
     665        12389 :           break;
     666              : 
     667              :         /* PCH makes no sense here, we do not catch -output-pch on purpose,
     668              :            that should flag an error.  */
     669            0 :         case OPT_fpch_deps:
     670            0 :         case OPT_fpch_preprocess:
     671            0 :         case OPT_Winvalid_pch:
     672            0 :           args[i] |= SKIPOPT;
     673            0 :           break;
     674              : 
     675            0 :         case OPT_static:
     676            0 :           static_link = 1;
     677            0 :           break;
     678              : 
     679            0 :         case OPT_static_libgcc:
     680            0 :           shared_libgcc = 0;
     681            0 :           break;
     682              : 
     683            0 :         case OPT_static_libstdc__:
     684            0 :           library = library >= 0 ? 2 : library;
     685              : #ifdef HAVE_LD_STATIC_DYNAMIC
     686              :           /* Remove -static-libstdc++ from the command only if target supports
     687              :              LD_STATIC_DYNAMIC.  When not supported, it is left in so that a
     688              :              back-end target can use outfile substitution.  */
     689            0 :           args[i] |= SKIPOPT;
     690              : #endif
     691            0 :           break;
     692              : 
     693            0 :         case OPT_static_libgm2:
     694            0 :           shared_libgm2 = false;
     695              : #ifdef HAVE_LD_STATIC_DYNAMIC
     696              :           /* Remove -static-libgm2 from the command only if target supports
     697              :              LD_STATIC_DYNAMIC.  When not supported, it is left in so that a
     698              :              back-end target can use outfile substitution.  */
     699            0 :           args[i] |= SKIPOPT;
     700              : #endif
     701            0 :           break;
     702              : 
     703            0 :         case OPT_stdlib_:
     704            0 :           which_library = (stdcxxlib_kind) decoded_options[i].value;
     705            0 :           break;
     706              : 
     707        26515 :         case OPT_SPECIAL_input_file:
     708        26515 :           {
     709        26515 :             const char *source_file = decoded_options[i].orig_option_with_args_text;
     710              : #if defined(DEBUG_ARG)
     711              :             printf ("seen OPT_SPECIAL_input_file: %s\n", source_file);
     712              : #endif
     713        26515 :             if (source_file != NULL)
     714              :               {
     715              :                 /* Record that this is a Modula-2 source file.  */
     716        26515 :                 const char *suffix = strrchr (source_file, '.');
     717              : #if defined(DEBUG_ARG)
     718              :                 printf ("ext = %s\n", suffix);
     719              : #endif
     720        26515 :                 if ((suffix != NULL)
     721        26512 :                     && ((strcmp (suffix, ".mod") == 0)
     722        11464 :                         || ((module_extension != NULL)
     723            6 :                             && (strcmp (suffix, module_extension) == 0))))
     724              :                   {
     725              : #if defined(DEBUG_ARG)
     726              :                     printf ("modula-2 source file detected: %s\n", source_file);
     727              : #endif
     728        15054 :                     args[i] |= M2SOURCE;
     729              :                   }
     730              :               }
     731              :           }
     732              :           break;
     733              : 
     734              :         default:
     735              :           break;
     736              :         }
     737              :     }
     738        19310 :   if (language != NULL && (strcmp (language, "modula-2") != 0))
     739              :     return;
     740              : 
     741        19310 :   if (! seen_pathname)
     742              :     /* Not seen -fm2-pathname therefore make current working directory
     743              :        the first place to look for modules.  */
     744         2176 :     push_back_Ipath (".");
     745              : 
     746              :   /* Override the default when the user specifies it.  */
     747        19310 :   if (seen_scaffold_static && scaffold_static && !seen_scaffold_dynamic)
     748            0 :     scaffold_dynamic = false;
     749              : 
     750              :   /* If both options have been seen and both are true, that means the user
     751              :      tried to set both.  */
     752        19310 :   if (seen_scaffold_dynamic && scaffold_dynamic
     753            0 :      && seen_scaffold_static && scaffold_static)
     754            0 :     error ("%qs and %qs cannot both be enabled",
     755              :            "-fscaffold-dynamic", "-fscaffold-static");
     756              : 
     757        19310 :   if (uselist && gen_module_list)
     758              :     {
     759            0 :       if (! seen_gen_module_list)
     760            0 :         gen_module_list = false;
     761            0 :       if (uselist && gen_module_list)
     762            0 :         error ("%qs and %qs cannot both be enabled",
     763              :                "-fgen-module-list=", "-fuse-list=");
     764              :     }
     765              : 
     766              :   /* There's no point adding -shared-libgcc if we don't have a shared
     767              :      libgcc.  */
     768              : #ifndef ENABLE_SHARED_LIBGCC
     769              :   shared_libgcc = 0;
     770              : #endif
     771              : 
     772              :   /* Second pass through arglist, transforming arguments as appropriate.  */
     773              : 
     774        19310 :   append_arg (&decoded_options[0]); /* Start with command name, of course.  */
     775       581206 :   for (i = 1; i < argc; ++i)
     776              :     {
     777              : #if defined(DEBUG_ARG)
     778              :       printf ("2nd pass: %s",
     779              :               decoded_options[i].orig_option_with_args_text);
     780              :       if ((args[i] & SKIPOPT) != 0)
     781              :         printf (" skipped");
     782              :       if ((args[i] & M2SOURCE) != 0)
     783              :         printf (" m2 source");
     784              :       printf ("\n");
     785              : #endif
     786       542586 :       if ((args[i] & SKIPOPT) == 0)
     787              :         {
     788       299014 :           if ((args[i] & M2SOURCE) == 0)
     789              :             {
     790       283960 :               append_arg (&decoded_options[i]);
     791              :               /* Make sure -lstdc++ is before the math library, since libstdc++
     792              :                  itself uses those math routines.  */
     793       283960 :               if (!saw_math && (args[i] & MATHLIB) && library > 0)
     794              :                 saw_math = &decoded_options[i];
     795              : 
     796       283960 :               if (!saw_libc && (args[i] & WITHLIBC) && library > 0)
     797              :                 saw_libc = &decoded_options[i];
     798              :             }
     799              :           else
     800              :             {
     801        15054 :               if ((! seen_x_flag) && module_extension)
     802              :                 {
     803              : #if defined(DEBUG_ARG)
     804              :                   printf (" adding: -x modula-2 ");
     805              : #endif
     806            6 :                   append_option (OPT_x, "modula-2", 1);
     807              :                 }
     808        15054 :               append_arg (&decoded_options[i]);
     809              : #if defined(DEBUG_ARG)
     810              :               printf (" adding: %s\n",
     811              :                       decoded_options[i].orig_option_with_args_text);
     812              : #endif
     813        15054 :               if ((! seen_x_flag) && module_extension)
     814              :                 {
     815              : #if defined(DEBUG_ARG)
     816              :                   printf (" adding: -x none ");
     817              : #endif
     818            6 :                   append_option (OPT_x, "none", 1);
     819              :                 }
     820              :             }
     821              :         }
     822              : #if defined(DEBUG_ARG)
     823              :       else
     824              :         printf ("skipping: %s\n",
     825              :                 decoded_options[i].orig_option_with_args_text);
     826              : #endif
     827              :     }
     828              : 
     829        19310 :   add_m2_I_path ();
     830              :   /* We now add in extra arguments to facilitate a successful link.
     831              :      Note that the libraries are added to the end of the link here
     832              :      and also placed earlier into the link by lang-specs.h.  Possibly
     833              :      this is needed because the m2pim,m2iso libraries are cross linked
     834              :      (--fixme-- combine all the m2 libraries into a single archive).
     835              : 
     836              :      We also add default scaffold linking options.  */
     837              : 
     838              :   /* If we have not seen either uselist or gen_module_list and we need
     839              :      to link or compile a module list then we turn on -fgen_module_list=-
     840              :      as the default.  */
     841        19310 :   if (!seen_uselist && !seen_gen_module_list
     842        19310 :       && (linking || scaffold_main))
     843         6938 :     append_option (OPT_fgen_module_list_, "-", 1);
     844              : 
     845              :   /* We checked that they were not both enabled above, if there was a set
     846              :      value (even iff that is 'off'), pass that to the FE.  */
     847        19310 :   if (seen_scaffold_dynamic || scaffold_dynamic)
     848        19310 :     append_option (OPT_fscaffold_dynamic, NULL, scaffold_dynamic);
     849        19310 :   if (seen_scaffold_static)
     850           22 :     append_option (OPT_fscaffold_static, NULL, scaffold_static);
     851              : 
     852              :   /* If the user has set fscaffold-main specifically, use that.  Otherwise, if
     853              :      we are linking then set it so that we generate the relevant code for the
     854              :      main module.  */
     855        19310 :   if (seen_scaffold_main)
     856           84 :     append_option (OPT_fscaffold_main, NULL, scaffold_main);
     857        19226 :   else if (linking)
     858         6884 :     append_option (OPT_fscaffold_main, NULL, true);
     859              : 
     860        19310 :   if (allow_libraries)
     861              :     {
     862              :       /* If the libraries have not been specified by the user, select the
     863              :          appropriate libraries for the active dialect.  */
     864         2800 :       if (libraries == NULL)
     865              :         {
     866         2800 :           if (strcmp (dialect, "iso") == 0)
     867          310 :             libraries = xstrdup ("m2iso,m2cor,m2pim,m2log");
     868              :           else
     869              :             /* Default to pim libraries otherwise.  */
     870         2490 :             libraries = xstrdup ("m2cor,m2log,m2pim,m2iso");
     871              :         }
     872         2800 :       libraries = convert_abbreviations (libraries);
     873         2800 :       append_option (OPT_flibs_, xstrdup (libraries), 1);
     874              :     }
     875              :   else
     876        16510 :     append_option (OPT_flibs_, xstrdup ("-"), 0); /* no system libs.  */
     877              : 
     878        19310 :   if (need_plugin)
     879          197 :     append_option (OPT_fplugin_, "m2rte", 1);
     880              : 
     881        19310 :   if (linking)
     882              :     {
     883         6926 :       if (allow_libraries)
     884              :         {
     885              : #ifdef HAVE_LD_STATIC_DYNAMIC
     886         2142 :           if (!shared_libgm2)
     887            0 :             append_option (OPT_Wl_, LD_STATIC_OPTION, 1);
     888              : #endif
     889         2142 :           added_libraries += add_default_libs (libraries);
     890              : #ifdef HAVE_LD_STATIC_DYNAMIC
     891         2142 :           if (!shared_libgm2)
     892            0 :             append_option (OPT_Wl_, LD_DYNAMIC_OPTION, 1);
     893              : #endif
     894              :         }
     895              : 
     896              :       /* Add `-lstdc++' if we haven't already done so.  */
     897              : #ifdef HAVE_LD_STATIC_DYNAMIC
     898         6926 :       if (library > 1 && !static_link)
     899            0 :         append_option (OPT_Wl_, LD_STATIC_OPTION, 1);
     900              : #endif
     901         6926 :       if (which_library == USE_LIBCXX)
     902              :         {
     903            0 :           append_option (OPT_l, saw_profile_flag ? LIBCXX_PROFILE : LIBCXX, 1);
     904            0 :           added_libraries++;
     905            0 :           if (LIBCXXABI != NULL)
     906              :             {
     907            0 :               append_option (OPT_l, saw_profile_flag ? LIBCXXABI_PROFILE
     908              :                              : LIBCXXABI, 1);
     909            0 :               added_libraries++;
     910              :             }
     911              :         }
     912              :       else
     913              :         {
     914         6926 :           append_option (OPT_l, saw_profile_flag ? LIBSTDCXX_PROFILE
     915              :                          : LIBSTDCXX, 1);
     916         6926 :           added_libraries++;
     917              :         }
     918              :       /* Add target-dependent static library, if necessary.  */
     919         6926 :       if ((static_link || library > 1) && LIBSTDCXX_STATIC != NULL)
     920              :         {
     921              :           append_option (OPT_l, LIBSTDCXX_STATIC, 1);
     922              :           added_libraries++;
     923              :         }
     924              : #ifdef HAVE_LD_STATIC_DYNAMIC
     925         6926 :       if (library > 1 && !static_link)
     926            0 :         append_option (OPT_Wl_, LD_DYNAMIC_OPTION, 1);
     927              : #endif
     928              :     }
     929        19310 :   if (need_math)
     930              :     {
     931        16632 :       append_option (OPT_l, saw_profile_flag ? MATH_LIBRARY_PROFILE :
     932              :                      MATH_LIBRARY, 1);
     933        16632 :       added_libraries++;
     934              :     }
     935        19310 :   if (need_pthread)
     936              :     {
     937        19310 :       append_option (OPT_l, "pthread", 1);
     938        19310 :       added_libraries++;
     939              :     }
     940        19310 :   if (shared_libgcc && !static_link)
     941        19310 :     append_option (OPT_shared_libgcc, NULL, 1);
     942              : 
     943        19310 :   if (verbose && gm2_new_decoded_options != gm2_x_decoded_options)
     944              :     {
     945            0 :       fprintf (stderr, _("Driving:"));
     946            0 :       for (i = 0; i < gm2_newargc; i++)
     947            0 :         fprintf (stderr, " %s",
     948            0 :                  gm2_new_decoded_options[i].orig_option_with_args_text);
     949            0 :       fprintf (stderr, "\n");
     950            0 :       fprintf (stderr, "new argc = %d, added_libraries = %d\n",
     951              :                gm2_newargc, added_libraries);
     952              :     }
     953              : 
     954        19310 :   *in_decoded_options_count = gm2_newargc;
     955        19310 :   *in_decoded_options = gm2_new_decoded_options;
     956        19310 :   *in_added_libraries = added_libraries;
     957              : }
     958              : 
     959              : 
     960              : /* Called before linking.  Returns 0 on success and -1 on failure.  */
     961              : int
     962        13276 : lang_specific_pre_link (void)  /* Not used for M2.  */
     963              : {
     964        13276 :   return 0;
     965              : }
     966              : 
     967              : /* Number of extra output files that lang_specific_pre_link may generate.  */
     968              : int lang_specific_extra_outfiles = 0;
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.