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