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