]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/go/gospec.cc
Update copyright years.
[thirdparty/gcc.git] / gcc / go / gospec.cc
1 /* gospec.cc -- Specific flags and argument handling of the gcc Go front end.
2 Copyright (C) 2009-2024 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 "opts.h"
25
26 /* This bit is set if we saw a `-xfoo' language specification. */
27 #define LANGSPEC (1<<1)
28 /* This bit is set if they did `-lm' or `-lmath'. */
29 #define MATHLIB (1<<2)
30 /* This bit is set if they did `-lpthread'. */
31 #define THREADLIB (1<<3)
32 /* This bit is set if they did `-lc'. */
33 #define WITHLIBC (1<<4)
34 /* Skip this option. */
35 #define SKIPOPT (1<<5)
36
37 #ifndef MATH_LIBRARY
38 #define MATH_LIBRARY "m"
39 #endif
40 #ifndef MATH_LIBRARY_PROFILE
41 #define MATH_LIBRARY_PROFILE MATH_LIBRARY
42 #endif
43
44 #define THREAD_LIBRARY "pthread"
45 #define THREAD_LIBRARY_PROFILE THREAD_LIBRARY
46
47 #define LIBGO "go"
48 #define LIBGO_PROFILE LIBGO
49 #define LIBGOBEGIN "gobegin"
50
51 void
52 lang_specific_driver (struct cl_decoded_option **in_decoded_options,
53 unsigned int *in_decoded_options_count,
54 int *in_added_libraries)
55 {
56 unsigned int i, j;
57
58 /* If true, the user gave us the `-p' or `-pg' flag. */
59 bool saw_profile_flag = false;
60
61 /* This is a tristate:
62 -1 means we should not link in libgo
63 0 means we should link in libgo if it is needed
64 1 means libgo is needed and should be linked in.
65 2 means libgo is needed and should be linked statically. */
66 int library = 0;
67
68 /* The new argument list will be contained in this. */
69 struct cl_decoded_option *new_decoded_options;
70
71 /* "-lm" or "-lmath" if it appears on the command line. */
72 const struct cl_decoded_option *saw_math = 0;
73
74 /* "-lpthread" if it appears on the command line. */
75 const struct cl_decoded_option *saw_thread = 0;
76
77 /* "-lc" if it appears on the command line. */
78 const struct cl_decoded_option *saw_libc = 0;
79
80 /* An array used to flag each argument that needs a bit set for
81 LANGSPEC, MATHLIB, or WITHLIBC. */
82 int *args;
83
84 /* Whether we need the thread library. */
85 int need_thread = 0;
86
87 /* By default, we throw on the math library if we have one. */
88 int need_math = (MATH_LIBRARY[0] != '\0');
89
90 /* True if we saw -static. */
91 int static_link = 0;
92
93 /* True if we should add -shared-libgcc to the command-line. */
94 int shared_libgcc = 1;
95
96 /* The total number of arguments with the new stuff. */
97 unsigned int argc;
98
99 /* The argument list. */
100 struct cl_decoded_option *decoded_options;
101
102 /* The number of libraries added in. */
103 int added_libraries;
104
105 /* The total number of arguments with the new stuff. */
106 int num_args = 1;
107
108 /* Supports split stack */
109 int supports_split_stack = 0;
110
111 /* Whether the -o option was used. */
112 bool saw_opt_o = false;
113
114 /* Whether the -c option was used. Also used for -E, -fsyntax-only,
115 in general anything which implies only compilation and not
116 linking. */
117 bool saw_opt_c = false;
118
119 /* Whether the -S option was used. */
120 bool saw_opt_S = false;
121
122 #ifdef TARGET_CAN_SPLIT_STACK_64BIT
123 /* Whether the -m64 option is in force. */
124 bool is_m64 = TARGET_CAN_SPLIT_STACK_64BIT;
125 #endif
126
127 /* The first input file with an extension of .go. */
128 const char *first_go_file = NULL;
129
130 /* Whether we saw any -g option. */
131 bool saw_opt_g = false;
132
133 argc = *in_decoded_options_count;
134 decoded_options = *in_decoded_options;
135 added_libraries = *in_added_libraries;
136
137 args = XCNEWVEC (int, argc);
138
139 for (i = 1; i < argc; i++)
140 {
141 const char *arg = decoded_options[i].arg;
142
143 switch (decoded_options[i].opt_index)
144 {
145 case OPT_r:
146 case OPT_nostdlib:
147 case OPT_nodefaultlibs:
148 library = -1;
149 break;
150
151 case OPT_l:
152 if (strcmp (arg, MATH_LIBRARY) == 0)
153 {
154 args[i] |= MATHLIB;
155 need_math = 0;
156 }
157 else if (strcmp (arg, THREAD_LIBRARY) == 0)
158 args[i] |= THREADLIB;
159 else if (strcmp (arg, "c") == 0)
160 args[i] |= WITHLIBC;
161 else
162 /* Unrecognized libraries (e.g. -lfoo) may require libgo. */
163 library = (library == 0) ? 1 : library;
164 break;
165
166 #ifdef TARGET_CAN_SPLIT_STACK_64BIT
167 case OPT_m32:
168 is_m64 = false;
169 break;
170
171 case OPT_m64:
172 is_m64 = true;
173 break;
174 #endif
175
176 case OPT_pg:
177 case OPT_p:
178 saw_profile_flag = true;
179 break;
180
181 case OPT_x:
182 if (library == 0 && strcmp (arg, "go") == 0)
183 library = 1;
184 break;
185
186 case OPT_Xlinker:
187 case OPT_Wl_:
188 /* Arguments that go directly to the linker might be .o files,
189 or something, and so might cause libgo to be needed. */
190 if (library == 0)
191 library = 1;
192 break;
193
194 case OPT_c:
195 case OPT_E:
196 case OPT_M:
197 case OPT_MM:
198 case OPT_fsyntax_only:
199 /* Don't specify libraries if we won't link, since that would
200 cause a warning. */
201 saw_opt_c = true;
202 library = -1;
203 break;
204
205 case OPT_S:
206 saw_opt_S = true;
207 library = -1;
208 break;
209
210 case OPT_o:
211 saw_opt_o = true;
212 break;
213
214 case OPT_g:
215 case OPT_gdwarf:
216 case OPT_gdwarf_:
217 case OPT_ggdb:
218 case OPT_gvms:
219 saw_opt_g = true;
220 break;
221
222 case OPT_static:
223 static_link = 1;
224 break;
225
226 case OPT_static_libgcc:
227 shared_libgcc = 0;
228 break;
229
230 case OPT_static_libgo:
231 library = library >= 0 ? 2 : library;
232 args[i] |= SKIPOPT;
233 break;
234
235 case OPT_SPECIAL_input_file:
236 if (library == 0)
237 library = 1;
238
239 if (first_go_file == NULL)
240 {
241 int len;
242
243 len = strlen (arg);
244 if (len > 3 && strcmp (arg + len - 3, ".go") == 0)
245 first_go_file = arg;
246 }
247
248 break;
249 }
250 }
251
252 /* There's no point adding -shared-libgcc if we don't have a shared
253 libgcc. */
254 #ifndef ENABLE_SHARED_LIBGCC
255 shared_libgcc = 0;
256 #endif
257
258 /* Make sure to have room for the trailing NULL argument. */
259 num_args = argc + need_math + shared_libgcc + (library > 0) * 5 + 10;
260 new_decoded_options = XNEWVEC (struct cl_decoded_option, num_args);
261
262 i = 0;
263 j = 0;
264
265 /* Copy the 0th argument, i.e., the name of the program itself. */
266 new_decoded_options[j++] = decoded_options[i++];
267
268 #ifdef TARGET_CAN_SPLIT_STACK
269 supports_split_stack = 1;
270 #endif
271
272 #ifdef TARGET_CAN_SPLIT_STACK_64BIT
273 if (is_m64)
274 supports_split_stack = 1;
275 #endif
276
277 /* If we are linking, pass -fsplit-stack if it is supported. */
278 if ((library >= 0) && supports_split_stack)
279 {
280 generate_option (OPT_fsplit_stack, NULL, 1, CL_DRIVER,
281 &new_decoded_options[j]);
282 j++;
283 }
284
285 /* The go1 compiler is going to enable debug info by default. If we
286 don't see any -g options, force -g, so that we invoke the
287 assembler with the right debug option. */
288 if (!saw_opt_g)
289 {
290 generate_option (OPT_g, "1", 0, CL_DRIVER, &new_decoded_options[j]);
291 j++;
292 }
293
294 /* NOTE: We start at 1 now, not 0. */
295 while (i < argc)
296 {
297 new_decoded_options[j] = decoded_options[i];
298
299 /* Make sure -lgo is before the math library, since libgo itself
300 uses those math routines. */
301 if (!saw_math && (args[i] & MATHLIB) && library > 0)
302 {
303 --j;
304 saw_math = &decoded_options[i];
305 }
306
307 if (!saw_thread && (args[i] & THREADLIB) && library > 0)
308 {
309 --j;
310 saw_thread = &decoded_options[i];
311 }
312
313 if (!saw_libc && (args[i] & WITHLIBC) && library > 0)
314 {
315 --j;
316 saw_libc = &decoded_options[i];
317 }
318
319 if ((args[i] & SKIPOPT) != 0)
320 --j;
321
322 i++;
323 j++;
324 }
325
326 /* If we didn't see a -o option, add one. This is because we need
327 the driver to pass all .go files to go1. Without a -o option the
328 driver will invoke go1 separately for each input file. FIXME:
329 This should probably use some other interface to force the driver
330 to set combine_inputs. */
331 if (first_go_file != NULL && !saw_opt_o)
332 {
333 if (saw_opt_c || saw_opt_S)
334 {
335 const char *base;
336 int baselen;
337 int alen;
338 char *out;
339
340 base = lbasename (first_go_file);
341 baselen = strlen (base) - 3;
342 alen = baselen + 3;
343 out = XNEWVEC (char, alen);
344 memcpy (out, base, baselen);
345 /* The driver will convert .o to some other suffix (e.g.,
346 .obj) if appropriate. */
347 out[baselen] = '.';
348 if (saw_opt_S)
349 out[baselen + 1] = 's';
350 else
351 out[baselen + 1] = 'o';
352 out[baselen + 2] = '\0';
353 generate_option (OPT_o, out, 1, CL_DRIVER,
354 &new_decoded_options[j]);
355 }
356 else
357 generate_option (OPT_o, "a.out", 1, CL_DRIVER,
358 &new_decoded_options[j]);
359 j++;
360 }
361
362 /* Add `-lgo' if we haven't already done so. */
363 if (library > 0)
364 {
365 generate_option (OPT_l, LIBGOBEGIN, 1, CL_DRIVER,
366 &new_decoded_options[j]);
367 added_libraries++;
368 j++;
369
370 #ifdef HAVE_LD_STATIC_DYNAMIC
371 if (library > 1 && !static_link)
372 {
373 generate_option (OPT_Wl_, LD_STATIC_OPTION, 1, CL_DRIVER,
374 &new_decoded_options[j]);
375 j++;
376 }
377 #endif
378
379 generate_option (OPT_l, saw_profile_flag ? LIBGO_PROFILE : LIBGO, 1,
380 CL_DRIVER, &new_decoded_options[j]);
381 added_libraries++;
382 j++;
383
384 #ifdef HAVE_LD_STATIC_DYNAMIC
385 if (library > 1 && !static_link)
386 {
387 generate_option (OPT_Wl_, LD_DYNAMIC_OPTION, 1, CL_DRIVER,
388 &new_decoded_options[j]);
389 j++;
390 }
391 #endif
392
393 /* When linking libgo statically we also need to link with the
394 pthread library. */
395 if (library > 1 || static_link)
396 need_thread = 1;
397 }
398
399 if (saw_thread)
400 new_decoded_options[j++] = *saw_thread;
401 else if (library > 0 && need_thread)
402 {
403 generate_option (OPT_l,
404 (saw_profile_flag
405 ? THREAD_LIBRARY_PROFILE
406 : THREAD_LIBRARY),
407 1, CL_DRIVER, &new_decoded_options[j]);
408 added_libraries++;
409 j++;
410 }
411
412 if (saw_math)
413 new_decoded_options[j++] = *saw_math;
414 else if (library > 0 && need_math)
415 {
416 generate_option (OPT_l,
417 saw_profile_flag ? MATH_LIBRARY_PROFILE : MATH_LIBRARY,
418 1, CL_DRIVER, &new_decoded_options[j]);
419 added_libraries++;
420 j++;
421 }
422
423 if (saw_libc)
424 new_decoded_options[j++] = *saw_libc;
425 if (shared_libgcc && !static_link)
426 generate_option (OPT_shared_libgcc, NULL, 1, CL_DRIVER,
427 &new_decoded_options[j++]);
428
429 /* libgcc wraps pthread_create to support split stack, however, due to
430 relative ordering of -lpthread and -lgcc, we can't just mark
431 __real_pthread_create in libgcc as non-weak. But we need to link in
432 pthread_create from pthread if we are statically linking, so we work-
433 around by passing -u pthread_create to the linker. */
434 if (static_link && supports_split_stack)
435 {
436 generate_option (OPT_Wl_, "-u,pthread_create", 1, CL_DRIVER,
437 &new_decoded_options[j]);
438 j++;
439 }
440
441 #if defined(TARGET_SOLARIS) && !defined(USE_GLD)
442 /* We use a common symbol for go$zerovalue. On Solaris, when not
443 using the GNU linker, the Solaris linker needs an option to not
444 warn about this. Everything works without this option, but you
445 get unsightly warnings at link time. */
446 generate_option (OPT_Wl_, "-t", 1, CL_DRIVER, &new_decoded_options[j]);
447 j++;
448 #endif
449
450 *in_decoded_options_count = j;
451 *in_decoded_options = new_decoded_options;
452 *in_added_libraries = added_libraries;
453 }
454
455 /* Called before linking. Returns 0 on success and -1 on failure. */
456 int lang_specific_pre_link (void) /* Not used for Go. */
457 {
458 return 0;
459 }
460
461 /* Number of extra output files that lang_specific_pre_link may generate. */
462 int lang_specific_extra_outfiles = 0; /* Not used for Go. */