LCOV - code coverage report
Current view: top level - gcc/cp - g++spec.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 87.2 % 218 190
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 2 2
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Specific flags and argument handling of the C++ front end.
       2              :    Copyright (C) 1996-2026 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       102879 : lang_specific_driver (struct cl_decoded_option **in_decoded_options,
      84              :                       unsigned int *in_decoded_options_count,
      85              :                       int *in_added_libraries)
      86              : {
      87       102879 :   unsigned int i, j;
      88              : 
      89              :   /* If nonzero, the user gave us the `-p' or `-pg' flag.  */
      90       102879 :   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       102879 :   int library = 0;
      98              : 
      99              :   /* Which c++ runtime library to link.  */
     100       102879 :   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       102879 :   int added = 0;
     106              : 
     107              :   /* The new argument list will be contained in this.  */
     108       102879 :   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       102879 :   int saw_speclang = 0;
     114              : 
     115              :   /* "-lm" or "-lmath" if it appears on the command line.  */
     116       102879 :   const struct cl_decoded_option *saw_math = NULL;
     117              : 
     118              :   /* "-lrt" or eqivalent if it appears on the command line.  */
     119       102879 :   const struct cl_decoded_option *saw_time = NULL;
     120              : 
     121              :   /* "-lc" if it appears on the command line.  */
     122       102879 :   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       102879 :   int *args;
     127              : 
     128              :   /* By default, we throw on the math library if we have one.  */
     129       102879 :   int need_math = (MATH_LIBRARY[0] != '\0');
     130              : 
     131              :   /* By default, we don't add -lstdc++exp.  */
     132       102879 :   bool need_experimental = false;
     133              : 
     134              :   /* Whether to also compile module std.  */
     135       102879 :   bool std_module = false;
     136              : 
     137              :   /* True if we saw -static.  */
     138       102879 :   int static_link = 0;
     139              : 
     140              :   /* True if we should add -shared-libgcc to the command-line.  */
     141       102879 :   int shared_libgcc = 1;
     142              : 
     143              :   /* The total number of arguments with the new stuff.  */
     144       102879 :   unsigned int argc;
     145              : 
     146              :   /* The argument list.  */
     147       102879 :   struct cl_decoded_option *decoded_options;
     148              : 
     149              :   /* The number of libraries added in.  */
     150       102879 :   int added_libraries;
     151              : 
     152              :   /* The total number of arguments with the new stuff.  */
     153       102879 :   unsigned int num_args = 1;
     154              : 
     155       102879 :   argc = *in_decoded_options_count;
     156       102879 :   decoded_options = *in_decoded_options;
     157       102879 :   added_libraries = *in_added_libraries;
     158              : 
     159       102879 :   args = XCNEWVEC (int, argc);
     160              : 
     161      2701223 :   for (i = 1; i < argc; i++)
     162              :     {
     163      2598344 :       const char *arg = decoded_options[i].arg;
     164      2598344 :       if (decoded_options[i].errors & CL_ERR_MISSING_ARG)
     165            0 :         continue; /* Avoid examining arguments of options missing them.  */
     166              : 
     167      2598344 :       switch (decoded_options[i].opt_index)
     168              :         {
     169              :         case OPT_fcontracts:
     170      2598344 :           need_experimental = true;
     171              :           break;
     172              : 
     173            3 :         case OPT_nostdlib__:
     174            3 :           args[i] |= SKIPOPT;
     175              :           /* FALLTHRU */
     176              :         case OPT_nostdlib:
     177              :         case OPT_nodefaultlibs:
     178              :           library = -1;
     179              :           break;
     180              : 
     181        21082 :         case OPT_l:
     182        21082 :           if (strcmp (arg, MATH_LIBRARY) == 0)
     183              :             {
     184        20876 :               args[i] |= MATHLIB;
     185        20876 :               need_math = 0;
     186              :             }
     187          206 :           else if (strcmp (arg, "c") == 0)
     188            0 :             args[i] |= WITHLIBC;
     189              :           else
     190              :             /* Unrecognized libraries (e.g. -lfoo) may require libstdc++.  */
     191          206 :             library = (library == 0) ? 1 : library;
     192              :           break;
     193              : 
     194           91 :         case OPT_pg:
     195           91 :         case OPT_p:
     196           91 :           saw_profile_flag++;
     197           91 :           break;
     198              : 
     199         2917 :         case OPT_x:
     200         2917 :           if (library == 0
     201         2861 :               && (strcmp (arg, "c++") == 0
     202         2861 :                   || strcmp (arg, "c++-cpp-output") == 0
     203         2861 :                   || strcmp (arg, "objective-c++") == 0
     204         2861 :                   || strcmp (arg, "objective-c++-cpp-output") == 0))
     205            0 :             library = 1;
     206              : 
     207              :           saw_speclang = 1;
     208              :           break;
     209              : 
     210         6373 :         case OPT_Xlinker:
     211         6373 :         case OPT_Wl_:
     212              :           /* Arguments that go directly to the linker might be .o files,
     213              :              or something, and so might cause libstdc++ to be needed.  */
     214         6373 :           if (library == 0)
     215      2598344 :             library = 1;
     216              :           break;
     217              : 
     218        78133 :         case OPT_c:
     219        78133 :         case OPT_r:
     220        78133 :         case OPT_S:
     221        78133 :         case OPT_E:
     222        78133 :         case OPT_M:
     223        78133 :         case OPT_MM:
     224        78133 :         case OPT_fsyntax_only:
     225              :           /* Don't specify libraries if we won't link, since that would
     226              :              cause a warning.  */
     227        78133 :           library = -1;
     228        78133 :           break;
     229              : 
     230           27 :         case OPT_static:
     231           27 :           static_link = 1;
     232           27 :           break;
     233              : 
     234            1 :         case OPT_static_libgcc:
     235            1 :           shared_libgcc = 0;
     236            1 :           break;
     237              : 
     238            8 :         case OPT_static_libstdc__:
     239            8 :           library = library >= 0 ? 2 : library;
     240              : #ifdef HAVE_LD_STATIC_DYNAMIC
     241              :           /* Remove -static-libstdc++ from the command only if target supports
     242              :              LD_STATIC_DYNAMIC.  When not supported, it is left in so that a
     243              :              back-end target can use outfile substitution.  */
     244            8 :           args[i] |= SKIPOPT;
     245              : #endif
     246            8 :           break;
     247              : 
     248            0 :         case OPT_stdlib_:
     249            0 :           which_library = (stdcxxlib_kind) decoded_options[i].value;
     250            0 :           break;
     251              : 
     252            1 :         case OPT__compile_std_module:
     253            1 :           std_module = true;
     254            1 :           break;
     255              : 
     256       106647 :         case OPT_SPECIAL_input_file:
     257       106647 :           {
     258       106647 :             int len;
     259              : 
     260              :             /* We don't do this anymore, since we don't get them with minus
     261              :                signs on them.  */
     262       106647 :             if (arg[0] == '\0' || arg[1] == '\0')
     263            0 :               continue;
     264              : 
     265       106647 :             if (saw_speclang)
     266              :               {
     267         2908 :                 saw_speclang = 0;
     268         2908 :                 continue;
     269              :               }
     270              : 
     271              :             /* If the filename ends in .[chi], put options around it.
     272              :                But not if a specified -x option is currently active.  */
     273       103739 :             len = strlen (arg);
     274       103739 :             if (len > 2
     275       103739 :                 && (arg[len - 1] == 'c'
     276        77843 :                     || arg[len - 1] == 'i'
     277        77843 :                     || arg[len - 1] == 'h')
     278        25896 :                 && arg[len - 2] == '.')
     279              :               {
     280        13340 :                 args[i] |= LANGSPEC;
     281        13340 :                 added += 2;
     282              :               }
     283              : 
     284              :             /* If we don't know that this is a header file, we might
     285              :                need to be linking in the libraries.  */
     286       103739 :             if (library == 0)
     287              :               {
     288        85958 :                 if ((len <= 2 || strcmp (arg + (len - 2), ".H") != 0)
     289        85958 :                     && (len <= 2 || strcmp (arg + (len - 2), ".h") != 0)
     290        84984 :                     && (len <= 4 || strcmp (arg + (len - 4), ".hpp") != 0)
     291        84984 :                     && (len <= 3 || strcmp (arg + (len - 3), ".hp") != 0)
     292        84984 :                     && (len <= 4 || strcmp (arg + (len - 4), ".hxx") != 0)
     293        84984 :                     && (len <= 4 || strcmp (arg + (len - 4), ".h++") != 0)
     294        84984 :                     && (len <= 4 || strcmp (arg + (len - 4), ".HPP") != 0)
     295        84984 :                     && (len <= 4 || strcmp (arg + (len - 4), ".tcc") != 0)
     296        84984 :                     && (len <= 3 || strcmp (arg + (len - 3), ".hh") != 0))
     297      2598344 :                   library = 1;
     298              :               }
     299              :           }
     300              :           break;
     301              :         }
     302              :     }
     303              : 
     304              :   /* There's no point adding -shared-libgcc if we don't have a shared
     305              :      libgcc.  */
     306              : #ifndef ENABLE_SHARED_LIBGCC
     307              :   shared_libgcc = 0;
     308              : #endif
     309              : 
     310              :   /* Add one for shared_libgcc or extra static library.  */
     311       205758 :   num_args = (argc + added + need_math + need_experimental
     312       102879 :               + (std_module * 5)
     313       102879 :               + (library > 0) * 4 + 1);
     314              :   /* For libc++, on most platforms, the ABI library (usually called libc++abi)
     315              :      is provided as a separate DSO, which we must also append.
     316              :      However, a platform might have the ability to forward the ABI library
     317              :      from libc++, or combine it in some other way; in that case, LIBCXXABI
     318              :      should be set to NULL to signal that it need not be appended.  */
     319       102879 :   if (which_library == USE_LIBCXX && LIBCXXABI != NULL)
     320            0 :     num_args += 4;
     321       102879 :   new_decoded_options = XNEWVEC (struct cl_decoded_option, num_args);
     322              : 
     323       102879 :   i = 0;
     324       102879 :   j = 0;
     325              : 
     326              :   /* Copy the 0th argument, i.e., the name of the program itself.  */
     327       102879 :   new_decoded_options[j++] = decoded_options[i++];
     328              : 
     329              :   /* NOTE: We start at 1 now, not 0.  */
     330      2701223 :   while (i < argc)
     331              :     {
     332      2598344 :       new_decoded_options[j] = decoded_options[i];
     333              : 
     334              :       /* Make sure -lstdc++ is before the math library, since libstdc++
     335              :          itself uses those math routines.  */
     336      2598344 :       if (!saw_math && (args[i] & MATHLIB) && library > 0)
     337              :         {
     338        20868 :           --j;
     339        20868 :           saw_math = &decoded_options[i];
     340              :         }
     341              : 
     342      2598344 :       if (!saw_libc && (args[i] & WITHLIBC) && library > 0)
     343              :         {
     344            0 :           --j;
     345            0 :           saw_libc = &decoded_options[i];
     346              :         }
     347              : 
     348              :       /* Insert --compile-std-module options before any -x or source files.  */
     349      2598344 :       size_t opt = decoded_options[i].opt_index;
     350      2598344 :       if (std_module
     351            4 :           && (opt == OPT__compile_std_module
     352            4 :               || opt == OPT_SPECIAL_input_file
     353            3 :               || opt == OPT_x))
     354              :         {
     355            1 :           generate_option (OPT_x, "c++-system-header", 1, CL_DRIVER,
     356            1 :                            &new_decoded_options[j++]);
     357            1 :           generate_option_input_file ("bits/stdc++.h",
     358            1 :                                       &new_decoded_options[j]);
     359              :           /* Tell process_command that this file was added by the driver.  */
     360            1 :           new_decoded_options[j++].mask = CL_DRIVER;
     361            1 :           generate_option (OPT_x, "c++-system-module", 1, CL_DRIVER,
     362            1 :                            &new_decoded_options[j++]);
     363            1 :           generate_option_input_file ("bits/std.cc",
     364            1 :                                       &new_decoded_options[j]);
     365            1 :           new_decoded_options[j++].mask = CL_DRIVER;
     366            1 :           generate_option_input_file ("bits/std.compat.cc",
     367            1 :                                       &new_decoded_options[j]);
     368            1 :           new_decoded_options[j++].mask = CL_DRIVER;
     369            1 :           generate_option (OPT_x, "none", 1, CL_DRIVER,
     370            1 :                            &new_decoded_options[j++]);
     371            1 :           new_decoded_options[j] = decoded_options[i];
     372            1 :           std_module = false;
     373              :         }
     374      2598344 :       if (opt == OPT__compile_std_module)
     375            1 :         --j;
     376              : 
     377              :       /* Wrap foo.[chi] files in a language specification to
     378              :          force the gcc compiler driver to run cc1plus on them.  */
     379      2598344 :       if (args[i] & LANGSPEC)
     380              :         {
     381        13340 :           const char *arg = decoded_options[i].arg;
     382        13340 :           int len = strlen (arg);
     383        13340 :           switch (arg[len - 1])
     384              :             {
     385        13340 :             case 'c':
     386        13340 :               generate_option (OPT_x, "c++", 1, CL_DRIVER,
     387        13340 :                                &new_decoded_options[j++]);
     388        13340 :               break;
     389            0 :             case 'i':
     390            0 :               generate_option (OPT_x, "c++-cpp-output", 1, CL_DRIVER,
     391            0 :                                &new_decoded_options[j++]);
     392            0 :               break;
     393            0 :             case 'h':
     394            0 :               generate_option (OPT_x, "c++-header", 1, CL_DRIVER,
     395            0 :                                &new_decoded_options[j++]);
     396            0 :               break;
     397            0 :             default:
     398            0 :               gcc_unreachable ();
     399              :             }
     400        13340 :           new_decoded_options[j++] = decoded_options[i];
     401        13340 :           generate_option (OPT_x, "none", 1, CL_DRIVER,
     402        13340 :                            &new_decoded_options[j]);
     403              :         }
     404              : 
     405      2598344 :       if ((args[i] & SKIPOPT) != 0)
     406           11 :         --j;
     407              : 
     408      2598344 :       i++;
     409      2598344 :       j++;
     410              :     }
     411              : 
     412              :   /* Add `-lstdc++' if we haven't already done so.  */
     413       102879 :   if (library > 0)
     414              :     {
     415        21288 :       if (need_experimental && which_library == USE_LIBSTDCXX)
     416              :         {
     417           51 :           generate_option (OPT_l, "stdc++exp", 1, CL_DRIVER,
     418           51 :                            &new_decoded_options[j++]);
     419           51 :           ++added_libraries;
     420              :         }
     421              : #ifdef HAVE_LD_STATIC_DYNAMIC
     422        21288 :       if (library > 1 && !static_link)
     423              :         {
     424            8 :           generate_option (OPT_Wl_, LD_STATIC_OPTION, 1, CL_DRIVER,
     425            8 :                            &new_decoded_options[j]);
     426            8 :           j++;
     427              :         }
     428              : #endif
     429        21288 :       if (which_library == USE_LIBCXX)
     430              :         {
     431            0 :           generate_option (OPT_l,
     432              :                          saw_profile_flag ? LIBCXX_PROFILE : LIBCXX, 1,
     433            0 :                          CL_DRIVER, &new_decoded_options[j]);
     434            0 :           if (LIBCXXABI != NULL)
     435              :             {
     436            0 :               j++;
     437            0 :               added_libraries++;
     438            0 :               generate_option (OPT_l,
     439              :                                saw_profile_flag ? LIBCXXABI_PROFILE
     440              :                                                 : LIBCXXABI, 1,
     441            0 :                                CL_DRIVER, &new_decoded_options[j]);
     442              :             }
     443              :         }
     444              :       else
     445        21288 :         generate_option (OPT_l,
     446              :                          saw_profile_flag ? LIBSTDCXX_PROFILE : LIBSTDCXX, 1,
     447        21288 :                          CL_DRIVER, &new_decoded_options[j]);
     448        21288 :       added_libraries++;
     449        21288 :       j++;
     450              :       /* Add target-dependent static library, if necessary.  */
     451        21288 :       if ((static_link || library > 1) && LIBSTDCXX_STATIC != NULL)
     452              :         {
     453              :           generate_option (OPT_l, LIBSTDCXX_STATIC, 1,
     454              :                            CL_DRIVER, &new_decoded_options[j]);
     455              :           added_libraries++;
     456              :           j++;
     457              :         }
     458              : #ifdef HAVE_LD_STATIC_DYNAMIC
     459        21288 :       if (library > 1 && !static_link)
     460              :         {
     461            8 :           generate_option (OPT_Wl_, LD_DYNAMIC_OPTION, 1, CL_DRIVER,
     462            8 :                            &new_decoded_options[j]);
     463            8 :           j++;
     464              :         }
     465              : #endif
     466              :     }
     467       102879 :   if (saw_math)
     468        20868 :     new_decoded_options[j++] = *saw_math;
     469        82011 :   else if (library > 0 && need_math)
     470              :     {
     471          420 :       generate_option (OPT_l,
     472              :                        saw_profile_flag ? MATH_LIBRARY_PROFILE : MATH_LIBRARY,
     473          420 :                        1, CL_DRIVER, &new_decoded_options[j]);
     474          420 :       added_libraries++;
     475          420 :       j++;
     476              :     }
     477       102879 :   if (saw_time)
     478              :     new_decoded_options[j++] = *saw_time;
     479       102879 :   if (saw_libc)
     480            0 :     new_decoded_options[j++] = *saw_libc;
     481       102879 :   if (shared_libgcc && !static_link)
     482       102851 :     generate_option (OPT_shared_libgcc, NULL, 1, CL_DRIVER,
     483       102851 :                      &new_decoded_options[j++]);
     484              : 
     485       102879 :   *in_decoded_options_count = j;
     486       102879 :   *in_decoded_options = new_decoded_options;
     487       102879 :   *in_added_libraries = added_libraries;
     488       102879 : }
     489              : 
     490              : /* Called before linking.  Returns 0 on success and -1 on failure.  */
     491        79408 : int lang_specific_pre_link (void)  /* Not used for C++.  */
     492              : {
     493        79408 :   return 0;
     494              : }
     495              : 
     496              : /* Number of extra output files that lang_specific_pre_link may generate.  */
     497              : int lang_specific_extra_outfiles = 0;  /* Not used for C++.  */
        

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.