PR testsuite/52641
[official-gcc.git] / gcc / go / gospec.c
blob0be7716be5c3afd72534e924fff8ade289888e89
1 /* gospec.c -- Specific flags and argument handling of the gcc Go front end.
2 Copyright (C) 2009-2013 Free Software Foundation, Inc.
4 This file is part of GCC.
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.
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.
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/>. */
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "tm.h"
24 #include "gcc.h"
25 #include "opts.h"
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)
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
45 #define THREAD_LIBRARY "pthread"
46 #define THREAD_LIBRARY_PROFILE THREAD_LIBRARY
48 #define LIBGO "go"
49 #define LIBGO_PROFILE LIBGO
50 #define LIBGOBEGIN "gobegin"
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)
57 unsigned int i, j;
59 /* If true, the user gave us the `-p' or `-pg' flag. */
60 bool saw_profile_flag = false;
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;
69 /* The new argument list will be contained in this. */
70 struct cl_decoded_option *new_decoded_options;
72 /* "-lm" or "-lmath" if it appears on the command line. */
73 const struct cl_decoded_option *saw_math = 0;
75 /* "-lpthread" if it appears on the command line. */
76 const struct cl_decoded_option *saw_thread = 0;
78 /* "-lc" if it appears on the command line. */
79 const struct cl_decoded_option *saw_libc = 0;
81 /* An array used to flag each argument that needs a bit set for
82 LANGSPEC, MATHLIB, or WITHLIBC. */
83 int *args;
85 /* Whether we need the thread library. */
86 int need_thread = 0;
88 /* By default, we throw on the math library if we have one. */
89 int need_math = (MATH_LIBRARY[0] != '\0');
91 /* True if we saw -static. */
92 int static_link = 0;
94 /* True if we should add -shared-libgcc to the command-line. */
95 int shared_libgcc = 1;
97 /* The total number of arguments with the new stuff. */
98 unsigned int argc;
100 /* The argument list. */
101 struct cl_decoded_option *decoded_options;
103 /* The number of libraries added in. */
104 int added_libraries;
106 /* The total number of arguments with the new stuff. */
107 int num_args = 1;
109 /* Whether the -o option was used. */
110 bool saw_opt_o = false;
112 /* Whether the -c option was used. Also used for -E, -fsyntax-only,
113 in general anything which implies only compilation and not
114 linking. */
115 bool saw_opt_c = false;
117 /* Whether the -S option was used. */
118 bool saw_opt_S = false;
120 /* The first input file with an extension of .go. */
121 const char *first_go_file = NULL;
123 argc = *in_decoded_options_count;
124 decoded_options = *in_decoded_options;
125 added_libraries = *in_added_libraries;
127 args = XCNEWVEC (int, argc);
129 for (i = 1; i < argc; i++)
131 const char *arg = decoded_options[i].arg;
133 switch (decoded_options[i].opt_index)
135 case OPT_nostdlib:
136 case OPT_nodefaultlibs:
137 library = -1;
138 break;
140 case OPT_l:
141 if (strcmp (arg, MATH_LIBRARY) == 0)
143 args[i] |= MATHLIB;
144 need_math = 0;
146 else if (strcmp (arg, THREAD_LIBRARY) == 0)
147 args[i] |= THREADLIB;
148 else if (strcmp (arg, "c") == 0)
149 args[i] |= WITHLIBC;
150 else
151 /* Unrecognized libraries (e.g. -lfoo) may require libgo. */
152 library = (library == 0) ? 1 : library;
153 break;
155 case OPT_pg:
156 case OPT_p:
157 saw_profile_flag = true;
158 break;
160 case OPT_x:
161 if (library == 0 && strcmp (arg, "go") == 0)
162 library = 1;
163 break;
165 case OPT_Xlinker:
166 case OPT_Wl_:
167 /* Arguments that go directly to the linker might be .o files,
168 or something, and so might cause libgo to be needed. */
169 if (library == 0)
170 library = 1;
171 break;
173 case OPT_c:
174 case OPT_E:
175 case OPT_M:
176 case OPT_MM:
177 case OPT_fsyntax_only:
178 /* Don't specify libraries if we won't link, since that would
179 cause a warning. */
180 saw_opt_c = true;
181 library = -1;
182 break;
184 case OPT_S:
185 saw_opt_S = true;
186 library = -1;
187 break;
189 case OPT_o:
190 saw_opt_o = true;
191 break;
193 case OPT_static:
194 static_link = 1;
195 break;
197 case OPT_static_libgcc:
198 shared_libgcc = 0;
199 break;
201 case OPT_static_libgo:
202 library = library >= 0 ? 2 : library;
203 args[i] |= SKIPOPT;
204 break;
206 case OPT_SPECIAL_input_file:
207 if (library == 0)
208 library = 1;
210 if (first_go_file == NULL)
212 int len;
214 len = strlen (arg);
215 if (len > 3 && strcmp (arg + len - 3, ".go") == 0)
216 first_go_file = arg;
219 break;
223 /* There's no point adding -shared-libgcc if we don't have a shared
224 libgcc. */
225 #ifndef ENABLE_SHARED_LIBGCC
226 shared_libgcc = 0;
227 #endif
229 /* Make sure to have room for the trailing NULL argument. */
230 num_args = argc + need_math + shared_libgcc + (library > 0) * 5 + 10;
231 new_decoded_options = XNEWVEC (struct cl_decoded_option, num_args);
233 i = 0;
234 j = 0;
236 /* Copy the 0th argument, i.e., the name of the program itself. */
237 new_decoded_options[j++] = decoded_options[i++];
239 /* If we are linking, pass -fsplit-stack if it is supported. */
240 #ifdef TARGET_CAN_SPLIT_STACK
241 if (library >= 0)
243 generate_option (OPT_fsplit_stack, NULL, 1, CL_DRIVER,
244 &new_decoded_options[j]);
245 j++;
247 #endif
249 /* NOTE: We start at 1 now, not 0. */
250 while (i < argc)
252 new_decoded_options[j] = decoded_options[i];
254 /* Make sure -lgo is before the math library, since libgo itself
255 uses those math routines. */
256 if (!saw_math && (args[i] & MATHLIB) && library > 0)
258 --j;
259 saw_math = &decoded_options[i];
262 if (!saw_thread && (args[i] & THREADLIB) && library > 0)
264 --j;
265 saw_thread = &decoded_options[i];
268 if (!saw_libc && (args[i] & WITHLIBC) && library > 0)
270 --j;
271 saw_libc = &decoded_options[i];
274 if ((args[i] & SKIPOPT) != 0)
275 --j;
277 i++;
278 j++;
281 /* If we didn't see a -o option, add one. This is because we need
282 the driver to pass all .go files to go1. Without a -o option the
283 driver will invoke go1 separately for each input file. FIXME:
284 This should probably use some other interface to force the driver
285 to set combine_inputs. */
286 if (first_go_file != NULL && !saw_opt_o)
288 if (saw_opt_c || saw_opt_S)
290 const char *base;
291 int baselen;
292 int alen;
293 char *out;
295 base = lbasename (first_go_file);
296 baselen = strlen (base) - 3;
297 alen = baselen + 3;
298 out = XNEWVEC (char, alen);
299 memcpy (out, base, baselen);
300 /* The driver will convert .o to some other suffix (e.g.,
301 .obj) if appropriate. */
302 out[baselen] = '.';
303 if (saw_opt_S)
304 out[baselen + 1] = 's';
305 else
306 out[baselen + 1] = 'o';
307 out[baselen + 2] = '\0';
308 generate_option (OPT_o, out, 1, CL_DRIVER,
309 &new_decoded_options[j]);
311 else
312 generate_option (OPT_o, "a.out", 1, CL_DRIVER,
313 &new_decoded_options[j]);
314 j++;
317 /* Add `-lgo' if we haven't already done so. */
318 if (library > 0)
320 generate_option (OPT_l, LIBGOBEGIN, 1, CL_DRIVER,
321 &new_decoded_options[j]);
322 added_libraries++;
323 j++;
325 #ifdef HAVE_LD_STATIC_DYNAMIC
326 if (library > 1 && !static_link)
328 generate_option (OPT_Wl_, LD_STATIC_OPTION, 1, CL_DRIVER,
329 &new_decoded_options[j]);
330 j++;
332 #endif
334 generate_option (OPT_l, saw_profile_flag ? LIBGO_PROFILE : LIBGO, 1,
335 CL_DRIVER, &new_decoded_options[j]);
336 added_libraries++;
337 j++;
339 #ifdef HAVE_LD_STATIC_DYNAMIC
340 if (library > 1 && !static_link)
342 generate_option (OPT_Wl_, LD_DYNAMIC_OPTION, 1, CL_DRIVER,
343 &new_decoded_options[j]);
344 j++;
346 #endif
348 /* When linking libgo statically we also need to link with the
349 pthread library. */
350 if (library > 1 || static_link)
351 need_thread = 1;
354 if (saw_thread)
355 new_decoded_options[j++] = *saw_thread;
356 else if (library > 0 && need_thread)
358 generate_option (OPT_l,
359 (saw_profile_flag
360 ? THREAD_LIBRARY_PROFILE
361 : THREAD_LIBRARY),
362 1, CL_DRIVER, &new_decoded_options[j]);
363 added_libraries++;
364 j++;
367 if (saw_math)
368 new_decoded_options[j++] = *saw_math;
369 else if (library > 0 && need_math)
371 generate_option (OPT_l,
372 saw_profile_flag ? MATH_LIBRARY_PROFILE : MATH_LIBRARY,
373 1, CL_DRIVER, &new_decoded_options[j]);
374 added_libraries++;
375 j++;
378 if (saw_libc)
379 new_decoded_options[j++] = *saw_libc;
380 if (shared_libgcc && !static_link)
381 generate_option (OPT_shared_libgcc, NULL, 1, CL_DRIVER,
382 &new_decoded_options[j++]);
384 #ifdef TARGET_CAN_SPLIT_STACK
385 /* libgcc wraps pthread_create to support split stack, however, due to
386 relative ordering of -lpthread and -lgcc, we can't just mark
387 __real_pthread_create in libgcc as non-weak. But we need to link in
388 pthread_create from pthread if we are statically linking, so we work-
389 around by passing -u pthread_create to to the linker. */
390 if (static_link)
392 generate_option (OPT_Wl_, "-u,pthread_create", 1, CL_DRIVER,
393 &new_decoded_options[j]);
394 j++;
396 #endif
398 *in_decoded_options_count = j;
399 *in_decoded_options = new_decoded_options;
400 *in_added_libraries = added_libraries;
403 /* Called before linking. Returns 0 on success and -1 on failure. */
404 int lang_specific_pre_link (void) /* Not used for Go. */
406 return 0;
409 /* Number of extra output files that lang_specific_pre_link may generate. */
410 int lang_specific_extra_outfiles = 0; /* Not used for Go. */