LCOV - code coverage report
Current view: top level - gcc/cp - g++spec.cc (source / functions) Hit Total Coverage
Test: gcc.info Lines: 160 189 84.7 %
Date: 2023-07-19 08:18:47 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /* Specific flags and argument handling of the C++ front end.
       2             :    Copyright (C) 1996-2023 Free Software Foundation, Inc.
       3             : 
       4             : This file is part of GCC.
       5             : 
       6             : GCC is free software; you can redistribute it and/or modify
       7             : it under the terms of the GNU General Public License as published by
       8             : the Free Software Foundation; either version 3, or (at your option)
       9             : any later version.
      10             : 
      11             : GCC is distributed in the hope that it will be useful,
      12             : but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             : GNU General Public License for more details.
      15             : 
      16             : You should have received a copy of the GNU General Public License
      17             : along with GCC; see the file COPYING3.  If not see
      18             : <http://www.gnu.org/licenses/>.  */
      19             : 
      20             : #include "config.h"
      21             : #include "system.h"
      22             : #include "coretypes.h"
      23             : #include "tm.h"
      24             : #include "opts.h"
      25             : 
      26             : /* This bit is set if we saw a `-xfoo' language specification.  */
      27             : #define LANGSPEC        (1<<1)
      28             : /* This bit is set if they did `-lm' or `-lmath'.  */
      29             : #define MATHLIB         (1<<2)
      30             : /* This bit is set if they did `-lc'.  */
      31             : #define WITHLIBC        (1<<3)
      32             : /* Skip this option.  */
      33             : #define SKIPOPT         (1<<4)
      34             : /* Add -lstdc++exp for experimental features that need library support.  */
      35             : #define EXPERIMENTAL    (1<<5)
      36             : 
      37             : #ifndef MATH_LIBRARY
      38             : #define MATH_LIBRARY "m"
      39             : #endif
      40             : #ifndef MATH_LIBRARY_PROFILE
      41             : #define MATH_LIBRARY_PROFILE MATH_LIBRARY
      42             : #endif
      43             : 
      44             : #ifndef LIBSTDCXX
      45             : #define LIBSTDCXX "stdc++"
      46             : #endif
      47             : #ifndef LIBSTDCXX_PROFILE
      48             : #define LIBSTDCXX_PROFILE LIBSTDCXX
      49             : #endif
      50             : #ifndef LIBSTDCXX_STATIC
      51             : #define LIBSTDCXX_STATIC NULL
      52             : #endif
      53             : 
      54             : #ifndef LIBCXX
      55             : #define LIBCXX "c++"
      56             : #endif
      57             : #ifndef LIBCXX_PROFILE
      58             : #define LIBCXX_PROFILE LIBCXX
      59             : #endif
      60             : #ifndef LIBCXX_STATIC
      61             : #define LIBCXX_STATIC NULL
      62             : #endif
      63             : 
      64             : #ifndef LIBCXXABI
      65             : #define LIBCXXABI "c++abi"
      66             : #endif
      67             : #ifndef LIBCXXABI_PROFILE
      68             : #define LIBCXXABI_PROFILE LIBCXXABI
      69             : #endif
      70             : #ifndef LIBCXXABI_STATIC
      71             : #define LIBCXXABI_STATIC NULL
      72             : #endif
      73             : 
      74             : /* The values used here must match those of the stdlib_kind enumeration
      75             :    in c.opt.  */
      76             : enum stdcxxlib_kind
      77             : {
      78             :   USE_LIBSTDCXX = 1,
      79             :   USE_LIBCXX = 2
      80             : };
      81             : 
      82             : void
      83       90588 : lang_specific_driver (struct cl_decoded_option **in_decoded_options,
      84             :                       unsigned int *in_decoded_options_count,
      85             :                       int *in_added_libraries)
      86             : {
      87       90588 :   unsigned int i, j;
      88             : 
      89             :   /* If nonzero, the user gave us the `-p' or `-pg' flag.  */
      90       90588 :   int saw_profile_flag = 0;
      91             : 
      92             :   /* What action to take for the c++ runtime library:
      93             :     -1  means we should not link it in.
      94             :      0  means we should link it if it is needed.
      95             :      1  means it is needed and should be linked in.
      96             :      2  means it is needed but should be linked statically.  */
      97       90588 :   int library = 0;
      98             : 
      99             :   /* Which c++ runtime library to link.  */
     100       90588 :   stdcxxlib_kind which_library = USE_LIBSTDCXX;
     101             : 
     102             :   /* The number of arguments being added to what's in argv, other than
     103             :      libraries.  We use this to track the number of times we've inserted
     104             :      -xc++/-xnone.  */
     105       90588 :   int added = 0;
     106             : 
     107             :   /* The new argument list will be contained in this.  */
     108       90588 :   struct cl_decoded_option *new_decoded_options;
     109             : 
     110             :   /* Nonzero if we saw a `-xfoo' language specification on the
     111             :      command line.  Used to avoid adding our own -xc++ if the user
     112             :      already gave a language for the file.  */
     113       90588 :   int saw_speclang = 0;
     114             : 
     115             :   /* "-lm" or "-lmath" if it appears on the command line.  */
     116       90588 :   const struct cl_decoded_option *saw_math = NULL;
     117             : 
     118             :   /* "-lrt" or eqivalent if it appears on the command line.  */
     119       90588 :   const struct cl_decoded_option *saw_time = NULL;
     120             : 
     121             :   /* "-lc" if it appears on the command line.  */
     122       90588 :   const struct cl_decoded_option *saw_libc = NULL;
     123             : 
     124             :   /* An array used to flag each argument that needs a bit set for
     125             :      LANGSPEC, MATHLIB, or WITHLIBC.  */
     126       90588 :   int *args;
     127             : 
     128             :   /* By default, we throw on the math library if we have one.  */
     129       90588 :   int need_math = (MATH_LIBRARY[0] != '\0');
     130             : 
     131             :   /* By default, we don't add -lstdc++exp.  */
     132       90588 :   bool need_experimental = false;
     133             : 
     134             :   /* True if we saw -static.  */
     135       90588 :   int static_link = 0;
     136             : 
     137             :   /* True if we should add -shared-libgcc to the command-line.  */
     138       90588 :   int shared_libgcc = 1;
     139             : 
     140             :   /* The total number of arguments with the new stuff.  */
     141       90588 :   unsigned int argc;
     142             : 
     143             :   /* The argument list.  */
     144       90588 :   struct cl_decoded_option *decoded_options;
     145             : 
     146             :   /* The number of libraries added in.  */
     147       90588 :   int added_libraries;
     148             : 
     149             :   /* The total number of arguments with the new stuff.  */
     150       90588 :   unsigned int num_args = 1;
     151             : 
     152       90588 :   argc = *in_decoded_options_count;
     153       90588 :   decoded_options = *in_decoded_options;
     154       90588 :   added_libraries = *in_added_libraries;
     155             : 
     156       90588 :   args = XCNEWVEC (int, argc);
     157             : 
     158     2202952 :   for (i = 1; i < argc; i++)
     159             :     {
     160     2112364 :       const char *arg = decoded_options[i].arg;
     161     2112364 :       if (decoded_options[i].errors & CL_ERR_MISSING_ARG)
     162           0 :         continue; /* Avoid examining arguments of options missing them.  */
     163             : 
     164     2112364 :       switch (decoded_options[i].opt_index)
     165             :         {
     166             :         case OPT_fcontracts:
     167     2112364 :           need_experimental = true;
     168             :           break;
     169             : 
     170           4 :         case OPT_nostdlib__:
     171           4 :           args[i] |= SKIPOPT;
     172             :           /* FALLTHRU */
     173             :         case OPT_nostdlib:
     174             :         case OPT_nodefaultlibs:
     175             :           library = -1;
     176             :           break;
     177             : 
     178       19713 :         case OPT_l:
     179       19713 :           if (strcmp (arg, MATH_LIBRARY) == 0)
     180             :             {
     181       19545 :               args[i] |= MATHLIB;
     182       19545 :               need_math = 0;
     183             :             }
     184         168 :           else if (strcmp (arg, "c") == 0)
     185           0 :             args[i] |= WITHLIBC;
     186             :           else
     187             :             /* Unrecognized libraries (e.g. -lfoo) may require libstdc++.  */
     188         168 :             library = (library == 0) ? 1 : library;
     189             :           break;
     190             : 
     191          67 :         case OPT_pg:
     192          67 :         case OPT_p:
     193          67 :           saw_profile_flag++;
     194          67 :           break;
     195             : 
     196        2312 :         case OPT_x:
     197        2312 :           if (library == 0
     198        2240 :               && (strcmp (arg, "c++") == 0
     199        2240 :                   || strcmp (arg, "c++-cpp-output") == 0
     200        2240 :                   || strcmp (arg, "objective-c++") == 0
     201        2240 :                   || strcmp (arg, "objective-c++-cpp-output") == 0))
     202           0 :             library = 1;
     203             :                 
     204             :           saw_speclang = 1;
     205             :           break;
     206             : 
     207        5120 :         case OPT_Xlinker:
     208        5120 :         case OPT_Wl_:
     209             :           /* Arguments that go directly to the linker might be .o files,
     210             :              or something, and so might cause libstdc++ to be needed.  */
     211        5120 :           if (library == 0)
     212           0 :             library = 1;
     213             :           break;
     214             : 
     215       70629 :         case OPT_c:
     216       70629 :         case OPT_r:
     217       70629 :         case OPT_S:
     218       70629 :         case OPT_E:
     219       70629 :         case OPT_M:
     220       70629 :         case OPT_MM:
     221       70629 :         case OPT_fsyntax_only:
     222             :           /* Don't specify libraries if we won't link, since that would
     223             :              cause a warning.  */
     224       70629 :           library = -1;
     225       70629 :           break;
     226             : 
     227          24 :         case OPT_static:
     228          24 :           static_link = 1;
     229          24 :           break;
     230             : 
     231           1 :         case OPT_static_libgcc:
     232           1 :           shared_libgcc = 0;
     233           1 :           break;
     234             : 
     235           3 :         case OPT_static_libstdc__:
     236           3 :           library = library >= 0 ? 2 : library;
     237             : #ifdef HAVE_LD_STATIC_DYNAMIC
     238             :           /* Remove -static-libstdc++ from the command only if target supports
     239             :              LD_STATIC_DYNAMIC.  When not supported, it is left in so that a
     240             :              back-end target can use outfile substitution.  */
     241           3 :           args[i] |= SKIPOPT;
     242             : #endif
     243           3 :           break;
     244             : 
     245           0 :         case OPT_stdlib_:
     246           0 :           which_library = (stdcxxlib_kind) decoded_options[i].value;
     247           0 :           break;
     248             : 
     249       96645 :         case OPT_SPECIAL_input_file:
     250       96645 :           {
     251       96645 :             int len;
     252             : 
     253             :             /* We don't do this anymore, since we don't get them with minus
     254             :                signs on them.  */
     255       96645 :             if (arg[0] == '\0' || arg[1] == '\0')
     256           0 :               continue;
     257             : 
     258       96645 :             if (saw_speclang)
     259             :               {
     260        2303 :                 saw_speclang = 0;
     261        2303 :                 continue;
     262             :               }
     263             : 
     264             :             /* If the filename ends in .[chi], put options around it.
     265             :                But not if a specified -x option is currently active.  */
     266       94342 :             len = strlen (arg);
     267       94342 :             if (len > 2
     268       94342 :                 && (arg[len - 1] == 'c'
     269       94342 :                     || arg[len - 1] == 'i'
     270       75220 :                     || arg[len - 1] == 'h')
     271       19122 :                 && arg[len - 2] == '.')
     272             :               {
     273        9707 :                 args[i] |= LANGSPEC;
     274        9707 :                 added += 2;
     275             :               }
     276             : 
     277             :             /* If we don't know that this is a header file, we might
     278             :                need to be linking in the libraries.  */
     279       94342 :             if (library == 0)
     280             :               {
     281       77468 :                 if ((len <= 2 || strcmp (arg + (len - 2), ".H") != 0)
     282       77468 :                     && (len <= 2 || strcmp (arg + (len - 2), ".h") != 0)
     283       76771 :                     && (len <= 4 || strcmp (arg + (len - 4), ".hpp") != 0)
     284       76771 :                     && (len <= 3 || strcmp (arg + (len - 3), ".hp") != 0)
     285       76771 :                     && (len <= 4 || strcmp (arg + (len - 4), ".hxx") != 0)
     286       76771 :                     && (len <= 4 || strcmp (arg + (len - 4), ".h++") != 0)
     287       76771 :                     && (len <= 4 || strcmp (arg + (len - 4), ".HPP") != 0)
     288       76771 :                     && (len <= 4 || strcmp (arg + (len - 4), ".tcc") != 0)
     289       76771 :                     && (len <= 3 || strcmp (arg + (len - 3), ".hh") != 0))
     290     2112364 :                   library = 1;
     291             :               }
     292             :           }
     293             :           break;
     294             :         }
     295             :     }
     296             : 
     297             :   /* There's no point adding -shared-libgcc if we don't have a shared
     298             :      libgcc.  */
     299             : #ifndef ENABLE_SHARED_LIBGCC
     300             :   shared_libgcc = 0;
     301             : #endif
     302             : 
     303             :   /* Add one for shared_libgcc or extra static library.  */
     304      181176 :   num_args = (argc + added + need_math + need_experimental
     305       90588 :               + (library > 0) * 4 + 1);
     306             :   /* For libc++, on most platforms, the ABI library (usually called libc++abi)
     307             :      is provided as a separate DSO, which we must also append.
     308             :      However, a platform might have the ability to forward the ABI library
     309             :      from libc++, or combine it in some other way; in that case, LIBCXXABI
     310             :      should be set to NULL to signal that it need not be appended.  */
     311       90588 :   if (which_library == USE_LIBCXX && LIBCXXABI != NULL)
     312           0 :     num_args += 4;
     313       90588 :   new_decoded_options = XNEWVEC (struct cl_decoded_option, num_args);
     314             : 
     315       90588 :   i = 0;
     316       90588 :   j = 0;
     317             : 
     318             :   /* Copy the 0th argument, i.e., the name of the program itself.  */
     319       90588 :   new_decoded_options[j++] = decoded_options[i++];
     320             : 
     321             :   /* NOTE: We start at 1 now, not 0.  */
     322     2202952 :   while (i < argc)
     323             :     {
     324     2112364 :       new_decoded_options[j] = decoded_options[i];
     325             : 
     326             :       /* Make sure -lstdc++ is before the math library, since libstdc++
     327             :          itself uses those math routines.  */
     328     2112364 :       if (!saw_math && (args[i] & MATHLIB) && library > 0)
     329             :         {
     330       19536 :           --j;
     331       19536 :           saw_math = &decoded_options[i];
     332             :         }
     333             : 
     334     2112364 :       if (!saw_libc && (args[i] & WITHLIBC) && library > 0)
     335             :         {
     336           0 :           --j;
     337           0 :           saw_libc = &decoded_options[i];
     338             :         }
     339             : 
     340             :       /* Wrap foo.[chi] files in a language specification to
     341             :          force the gcc compiler driver to run cc1plus on them.  */
     342     2112364 :       if (args[i] & LANGSPEC)
     343             :         {
     344        9707 :           const char *arg = decoded_options[i].arg;
     345        9707 :           int len = strlen (arg);
     346        9707 :           switch (arg[len - 1])
     347             :             {
     348        9707 :             case 'c':
     349        9707 :               generate_option (OPT_x, "c++", 1, CL_DRIVER,
     350        9707 :                                &new_decoded_options[j++]);
     351        9707 :               break;
     352           0 :             case 'i':
     353           0 :               generate_option (OPT_x, "c++-cpp-output", 1, CL_DRIVER,
     354           0 :                                &new_decoded_options[j++]);
     355           0 :               break;
     356           0 :             case 'h':
     357           0 :               generate_option (OPT_x, "c++-header", 1, CL_DRIVER,
     358           0 :                                &new_decoded_options[j++]);
     359           0 :               break;
     360           0 :             default:
     361           0 :               gcc_unreachable ();
     362             :             }
     363        9707 :           new_decoded_options[j++] = decoded_options[i];
     364        9707 :           generate_option (OPT_x, "none", 1, CL_DRIVER,
     365        9707 :                            &new_decoded_options[j]);
     366             :         }
     367             : 
     368     2112364 :       if ((args[i] & SKIPOPT) != 0)
     369           7 :         --j;
     370             : 
     371     2112364 :       i++;
     372     2112364 :       j++;
     373             :     }
     374             : 
     375             :   /* Add `-lstdc++' if we haven't already done so.  */
     376       90588 :   if (library > 0)
     377             :     {
     378       19897 :       if (need_experimental && which_library == USE_LIBSTDCXX)
     379             :         {
     380          61 :           generate_option (OPT_l, "stdc++exp", 1, CL_DRIVER,
     381          61 :                            &new_decoded_options[j++]);
     382          61 :           ++added_libraries;
     383             :         }
     384             : #ifdef HAVE_LD_STATIC_DYNAMIC
     385       19897 :       if (library > 1 && !static_link)
     386             :         {
     387           3 :           generate_option (OPT_Wl_, LD_STATIC_OPTION, 1, CL_DRIVER,
     388           3 :                            &new_decoded_options[j]);
     389           3 :           j++;
     390             :         }
     391             : #endif
     392       19897 :       if (which_library == USE_LIBCXX)
     393             :         {
     394           0 :           generate_option (OPT_l,
     395             :                          saw_profile_flag ? LIBCXX_PROFILE : LIBCXX, 1,
     396           0 :                          CL_DRIVER, &new_decoded_options[j]);
     397           0 :           if (LIBCXXABI != NULL)
     398             :             {
     399           0 :               j++;
     400           0 :               added_libraries++;
     401           0 :               generate_option (OPT_l,
     402             :                                saw_profile_flag ? LIBCXXABI_PROFILE
     403             :                                                 : LIBCXXABI, 1,
     404           0 :                                CL_DRIVER, &new_decoded_options[j]);
     405             :             }
     406             :         }
     407             :       else
     408       19897 :         generate_option (OPT_l,
     409             :                          saw_profile_flag ? LIBSTDCXX_PROFILE : LIBSTDCXX, 1,
     410       19897 :                          CL_DRIVER, &new_decoded_options[j]);
     411       19897 :       added_libraries++;
     412       19897 :       j++;
     413             :       /* Add target-dependent static library, if necessary.  */
     414       19897 :       if ((static_link || library > 1) && LIBSTDCXX_STATIC != NULL)
     415             :         {
     416             :           generate_option (OPT_l, LIBSTDCXX_STATIC, 1,
     417             :                            CL_DRIVER, &new_decoded_options[j]);
     418             :           added_libraries++;
     419             :           j++;
     420             :         }
     421             : #ifdef HAVE_LD_STATIC_DYNAMIC
     422       19897 :       if (library > 1 && !static_link)
     423             :         {
     424           3 :           generate_option (OPT_Wl_, LD_DYNAMIC_OPTION, 1, CL_DRIVER,
     425           3 :                            &new_decoded_options[j]);
     426           3 :           j++;
     427             :         }
     428             : #endif
     429             :     }
     430       90588 :   if (saw_math)
     431       19536 :     new_decoded_options[j++] = *saw_math;
     432       71052 :   else if (library > 0 && need_math)
     433             :     {
     434         361 :       generate_option (OPT_l,
     435             :                        saw_profile_flag ? MATH_LIBRARY_PROFILE : MATH_LIBRARY,
     436         361 :                        1, CL_DRIVER, &new_decoded_options[j]);
     437         361 :       added_libraries++;
     438         361 :       j++;
     439             :     }
     440       90588 :   if (saw_time)
     441             :     new_decoded_options[j++] = *saw_time;
     442       90588 :   if (saw_libc)
     443           0 :     new_decoded_options[j++] = *saw_libc;
     444       90588 :   if (shared_libgcc && !static_link)
     445       90563 :     generate_option (OPT_shared_libgcc, NULL, 1, CL_DRIVER,
     446       90563 :                      &new_decoded_options[j++]);
     447             : 
     448       90588 :   *in_decoded_options_count = j;
     449       90588 :   *in_decoded_options = new_decoded_options;
     450       90588 :   *in_added_libraries = added_libraries;
     451       90588 : }
     452             : 
     453             : /* Called before linking.  Returns 0 on success and -1 on failure.  */
     454       71516 : int lang_specific_pre_link (void)  /* Not used for C++.  */
     455             : {
     456       71516 :   return 0;
     457             : }
     458             : 
     459             : /* Number of extra output files that lang_specific_pre_link may generate.  */
     460             : int lang_specific_extra_outfiles = 0;  /* Not used for C++.  */

Generated by: LCOV version 1.16