OSDN Git Service

Add Go frontend, libgo library, and Go testsuite.
[pf3gnuchains/gcc-fork.git] / gcc / go / gospec.c
1 /* gospec.c -- Specific flags and argument handling of the gcc Go front end.
2    Copyright (C) 2009, 2010 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3.  If not see
18 <http://www.gnu.org/licenses/>.  */
19
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "tm.h"
24 #include "gcc.h"
25 #include "opts.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 `-lpthread'.  */
32 #define THREADLIB       (1<<3)
33 /* This bit is set if they did `-lc'.  */
34 #define WITHLIBC        (1<<4)
35 /* Skip this option.  */
36 #define SKIPOPT         (1<<5)
37
38 #ifndef MATH_LIBRARY
39 #define MATH_LIBRARY "m"
40 #endif
41 #ifndef MATH_LIBRARY_PROFILE
42 #define MATH_LIBRARY_PROFILE MATH_LIBRARY
43 #endif
44
45 #define THREAD_LIBRARY "pthread"
46 #define THREAD_LIBRARY_PROFILE THREAD_LIBRARY
47
48 #define LIBGO "go"
49 #define LIBGO_PROFILE LIBGO
50 #define LIBGOBEGIN "gobegin"
51
52 void
53 lang_specific_driver (struct cl_decoded_option **in_decoded_options,
54                       unsigned int *in_decoded_options_count,
55                       int *in_added_libraries)
56 {
57   unsigned int i, j;
58
59   /* If true, the user gave us the `-p' or `-pg' flag.  */
60   bool saw_profile_flag = false;
61
62   /* This is a tristate:
63      -1 means we should not link in libgo
64      0  means we should link in libgo if it is needed
65      1  means libgo is needed and should be linked in.
66      2  means libgo is needed and should be linked statically.  */
67   int library = 0;
68
69   /* The new argument list will be contained in this.  */
70   struct cl_decoded_option *new_decoded_options;
71
72   /* "-lm" or "-lmath" if it appears on the command line.  */
73   const struct cl_decoded_option *saw_math = 0;
74
75   /* "-lpthread" if it appears on the command line.  */
76   const struct cl_decoded_option *saw_thread = 0;
77
78   /* "-lc" if it appears on the command line.  */
79   const struct cl_decoded_option *saw_libc = 0;
80
81   /* An array used to flag each argument that needs a bit set for
82      LANGSPEC, MATHLIB, or WITHLIBC.  */
83   int *args;
84
85   /* Whether we need the thread library.  */
86   int need_thread = 0;
87
88   /* By default, we throw on the math library if we have one.  */
89   int need_math = (MATH_LIBRARY[0] != '\0');
90
91   /* True if we saw -static.  */
92   int static_link = 0;
93
94   /* True if we should add -shared-libgcc to the command-line.  */
95   int shared_libgcc = 1;
96
97   /* The total number of arguments with the new stuff.  */
98   unsigned int argc;
99
100   /* The argument list.  */
101   struct cl_decoded_option *decoded_options;
102
103   /* The number of libraries added in.  */
104   int added_libraries;
105
106   /* The total number of arguments with the new stuff.  */
107   int num_args = 1;
108
109   argc = *in_decoded_options_count;
110   decoded_options = *in_decoded_options;
111   added_libraries = *in_added_libraries;
112
113   args = XCNEWVEC (int, argc);
114
115   for (i = 1; i < argc; i++)
116     {
117       const char *arg = decoded_options[i].arg;
118
119       switch (decoded_options[i].opt_index)
120         {
121         case OPT_nostdlib:
122         case OPT_nodefaultlibs:
123           library = -1;
124           break;
125
126         case OPT_l:
127           if (strcmp (arg, MATH_LIBRARY) == 0)
128             {
129               args[i] |= MATHLIB;
130               need_math = 0;
131             }
132           else if (strcmp (arg, THREAD_LIBRARY) == 0)
133             args[i] |= THREADLIB;
134           else if (strcmp (arg, "c") == 0)
135             args[i] |= WITHLIBC;
136           else
137             /* Unrecognized libraries (e.g. -lfoo) may require libgo.  */
138             library = (library == 0) ? 1 : library;
139           break;
140
141         case OPT_pg:
142         case OPT_p:
143           saw_profile_flag = true;
144           break;
145
146         case OPT_x:
147           if (library == 0 && strcmp (arg, "go") == 0)
148             library = 1;
149           break;
150
151         case OPT_Xlinker:
152         case OPT_Wl_:
153           /* Arguments that go directly to the linker might be .o files,
154              or something, and so might cause libgo to be needed.  */
155           if (library == 0)
156             library = 1;
157           break;
158
159         case OPT_c:
160         case OPT_S:
161         case OPT_E:
162         case OPT_M:
163         case OPT_MM:
164         case OPT_fsyntax_only:
165           /* Don't specify libraries if we won't link, since that would
166              cause a warning.  */
167           library = -1;
168           break;
169
170         case OPT_static:
171           static_link = 1;
172           break;
173
174         case OPT_static_libgcc:
175           shared_libgcc = 0;
176           break;
177
178         case OPT_static_libgo:
179           library = library >= 0 ? 2 : library;
180           args[i] |= SKIPOPT;
181           break;
182
183         case OPT_SPECIAL_input_file:
184           if (library == 0)
185             library = 1;
186           break;
187         }
188     }
189
190   /* There's no point adding -shared-libgcc if we don't have a shared
191      libgcc.  */
192 #ifndef ENABLE_SHARED_LIBGCC
193   shared_libgcc = 0;
194 #endif
195
196   /* Make sure to have room for the trailing NULL argument.  */
197   num_args = argc + need_math + shared_libgcc + (library > 0) * 5 + 5;
198   new_decoded_options = XNEWVEC (struct cl_decoded_option, num_args);
199
200   i = 0;
201   j = 0;
202
203   /* Copy the 0th argument, i.e., the name of the program itself.  */
204   new_decoded_options[j++] = decoded_options[i++];
205
206   /* If we are linking, pass -fsplit-stack if it is supported.  */
207 #ifdef TARGET_CAN_SPLIT_STACK
208   if (library >= 0)
209     {
210       generate_option (OPT_fsplit_stack, NULL, 1, CL_DRIVER,
211                        &new_decoded_options[j]);
212       j++;
213     }
214 #endif
215
216   /* NOTE: We start at 1 now, not 0.  */
217   while (i < argc)
218     {
219       new_decoded_options[j] = decoded_options[i];
220
221       /* Make sure -lgo is before the math library, since libgo itself
222          uses those math routines.  */
223       if (!saw_math && (args[i] & MATHLIB) && library > 0)
224         {
225           --j;
226           saw_math = &decoded_options[i];
227         }
228
229       if (!saw_thread && (args[i] & THREADLIB) && library > 0)
230         {
231           --j;
232           saw_thread = &decoded_options[i];
233         }
234
235       if (!saw_libc && (args[i] & WITHLIBC) && library > 0)
236         {
237           --j;
238           saw_libc = &decoded_options[i];
239         }
240
241       if ((args[i] & SKIPOPT) != 0)
242         --j;
243
244       i++;
245       j++;
246     }
247
248   /* Add `-lgo' if we haven't already done so.  */
249   if (library > 0)
250     {
251       generate_option (OPT_l, LIBGOBEGIN, 1, CL_DRIVER,
252                        &new_decoded_options[j]);
253       added_libraries++;
254       j++;
255
256 #ifdef HAVE_LD_STATIC_DYNAMIC
257       if (library > 1 && !static_link)
258         {
259           generate_option (OPT_Wl_, "-Bstatic", 1, CL_DRIVER,
260                            &new_decoded_options[j]);
261           j++;
262         }
263 #endif
264
265       generate_option (OPT_l, saw_profile_flag ? LIBGO_PROFILE : LIBGO, 1,
266                        CL_DRIVER, &new_decoded_options[j]);
267       added_libraries++;
268       j++;
269
270 #ifdef HAVE_LD_STATIC_DYNAMIC
271       if (library > 1 && !static_link)
272         {
273           generate_option (OPT_Wl_, "-Bdynamic", 1, CL_DRIVER,
274                            &new_decoded_options[j]);
275           j++;
276         }
277 #endif
278
279       /* When linking libgo statically we also need to link with the
280          pthread library.  */
281       if (library > 1 || static_link)
282         need_thread = 1;
283     }
284
285   if (saw_thread)
286     new_decoded_options[j++] = *saw_thread;
287   else if (library > 0 && need_thread)
288     {
289       generate_option (OPT_l,
290                        (saw_profile_flag
291                         ? THREAD_LIBRARY_PROFILE
292                         : THREAD_LIBRARY),
293                        1, CL_DRIVER, &new_decoded_options[j]);
294       added_libraries++;
295       j++;
296     }
297
298   if (saw_math)
299     new_decoded_options[j++] = *saw_math;
300   else if (library > 0 && need_math)
301     {
302       generate_option (OPT_l,
303                        saw_profile_flag ? MATH_LIBRARY_PROFILE : MATH_LIBRARY,
304                        1, CL_DRIVER, &new_decoded_options[j]);
305       added_libraries++;
306       j++;
307     }
308
309   if (saw_libc)
310     new_decoded_options[j++] = *saw_libc;
311   if (shared_libgcc && !static_link)
312     generate_option (OPT_shared_libgcc, NULL, 1, CL_DRIVER,
313                      &new_decoded_options[j++]);
314
315   *in_decoded_options_count = j;
316   *in_decoded_options = new_decoded_options;
317   *in_added_libraries = added_libraries;
318 }
319
320 /* Called before linking.  Returns 0 on success and -1 on failure.  */
321 int lang_specific_pre_link (void)  /* Not used for Go.  */
322 {
323   return 0;
324 }
325
326 /* Number of extra output files that lang_specific_pre_link may generate.  */
327 int lang_specific_extra_outfiles = 0;  /* Not used for Go.  */