11debfc3dSmrg /* Specific flags and argument handling of the C++ front end.
2*8feb0f0bSmrg Copyright (C) 1996-2020 Free Software Foundation, Inc.
31debfc3dSmrg
41debfc3dSmrg This file is part of GCC.
51debfc3dSmrg
61debfc3dSmrg GCC is free software; you can redistribute it and/or modify
71debfc3dSmrg it under the terms of the GNU General Public License as published by
81debfc3dSmrg the Free Software Foundation; either version 3, or (at your option)
91debfc3dSmrg any later version.
101debfc3dSmrg
111debfc3dSmrg GCC is distributed in the hope that it will be useful,
121debfc3dSmrg but WITHOUT ANY WARRANTY; without even the implied warranty of
131debfc3dSmrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
141debfc3dSmrg GNU General Public License for more details.
151debfc3dSmrg
161debfc3dSmrg You should have received a copy of the GNU General Public License
171debfc3dSmrg along with GCC; see the file COPYING3. If not see
181debfc3dSmrg <http://www.gnu.org/licenses/>. */
191debfc3dSmrg
201debfc3dSmrg #include "config.h"
211debfc3dSmrg #include "system.h"
221debfc3dSmrg #include "coretypes.h"
231debfc3dSmrg #include "tm.h"
241debfc3dSmrg #include "opts.h"
251debfc3dSmrg
261debfc3dSmrg /* This bit is set if we saw a `-xfoo' language specification. */
271debfc3dSmrg #define LANGSPEC (1<<1)
281debfc3dSmrg /* This bit is set if they did `-lm' or `-lmath'. */
291debfc3dSmrg #define MATHLIB (1<<2)
301debfc3dSmrg /* This bit is set if they did `-lrt' or equivalent. */
311debfc3dSmrg #define TIMELIB (1<<3)
321debfc3dSmrg /* This bit is set if they did `-lc'. */
331debfc3dSmrg #define WITHLIBC (1<<4)
341debfc3dSmrg /* Skip this option. */
351debfc3dSmrg #define SKIPOPT (1<<5)
361debfc3dSmrg
371debfc3dSmrg #ifndef MATH_LIBRARY
381debfc3dSmrg #define MATH_LIBRARY "m"
391debfc3dSmrg #endif
401debfc3dSmrg #ifndef MATH_LIBRARY_PROFILE
411debfc3dSmrg #define MATH_LIBRARY_PROFILE MATH_LIBRARY
421debfc3dSmrg #endif
431debfc3dSmrg
441debfc3dSmrg #ifndef TIME_LIBRARY
451debfc3dSmrg #define TIME_LIBRARY ""
461debfc3dSmrg #endif
471debfc3dSmrg
481debfc3dSmrg #ifndef LIBSTDCXX
491debfc3dSmrg #define LIBSTDCXX "stdc++"
501debfc3dSmrg #endif
511debfc3dSmrg #ifndef LIBSTDCXX_PROFILE
521debfc3dSmrg #define LIBSTDCXX_PROFILE LIBSTDCXX
531debfc3dSmrg #endif
541debfc3dSmrg #ifndef LIBSTDCXX_STATIC
551debfc3dSmrg #define LIBSTDCXX_STATIC NULL
561debfc3dSmrg #endif
571debfc3dSmrg
581debfc3dSmrg void
lang_specific_driver(struct cl_decoded_option ** in_decoded_options,unsigned int * in_decoded_options_count,int * in_added_libraries)591debfc3dSmrg lang_specific_driver (struct cl_decoded_option **in_decoded_options,
601debfc3dSmrg unsigned int *in_decoded_options_count,
611debfc3dSmrg int *in_added_libraries)
621debfc3dSmrg {
631debfc3dSmrg unsigned int i, j;
641debfc3dSmrg
651debfc3dSmrg /* If nonzero, the user gave us the `-p' or `-pg' flag. */
661debfc3dSmrg int saw_profile_flag = 0;
671debfc3dSmrg
681debfc3dSmrg /* What do with libstdc++:
691debfc3dSmrg -1 means we should not link in libstdc++
701debfc3dSmrg 0 means we should link in libstdc++ if it is needed
711debfc3dSmrg 1 means libstdc++ is needed and should be linked in.
721debfc3dSmrg 2 means libstdc++ is needed and should be linked statically. */
731debfc3dSmrg int library = 0;
741debfc3dSmrg
751debfc3dSmrg /* The number of arguments being added to what's in argv, other than
761debfc3dSmrg libraries. We use this to track the number of times we've inserted
771debfc3dSmrg -xc++/-xnone. */
781debfc3dSmrg int added = 0;
791debfc3dSmrg
801debfc3dSmrg /* The new argument list will be contained in this. */
811debfc3dSmrg struct cl_decoded_option *new_decoded_options;
821debfc3dSmrg
831debfc3dSmrg /* Nonzero if we saw a `-xfoo' language specification on the
841debfc3dSmrg command line. Used to avoid adding our own -xc++ if the user
851debfc3dSmrg already gave a language for the file. */
861debfc3dSmrg int saw_speclang = 0;
871debfc3dSmrg
881debfc3dSmrg /* "-lm" or "-lmath" if it appears on the command line. */
891debfc3dSmrg const struct cl_decoded_option *saw_math = NULL;
901debfc3dSmrg
911debfc3dSmrg /* "-lrt" or eqivalent if it appears on the command line. */
921debfc3dSmrg const struct cl_decoded_option *saw_time = NULL;
931debfc3dSmrg
941debfc3dSmrg /* "-lc" if it appears on the command line. */
951debfc3dSmrg const struct cl_decoded_option *saw_libc = NULL;
961debfc3dSmrg
971debfc3dSmrg /* An array used to flag each argument that needs a bit set for
981debfc3dSmrg LANGSPEC, MATHLIB, TIMELIB, or WITHLIBC. */
991debfc3dSmrg int *args;
1001debfc3dSmrg
1011debfc3dSmrg /* By default, we throw on the math library if we have one. */
1021debfc3dSmrg int need_math = (MATH_LIBRARY[0] != '\0');
1031debfc3dSmrg
1041debfc3dSmrg /* By default, we throw on the time library if we have one. */
1051debfc3dSmrg int need_time = (TIME_LIBRARY[0] != '\0');
1061debfc3dSmrg
1071debfc3dSmrg /* True if we saw -static. */
1081debfc3dSmrg int static_link = 0;
1091debfc3dSmrg
1101debfc3dSmrg /* True if we should add -shared-libgcc to the command-line. */
1111debfc3dSmrg int shared_libgcc = 1;
1121debfc3dSmrg
1131debfc3dSmrg /* The total number of arguments with the new stuff. */
1141debfc3dSmrg unsigned int argc;
1151debfc3dSmrg
1161debfc3dSmrg /* The argument list. */
1171debfc3dSmrg struct cl_decoded_option *decoded_options;
1181debfc3dSmrg
1191debfc3dSmrg /* The number of libraries added in. */
1201debfc3dSmrg int added_libraries;
1211debfc3dSmrg
1221debfc3dSmrg /* The total number of arguments with the new stuff. */
1231debfc3dSmrg unsigned int num_args = 1;
1241debfc3dSmrg
1251debfc3dSmrg argc = *in_decoded_options_count;
1261debfc3dSmrg decoded_options = *in_decoded_options;
1271debfc3dSmrg added_libraries = *in_added_libraries;
1281debfc3dSmrg
1291debfc3dSmrg args = XCNEWVEC (int, argc);
1301debfc3dSmrg
1311debfc3dSmrg for (i = 1; i < argc; i++)
1321debfc3dSmrg {
1331debfc3dSmrg const char *arg = decoded_options[i].arg;
1341debfc3dSmrg if (decoded_options[i].errors & CL_ERR_MISSING_ARG)
1351debfc3dSmrg continue; /* Avoid examining arguments of options missing them. */
1361debfc3dSmrg
1371debfc3dSmrg switch (decoded_options[i].opt_index)
1381debfc3dSmrg {
1391debfc3dSmrg case OPT_nostdlib:
1401debfc3dSmrg case OPT_nodefaultlibs:
1411debfc3dSmrg library = -1;
1421debfc3dSmrg break;
1431debfc3dSmrg
1441debfc3dSmrg case OPT_l:
1451debfc3dSmrg if (strcmp (arg, MATH_LIBRARY) == 0)
1461debfc3dSmrg {
1471debfc3dSmrg args[i] |= MATHLIB;
1481debfc3dSmrg need_math = 0;
1491debfc3dSmrg }
1501debfc3dSmrg else if (strcmp (arg, TIME_LIBRARY) == 0)
1511debfc3dSmrg {
1521debfc3dSmrg args[i] |= TIMELIB;
1531debfc3dSmrg need_time = 0;
1541debfc3dSmrg }
1551debfc3dSmrg else if (strcmp (arg, "c") == 0)
1561debfc3dSmrg args[i] |= WITHLIBC;
1571debfc3dSmrg else
1581debfc3dSmrg /* Unrecognized libraries (e.g. -lfoo) may require libstdc++. */
1591debfc3dSmrg library = (library == 0) ? 1 : library;
1601debfc3dSmrg break;
1611debfc3dSmrg
1621debfc3dSmrg case OPT_pg:
1631debfc3dSmrg case OPT_p:
1641debfc3dSmrg saw_profile_flag++;
1651debfc3dSmrg break;
1661debfc3dSmrg
1671debfc3dSmrg case OPT_x:
1681debfc3dSmrg if (library == 0
1691debfc3dSmrg && (strcmp (arg, "c++") == 0
1701debfc3dSmrg || strcmp (arg, "c++-cpp-output") == 0
1711debfc3dSmrg || strcmp (arg, "objective-c++") == 0
1721debfc3dSmrg || strcmp (arg, "objective-c++-cpp-output") == 0))
1731debfc3dSmrg library = 1;
1741debfc3dSmrg
1751debfc3dSmrg saw_speclang = 1;
1761debfc3dSmrg break;
1771debfc3dSmrg
1781debfc3dSmrg case OPT_Xlinker:
1791debfc3dSmrg case OPT_Wl_:
1801debfc3dSmrg /* Arguments that go directly to the linker might be .o files,
1811debfc3dSmrg or something, and so might cause libstdc++ to be needed. */
1821debfc3dSmrg if (library == 0)
1831debfc3dSmrg library = 1;
1841debfc3dSmrg break;
1851debfc3dSmrg
1861debfc3dSmrg case OPT_c:
187c0a68be4Smrg case OPT_r:
1881debfc3dSmrg case OPT_S:
1891debfc3dSmrg case OPT_E:
1901debfc3dSmrg case OPT_M:
1911debfc3dSmrg case OPT_MM:
1921debfc3dSmrg case OPT_fsyntax_only:
1931debfc3dSmrg /* Don't specify libraries if we won't link, since that would
1941debfc3dSmrg cause a warning. */
1951debfc3dSmrg library = -1;
1961debfc3dSmrg break;
1971debfc3dSmrg
1981debfc3dSmrg case OPT_static:
1991debfc3dSmrg static_link = 1;
2001debfc3dSmrg break;
2011debfc3dSmrg
2021debfc3dSmrg case OPT_static_libgcc:
2031debfc3dSmrg shared_libgcc = 0;
2041debfc3dSmrg break;
2051debfc3dSmrg
2061debfc3dSmrg case OPT_static_libstdc__:
2071debfc3dSmrg library = library >= 0 ? 2 : library;
2081debfc3dSmrg args[i] |= SKIPOPT;
2091debfc3dSmrg break;
2101debfc3dSmrg
2111debfc3dSmrg case OPT_SPECIAL_input_file:
2121debfc3dSmrg {
2131debfc3dSmrg int len;
2141debfc3dSmrg
2151debfc3dSmrg /* We don't do this anymore, since we don't get them with minus
2161debfc3dSmrg signs on them. */
2171debfc3dSmrg if (arg[0] == '\0' || arg[1] == '\0')
2181debfc3dSmrg continue;
2191debfc3dSmrg
2201debfc3dSmrg if (saw_speclang)
2211debfc3dSmrg {
2221debfc3dSmrg saw_speclang = 0;
2231debfc3dSmrg continue;
2241debfc3dSmrg }
2251debfc3dSmrg
2261debfc3dSmrg /* If the filename ends in .[chi], put options around it.
2271debfc3dSmrg But not if a specified -x option is currently active. */
2281debfc3dSmrg len = strlen (arg);
2291debfc3dSmrg if (len > 2
2301debfc3dSmrg && (arg[len - 1] == 'c'
2311debfc3dSmrg || arg[len - 1] == 'i'
2321debfc3dSmrg || arg[len - 1] == 'h')
2331debfc3dSmrg && arg[len - 2] == '.')
2341debfc3dSmrg {
2351debfc3dSmrg args[i] |= LANGSPEC;
2361debfc3dSmrg added += 2;
2371debfc3dSmrg }
2381debfc3dSmrg
2391debfc3dSmrg /* If we don't know that this is a header file, we might
2401debfc3dSmrg need to be linking in the libraries. */
2411debfc3dSmrg if (library == 0)
2421debfc3dSmrg {
2431debfc3dSmrg if ((len <= 2 || strcmp (arg + (len - 2), ".H") != 0)
2441debfc3dSmrg && (len <= 2 || strcmp (arg + (len - 2), ".h") != 0)
2451debfc3dSmrg && (len <= 4 || strcmp (arg + (len - 4), ".hpp") != 0)
2461debfc3dSmrg && (len <= 3 || strcmp (arg + (len - 3), ".hp") != 0)
2471debfc3dSmrg && (len <= 4 || strcmp (arg + (len - 4), ".hxx") != 0)
2481debfc3dSmrg && (len <= 4 || strcmp (arg + (len - 4), ".h++") != 0)
2491debfc3dSmrg && (len <= 4 || strcmp (arg + (len - 4), ".HPP") != 0)
2501debfc3dSmrg && (len <= 4 || strcmp (arg + (len - 4), ".tcc") != 0)
2511debfc3dSmrg && (len <= 3 || strcmp (arg + (len - 3), ".hh") != 0))
2521debfc3dSmrg library = 1;
2531debfc3dSmrg }
2541debfc3dSmrg }
2551debfc3dSmrg break;
2561debfc3dSmrg }
2571debfc3dSmrg }
2581debfc3dSmrg
2591debfc3dSmrg /* There's no point adding -shared-libgcc if we don't have a shared
2601debfc3dSmrg libgcc. */
2611debfc3dSmrg #ifndef ENABLE_SHARED_LIBGCC
2621debfc3dSmrg shared_libgcc = 0;
2631debfc3dSmrg #endif
2641debfc3dSmrg
2651debfc3dSmrg /* Add one for shared_libgcc or extra static library. */
2661debfc3dSmrg num_args = argc + added + need_math + (library > 0) * 4 + 1;
2671debfc3dSmrg new_decoded_options = XNEWVEC (struct cl_decoded_option, num_args);
2681debfc3dSmrg
2691debfc3dSmrg i = 0;
2701debfc3dSmrg j = 0;
2711debfc3dSmrg
2721debfc3dSmrg /* Copy the 0th argument, i.e., the name of the program itself. */
2731debfc3dSmrg new_decoded_options[j++] = decoded_options[i++];
2741debfc3dSmrg
2751debfc3dSmrg /* NOTE: We start at 1 now, not 0. */
2761debfc3dSmrg while (i < argc)
2771debfc3dSmrg {
2781debfc3dSmrg new_decoded_options[j] = decoded_options[i];
2791debfc3dSmrg
2801debfc3dSmrg /* Make sure -lstdc++ is before the math library, since libstdc++
2811debfc3dSmrg itself uses those math routines. */
2821debfc3dSmrg if (!saw_math && (args[i] & MATHLIB) && library > 0)
2831debfc3dSmrg {
2841debfc3dSmrg --j;
2851debfc3dSmrg saw_math = &decoded_options[i];
2861debfc3dSmrg }
2871debfc3dSmrg
2881debfc3dSmrg if (!saw_time && (args[i] & TIMELIB) && library > 0)
2891debfc3dSmrg {
2901debfc3dSmrg --j;
2911debfc3dSmrg saw_time = &decoded_options[i];
2921debfc3dSmrg }
2931debfc3dSmrg
2941debfc3dSmrg if (!saw_libc && (args[i] & WITHLIBC) && library > 0)
2951debfc3dSmrg {
2961debfc3dSmrg --j;
2971debfc3dSmrg saw_libc = &decoded_options[i];
2981debfc3dSmrg }
2991debfc3dSmrg
3001debfc3dSmrg /* Wrap foo.[chi] files in a language specification to
3011debfc3dSmrg force the gcc compiler driver to run cc1plus on them. */
3021debfc3dSmrg if (args[i] & LANGSPEC)
3031debfc3dSmrg {
3041debfc3dSmrg const char *arg = decoded_options[i].arg;
3051debfc3dSmrg int len = strlen (arg);
3061debfc3dSmrg switch (arg[len - 1])
3071debfc3dSmrg {
3081debfc3dSmrg case 'c':
3091debfc3dSmrg generate_option (OPT_x, "c++", 1, CL_DRIVER,
3101debfc3dSmrg &new_decoded_options[j++]);
3111debfc3dSmrg break;
3121debfc3dSmrg case 'i':
3131debfc3dSmrg generate_option (OPT_x, "c++-cpp-output", 1, CL_DRIVER,
3141debfc3dSmrg &new_decoded_options[j++]);
3151debfc3dSmrg break;
3161debfc3dSmrg case 'h':
3171debfc3dSmrg generate_option (OPT_x, "c++-header", 1, CL_DRIVER,
3181debfc3dSmrg &new_decoded_options[j++]);
3191debfc3dSmrg break;
3201debfc3dSmrg default:
3211debfc3dSmrg gcc_unreachable ();
3221debfc3dSmrg }
3231debfc3dSmrg new_decoded_options[j++] = decoded_options[i];
3241debfc3dSmrg generate_option (OPT_x, "none", 1, CL_DRIVER,
3251debfc3dSmrg &new_decoded_options[j]);
3261debfc3dSmrg }
3271debfc3dSmrg
3281debfc3dSmrg if ((args[i] & SKIPOPT) != 0)
3291debfc3dSmrg --j;
3301debfc3dSmrg
3311debfc3dSmrg i++;
3321debfc3dSmrg j++;
3331debfc3dSmrg }
3341debfc3dSmrg
3351debfc3dSmrg /* Add `-lstdc++' if we haven't already done so. */
3361debfc3dSmrg if (library > 0)
3371debfc3dSmrg {
3381debfc3dSmrg #ifdef HAVE_LD_STATIC_DYNAMIC
3391debfc3dSmrg if (library > 1 && !static_link)
3401debfc3dSmrg {
3411debfc3dSmrg generate_option (OPT_Wl_, LD_STATIC_OPTION, 1, CL_DRIVER,
3421debfc3dSmrg &new_decoded_options[j]);
3431debfc3dSmrg j++;
3441debfc3dSmrg }
3451debfc3dSmrg #endif
3461debfc3dSmrg generate_option (OPT_l,
3471debfc3dSmrg saw_profile_flag ? LIBSTDCXX_PROFILE : LIBSTDCXX, 1,
3481debfc3dSmrg CL_DRIVER, &new_decoded_options[j]);
3491debfc3dSmrg added_libraries++;
3501debfc3dSmrg j++;
3511debfc3dSmrg /* Add target-dependent static library, if necessary. */
3521debfc3dSmrg if ((static_link || library > 1) && LIBSTDCXX_STATIC != NULL)
3531debfc3dSmrg {
3541debfc3dSmrg generate_option (OPT_l, LIBSTDCXX_STATIC, 1,
3551debfc3dSmrg CL_DRIVER, &new_decoded_options[j]);
3561debfc3dSmrg added_libraries++;
3571debfc3dSmrg j++;
3581debfc3dSmrg }
3591debfc3dSmrg #ifdef HAVE_LD_STATIC_DYNAMIC
3601debfc3dSmrg if (library > 1 && !static_link)
3611debfc3dSmrg {
3621debfc3dSmrg generate_option (OPT_Wl_, LD_DYNAMIC_OPTION, 1, CL_DRIVER,
3631debfc3dSmrg &new_decoded_options[j]);
3641debfc3dSmrg j++;
3651debfc3dSmrg }
3661debfc3dSmrg #endif
3671debfc3dSmrg }
3681debfc3dSmrg if (saw_math)
3691debfc3dSmrg new_decoded_options[j++] = *saw_math;
3701debfc3dSmrg else if (library > 0 && need_math)
3711debfc3dSmrg {
3721debfc3dSmrg generate_option (OPT_l,
3731debfc3dSmrg saw_profile_flag ? MATH_LIBRARY_PROFILE : MATH_LIBRARY,
3741debfc3dSmrg 1, CL_DRIVER, &new_decoded_options[j]);
3751debfc3dSmrg added_libraries++;
3761debfc3dSmrg j++;
3771debfc3dSmrg }
3781debfc3dSmrg if (saw_time)
3791debfc3dSmrg new_decoded_options[j++] = *saw_time;
3801debfc3dSmrg else if (library > 0 && need_time)
3811debfc3dSmrg {
3821debfc3dSmrg generate_option (OPT_l, TIME_LIBRARY, 1, CL_DRIVER,
3831debfc3dSmrg &new_decoded_options[j]);
3841debfc3dSmrg added_libraries++;
3851debfc3dSmrg j++;
3861debfc3dSmrg }
3871debfc3dSmrg if (saw_libc)
3881debfc3dSmrg new_decoded_options[j++] = *saw_libc;
3891debfc3dSmrg if (shared_libgcc && !static_link)
3901debfc3dSmrg generate_option (OPT_shared_libgcc, NULL, 1, CL_DRIVER,
3911debfc3dSmrg &new_decoded_options[j++]);
3921debfc3dSmrg
3931debfc3dSmrg *in_decoded_options_count = j;
3941debfc3dSmrg *in_decoded_options = new_decoded_options;
3951debfc3dSmrg *in_added_libraries = added_libraries;
3961debfc3dSmrg }
3971debfc3dSmrg
3981debfc3dSmrg /* Called before linking. Returns 0 on success and -1 on failure. */
lang_specific_pre_link(void)3991debfc3dSmrg int lang_specific_pre_link (void) /* Not used for C++. */
4001debfc3dSmrg {
4011debfc3dSmrg return 0;
4021debfc3dSmrg }
4031debfc3dSmrg
4041debfc3dSmrg /* Number of extra output files that lang_specific_pre_link may generate. */
4051debfc3dSmrg int lang_specific_extra_outfiles = 0; /* Not used for C++. */
406