xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/cp/g++spec.c (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
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