OSDN Git Service

PR c++/33407
[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, 2002, 2003, 2004,
3    2007  Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
7 GCC 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 GCC 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 #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 MATH_LIBRARY
39 #endif
40
41 #ifndef LIBSTDCXX
42 #define LIBSTDCXX "-lstdc++"
43 #endif
44 #ifndef LIBSTDCXX_PROFILE
45 #define LIBSTDCXX_PROFILE LIBSTDCXX
46 #endif
47
48 void
49 lang_specific_driver (int *in_argc, const char *const **in_argv,
50                       int *in_added_libraries)
51 {
52   int i, j;
53
54   /* If nonzero, the user gave us the `-p' or `-pg' flag.  */
55   int saw_profile_flag = 0;
56
57   /* If nonzero, the user gave us the `-v' flag.  */
58   int saw_verbose_flag = 0;
59
60   /* This is a tristate:
61      -1 means we should not link in libstdc++
62      0  means we should link in libstdc++ if it is needed
63      1  means libstdc++ is needed and should be linked in.  */
64   int library = 0;
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 = 0;
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 = XCNEWVEC (int, argc);
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 (strcmp (argv[i], "-nostdlib") == 0
134               || strcmp (argv[i], "-nodefaultlibs") == 0)
135             {
136               library = -1;
137             }
138           else if (strcmp (argv[i], MATH_LIBRARY) == 0)
139             {
140               args[i] |= MATHLIB;
141               need_math = 0;
142             }
143           else if (strcmp (argv[i], "-lc") == 0)
144             args[i] |= WITHLIBC;
145           else if (strcmp (argv[i], "-pg") == 0 || strcmp (argv[i], "-p") == 0)
146             saw_profile_flag++;
147           else if (strcmp (argv[i], "-v") == 0)
148             saw_verbose_flag = 1;
149           else if (strncmp (argv[i], "-x", 2) == 0)
150             {
151               const char * arg;
152               if (argv[i][2] != '\0')
153                 arg = argv[i]+2;
154               else if ((argv[i+1]) != NULL)
155                 /* We need to swallow arg on next loop.  */
156                 quote = arg = argv[i+1];
157               else  /* Error condition, message will be printed later.  */
158                 arg = "";
159               if (library == 0
160                   && (strcmp (arg, "c++") == 0
161                       || strcmp (arg, "c++-cpp-output") == 0
162                       || strcmp (arg, "objective-c++") == 0
163                       || strcmp (arg, "objective-c++-cpp-output") == 0))
164                 library = 1;
165                 
166               saw_speclang = 1;
167             }
168           else if (strcmp (argv[i], "-ObjC++") == 0)
169             {
170               if (library == 0)
171                 library = 1;
172               saw_speclang = 1;
173             }
174           /* Arguments that go directly to the linker might be .o files,
175              or something, and so might cause libstdc++ to be needed.  */
176           else if (strcmp (argv[i], "-Xlinker") == 0)
177             {
178               quote = argv[i];
179               if (library == 0)
180                 library = 1;
181             }
182           else if (strncmp (argv[i], "-Wl,", 4) == 0)
183             library = (library == 0) ? 1 : library;
184           /* Unrecognized libraries (e.g. -lfoo) may require libstdc++.  */
185           else if (strncmp (argv[i], "-l", 2) == 0)
186             library = (library == 0) ? 1 : library;
187           else if (((argv[i][2] == '\0'
188                      && strchr ("bBVDUoeTuIYmLiA", argv[i][1]) != NULL)
189                     || strcmp (argv[i], "-Tdata") == 0))
190             quote = argv[i];
191           else if ((argv[i][2] == '\0'
192                     && strchr ("cSEM", argv[i][1]) != NULL)
193                    || strcmp (argv[i], "-MM") == 0
194                    || strcmp (argv[i], "-fsyntax-only") == 0)
195             {
196               /* Don't specify libraries if we won't link, since that would
197                  cause a warning.  */
198               library = -1;
199             }
200           else if (strcmp (argv[i], "-static-libgcc") == 0
201                    || strcmp (argv[i], "-static") == 0)
202             shared_libgcc = 0;
203           else if (DEFAULT_WORD_SWITCH_TAKES_ARG (&argv[i][1]))
204             i++;
205           else
206             /* Pass other options through.  */
207             continue;
208         }
209       else
210         {
211           int len;
212
213           if (saw_speclang)
214             {
215               saw_speclang = 0;
216               continue;
217             }
218
219           /* If the filename ends in .[chi], put options around it.
220              But not if a specified -x option is currently active.  */
221           len = strlen (argv[i]);
222           if (len > 2
223               && (argv[i][len - 1] == 'c'
224                   || argv[i][len - 1] == 'i'
225                   || argv[i][len - 1] == 'h')
226               && argv[i][len - 2] == '.')
227             {
228               args[i] |= LANGSPEC;
229               added += 2;
230             }
231
232           /* If we don't know that this is a header file, we might
233              need to be linking in the libraries.  */
234           if (library == 0)
235             {
236               if ((len <= 2 || strcmp (argv[i] + (len - 2), ".H") != 0)
237                   && (len <= 2 || strcmp (argv[i] + (len - 2), ".h") != 0)
238                   && (len <= 4 || strcmp (argv[i] + (len - 4), ".hpp") != 0)
239                   && (len <= 3 || strcmp (argv[i] + (len - 3), ".hp") != 0)
240                   && (len <= 4 || strcmp (argv[i] + (len - 4), ".hxx") != 0)
241                   && (len <= 4 || strcmp (argv[i] + (len - 4), ".h++") != 0)
242                   && (len <= 4 || strcmp (argv[i] + (len - 4), ".HPP") != 0)
243                   && (len <= 4 || strcmp (argv[i] + (len - 4), ".tcc") != 0)
244                   && (len <= 3 || strcmp (argv[i] + (len - 3), ".hh") != 0))
245                 library = 1;
246             }
247         }
248     }
249
250   if (quote)
251     fatal ("argument to '%s' missing\n", quote);
252
253   /* There's no point adding -shared-libgcc if we don't have a shared
254      libgcc.  */
255 #ifndef ENABLE_SHARED_LIBGCC
256   shared_libgcc = 0;
257 #endif
258
259   /* Make sure to have room for the trailing NULL argument.  */
260   num_args = argc + added + need_math + shared_libgcc + (library > 0) + 1;
261   arglist = XNEWVEC (const char *, num_args);
262
263   i = 0;
264   j = 0;
265
266   /* Copy the 0th argument, i.e., the name of the program itself.  */
267   arglist[i++] = argv[j++];
268
269   /* NOTE: We start at 1 now, not 0.  */
270   while (i < argc)
271     {
272       arglist[j] = argv[i];
273
274       /* Make sure -lstdc++ is before the math library, since libstdc++
275          itself uses those math routines.  */
276       if (!saw_math && (args[i] & MATHLIB) && library > 0)
277         {
278           --j;
279           saw_math = argv[i];
280         }
281
282       if (!saw_libc && (args[i] & WITHLIBC) && library > 0)
283         {
284           --j;
285           saw_libc = argv[i];
286         }
287
288       /* Wrap foo.[chi] files in a language specification to
289          force the gcc compiler driver to run cc1plus on them.  */
290       if (args[i] & LANGSPEC)
291         {
292           int len = strlen (argv[i]);
293           switch (argv[i][len - 1])
294             {
295             case 'c':
296               arglist[j++] = "-xc++";
297               break;
298             case 'i':
299               arglist[j++] = "-xc++-cpp-output";
300               break;
301             case 'h':
302               arglist[j++] = "-xc++-header";
303               break;
304             default:
305               gcc_unreachable ();
306             }
307           arglist[j++] = argv[i];
308           arglist[j] = "-xnone";
309         }
310
311       i++;
312       j++;
313     }
314
315   /* Add `-lstdc++' if we haven't already done so.  */
316   if (library > 0)
317     {
318       arglist[j] = saw_profile_flag ? LIBSTDCXX_PROFILE : LIBSTDCXX;
319       if (arglist[j][0] != '-' || arglist[j][1] == 'l')
320         added_libraries++;
321       j++;
322     }
323   if (saw_math)
324     arglist[j++] = saw_math;
325   else if (library > 0 && need_math)
326     {
327       arglist[j] = saw_profile_flag ? MATH_LIBRARY_PROFILE : MATH_LIBRARY;
328       if (arglist[j][0] != '-' || arglist[j][1] == 'l')
329         added_libraries++;
330       j++;
331     }
332   if (saw_libc)
333     arglist[j++] = saw_libc;
334   if (shared_libgcc)
335     arglist[j++] = "-shared-libgcc";
336
337   arglist[j] = NULL;
338
339   *in_argc = j;
340   *in_argv = arglist;
341   *in_added_libraries = added_libraries;
342 }
343
344 /* Called before linking.  Returns 0 on success and -1 on failure.  */
345 int lang_specific_pre_link (void)  /* Not used for C++.  */
346 {
347   return 0;
348 }
349
350 /* Number of extra output files that lang_specific_pre_link may generate.  */
351 int lang_specific_extra_outfiles = 0;  /* Not used for C++.  */