OSDN Git Service

be9830386f731b7c9086ea07adfc6dd8e185de87
[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, 2007
3    Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
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.
11
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.
16
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/>.  */
20
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.
28
29    For GNU Fortran 95(gfortran), we do the following to the argument list
30    before passing it to `gcc':
31
32    1.  Make sure `-lgfortran -lm' is at the end of the list.
33
34    2.  Make sure each time `-lgfortran' or `-lm' is seen, it forms
35        part of the series `-lgfortran -lm'.
36
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.
40
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.  */
47
48 #include "config.h"
49 #include "system.h"
50 #include "gcc.h"
51
52 #include "coretypes.h"
53 #include "tm.h"
54 #include "intl.h"
55
56 #ifndef MATH_LIBRARY
57 #define MATH_LIBRARY "-lm"
58 #endif
59
60 #ifndef FORTRAN_INIT
61 #define FORTRAN_INIT "-lgfortranbegin"
62 #endif
63
64 #ifndef FORTRAN_LIBRARY
65 #define FORTRAN_LIBRARY "-lgfortran"
66 #endif
67
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"); \
76   }
77 #else
78 #define ADD_ARG_LIBGFORTRAN(arg) append_arg (arg);
79 #endif
80
81
82 /* Options this driver needs to recognize, not just know how to
83    skip over.  */
84 typedef enum
85 {
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.  */
106 }
107 Option;
108
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 *);
114
115 /* The new argument list will be built here.  */
116 static int g77_newargc;
117 static const char **g77_newargv;
118
119 /* --- This comes from gcc.c (2.8.1) verbatim: */
120
121 /* This defines which switch letters take arguments.  */
122
123 #ifndef SWITCH_TAKES_ARG
124 #define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR)
125 #endif
126
127 /* This defines which multi-letter switches take arguments.  */
128
129 #ifndef WORD_SWITCH_TAKES_ARG
130 #define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR)
131 #endif
132
133 /* --- End of verbatim.  */
134
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).
139
140    Note that this also assumes gcc.c's pass converting long options
141    to short ones, where available, has already been run.  */
142
143 static void
144 lookup_option (Option *xopt, int *xskip, const char **xarg, const char *text)
145 {
146   Option opt = OPTION_;
147   int skip;
148   const char *arg = NULL;
149
150   if ((skip = SWITCH_TAKES_ARG (text[1])))
151     skip -= (text[2] != '\0');  /* See gcc.c.  */
152
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
178     {
179       if ((skip = WORD_SWITCH_TAKES_ARG (text + 1)) != 0)  /* See gcc.c.  */
180         ;
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;
198     }
199
200   if (xopt != NULL)
201     *xopt = opt;
202   if (xskip != NULL)
203     *xskip = skip;
204   if (xarg != NULL)
205     {
206       if ((arg != NULL) && (arg[0] == '\0'))
207         *xarg = NULL;
208       else
209         *xarg = arg;
210     }
211 }
212
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.  */
216
217 static void
218 append_arg (const char *arg)
219 {
220   static int newargsize;
221
222 #if 0
223   fprintf (stderr, "`%s'\n", arg);
224 #endif
225
226   if (g77_newargv == g77_xargv
227       && g77_newargc < g77_xargc
228       && (arg == g77_xargv[g77_newargc]
229           || !strcmp (arg, g77_xargv[g77_newargc])))
230     {
231       ++g77_newargc;
232       return;                   /* Nothing new here.  */
233     }
234
235   if (g77_newargv == g77_xargv)
236     {                           /* Make new arglist.  */
237       int i;
238
239       newargsize = (g77_xargc << 2) + 20;       /* This should handle all.  */
240       g77_newargv = (const char **) xmalloc (newargsize * sizeof (char *));
241
242       /* Copy what has been done so far.  */
243       for (i = 0; i < g77_newargc; ++i)
244         g77_newargv[i] = g77_xargv[i];
245     }
246
247   if (g77_newargc == newargsize)
248     fatal ("overflowed output arg list for '%s'", arg);
249
250   g77_newargv[g77_newargc++] = arg;
251 }
252
253 void
254 lang_specific_driver (int *in_argc, const char *const **in_argv,
255                       int *in_added_libraries ATTRIBUTE_UNUSED)
256 {
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;
264
265   /* This will be NULL if we encounter a situation where we should not
266      link in libf2c.  */
267   const char *library = FORTRAN_LIBRARY;
268
269   /* 0 => -xnone in effect.
270      1 => -xfoo in effect.  */
271   int saw_speclang = 0;
272
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;
277
278   /* 0 => initial/reset state
279      1 => FORTRAN_INIT linked in */
280   int use_init = 0;
281
282   /* By default, we throw on the math library if we have one.  */
283   int need_math = (MATH_LIBRARY[0] != '\0');
284
285   /* Whether we should link a static libgfortran.  */
286   int static_lib = 0;
287
288   /* Whether we need to link statically.  */
289   int static_linking = 0;
290
291   /* The number of input and output files in the incoming arg list.  */
292   int n_infiles = 0;
293   int n_outfiles = 0;
294
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
301
302   g77_xargc = argc;
303   g77_xargv = argv;
304   g77_newargc = 0;
305   g77_newargv = CONST_CAST2 (const char **, const char *const *, argv);
306
307   /* First pass through arglist.
308
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.
316
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.  */
321
322   for (i = 1; i < argc; ++i)
323     {
324       if ((argv[i][0] == '+') && (argv[i][1] == 'e'))
325         {
326           continue;
327         }
328
329       if ((argv[i][0] != '-') || (argv[i][1] == '\0'))
330         {
331           ++n_infiles;
332           continue;
333         }
334
335       lookup_option (&opt, &skip, NULL, argv[i]);
336
337       switch (opt)
338         {
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;
348
349         case OPTION_static_libgfortran:
350           static_lib = 1;
351           break;
352
353         case OPTION_static:
354           static_linking = 1;
355
356         case OPTION_l:
357           ++n_infiles;
358           break;
359
360         case OPTION_o:
361           ++n_outfiles;
362           break;
363
364         case OPTION_v:
365           verbose = 1;
366           break;
367
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;
376
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;
387
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;
392
393         default:
394           break;
395         }
396
397       /* This is the one place we check for missing arguments in the
398          program.  */
399
400       if (i + skip < argc)
401         i += skip;
402       else
403         fatal ("argument to '%s' missing", argv[i]);
404     }
405
406   if ((n_outfiles != 0) && (n_infiles == 0))
407     fatal ("no input files; unwilling to write output files");
408
409   /* If there are no input files, no need for the library.  */
410   if (n_infiles == 0)
411     library = 0;
412
413   /* Second pass through arglist, transforming arguments as appropriate.  */
414
415   append_arg (argv[0]);         /* Start with command name, of course.  */
416
417   for (i = 1; i < argc; ++i)
418     {
419       if (argv[i][0] == '\0')
420         {
421           append_arg (argv[i]); /* Interesting.  Just append as is.  */
422           continue;
423         }
424
425       if ((argv[i][0] == '-') && (argv[i][1] == 'M'))
426         {
427           char *p;
428
429           if (argv[i][2] == '\0')
430             {
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++;
436             }
437           else
438             {
439               p = XNEWVEC (char, strlen (argv[i]) + 1);
440               strcpy (p, argv[i]);
441             }
442           append_arg (p);
443           continue;
444         }
445
446       if ((argv[i][0] == '-') && (argv[i][1] != 'l'))
447         {
448           /* Not a filename or library.  */
449
450           if (saw_library == 1 && need_math)    /* -l<library>.  */
451             append_arg (MATH_LIBRARY);
452
453           saw_library = 0;
454
455           lookup_option (&opt, &skip, &arg, argv[i]);
456
457           if (argv[i][1] == '\0')
458             {
459               append_arg (argv[i]);     /* "-" == Standard input.  */
460               continue;
461             }
462
463           if (opt == OPTION_x)
464             {
465               /* Track input language.  */
466               const char *lang;
467
468               if (arg == NULL)
469                 lang = argv[i + 1];
470               else
471                 lang = arg;
472
473               saw_speclang = (strcmp (lang, "none") != 0);
474             }
475
476           append_arg (argv[i]);
477
478           for (; skip != 0; --skip)
479             append_arg (argv[++i]);
480
481           continue;
482         }
483
484       /* A filename/library, not an option.  */
485
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)
491             {
492               if (saw_library == 1)
493                 saw_library = 2;        /* -l<library> -lm.  */
494               else
495                 {
496                   if (0 == use_init)
497                     {
498                       append_arg (FORTRAN_INIT);
499                       use_init = 1;
500                     }
501
502                   ADD_ARG_LIBGFORTRAN (FORTRAN_LIBRARY);
503                 }
504             }
505           else if (strcmp (argv[i], FORTRAN_LIBRARY) == 0)
506             {
507               saw_library = 1;  /* -l<library>.  */
508               ADD_ARG_LIBGFORTRAN (argv[i]);
509               continue;
510             }
511           else
512             {                   /* Other library, or filename.  */
513               if (saw_library == 1 && need_math)
514                 append_arg (MATH_LIBRARY);
515               saw_library = 0;
516             }
517         }
518       append_arg (argv[i]);
519     }
520
521   /* Append `-lg2c -lm' as necessary.  */
522
523   if (library)
524     {                           /* Doing a link and no -nostdlib.  */
525       if (saw_speclang)
526         append_arg ("-xnone");
527
528       switch (saw_library)
529         {
530         case 0:
531           if (0 == use_init)
532             {
533               append_arg (FORTRAN_INIT);
534               use_init = 1;
535             }
536           ADD_ARG_LIBGFORTRAN (library);
537           /* Fall through.  */
538
539         case 1:
540           if (need_math)
541             append_arg (MATH_LIBRARY);
542         default:
543           break;
544         }
545     }
546
547 #ifdef ENABLE_SHARED_LIBGCC
548   if (library)
549     {
550       int i;
551
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;
557
558       if (i == g77_newargc)
559         append_arg ("-shared-libgcc");
560     }
561
562 #endif
563
564   if (verbose && g77_newargv != g77_xargv)
565     {
566       fprintf (stderr, _("Driving:"));
567       for (i = 0; i < g77_newargc; i++)
568         fprintf (stderr, " %s", g77_newargv[i]);
569       fprintf (stderr, "\n");
570     }
571
572   *in_argc = g77_newargc;
573   *in_argv = g77_newargv;
574 }
575
576
577 /* Called before linking.  Returns 0 on success and -1 on failure.  */
578 int
579 lang_specific_pre_link (void)   /* Not used for F77.  */
580 {
581   return 0;
582 }
583
584 /* Number of extra output files that lang_specific_pre_link may generate.  */
585 int lang_specific_extra_outfiles = 0;   /* Not used for F77.  */