OSDN Git Service

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