OSDN Git Service

Merge basic-improvements-branch to trunk
[pf3gnuchains/gcc-fork.git] / gcc / cp / g++spec.c
1 /* Specific flags and argument handling of the C++ front-end.
2    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING.  If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.  */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "gcc.h"
26
27 /* This bit is set if we saw a `-xfoo' language specification.  */
28 #define LANGSPEC        (1<<1)
29 /* This bit is set if they did `-lm' or `-lmath'.  */
30 #define MATHLIB         (1<<2)
31 /* This bit is set if they did `-lc'.  */
32 #define WITHLIBC        (1<<3)
33
34 #ifndef MATH_LIBRARY
35 #define MATH_LIBRARY "-lm"
36 #endif
37 #ifndef MATH_LIBRARY_PROFILE
38 #define MATH_LIBRARY_PROFILE "-lm"
39 #endif
40
41 #ifndef LIBSTDCXX
42 #define LIBSTDCXX "-lstdc++"
43 #endif
44 #ifndef LIBSTDCXX_PROFILE
45 #define LIBSTDCXX_PROFILE "-lstdc++"
46 #endif
47
48 void
49 lang_specific_driver (in_argc, in_argv, in_added_libraries)
50      int *in_argc;
51      const char *const **in_argv;
52      int *in_added_libraries;
53 {
54   int i, j;
55
56   /* If nonzero, the user gave us the `-p' or `-pg' flag.  */
57   int saw_profile_flag = 0;
58
59   /* If nonzero, the user gave us the `-v' flag.  */
60   int saw_verbose_flag = 0;
61
62   /* This will be 0 if we encounter a situation where we should not
63      link in libstdc++.  */
64   int library = 1;
65
66   /* The number of arguments being added to what's in argv, other than
67      libraries.  We use this to track the number of times we've inserted
68      -xc++/-xnone.  */
69   int added = 2;
70
71   /* Used to track options that take arguments, so we don't go wrapping
72      those with -xc++/-xnone.  */
73   const char *quote = NULL;
74
75   /* The new argument list will be contained in this.  */
76   const char **arglist;
77
78   /* Nonzero if we saw a `-xfoo' language specification on the
79      command line.  Used to avoid adding our own -xc++ if the user
80      already gave a language for the file.  */
81   int saw_speclang = 0;
82
83   /* "-lm" or "-lmath" if it appears on the command line.  */
84   const char *saw_math = 0;
85
86   /* "-lc" if it appears on the command line.  */
87   const char *saw_libc = 0;
88
89   /* An array used to flag each argument that needs a bit set for
90      LANGSPEC, MATHLIB, or WITHLIBC.  */
91   int *args;
92
93   /* By default, we throw on the math library if we have one.  */
94   int need_math = (MATH_LIBRARY[0] != '\0');
95
96   /* True if we should add -shared-libgcc to the command-line.  */
97   int shared_libgcc = 1;
98
99   /* The total number of arguments with the new stuff.  */
100   int argc;
101
102   /* The argument list.  */
103   const char *const *argv;
104
105   /* The number of libraries added in.  */
106   int added_libraries;
107
108   /* The total number of arguments with the new stuff.  */
109   int num_args = 1;
110
111   argc = *in_argc;
112   argv = *in_argv;
113   added_libraries = *in_added_libraries;
114
115   args = (int *) xcalloc (argc, sizeof (int));
116
117   for (i = 1; i < argc; i++)
118     {
119       /* If the previous option took an argument, we swallow it here.  */
120       if (quote)
121         {
122           quote = NULL;
123           continue;
124         }
125
126       /* We don't do this anymore, since we don't get them with minus
127          signs on them.  */
128       if (argv[i][0] == '\0' || argv[i][1] == '\0')
129         continue;
130
131       if (argv[i][0] == '-')
132         {
133           if (library != 0 && (strcmp (argv[i], "-nostdlib") == 0
134                                || strcmp (argv[i], "-nodefaultlibs") == 0))
135             {
136               library = 0;
137             }
138           else if (strcmp (argv[i], "-lm") == 0
139                    || strcmp (argv[i], "-lmath") == 0
140                    || strcmp (argv[i], MATH_LIBRARY) == 0
141 #ifdef ALT_LIBM
142                    || strcmp (argv[i], ALT_LIBM) == 0
143 #endif
144                   )
145             {
146               args[i] |= MATHLIB;
147               need_math = 0;
148             }
149           else if (strcmp (argv[i], "-lc") == 0)
150             args[i] |= WITHLIBC;
151           else if (strcmp (argv[i], "-pg") == 0 || strcmp (argv[i], "-p") == 0)
152             saw_profile_flag++;
153           else if (strcmp (argv[i], "-v") == 0)
154             {
155               saw_verbose_flag = 1;
156               if (argc == 2)
157                 {
158                   /* If they only gave us `-v', don't try to link
159                      in libg++.  */ 
160                   library = 0;
161                 }
162             }
163           else if (strncmp (argv[i], "-x", 2) == 0)
164             saw_speclang = 1;
165           else if (((argv[i][2] == '\0'
166                      && (char *)strchr ("bBVDUoeTuIYmLiA", argv[i][1]) != NULL)
167                     || strcmp (argv[i], "-Xlinker") == 0
168                     || strcmp (argv[i], "-Tdata") == 0))
169             quote = argv[i];
170           else if (library != 0 && ((argv[i][2] == '\0'
171                      && (char *) strchr ("cSEM", argv[i][1]) != NULL)
172                     || strcmp (argv[i], "-MM") == 0
173                     || strcmp (argv[i], "-fsyntax-only") == 0))
174             {
175               /* Don't specify libraries if we won't link, since that would
176                  cause a warning.  */
177               library = 0;
178               added -= 2;
179             }
180           else if (strcmp (argv[i], "-static-libgcc") == 0 
181                    || strcmp (argv[i], "-static") == 0)
182             shared_libgcc = 0;
183           else
184             /* Pass other options through.  */
185             continue;
186         }
187       else
188         {
189           int len; 
190
191           if (saw_speclang)
192             {
193               saw_speclang = 0;
194               continue;
195             }
196
197           /* If the filename ends in .c or .i, put options around it.
198              But not if a specified -x option is currently active.  */
199           len = strlen (argv[i]);
200           if (len > 2
201               && (argv[i][len - 1] == 'c' || argv[i][len - 1] == 'i')
202               && argv[i][len - 2] == '.')
203             {
204               args[i] |= LANGSPEC;
205               added += 2;
206             }
207         }
208     }
209
210   if (quote)
211     fatal ("argument to `%s' missing\n", quote);
212
213   /* If we know we don't have to do anything, bail now.  */
214   if (! added && ! library)
215     {
216       free (args);
217       return;
218     }
219
220   /* There's no point adding -shared-libgcc if we don't have a shared
221      libgcc.  */
222 #ifndef ENABLE_SHARED_LIBGCC
223   shared_libgcc = 0;
224 #endif
225
226   /* Make sure to have room for the trailing NULL argument.  */
227   num_args = argc + added + need_math + shared_libgcc + 1;
228   arglist = (const char **) xmalloc (num_args * sizeof (char *));
229
230   i = 0;
231   j = 0;
232   
233   /* Copy the 0th argument, i.e., the name of the program itself.  */
234   arglist[i++] = argv[j++];
235
236   /* NOTE: We start at 1 now, not 0.  */
237   while (i < argc)
238     {
239       arglist[j] = argv[i];
240
241       /* Make sure -lstdc++ is before the math library, since libstdc++
242          itself uses those math routines.  */
243       if (!saw_math && (args[i] & MATHLIB) && library)
244         {
245           --j;
246           saw_math = argv[i];
247         }
248
249       if (!saw_libc && (args[i] & WITHLIBC) && library)
250         {
251           --j;
252           saw_libc = argv[i];
253         }
254
255       /* Wrap foo.c and foo.i files in a language specification to
256          force the gcc compiler driver to run cc1plus on them.  */
257       if (args[i] & LANGSPEC)
258         {
259           int len = strlen (argv[i]);
260           if (argv[i][len - 1] == 'i')
261             arglist[j++] = "-xc++-cpp-output";
262           else
263             arglist[j++] = "-xc++";
264           arglist[j++] = argv[i];
265           arglist[j] = "-xnone";
266         }
267
268       i++;
269       j++;
270     }
271
272   /* Add `-lstdc++' if we haven't already done so.  */
273   if (library)
274     {
275       arglist[j++] = saw_profile_flag ? LIBSTDCXX_PROFILE : LIBSTDCXX;
276       added_libraries++;
277 #ifdef USE_LIBUNWIND_EXCEPTIONS
278 # ifndef LIBUNWIND
279 #  define LIBUNWIND "-lunwind"
280 # endif
281       arglist[j++] = LIBUNWIND;
282       added_libraries++;
283 #endif
284     }
285   if (saw_math)
286     arglist[j++] = saw_math;
287   else if (library && need_math)
288     {
289       arglist[j++] = saw_profile_flag ? MATH_LIBRARY_PROFILE : MATH_LIBRARY;
290       added_libraries++;
291     }
292   if (saw_libc)
293     arglist[j++] = saw_libc;
294   if (shared_libgcc)
295     arglist[j++] = "-shared-libgcc";
296
297   arglist[j] = NULL;
298
299   *in_argc = j;
300   *in_argv = arglist;
301   *in_added_libraries = added_libraries;
302 }
303
304 /* Called before linking.  Returns 0 on success and -1 on failure.  */
305 int lang_specific_pre_link ()  /* Not used for C++.  */
306 {
307   return 0;
308 }
309
310 /* Number of extra output files that lang_specific_pre_link may generate.  */
311 int lang_specific_extra_outfiles = 0;  /* Not used for C++.  */
312
313 /* Table of language-specific spec functions.  */ 
314 const struct spec_function lang_specific_spec_functions[] =
315 {
316   { 0, 0 }
317 };