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