OSDN Git Service

Update Copyright years for files modified in 2008 and/or 2009.
[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, 2008  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 #ifndef LIBSTDCXX_STATIC
48 #define LIBSTDCXX_STATIC LIBSTDCXX
49 #endif
50
51 void
52 lang_specific_driver (int *in_argc, const char *const **in_argv,
53                       int *in_added_libraries)
54 {
55   int i, j;
56
57   /* If nonzero, the user gave us the `-p' or `-pg' flag.  */
58   int saw_profile_flag = 0;
59
60   /* If nonzero, the user gave us the `-v' flag.  */
61   int saw_verbose_flag = 0;
62
63   /* This is a tristate:
64      -1 means we should not link in libstdc++
65      0  means we should link in libstdc++ if it is needed
66      1  means libstdc++ is needed and should be linked in.  */
67   int library = 0;
68
69   /* The number of arguments being added to what's in argv, other than
70      libraries.  We use this to track the number of times we've inserted
71      -xc++/-xnone.  */
72   int added = 0;
73
74   /* Used to track options that take arguments, so we don't go wrapping
75      those with -xc++/-xnone.  */
76   const char *quote = NULL;
77
78   /* The new argument list will be contained in this.  */
79   const char **arglist;
80
81   /* Nonzero if we saw a `-xfoo' language specification on the
82      command line.  Used to avoid adding our own -xc++ if the user
83      already gave a language for the file.  */
84   int saw_speclang = 0;
85
86   /* "-lm" or "-lmath" if it appears on the command line.  */
87   const char *saw_math = 0;
88
89   /* "-lc" if it appears on the command line.  */
90   const char *saw_libc = 0;
91
92   /* An array used to flag each argument that needs a bit set for
93      LANGSPEC, MATHLIB, or WITHLIBC.  */
94   int *args;
95
96   /* By default, we throw on the math library if we have one.  */
97   int need_math = (MATH_LIBRARY[0] != '\0');
98
99   /* True if we should add -shared-libgcc to the command-line.  */
100   int shared_libgcc = 1;
101
102   /* The total number of arguments with the new stuff.  */
103   int argc;
104
105   /* The argument list.  */
106   const char *const *argv;
107
108   /* The number of libraries added in.  */
109   int added_libraries;
110
111   /* The total number of arguments with the new stuff.  */
112   int num_args = 1;
113
114   argc = *in_argc;
115   argv = *in_argv;
116   added_libraries = *in_added_libraries;
117
118   args = XCNEWVEC (int, argc);
119
120   for (i = 1; i < argc; i++)
121     {
122       /* If the previous option took an argument, we swallow it here.  */
123       if (quote)
124         {
125           quote = NULL;
126           continue;
127         }
128
129       /* We don't do this anymore, since we don't get them with minus
130          signs on them.  */
131       if (argv[i][0] == '\0' || argv[i][1] == '\0')
132         continue;
133
134       if (argv[i][0] == '-')
135         {
136           if (strcmp (argv[i], "-nostdlib") == 0
137               || strcmp (argv[i], "-nodefaultlibs") == 0)
138             {
139               library = -1;
140             }
141           else if (strcmp (argv[i], MATH_LIBRARY) == 0)
142             {
143               args[i] |= MATHLIB;
144               need_math = 0;
145             }
146           else if (strcmp (argv[i], "-lc") == 0)
147             args[i] |= WITHLIBC;
148           else if (strcmp (argv[i], "-pg") == 0 || strcmp (argv[i], "-p") == 0)
149             saw_profile_flag++;
150           else if (strcmp (argv[i], "-v") == 0)
151             saw_verbose_flag = 1;
152           else if (strncmp (argv[i], "-x", 2) == 0)
153             {
154               const char * arg;
155               if (argv[i][2] != '\0')
156                 arg = argv[i]+2;
157               else if ((argv[i+1]) != NULL)
158                 /* We need to swallow arg on next loop.  */
159                 quote = arg = argv[i+1];
160               else  /* Error condition, message will be printed later.  */
161                 arg = "";
162               if (library == 0
163                   && (strcmp (arg, "c++") == 0
164                       || strcmp (arg, "c++-cpp-output") == 0
165                       || strcmp (arg, "objective-c++") == 0
166                       || strcmp (arg, "objective-c++-cpp-output") == 0))
167                 library = 1;
168                 
169               saw_speclang = 1;
170             }
171           else if (strcmp (argv[i], "-ObjC++") == 0)
172             {
173               if (library == 0)
174                 library = 1;
175               saw_speclang = 1;
176             }
177           /* Arguments that go directly to the linker might be .o files,
178              or something, and so might cause libstdc++ to be needed.  */
179           else if (strcmp (argv[i], "-Xlinker") == 0)
180             {
181               quote = argv[i];
182               if (library == 0)
183                 library = 1;
184             }
185           else if (strncmp (argv[i], "-Wl,", 4) == 0)
186             library = (library == 0) ? 1 : library;
187           /* Unrecognized libraries (e.g. -lfoo) may require libstdc++.  */
188           else if (strncmp (argv[i], "-l", 2) == 0)
189             library = (library == 0) ? 1 : library;
190           else if (((argv[i][2] == '\0'
191                      && strchr ("bBVDUoeTuIYmLiA", argv[i][1]) != NULL)
192                     || strcmp (argv[i], "-Tdata") == 0))
193             quote = argv[i];
194           else if ((argv[i][2] == '\0'
195                     && strchr ("cSEM", argv[i][1]) != NULL)
196                    || strcmp (argv[i], "-MM") == 0
197                    || strcmp (argv[i], "-fsyntax-only") == 0)
198             {
199               /* Don't specify libraries if we won't link, since that would
200                  cause a warning.  */
201               library = -1;
202             }
203           else if (strcmp (argv[i], "-static-libgcc") == 0
204                    || strcmp (argv[i], "-static") == 0)
205             shared_libgcc = 0;
206           else if (DEFAULT_WORD_SWITCH_TAKES_ARG (&argv[i][1]))
207             i++;
208           else
209             /* Pass other options through.  */
210             continue;
211         }
212       else
213         {
214           int len;
215
216           if (saw_speclang)
217             {
218               saw_speclang = 0;
219               continue;
220             }
221
222           /* If the filename ends in .[chi], put options around it.
223              But not if a specified -x option is currently active.  */
224           len = strlen (argv[i]);
225           if (len > 2
226               && (argv[i][len - 1] == 'c'
227                   || argv[i][len - 1] == 'i'
228                   || argv[i][len - 1] == 'h')
229               && argv[i][len - 2] == '.')
230             {
231               args[i] |= LANGSPEC;
232               added += 2;
233             }
234
235           /* If we don't know that this is a header file, we might
236              need to be linking in the libraries.  */
237           if (library == 0)
238             {
239               if ((len <= 2 || strcmp (argv[i] + (len - 2), ".H") != 0)
240                   && (len <= 2 || strcmp (argv[i] + (len - 2), ".h") != 0)
241                   && (len <= 4 || strcmp (argv[i] + (len - 4), ".hpp") != 0)
242                   && (len <= 3 || strcmp (argv[i] + (len - 3), ".hp") != 0)
243                   && (len <= 4 || strcmp (argv[i] + (len - 4), ".hxx") != 0)
244                   && (len <= 4 || strcmp (argv[i] + (len - 4), ".h++") != 0)
245                   && (len <= 4 || strcmp (argv[i] + (len - 4), ".HPP") != 0)
246                   && (len <= 4 || strcmp (argv[i] + (len - 4), ".tcc") != 0)
247                   && (len <= 3 || strcmp (argv[i] + (len - 3), ".hh") != 0))
248                 library = 1;
249             }
250         }
251     }
252
253   if (quote)
254     fatal ("argument to '%s' missing\n", quote);
255
256   /* There's no point adding -shared-libgcc if we don't have a shared
257      libgcc.  */
258 #ifndef ENABLE_SHARED_LIBGCC
259   shared_libgcc = 0;
260 #endif
261
262   /* Make sure to have room for the trailing NULL argument.  */
263   num_args = argc + added + need_math + shared_libgcc + (library > 0) + 1;
264   arglist = XNEWVEC (const char *, num_args);
265
266   i = 0;
267   j = 0;
268
269   /* Copy the 0th argument, i.e., the name of the program itself.  */
270   arglist[i++] = argv[j++];
271
272   /* NOTE: We start at 1 now, not 0.  */
273   while (i < argc)
274     {
275       arglist[j] = argv[i];
276
277       /* Make sure -lstdc++ is before the math library, since libstdc++
278          itself uses those math routines.  */
279       if (!saw_math && (args[i] & MATHLIB) && library > 0)
280         {
281           --j;
282           saw_math = argv[i];
283         }
284
285       if (!saw_libc && (args[i] & WITHLIBC) && library > 0)
286         {
287           --j;
288           saw_libc = argv[i];
289         }
290
291       /* Wrap foo.[chi] files in a language specification to
292          force the gcc compiler driver to run cc1plus on them.  */
293       if (args[i] & LANGSPEC)
294         {
295           int len = strlen (argv[i]);
296           switch (argv[i][len - 1])
297             {
298             case 'c':
299               arglist[j++] = "-xc++";
300               break;
301             case 'i':
302               arglist[j++] = "-xc++-cpp-output";
303               break;
304             case 'h':
305               arglist[j++] = "-xc++-header";
306               break;
307             default:
308               gcc_unreachable ();
309             }
310           arglist[j++] = argv[i];
311           arglist[j] = "-xnone";
312         }
313
314       i++;
315       j++;
316     }
317
318   /* Add `-lstdc++' if we haven't already done so.  */
319   if (library > 0)
320     {
321       arglist[j] = shared_libgcc == 0 ? LIBSTDCXX_STATIC
322         : saw_profile_flag ? LIBSTDCXX_PROFILE : LIBSTDCXX;
323       if (arglist[j][0] != '-' || arglist[j][1] == 'l')
324         added_libraries++;
325       j++;
326     }
327   if (saw_math)
328     arglist[j++] = saw_math;
329   else if (library > 0 && need_math)
330     {
331       arglist[j] = saw_profile_flag ? MATH_LIBRARY_PROFILE : MATH_LIBRARY;
332       if (arglist[j][0] != '-' || arglist[j][1] == 'l')
333         added_libraries++;
334       j++;
335     }
336   if (saw_libc)
337     arglist[j++] = saw_libc;
338   if (shared_libgcc)
339     arglist[j++] = "-shared-libgcc";
340
341   arglist[j] = NULL;
342
343   *in_argc = j;
344   *in_argv = arglist;
345   *in_added_libraries = added_libraries;
346 }
347
348 /* Called before linking.  Returns 0 on success and -1 on failure.  */
349 int lang_specific_pre_link (void)  /* Not used for C++.  */
350 {
351   return 0;
352 }
353
354 /* Number of extra output files that lang_specific_pre_link may generate.  */
355 int lang_specific_extra_outfiles = 0;  /* Not used for C++.  */