Merge -r 127928:132243 from trunk
[official-gcc.git] / gcc / fortran / gfortranspec.c
blobbe9830386f731b7c9086ea07adfc6dd8e185de87
1 /* Specific flags and argument handling of the Fortran front-end.
2 Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
3 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 /* This file is copied more or less verbatim from g77. */
22 /* This file contains a filter for the main `gcc' driver, which is
23 replicated for the `gfortran' driver by adding this filter. The purpose
24 of this filter is to be basically identical to gcc (in that
25 it faithfully passes all of the original arguments to gcc) but,
26 unless explicitly overridden by the user in certain ways, ensure
27 that the needs of the language supported by this wrapper are met.
29 For GNU Fortran 95(gfortran), we do the following to the argument list
30 before passing it to `gcc':
32 1. Make sure `-lgfortran -lm' is at the end of the list.
34 2. Make sure each time `-lgfortran' or `-lm' is seen, it forms
35 part of the series `-lgfortran -lm'.
37 #1 and #2 are not done if `-nostdlib' or any option that disables
38 the linking phase is present, or if `-xfoo' is in effect. Note that
39 a lack of source files or -l options disables linking.
41 This program was originally made out of gcc/cp/g++spec.c, but the
42 way it builds the new argument list was rewritten so it is much
43 easier to maintain, improve the way it decides to add or not add
44 extra arguments, etc. And several improvements were made in the
45 handling of arguments, primarily to make it more consistent with
46 `gcc' itself. */
48 #include "config.h"
49 #include "system.h"
50 #include "gcc.h"
52 #include "coretypes.h"
53 #include "tm.h"
54 #include "intl.h"
56 #ifndef MATH_LIBRARY
57 #define MATH_LIBRARY "-lm"
58 #endif
60 #ifndef FORTRAN_INIT
61 #define FORTRAN_INIT "-lgfortranbegin"
62 #endif
64 #ifndef FORTRAN_LIBRARY
65 #define FORTRAN_LIBRARY "-lgfortran"
66 #endif
68 #ifdef HAVE_LD_STATIC_DYNAMIC
69 #define ADD_ARG_LIBGFORTRAN(arg) \
70 { \
71 if (static_lib && !static_linking) \
72 append_arg ("-Wl,-Bstatic"); \
73 append_arg (arg); \
74 if (static_lib && !static_linking) \
75 append_arg ("-Wl,-Bdynamic"); \
77 #else
78 #define ADD_ARG_LIBGFORTRAN(arg) append_arg (arg);
79 #endif
82 /* Options this driver needs to recognize, not just know how to
83 skip over. */
84 typedef enum
86 OPTION_b, /* Aka --prefix. */
87 OPTION_B, /* Aka --target. */
88 OPTION_c, /* Aka --compile. */
89 OPTION_E, /* Aka --preprocess. */
90 OPTION_help, /* --help. */
91 OPTION_i, /* -imacros, -include, -include-*. */
92 OPTION_l,
93 OPTION_L, /* Aka --library-directory. */
94 OPTION_nostdlib, /* Aka --no-standard-libraries, or
95 -nodefaultlibs. */
96 OPTION_o, /* Aka --output. */
97 OPTION_S, /* Aka --assemble. */
98 OPTION_static, /* -static. */
99 OPTION_static_libgfortran, /* -static-libgfortran. */
100 OPTION_syntax_only, /* -fsyntax-only. */
101 OPTION_v, /* Aka --verbose. */
102 OPTION_version, /* --version. */
103 OPTION_V, /* Aka --use-version. */
104 OPTION_x, /* Aka --language. */
105 OPTION_ /* Unrecognized or unimportant. */
107 Option;
109 /* The original argument list and related info is copied here. */
110 static int g77_xargc;
111 static const char *const *g77_xargv;
112 static void lookup_option (Option *, int *, const char **, const char *);
113 static void append_arg (const char *);
115 /* The new argument list will be built here. */
116 static int g77_newargc;
117 static const char **g77_newargv;
119 /* --- This comes from gcc.c (2.8.1) verbatim: */
121 /* This defines which switch letters take arguments. */
123 #ifndef SWITCH_TAKES_ARG
124 #define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR)
125 #endif
127 /* This defines which multi-letter switches take arguments. */
129 #ifndef WORD_SWITCH_TAKES_ARG
130 #define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR)
131 #endif
133 /* --- End of verbatim. */
135 /* Assumes text[0] == '-'. Returns number of argv items that belong to
136 (and follow) this one, an option id for options important to the
137 caller, and a pointer to the first char of the arg, if embedded (else
138 returns NULL, meaning no arg or it's the next argv).
140 Note that this also assumes gcc.c's pass converting long options
141 to short ones, where available, has already been run. */
143 static void
144 lookup_option (Option *xopt, int *xskip, const char **xarg, const char *text)
146 Option opt = OPTION_;
147 int skip;
148 const char *arg = NULL;
150 if ((skip = SWITCH_TAKES_ARG (text[1])))
151 skip -= (text[2] != '\0'); /* See gcc.c. */
153 if (text[1] == 'B')
154 opt = OPTION_B, skip = (text[2] == '\0'), arg = text + 2;
155 else if (text[1] == 'b')
156 opt = OPTION_b, skip = (text[2] == '\0'), arg = text + 2;
157 else if ((text[1] == 'c') && (text[2] == '\0'))
158 opt = OPTION_c, skip = 0;
159 else if ((text[1] == 'E') && (text[2] == '\0'))
160 opt = OPTION_E, skip = 0;
161 else if (text[1] == 'i')
162 opt = OPTION_i, skip = 0;
163 else if (text[1] == 'l')
164 opt = OPTION_l;
165 else if (text[1] == 'L')
166 opt = OPTION_L, arg = text + 2;
167 else if (text[1] == 'o')
168 opt = OPTION_o;
169 else if ((text[1] == 'S') && (text[2] == '\0'))
170 opt = OPTION_S, skip = 0;
171 else if (text[1] == 'V')
172 opt = OPTION_V, skip = (text[2] == '\0');
173 else if ((text[1] == 'v') && (text[2] == '\0'))
174 opt = OPTION_v, skip = 0;
175 else if (text[1] == 'x')
176 opt = OPTION_x, arg = text + 2;
177 else
179 if ((skip = WORD_SWITCH_TAKES_ARG (text + 1)) != 0) /* See gcc.c. */
181 else if (!strcmp (text, "-fhelp")) /* Really --help!! */
182 opt = OPTION_help;
183 else if (!strcmp (text, "-nostdlib")
184 || !strcmp (text, "-nodefaultlibs"))
185 opt = OPTION_nostdlib;
186 else if (!strcmp (text, "-fsyntax-only"))
187 opt = OPTION_syntax_only;
188 else if (!strcmp (text, "-static-libgfortran"))
189 opt = OPTION_static_libgfortran;
190 else if (!strcmp (text, "-dumpversion"))
191 opt = OPTION_version;
192 else if (!strcmp (text, "-fversion")) /* Really --version!! */
193 opt = OPTION_version;
194 else if (!strcmp (text, "-Xlinker") || !strcmp (text, "-specs"))
195 skip = 1;
196 else
197 skip = 0;
200 if (xopt != NULL)
201 *xopt = opt;
202 if (xskip != NULL)
203 *xskip = skip;
204 if (xarg != NULL)
206 if ((arg != NULL) && (arg[0] == '\0'))
207 *xarg = NULL;
208 else
209 *xarg = arg;
213 /* Append another argument to the list being built. As long as it is
214 identical to the corresponding arg in the original list, just increment
215 the new arg count. Otherwise allocate a new list, etc. */
217 static void
218 append_arg (const char *arg)
220 static int newargsize;
222 #if 0
223 fprintf (stderr, "`%s'\n", arg);
224 #endif
226 if (g77_newargv == g77_xargv
227 && g77_newargc < g77_xargc
228 && (arg == g77_xargv[g77_newargc]
229 || !strcmp (arg, g77_xargv[g77_newargc])))
231 ++g77_newargc;
232 return; /* Nothing new here. */
235 if (g77_newargv == g77_xargv)
236 { /* Make new arglist. */
237 int i;
239 newargsize = (g77_xargc << 2) + 20; /* This should handle all. */
240 g77_newargv = (const char **) xmalloc (newargsize * sizeof (char *));
242 /* Copy what has been done so far. */
243 for (i = 0; i < g77_newargc; ++i)
244 g77_newargv[i] = g77_xargv[i];
247 if (g77_newargc == newargsize)
248 fatal ("overflowed output arg list for '%s'", arg);
250 g77_newargv[g77_newargc++] = arg;
253 void
254 lang_specific_driver (int *in_argc, const char *const **in_argv,
255 int *in_added_libraries ATTRIBUTE_UNUSED)
257 int argc = *in_argc;
258 const char *const *argv = *in_argv;
259 int i;
260 int verbose = 0;
261 Option opt;
262 int skip;
263 const char *arg;
265 /* This will be NULL if we encounter a situation where we should not
266 link in libf2c. */
267 const char *library = FORTRAN_LIBRARY;
269 /* 0 => -xnone in effect.
270 1 => -xfoo in effect. */
271 int saw_speclang = 0;
273 /* 0 => initial/reset state
274 1 => last arg was -l<library>
275 2 => last two args were -l<library> -lm. */
276 int saw_library = 0;
278 /* 0 => initial/reset state
279 1 => FORTRAN_INIT linked in */
280 int use_init = 0;
282 /* By default, we throw on the math library if we have one. */
283 int need_math = (MATH_LIBRARY[0] != '\0');
285 /* Whether we should link a static libgfortran. */
286 int static_lib = 0;
288 /* Whether we need to link statically. */
289 int static_linking = 0;
291 /* The number of input and output files in the incoming arg list. */
292 int n_infiles = 0;
293 int n_outfiles = 0;
295 #if 0
296 fprintf (stderr, "Incoming:");
297 for (i = 0; i < argc; i++)
298 fprintf (stderr, " %s", argv[i]);
299 fprintf (stderr, "\n");
300 #endif
302 g77_xargc = argc;
303 g77_xargv = argv;
304 g77_newargc = 0;
305 g77_newargv = CONST_CAST2 (const char **, const char *const *, argv);
307 /* First pass through arglist.
309 If -nostdlib or a "turn-off-linking" option is anywhere in the
310 command line, don't do any library-option processing (except
311 relating to -x). Also, if -v is specified, but no other options
312 that do anything special (allowing -V version, etc.), remember
313 to add special stuff to make gcc command actually invoke all
314 the different phases of the compilation process so all the version
315 numbers can be seen.
317 Also, here is where all problems with missing arguments to options
318 are caught. If this loop is exited normally, it means all options
319 have the appropriate number of arguments as far as the rest of this
320 program is concerned. */
322 for (i = 1; i < argc; ++i)
324 if ((argv[i][0] == '+') && (argv[i][1] == 'e'))
326 continue;
329 if ((argv[i][0] != '-') || (argv[i][1] == '\0'))
331 ++n_infiles;
332 continue;
335 lookup_option (&opt, &skip, NULL, argv[i]);
337 switch (opt)
339 case OPTION_nostdlib:
340 case OPTION_c:
341 case OPTION_S:
342 case OPTION_syntax_only:
343 case OPTION_E:
344 /* These options disable linking entirely or linking of the
345 standard libraries. */
346 library = 0;
347 break;
349 case OPTION_static_libgfortran:
350 static_lib = 1;
351 break;
353 case OPTION_static:
354 static_linking = 1;
356 case OPTION_l:
357 ++n_infiles;
358 break;
360 case OPTION_o:
361 ++n_outfiles;
362 break;
364 case OPTION_v:
365 verbose = 1;
366 break;
368 case OPTION_b:
369 case OPTION_B:
370 case OPTION_L:
371 case OPTION_i:
372 case OPTION_V:
373 /* These options are useful in conjunction with -v to get
374 appropriate version info. */
375 break;
377 case OPTION_version:
378 printf ("GNU Fortran %s%s\n", pkgversion_string, version_string);
379 printf ("Copyright %s 2007 Free Software Foundation, Inc.\n\n",
380 _("(C)"));
381 printf (_("GNU Fortran comes with NO WARRANTY, to the extent permitted by law.\n\
382 You may redistribute copies of GNU Fortran\n\
383 under the terms of the GNU General Public License.\n\
384 For more information about these matters, see the file named COPYING\n\n"));
385 exit (0);
386 break;
388 case OPTION_help:
389 /* Let gcc.c handle this, as it has a really
390 cool facility for handling --help and --verbose --help. */
391 return;
393 default:
394 break;
397 /* This is the one place we check for missing arguments in the
398 program. */
400 if (i + skip < argc)
401 i += skip;
402 else
403 fatal ("argument to '%s' missing", argv[i]);
406 if ((n_outfiles != 0) && (n_infiles == 0))
407 fatal ("no input files; unwilling to write output files");
409 /* If there are no input files, no need for the library. */
410 if (n_infiles == 0)
411 library = 0;
413 /* Second pass through arglist, transforming arguments as appropriate. */
415 append_arg (argv[0]); /* Start with command name, of course. */
417 for (i = 1; i < argc; ++i)
419 if (argv[i][0] == '\0')
421 append_arg (argv[i]); /* Interesting. Just append as is. */
422 continue;
425 if ((argv[i][0] == '-') && (argv[i][1] == 'M'))
427 char *p;
429 if (argv[i][2] == '\0')
431 p = XNEWVEC (char, strlen (argv[i + 1]) + 2);
432 p[0] = '-';
433 p[1] = 'J';
434 strcpy (&p[2], argv[i + 1]);
435 i++;
437 else
439 p = XNEWVEC (char, strlen (argv[i]) + 1);
440 strcpy (p, argv[i]);
442 append_arg (p);
443 continue;
446 if ((argv[i][0] == '-') && (argv[i][1] != 'l'))
448 /* Not a filename or library. */
450 if (saw_library == 1 && need_math) /* -l<library>. */
451 append_arg (MATH_LIBRARY);
453 saw_library = 0;
455 lookup_option (&opt, &skip, &arg, argv[i]);
457 if (argv[i][1] == '\0')
459 append_arg (argv[i]); /* "-" == Standard input. */
460 continue;
463 if (opt == OPTION_x)
465 /* Track input language. */
466 const char *lang;
468 if (arg == NULL)
469 lang = argv[i + 1];
470 else
471 lang = arg;
473 saw_speclang = (strcmp (lang, "none") != 0);
476 append_arg (argv[i]);
478 for (; skip != 0; --skip)
479 append_arg (argv[++i]);
481 continue;
484 /* A filename/library, not an option. */
486 if (saw_speclang)
487 saw_library = 0; /* -xfoo currently active. */
488 else
489 { /* -lfoo or filename. */
490 if (strcmp (argv[i], MATH_LIBRARY) == 0)
492 if (saw_library == 1)
493 saw_library = 2; /* -l<library> -lm. */
494 else
496 if (0 == use_init)
498 append_arg (FORTRAN_INIT);
499 use_init = 1;
502 ADD_ARG_LIBGFORTRAN (FORTRAN_LIBRARY);
505 else if (strcmp (argv[i], FORTRAN_LIBRARY) == 0)
507 saw_library = 1; /* -l<library>. */
508 ADD_ARG_LIBGFORTRAN (argv[i]);
509 continue;
511 else
512 { /* Other library, or filename. */
513 if (saw_library == 1 && need_math)
514 append_arg (MATH_LIBRARY);
515 saw_library = 0;
518 append_arg (argv[i]);
521 /* Append `-lg2c -lm' as necessary. */
523 if (library)
524 { /* Doing a link and no -nostdlib. */
525 if (saw_speclang)
526 append_arg ("-xnone");
528 switch (saw_library)
530 case 0:
531 if (0 == use_init)
533 append_arg (FORTRAN_INIT);
534 use_init = 1;
536 ADD_ARG_LIBGFORTRAN (library);
537 /* Fall through. */
539 case 1:
540 if (need_math)
541 append_arg (MATH_LIBRARY);
542 default:
543 break;
547 #ifdef ENABLE_SHARED_LIBGCC
548 if (library)
550 int i;
552 for (i = 1; i < g77_newargc; i++)
553 if (g77_newargv[i][0] == '-')
554 if (strcmp (g77_newargv[i], "-static-libgcc") == 0
555 || strcmp (g77_newargv[i], "-static") == 0)
556 break;
558 if (i == g77_newargc)
559 append_arg ("-shared-libgcc");
562 #endif
564 if (verbose && g77_newargv != g77_xargv)
566 fprintf (stderr, _("Driving:"));
567 for (i = 0; i < g77_newargc; i++)
568 fprintf (stderr, " %s", g77_newargv[i]);
569 fprintf (stderr, "\n");
572 *in_argc = g77_newargc;
573 *in_argv = g77_newargv;
577 /* Called before linking. Returns 0 on success and -1 on failure. */
579 lang_specific_pre_link (void) /* Not used for F77. */
581 return 0;
584 /* Number of extra output files that lang_specific_pre_link may generate. */
585 int lang_specific_extra_outfiles = 0; /* Not used for F77. */