1/* Specific flags and argument handling of the Fortran front-end.
2   Copyright (C) 1997-2015 Free Software Foundation, Inc.
3
4This file is part of GCC.
5
6GNU CC 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
11GNU CC 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/* This file is copied more or less verbatim from g77.  */
21/* This file contains a filter for the main `gcc' driver, which is
22   replicated for the `gfortran' driver by adding this filter.  The purpose
23   of this filter is to be basically identical to gcc (in that
24   it faithfully passes all of the original arguments to gcc) but,
25   unless explicitly overridden by the user in certain ways, ensure
26   that the needs of the language supported by this wrapper are met.
27
28   For GNU Fortran 95(gfortran), we do the following to the argument list
29   before passing it to `gcc':
30
31   1.  Make sure `-lgfortran -lm' is at the end of the list.
32
33   2.  Make sure each time `-lgfortran' or `-lm' is seen, it forms
34       part of the series `-lgfortran -lm'.
35
36   #1 and #2 are not done if `-nostdlib' or any option that disables
37   the linking phase is present, or if `-xfoo' is in effect.  Note that
38   a lack of source files or -l options disables linking.
39
40   This program was originally made out of gcc/cp/g++spec.c, but the
41   way it builds the new argument list was rewritten so it is much
42   easier to maintain, improve the way it decides to add or not add
43   extra arguments, etc.  And several improvements were made in the
44   handling of arguments, primarily to make it more consistent with
45   `gcc' itself.  */
46
47#include "config.h"
48#include "system.h"
49#include "coretypes.h"
50#include "gcc.h"
51#include "opts.h"
52
53#include "tm.h"
54#include "intl.h"
55
56#ifndef MATH_LIBRARY
57#define MATH_LIBRARY "m"
58#endif
59
60#ifndef FORTRAN_LIBRARY
61#define FORTRAN_LIBRARY "gfortran"
62#endif
63
64/* Name of the spec file.  */
65#define SPEC_FILE "libgfortran.spec"
66
67/* The original argument list and related info is copied here.  */
68static unsigned int g77_xargc;
69static const struct cl_decoded_option *g77_x_decoded_options;
70static void append_arg (const struct cl_decoded_option *);
71
72/* The new argument list will be built here.  */
73static unsigned int g77_newargc;
74static struct cl_decoded_option *g77_new_decoded_options;
75
76/* This will be NULL if we encounter a situation where we should not
77   link in the fortran libraries.  */
78static const char *library = NULL;
79
80
81/* Return whether strings S1 and S2 are both NULL or both the same
82   string.  */
83
84static bool
85strings_same (const char *s1, const char *s2)
86{
87  return s1 == s2 || (s1 != NULL && s2 != NULL && strcmp (s1, s2) == 0);
88}
89
90/* Return whether decoded option structures OPT1 and OPT2 are the
91   same.  */
92
93static bool
94options_same (const struct cl_decoded_option *opt1,
95	      const struct cl_decoded_option *opt2)
96{
97  return (opt1->opt_index == opt2->opt_index
98	  && strings_same (opt1->arg, opt2->arg)
99	  && strings_same (opt1->orig_option_with_args_text,
100			   opt2->orig_option_with_args_text)
101	  && strings_same (opt1->canonical_option[0],
102			   opt2->canonical_option[0])
103	  && strings_same (opt1->canonical_option[1],
104			   opt2->canonical_option[1])
105	  && strings_same (opt1->canonical_option[2],
106			   opt2->canonical_option[2])
107	  && strings_same (opt1->canonical_option[3],
108			   opt2->canonical_option[3])
109	  && (opt1->canonical_option_num_elements
110	      == opt2->canonical_option_num_elements)
111	  && opt1->value == opt2->value
112	  && opt1->errors == opt2->errors);
113}
114
115/* Append another argument to the list being built.  As long as it is
116   identical to the corresponding arg in the original list, just increment
117   the new arg count.  Otherwise allocate a new list, etc.  */
118
119static void
120append_arg (const struct cl_decoded_option *arg)
121{
122  static unsigned int newargsize;
123
124  if (g77_new_decoded_options == g77_x_decoded_options
125      && g77_newargc < g77_xargc
126      && options_same (arg, &g77_x_decoded_options[g77_newargc]))
127    {
128      ++g77_newargc;
129      return;			/* Nothing new here.  */
130    }
131
132  if (g77_new_decoded_options == g77_x_decoded_options)
133    {				/* Make new arglist.  */
134      unsigned int i;
135
136      newargsize = (g77_xargc << 2) + 20;	/* This should handle all.  */
137      g77_new_decoded_options = XNEWVEC (struct cl_decoded_option, newargsize);
138
139      /* Copy what has been done so far.  */
140      for (i = 0; i < g77_newargc; ++i)
141	g77_new_decoded_options[i] = g77_x_decoded_options[i];
142    }
143
144  if (g77_newargc == newargsize)
145    fatal_error (input_location, "overflowed output arg list for %qs",
146		 arg->orig_option_with_args_text);
147
148  g77_new_decoded_options[g77_newargc++] = *arg;
149}
150
151/* Append an option described by OPT_INDEX, ARG and VALUE to the list
152   being built.  */
153static void
154append_option (size_t opt_index, const char *arg, int value)
155{
156  struct cl_decoded_option decoded;
157
158  generate_option (opt_index, arg, value, CL_DRIVER, &decoded);
159  append_arg (&decoded);
160}
161
162/* Append a libgfortran argument to the list being built.  If
163   FORCE_STATIC, ensure the library is linked statically.  */
164
165static void
166add_arg_libgfortran (bool force_static ATTRIBUTE_UNUSED)
167{
168#ifdef HAVE_LD_STATIC_DYNAMIC
169  if (force_static)
170    append_option (OPT_Wl_, LD_STATIC_OPTION, 1);
171#endif
172  append_option (OPT_l, FORTRAN_LIBRARY, 1);
173#ifdef HAVE_LD_STATIC_DYNAMIC
174  if (force_static)
175    append_option (OPT_Wl_, LD_DYNAMIC_OPTION, 1);
176#endif
177}
178
179void
180lang_specific_driver (struct cl_decoded_option **in_decoded_options,
181		      unsigned int *in_decoded_options_count,
182		      int *in_added_libraries ATTRIBUTE_UNUSED)
183{
184  unsigned int argc = *in_decoded_options_count;
185  struct cl_decoded_option *decoded_options = *in_decoded_options;
186  unsigned int i;
187  int verbose = 0;
188
189  /* 0 => -xnone in effect.
190     1 => -xfoo in effect.  */
191  int saw_speclang = 0;
192
193  /* 0 => initial/reset state
194     1 => last arg was -l<library>
195     2 => last two args were -l<library> -lm.  */
196  int saw_library = 0;
197
198  /* By default, we throw on the math library if we have one.  */
199  int need_math = (MATH_LIBRARY[0] != '\0');
200
201  /* Whether we should link a static libgfortran.  */
202  int static_lib = 0;
203
204  /* Whether we need to link statically.  */
205  int static_linking = 0;
206
207  /* The number of input and output files in the incoming arg list.  */
208  int n_infiles = 0;
209  int n_outfiles = 0;
210
211  library = FORTRAN_LIBRARY;
212
213#if 0
214  fprintf (stderr, "Incoming:");
215  for (i = 0; i < argc; i++)
216    fprintf (stderr, " %s", decoded_options[i].orig_option_with_args_text);
217  fprintf (stderr, "\n");
218#endif
219
220  g77_xargc = argc;
221  g77_x_decoded_options = decoded_options;
222  g77_newargc = 0;
223  g77_new_decoded_options = decoded_options;
224
225  /* First pass through arglist.
226
227     If -nostdlib or a "turn-off-linking" option is anywhere in the
228     command line, don't do any library-option processing (except
229     relating to -x).  */
230
231  for (i = 1; i < argc; ++i)
232    {
233      if (decoded_options[i].errors & CL_ERR_MISSING_ARG)
234	continue;
235
236      switch (decoded_options[i].opt_index)
237	{
238	case OPT_SPECIAL_input_file:
239	  ++n_infiles;
240	  continue;
241
242	case OPT_nostdlib:
243	case OPT_nodefaultlibs:
244	case OPT_c:
245	case OPT_S:
246	case OPT_fsyntax_only:
247	case OPT_E:
248	  /* These options disable linking entirely or linking of the
249	     standard libraries.  */
250	  library = 0;
251	  break;
252
253	case OPT_static_libgfortran:
254#ifdef HAVE_LD_STATIC_DYNAMIC
255	  static_lib = 1;
256#endif
257	  break;
258
259	case OPT_static:
260#ifdef HAVE_LD_STATIC_DYNAMIC
261	  static_linking = 1;
262#endif
263	  break;
264
265	case OPT_l:
266	  ++n_infiles;
267	  break;
268
269	case OPT_o:
270	  ++n_outfiles;
271	  break;
272
273	case OPT_v:
274	  verbose = 1;
275	  break;
276
277	case OPT__version:
278	  printf ("GNU Fortran %s%s\n", pkgversion_string, version_string);
279	  printf ("Copyright %s 2015 Free Software Foundation, Inc.\n\n",
280		  _("(C)"));
281	  printf (_("GNU Fortran comes with NO WARRANTY, to the extent permitted by law.\n\
282You may redistribute copies of GNU Fortran\n\
283under the terms of the GNU General Public License.\n\
284For more information about these matters, see the file named COPYING\n\n"));
285	  exit (0);
286	  break;
287
288	case OPT__help:
289	  /* Let gcc.c handle this, as it has a really
290	     cool facility for handling --help and --verbose --help.  */
291	  return;
292
293	default:
294	  break;
295	}
296    }
297
298  if ((n_outfiles != 0) && (n_infiles == 0))
299    fatal_error (input_location,
300		 "no input files; unwilling to write output files");
301
302  /* If there are no input files, no need for the library.  */
303  if (n_infiles == 0)
304    library = 0;
305
306  /* Second pass through arglist, transforming arguments as appropriate.  */
307
308  append_arg (&decoded_options[0]); /* Start with command name, of course.  */
309
310  for (i = 1; i < argc; ++i)
311    {
312      if (decoded_options[i].errors & CL_ERR_MISSING_ARG)
313	{
314	  append_arg (&decoded_options[i]);
315	  continue;
316	}
317
318      if (decoded_options[i].opt_index == OPT_SPECIAL_input_file
319	  && decoded_options[i].arg[0] == '\0')
320	{
321	  /* Interesting.  Just append as is.  */
322	  append_arg (&decoded_options[i]);
323	  continue;
324	}
325
326      if (decoded_options[i].opt_index != OPT_l
327	  && (decoded_options[i].opt_index != OPT_SPECIAL_input_file
328	      || strcmp (decoded_options[i].arg, "-") == 0))
329	{
330	  /* Not a filename or library.  */
331
332	  if (saw_library == 1 && need_math)	/* -l<library>.  */
333	    append_option (OPT_l, MATH_LIBRARY, 1);
334
335	  saw_library = 0;
336
337	  if (decoded_options[i].opt_index == OPT_SPECIAL_input_file)
338	    {
339	      append_arg (&decoded_options[i]);	/* "-" == Standard input.  */
340	      continue;
341	    }
342
343	  if (decoded_options[i].opt_index == OPT_x)
344	    {
345	      /* Track input language.  */
346	      const char *lang = decoded_options[i].arg;
347
348	      saw_speclang = (strcmp (lang, "none") != 0);
349	    }
350
351	  append_arg (&decoded_options[i]);
352
353	  continue;
354	}
355
356      /* A filename/library, not an option.  */
357
358      if (saw_speclang)
359	saw_library = 0;	/* -xfoo currently active.  */
360      else
361	{			/* -lfoo or filename.  */
362	  if (decoded_options[i].opt_index == OPT_l
363	      && strcmp (decoded_options[i].arg, MATH_LIBRARY) == 0)
364	    {
365	      if (saw_library == 1)
366		saw_library = 2;	/* -l<library> -lm.  */
367	      else
368		add_arg_libgfortran (static_lib && !static_linking);
369	    }
370	  else if (decoded_options[i].opt_index == OPT_l
371	      && strcmp (decoded_options[i].arg, FORTRAN_LIBRARY) == 0)
372	    {
373	      saw_library = 1;	/* -l<library>.  */
374	      add_arg_libgfortran (static_lib && !static_linking);
375	      continue;
376	    }
377	  else
378	    {			/* Other library, or filename.  */
379	      if (saw_library == 1 && need_math)
380		append_option (OPT_l, MATH_LIBRARY, 1);
381	      saw_library = 0;
382	    }
383	}
384      append_arg (&decoded_options[i]);
385    }
386
387  /* Append `-lgfortran -lm' as necessary.  */
388
389  if (library)
390    {				/* Doing a link and no -nostdlib.  */
391      if (saw_speclang)
392	append_option (OPT_x, "none", 1);
393
394      switch (saw_library)
395	{
396	case 0:
397	  add_arg_libgfortran (static_lib && !static_linking);
398	  /* Fall through.  */
399
400	case 1:
401	  if (need_math)
402	    append_option (OPT_l, MATH_LIBRARY, 1);
403	default:
404	  break;
405	}
406    }
407
408#ifdef ENABLE_SHARED_LIBGCC
409  if (library)
410    {
411      unsigned int i;
412
413      for (i = 1; i < g77_newargc; i++)
414	if (g77_new_decoded_options[i].opt_index == OPT_static_libgcc
415	    || g77_new_decoded_options[i].opt_index == OPT_static)
416	  break;
417
418      if (i == g77_newargc)
419	append_option (OPT_shared_libgcc, NULL, 1);
420    }
421
422#endif
423
424  if (verbose && g77_new_decoded_options != g77_x_decoded_options)
425    {
426      fprintf (stderr, _("Driving:"));
427      for (i = 0; i < g77_newargc; i++)
428	fprintf (stderr, " %s",
429		 g77_new_decoded_options[i].orig_option_with_args_text);
430      fprintf (stderr, "\n");
431    }
432
433  *in_decoded_options_count = g77_newargc;
434  *in_decoded_options = g77_new_decoded_options;
435}
436
437
438/* Called before linking.  Returns 0 on success and -1 on failure.  */
439int
440lang_specific_pre_link (void)
441{
442  if (library)
443    do_spec ("%:include(libgfortran.spec)");
444
445  return 0;
446}
447
448/* Number of extra output files that lang_specific_pre_link may generate.  */
449int lang_specific_extra_outfiles = 0;	/* Not used for F77.  */
450