Line data Source code
1 : /* gm2spec.cc specific flags and argument handling within GNU Modula-2.
2 :
3 : Copyright (C) 2007-2026 Free Software Foundation, Inc.
4 : Contributed by Gaius Mulley <gaius@glam.ac.uk>.
5 :
6 : This file is part of GNU Modula-2.
7 :
8 : GNU Modula-2 is free software; you can redistribute it and/or modify
9 : it under the terms of the GNU General Public License as published by
10 : the Free Software Foundation; either version 3, or (at your option)
11 : any later version.
12 :
13 : GNU Modula-2 is distributed in the hope that it will be useful, but
14 : WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 : General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with GNU Modula-2; see the file COPYING3. If not see
20 : <http://www.gnu.org/licenses/>. */
21 :
22 : #include "config.h"
23 : #define INCLUDE_STRING
24 : #define INCLUDE_VECTOR
25 : #include "system.h"
26 : #include "coretypes.h"
27 : #include "tm.h"
28 : #include "xregex.h"
29 : #include "obstack.h"
30 : #include "intl.h"
31 : #include "prefix.h"
32 : #include "opt-suggestions.h"
33 : #include "gcc.h"
34 : #include "opts.h"
35 : #include "vec.h"
36 :
37 : #include "m2/gm2config.h"
38 :
39 : #ifdef HAVE_DIRENT_H
40 : #include <dirent.h>
41 : #else
42 : #ifdef HAVE_SYS_NDIR_H
43 : #include <sys/ndir.h>
44 : #endif
45 : #ifdef HAVE_SYS_DIR_H
46 : #include <sys/dir.h>
47 : #endif
48 : #ifdef HAVE_NDIR_H
49 : #include <ndir.h>
50 : #endif
51 : #endif
52 :
53 : /* This bit is set if the arguments is a M2 source file. */
54 : #define M2SOURCE (1<<1)
55 : /* This bit is set if we saw a `-xfoo' language specification. */
56 : #define LANGSPEC (1<<2)
57 : /* This bit is set if they did `-lm' or `-lmath'. */
58 : #define MATHLIB (1<<3)
59 : /* This bit is set if they did `-lc'. */
60 : #define WITHLIBC (1<<4)
61 : /* Skip this option. */
62 : #define SKIPOPT (1<<5)
63 :
64 : #ifndef MATH_LIBRARY
65 : #define MATH_LIBRARY "m"
66 : #endif
67 : #ifndef MATH_LIBRARY_PROFILE
68 : #define MATH_LIBRARY_PROFILE MATH_LIBRARY
69 : #endif
70 :
71 : #ifndef LIBSTDCXX
72 : #define LIBSTDCXX "stdc++"
73 : #endif
74 : #ifndef LIBSTDCXX_PROFILE
75 : #define LIBSTDCXX_PROFILE LIBSTDCXX
76 : #endif
77 : #ifndef LIBSTDCXX_STATIC
78 : #define LIBSTDCXX_STATIC NULL
79 : #endif
80 :
81 : #ifndef LIBCXX
82 : #define LIBCXX "c++"
83 : #endif
84 : #ifndef LIBCXX_PROFILE
85 : #define LIBCXX_PROFILE LIBCXX
86 : #endif
87 : #ifndef LIBCXX_STATIC
88 : #define LIBCXX_STATIC NULL
89 : #endif
90 :
91 : #ifndef LIBCXXABI
92 : #define LIBCXXABI "c++abi"
93 : #endif
94 : #ifndef LIBCXXABI_PROFILE
95 : #define LIBCXXABI_PROFILE LIBCXXABI
96 : #endif
97 : #ifndef LIBCXXABI_STATIC
98 : #define LIBCXXABI_STATIC NULL
99 : #endif
100 :
101 : /* The values used here must match those of the stdlib_kind enumeration
102 : in c.opt. */
103 : enum stdcxxlib_kind
104 : {
105 : USE_LIBSTDCXX = 1,
106 : USE_LIBCXX = 2
107 : };
108 :
109 : #define DEFAULT_DIALECT "pim"
110 :
111 : #undef DEBUG_ARG
112 :
113 : typedef enum { iso, pim, min, logitech, pimcoroutine, maxlib } libs;
114 :
115 : /* These are the library names which are installed as part of gm2 and reflect
116 : -flibs=name. The -flibs= option provides the user with a short cut to add
117 : libraries without having to know the include and link path. */
118 :
119 : static const char *library_name[maxlib]
120 : = { "m2iso", "m2pim", "m2min", "m2log", "m2cor" };
121 :
122 : /* They match the installed archive name for example libm2iso.a,
123 : libm2pim.a, libm2min.a, libm2log.a and libm2cor.a. They also match a
124 : subdirectory name where the definition modules are kept. The driver
125 : checks the argument to -flibs= for an entry in library_name or
126 : alternatively the existance of the subdirectory (to allow for third
127 : party libraries to coexist). */
128 :
129 : static const char *library_abbrev[maxlib]
130 : = { "iso", "pim", "min", "log", "cor" };
131 :
132 : /* Users may specifiy -flibs=pim,iso etc which are mapped onto
133 : -flibs=m2pim,m2iso respectively. This provides a match between
134 : the dialect of Modula-2 and the library set. */
135 :
136 : static bool seen_scaffold_static = false;
137 : static bool seen_scaffold_dynamic = false;
138 : static bool seen_scaffold_main = false;
139 : static bool scaffold_static = false;
140 : static bool scaffold_dynamic = true; // Default uses -fscaffold-dynamic.
141 : static bool scaffold_main = false;
142 : static bool seen_gen_module_list = false;
143 : static bool seen_uselist = false;
144 : static bool uselist = false;
145 : static bool gen_module_list = true; // Default uses -fgen-module-list=-.
146 : static const char *gen_module_filename = "-";
147 : /* The original argument list and related info is copied here. */
148 : static unsigned int gm2_xargc;
149 : static const struct cl_decoded_option *gm2_x_decoded_options;
150 : static void append_arg (const struct cl_decoded_option *);
151 :
152 : /* The new argument list will be built here. */
153 : static unsigned int gm2_newargc;
154 : static struct cl_decoded_option *gm2_new_decoded_options;
155 : static const char *libraries = NULL; /* Abbreviated libraries. */
156 : static const char *m2_path_name = "";
157 :
158 361506 : typedef struct named_path_s {
159 : std::vector<const char*>path;
160 : const char *name;
161 : bool lib_root;
162 : } named_path;
163 :
164 : static std::vector<named_path>Ipaths;
165 :
166 : /* push_back_Ipath pushes a named path to the Ipaths global variable. */
167 :
168 : static void
169 123189 : push_back_Ipath (const char *arg)
170 : {
171 123189 : if (Ipaths.empty ())
172 : {
173 19310 : named_path np;
174 19310 : np.path.push_back (arg);
175 19310 : np.name = m2_path_name;
176 19310 : np.lib_root = false;
177 19310 : Ipaths.push_back (np);
178 19310 : }
179 : else
180 : {
181 103879 : if (strcmp (Ipaths.back ().name,
182 : m2_path_name) == 0)
183 36585 : Ipaths.back ().path.push_back (arg);
184 : else
185 : {
186 67294 : named_path np;
187 67294 : np.path.push_back (arg);
188 67294 : np.name = m2_path_name;
189 67294 : np.lib_root = false;
190 67294 : Ipaths.push_back (np);
191 67294 : }
192 : }
193 123189 : }
194 :
195 : /* push_back_lib_root pushes a lib_root onto the Ipaths vector.
196 : The ordering of the -fm2_add_lib_root=, -I and named paths
197 : must be preserved. */
198 :
199 : static void
200 24 : push_back_lib_root (const char *arg)
201 : {
202 24 : named_path np;
203 24 : np.name = arg;
204 24 : np.lib_root = true;
205 24 : Ipaths.push_back (np);
206 24 : }
207 :
208 : /* Return whether strings S1 and S2 are both NULL or both the same
209 : string. */
210 :
211 : static bool
212 503358 : strings_same (const char *s1, const char *s2)
213 : {
214 503358 : return s1 == s2 || (s1 != NULL && s2 != NULL && strcmp (s1, s2) == 0);
215 : }
216 :
217 : bool
218 101049 : options_same (const struct cl_decoded_option *opt1,
219 : const struct cl_decoded_option *opt2)
220 : {
221 101049 : return (opt1->opt_index == opt2->opt_index
222 83893 : && strings_same (opt1->arg, opt2->arg)
223 83893 : && strings_same (opt1->orig_option_with_args_text,
224 83893 : opt2->orig_option_with_args_text)
225 83893 : && strings_same (opt1->canonical_option[0],
226 83893 : opt2->canonical_option[0])
227 83893 : && strings_same (opt1->canonical_option[1],
228 83893 : opt2->canonical_option[1])
229 83893 : && strings_same (opt1->canonical_option[2],
230 83893 : opt2->canonical_option[2])
231 83893 : && strings_same (opt1->canonical_option[3],
232 83893 : opt2->canonical_option[3])
233 83893 : && (opt1->canonical_option_num_elements
234 83893 : == opt2->canonical_option_num_elements)
235 83893 : && opt1->value == opt2->value
236 184942 : && opt1->errors == opt2->errors);
237 : }
238 :
239 : /* Append another argument to the list being built. */
240 :
241 : static void
242 651644 : append_arg (const struct cl_decoded_option *arg)
243 : {
244 651644 : static unsigned int newargsize;
245 :
246 651644 : if (gm2_new_decoded_options == gm2_x_decoded_options
247 103203 : && gm2_newargc < gm2_xargc
248 752693 : && options_same (arg, &gm2_x_decoded_options[gm2_newargc]))
249 : {
250 83893 : ++gm2_newargc;
251 83893 : return; /* Nothing new here. */
252 : }
253 :
254 567751 : if (gm2_new_decoded_options == gm2_x_decoded_options)
255 : { /* Make new arglist. */
256 19310 : unsigned int i;
257 :
258 19310 : newargsize = (gm2_xargc << 2) + 20; /* This should handle all. */
259 19310 : gm2_new_decoded_options = XNEWVEC (struct cl_decoded_option, newargsize);
260 :
261 : /* Copy what has been done so far. */
262 103203 : for (i = 0; i < gm2_newargc; ++i)
263 83893 : gm2_new_decoded_options[i] = gm2_x_decoded_options[i];
264 : }
265 :
266 567751 : if (gm2_newargc == newargsize)
267 0 : fatal_error (input_location, "overflowed output argument list for %qs",
268 0 : arg->orig_option_with_args_text);
269 :
270 567751 : gm2_new_decoded_options[gm2_newargc++] = *arg;
271 : }
272 :
273 : /* Append an option described by OPT_INDEX, ARG and VALUE to the list
274 : being built. */
275 :
276 : static void
277 333320 : append_option (size_t opt_index, const char *arg, int value)
278 : {
279 333320 : struct cl_decoded_option decoded;
280 :
281 333320 : generate_option (opt_index, arg, value, CL_DRIVER, &decoded);
282 333320 : append_arg (&decoded);
283 333320 : }
284 :
285 : /* safe_strdup safely duplicates a string. */
286 :
287 : static char *
288 218385 : safe_strdup (const char *s)
289 : {
290 0 : if (s != NULL)
291 123213 : return xstrdup (s);
292 : return NULL;
293 : }
294 :
295 : /* add_default_libs adds the -l option which is derived from the
296 : libraries. */
297 :
298 : static int
299 2142 : add_default_libs (const char *libraries)
300 : {
301 2142 : const char *l = libraries;
302 2142 : const char *e;
303 2142 : char *libname;
304 2142 : unsigned int libcount = 0;
305 :
306 8568 : while ((l != NULL) && (l[0] != (char)0))
307 : {
308 8568 : e = index (l, ',');
309 8568 : if (e == NULL)
310 : {
311 2142 : libname = xstrdup (l);
312 2142 : l = NULL;
313 2142 : append_option (OPT_l, safe_strdup (libname), 1);
314 2142 : libcount++;
315 2142 : free (libname);
316 : }
317 : else
318 : {
319 6426 : libname = xstrndup (l, e - l);
320 6426 : l = e + 1;
321 6426 : append_option (OPT_l, safe_strdup (libname), 1);
322 6426 : libcount++;
323 6426 : free (libname);
324 : }
325 : }
326 2142 : return libcount;
327 : }
328 :
329 : /* add_word returns a new string which has the contents of lib
330 : appended to list. If list is NULL then lib is duplicated and
331 : returned otherwise the list is appended by "," and the contents of
332 : lib. */
333 :
334 : static const char *
335 11200 : add_word (const char *list, const char *lib)
336 : {
337 11200 : char *copy;
338 11200 : if (list == NULL)
339 2800 : return xstrdup (lib);
340 8400 : copy = (char *) xmalloc (strlen (list) + strlen (lib) + 1 + 1);
341 8400 : strcpy (copy, list);
342 8400 : strcat (copy, ",");
343 8400 : strcat (copy, lib);
344 8400 : return copy;
345 : }
346 :
347 : /* convert_abbreviation checks abbreviation against known library
348 : abbreviations. If an abbreviation is found it converts the element
349 : to the full library name, otherwise the user supplied name is added
350 : to the full_libraries list. A new string is returned. */
351 :
352 : static const char *
353 11200 : convert_abbreviation (const char *full_libraries, const char *abbreviation)
354 : {
355 67200 : for (int i = 0; i < maxlib; i++)
356 56000 : if (strcmp (abbreviation, library_abbrev[i]) == 0)
357 0 : return add_word (full_libraries, library_name[i]);
358 : /* Perhaps the user typed in the whole lib name rather than an abbrev. */
359 33600 : for (int i = 0; i < maxlib; i++)
360 33600 : if (strcmp (abbreviation, library_name[i]) == 0)
361 11200 : return add_word (full_libraries, abbreviation);
362 : /* Not found, probably a user typo. */
363 0 : error ("%qs is not a valid Modula-2 system library name or abbreviation",
364 : abbreviation);
365 0 : return full_libraries;
366 : }
367 :
368 : /* convert_abbreviations checks each element in the library list to
369 : see if an a known library abbreviation was used. If found it
370 : converts the element to the full library name, otherwise the
371 : element is copied into the list. A new string is returned. */
372 :
373 : static const char *
374 2800 : convert_abbreviations (const char *libraries)
375 : {
376 2800 : const char *start = libraries;
377 2800 : const char *end;
378 2800 : const char *full_libraries = NULL;
379 :
380 11200 : do
381 : {
382 11200 : end = index (start, ',');
383 11200 : if (end == NULL)
384 : {
385 2800 : full_libraries = convert_abbreviation (full_libraries, start);
386 2800 : start = NULL;
387 : }
388 : else
389 : {
390 8400 : full_libraries = convert_abbreviation (full_libraries,
391 8400 : xstrndup (start, end - start));
392 8400 : start = end + 1;
393 : }
394 : }
395 11200 : while ((start != NULL) && (start[0] != (char)0));
396 2800 : return full_libraries;
397 : }
398 :
399 : /* add_m2_I_path appends -fm2-pathname, -fm2-pathnameI and -fm2-add-lib-root
400 : options to the command line which are contructed in the saved Ipaths.
401 : The order of these options must be maintained. */
402 :
403 : static void
404 19310 : add_m2_I_path (void)
405 : {
406 105938 : for (auto np : Ipaths)
407 : {
408 86628 : if (np.lib_root)
409 48 : append_option (OPT_fm2_pathname_rootI_, safe_strdup (np.name), 1);
410 86604 : else if (strcmp (np.name, "") == 0)
411 2176 : append_option (OPT_fm2_pathname_, safe_strdup ("-"), 1);
412 : else
413 84428 : append_option (OPT_fm2_pathname_, safe_strdup (np.name), 1);
414 209817 : for (auto *s : np.path)
415 246378 : append_option (OPT_fm2_pathnameI, safe_strdup (s), 1);
416 86628 : }
417 19310 : Ipaths.clear();
418 19310 : }
419 :
420 :
421 : void
422 19310 : lang_specific_driver (struct cl_decoded_option **in_decoded_options,
423 : unsigned int *in_decoded_options_count,
424 : int *in_added_libraries)
425 : {
426 19310 : unsigned int argc = *in_decoded_options_count;
427 19310 : struct cl_decoded_option *decoded_options = *in_decoded_options;
428 19310 : unsigned int i;
429 :
430 : /* True if we saw a `-xfoo' language specification on the command
431 : line. This function will add a -xmodula-2 if the user has not
432 : already placed one onto the command line. */
433 19310 : bool seen_x_flag = false;
434 19310 : const char *language = NULL;
435 :
436 : /* If nonzero, the user gave us the `-p' or `-pg' flag. */
437 19310 : int saw_profile_flag = 0;
438 :
439 : /* What action to take for the c++ runtime library:
440 : -1 means we should not link it in.
441 : 0 means we should link it if it is needed.
442 : 1 means it is needed and should be linked in.
443 : 2 means it is needed but should be linked statically. */
444 19310 : int library = 0;
445 :
446 : /* Which c++ runtime library to link. */
447 19310 : stdcxxlib_kind which_library = USE_LIBSTDCXX;
448 :
449 19310 : const char *dialect = DEFAULT_DIALECT;
450 :
451 : /* An array used to flag each argument that needs a bit set for
452 : LANGSPEC, MATHLIB, or WITHLIBC. */
453 19310 : int *args;
454 :
455 : /* Have we seen -fmod=? */
456 19310 : char *module_extension = NULL;
457 :
458 : /* Should the driver perform a link? */
459 19310 : bool linking = true;
460 :
461 : /* Should the driver link the shared gm2 libs? */
462 19310 : bool shared_libgm2 = true;
463 :
464 : /* "-lm" or "-lmath" if it appears on the command line. */
465 19310 : const struct cl_decoded_option *saw_math = NULL;
466 :
467 : /* "-lc" if it appears on the command line. */
468 19310 : const struct cl_decoded_option *saw_libc = NULL;
469 :
470 : /* By default, we throw on the math library if we have one. */
471 19310 : int need_math = (MATH_LIBRARY[0] != '\0');
472 :
473 : /* 1 if we should add -lpthread to the command-line.
474 : FIXME: the default should be a configuration choice. */
475 19310 : int need_pthread = 1;
476 :
477 : /* True if we saw -static. */
478 19310 : int static_link = 0;
479 :
480 : /* True if we should add -shared-libgcc to the command-line. */
481 19310 : int shared_libgcc = 1;
482 :
483 : /* Have we seen the -v flag? */
484 19310 : bool verbose = false;
485 :
486 : /* Have we seen the -fm2-pathname flag? */
487 19310 : bool seen_pathname = false;
488 :
489 : /* The number of libraries added in. */
490 19310 : int added_libraries;
491 :
492 : /* True if we should add -fplugin=m2rte to the command-line. */
493 19310 : bool need_plugin = false;
494 :
495 : /* True if we should set up include paths and library paths. */
496 19310 : bool allow_libraries = true;
497 :
498 : #if defined(DEBUG_ARG)
499 : printf ("argc = %d\n", argc);
500 : fprintf (stderr, "Incoming:");
501 : for (i = 0; i < argc; i++)
502 : fprintf (stderr, " %s", decoded_options[i].orig_option_with_args_text);
503 : fprintf (stderr, "\n");
504 : #endif
505 :
506 : // add_spec_function ("m2I", add_m2_I_path);
507 19310 : gm2_xargc = argc;
508 19310 : gm2_x_decoded_options = decoded_options;
509 19310 : gm2_newargc = 0;
510 19310 : gm2_new_decoded_options = decoded_options;
511 19310 : added_libraries = *in_added_libraries;
512 19310 : args = XCNEWVEC (int, argc);
513 :
514 : /* First pass through arglist.
515 :
516 : If -nostdlib or a "turn-off-linking" option is anywhere in the
517 : command line, don't do any library-option processing (except
518 : relating to -x). */
519 :
520 561896 : for (i = 1; i < argc; i++)
521 : {
522 542586 : const char *arg = decoded_options[i].arg;
523 542586 : args[i] = 0;
524 : #if defined(DEBUG_ARG)
525 : printf ("1st pass: %s\n",
526 : decoded_options[i].orig_option_with_args_text);
527 : #endif
528 542586 : switch (decoded_options[i].opt_index)
529 : {
530 : case OPT_fiso:
531 542586 : dialect = "iso";
532 : break;
533 158 : case OPT_fpim2:
534 158 : dialect = "pim2";
535 158 : break;
536 30 : case OPT_fpim3:
537 30 : dialect = "pim3";
538 30 : break;
539 184 : case OPT_fpim4:
540 184 : dialect = "pim4";
541 184 : break;
542 11563 : case OPT_fpim:
543 11563 : dialect = "pim";
544 11563 : break;
545 19187 : case OPT_flibs_:
546 19187 : libraries = xstrdup (arg);
547 19187 : allow_libraries = decoded_options[i].value;
548 19187 : args[i] |= SKIPOPT; /* We will add the option if it is needed. */
549 19187 : break;
550 6 : case OPT_fmod_:
551 6 : module_extension = xstrdup (arg);
552 : #if defined(DEBUG_ARG)
553 : printf ("seen -fmod=%s\n", module_extension);
554 : #endif
555 6 : break;
556 0 : case OPT_fpthread:
557 0 : need_pthread = decoded_options[i].value;
558 0 : args[i] |= SKIPOPT; /* We will add the option if it is needed. */
559 0 : break;
560 491 : case OPT_fm2_plugin:
561 491 : need_plugin = decoded_options[i].value;
562 : #ifndef ENABLE_PLUGIN
563 : if (need_plugin)
564 : error ("plugin support is disabled; configure with "
565 : "%<--enable-plugin%>");
566 : #endif
567 491 : args[i] |= SKIPOPT; /* We will add the option if it is needed. */
568 491 : break;
569 62 : case OPT_fscaffold_dynamic:
570 62 : seen_scaffold_dynamic = true;
571 62 : scaffold_dynamic = decoded_options[i].value;
572 62 : args[i] |= SKIPOPT; /* We will add the option if it is needed. */
573 62 : break;
574 22 : case OPT_fscaffold_static:
575 22 : seen_scaffold_static = true;
576 22 : scaffold_static = decoded_options[i].value;
577 22 : args[i] |= SKIPOPT; /* We will add the option if it is needed. */
578 22 : break;
579 84 : case OPT_fscaffold_main:
580 84 : seen_scaffold_main = true;
581 84 : scaffold_main = decoded_options[i].value;
582 84 : args[i] |= SKIPOPT; /* We will add the option if it is needed. */
583 84 : break;
584 0 : case OPT_fgen_module_list_:
585 0 : seen_gen_module_list = true;
586 0 : gen_module_list = decoded_options[i].value;
587 0 : if (gen_module_list)
588 0 : gen_module_filename = decoded_options[i].arg;
589 : break;
590 0 : case OPT_fuse_list_:
591 0 : seen_uselist = true;
592 0 : uselist = decoded_options[i].value;
593 0 : break;
594 102689 : case OPT_fm2_pathname_:
595 102689 : seen_pathname = true;
596 102689 : args[i] |= SKIPOPT; /* We will add the option if it is needed. */
597 102689 : m2_path_name = decoded_options[i].arg;
598 102689 : break;
599 24 : case OPT_fm2_pathname_root_:
600 24 : args[i] |= SKIPOPT; /* We will add the option if it is needed. */
601 24 : push_back_lib_root (decoded_options[i].arg);
602 24 : break;
603 0 : case OPT__help:
604 0 : case OPT__help_:
605 : /* Let gcc.cc handle this, as it has a really
606 : cool facility for handling --help and --verbose --help. */
607 0 : *in_added_libraries = 0;
608 0 : return;
609 121013 : case OPT_I:
610 121013 : args[i] |= SKIPOPT; /* We will add the option if it is needed. */
611 121013 : push_back_Ipath (decoded_options[i].arg);
612 121013 : break;
613 0 : case OPT_nostdlib:
614 0 : case OPT_nostdlib__:
615 0 : case OPT_nodefaultlibs:
616 0 : library = -1;
617 0 : break;
618 :
619 2678 : case OPT_l:
620 2678 : if (strcmp (arg, MATH_LIBRARY) == 0)
621 : {
622 2678 : args[i] |= MATHLIB;
623 2678 : need_math = 0;
624 : }
625 0 : else if (strcmp (arg, "c") == 0)
626 0 : args[i] |= WITHLIBC;
627 : else
628 : /* Unrecognized libraries (e.g. -lfoo) may require libstdc++. */
629 0 : library = (library == 0) ? 1 : library;
630 : break;
631 :
632 0 : case OPT_pg:
633 0 : case OPT_p:
634 0 : saw_profile_flag++;
635 0 : break;
636 :
637 0 : case OPT_x:
638 0 : seen_x_flag = true;
639 0 : language = arg;
640 0 : break;
641 :
642 0 : case OPT_v:
643 0 : verbose = true;
644 0 : break;
645 :
646 0 : case OPT_Xlinker:
647 0 : case OPT_Wl_:
648 : /* Arguments that go directly to the linker might be .o files,
649 : or something, and so might cause libstdc++ to be needed. */
650 0 : if (library == 0)
651 542586 : library = 1;
652 : break;
653 :
654 12389 : case OPT_c:
655 12389 : case OPT_r:
656 12389 : case OPT_S:
657 12389 : case OPT_E:
658 12389 : case OPT_M:
659 12389 : case OPT_MM:
660 12389 : case OPT_fsyntax_only:
661 : /* Don't specify libraries if we won't link, since that would
662 : cause a warning. */
663 12389 : linking = false;
664 12389 : library = -1;
665 12389 : break;
666 :
667 : /* PCH makes no sense here, we do not catch -output-pch on purpose,
668 : that should flag an error. */
669 0 : case OPT_fpch_deps:
670 0 : case OPT_fpch_preprocess:
671 0 : case OPT_Winvalid_pch:
672 0 : args[i] |= SKIPOPT;
673 0 : break;
674 :
675 0 : case OPT_static:
676 0 : static_link = 1;
677 0 : break;
678 :
679 0 : case OPT_static_libgcc:
680 0 : shared_libgcc = 0;
681 0 : break;
682 :
683 0 : case OPT_static_libstdc__:
684 0 : library = library >= 0 ? 2 : library;
685 : #ifdef HAVE_LD_STATIC_DYNAMIC
686 : /* Remove -static-libstdc++ from the command only if target supports
687 : LD_STATIC_DYNAMIC. When not supported, it is left in so that a
688 : back-end target can use outfile substitution. */
689 0 : args[i] |= SKIPOPT;
690 : #endif
691 0 : break;
692 :
693 0 : case OPT_static_libgm2:
694 0 : shared_libgm2 = false;
695 : #ifdef HAVE_LD_STATIC_DYNAMIC
696 : /* Remove -static-libgm2 from the command only if target supports
697 : LD_STATIC_DYNAMIC. When not supported, it is left in so that a
698 : back-end target can use outfile substitution. */
699 0 : args[i] |= SKIPOPT;
700 : #endif
701 0 : break;
702 :
703 0 : case OPT_stdlib_:
704 0 : which_library = (stdcxxlib_kind) decoded_options[i].value;
705 0 : break;
706 :
707 26515 : case OPT_SPECIAL_input_file:
708 26515 : {
709 26515 : const char *source_file = decoded_options[i].orig_option_with_args_text;
710 : #if defined(DEBUG_ARG)
711 : printf ("seen OPT_SPECIAL_input_file: %s\n", source_file);
712 : #endif
713 26515 : if (source_file != NULL)
714 : {
715 : /* Record that this is a Modula-2 source file. */
716 26515 : const char *suffix = strrchr (source_file, '.');
717 : #if defined(DEBUG_ARG)
718 : printf ("ext = %s\n", suffix);
719 : #endif
720 26515 : if ((suffix != NULL)
721 26512 : && ((strcmp (suffix, ".mod") == 0)
722 11464 : || ((module_extension != NULL)
723 6 : && (strcmp (suffix, module_extension) == 0))))
724 : {
725 : #if defined(DEBUG_ARG)
726 : printf ("modula-2 source file detected: %s\n", source_file);
727 : #endif
728 15054 : args[i] |= M2SOURCE;
729 : }
730 : }
731 : }
732 : break;
733 :
734 : default:
735 : break;
736 : }
737 : }
738 19310 : if (language != NULL && (strcmp (language, "modula-2") != 0))
739 : return;
740 :
741 19310 : if (! seen_pathname)
742 : /* Not seen -fm2-pathname therefore make current working directory
743 : the first place to look for modules. */
744 2176 : push_back_Ipath (".");
745 :
746 : /* Override the default when the user specifies it. */
747 19310 : if (seen_scaffold_static && scaffold_static && !seen_scaffold_dynamic)
748 0 : scaffold_dynamic = false;
749 :
750 : /* If both options have been seen and both are true, that means the user
751 : tried to set both. */
752 19310 : if (seen_scaffold_dynamic && scaffold_dynamic
753 0 : && seen_scaffold_static && scaffold_static)
754 0 : error ("%qs and %qs cannot both be enabled",
755 : "-fscaffold-dynamic", "-fscaffold-static");
756 :
757 19310 : if (uselist && gen_module_list)
758 : {
759 0 : if (! seen_gen_module_list)
760 0 : gen_module_list = false;
761 0 : if (uselist && gen_module_list)
762 0 : error ("%qs and %qs cannot both be enabled",
763 : "-fgen-module-list=", "-fuse-list=");
764 : }
765 :
766 : /* There's no point adding -shared-libgcc if we don't have a shared
767 : libgcc. */
768 : #ifndef ENABLE_SHARED_LIBGCC
769 : shared_libgcc = 0;
770 : #endif
771 :
772 : /* Second pass through arglist, transforming arguments as appropriate. */
773 :
774 19310 : append_arg (&decoded_options[0]); /* Start with command name, of course. */
775 581206 : for (i = 1; i < argc; ++i)
776 : {
777 : #if defined(DEBUG_ARG)
778 : printf ("2nd pass: %s",
779 : decoded_options[i].orig_option_with_args_text);
780 : if ((args[i] & SKIPOPT) != 0)
781 : printf (" skipped");
782 : if ((args[i] & M2SOURCE) != 0)
783 : printf (" m2 source");
784 : printf ("\n");
785 : #endif
786 542586 : if ((args[i] & SKIPOPT) == 0)
787 : {
788 299014 : if ((args[i] & M2SOURCE) == 0)
789 : {
790 283960 : append_arg (&decoded_options[i]);
791 : /* Make sure -lstdc++ is before the math library, since libstdc++
792 : itself uses those math routines. */
793 283960 : if (!saw_math && (args[i] & MATHLIB) && library > 0)
794 : saw_math = &decoded_options[i];
795 :
796 283960 : if (!saw_libc && (args[i] & WITHLIBC) && library > 0)
797 : saw_libc = &decoded_options[i];
798 : }
799 : else
800 : {
801 15054 : if ((! seen_x_flag) && module_extension)
802 : {
803 : #if defined(DEBUG_ARG)
804 : printf (" adding: -x modula-2 ");
805 : #endif
806 6 : append_option (OPT_x, "modula-2", 1);
807 : }
808 15054 : append_arg (&decoded_options[i]);
809 : #if defined(DEBUG_ARG)
810 : printf (" adding: %s\n",
811 : decoded_options[i].orig_option_with_args_text);
812 : #endif
813 15054 : if ((! seen_x_flag) && module_extension)
814 : {
815 : #if defined(DEBUG_ARG)
816 : printf (" adding: -x none ");
817 : #endif
818 6 : append_option (OPT_x, "none", 1);
819 : }
820 : }
821 : }
822 : #if defined(DEBUG_ARG)
823 : else
824 : printf ("skipping: %s\n",
825 : decoded_options[i].orig_option_with_args_text);
826 : #endif
827 : }
828 :
829 19310 : add_m2_I_path ();
830 : /* We now add in extra arguments to facilitate a successful link.
831 : Note that the libraries are added to the end of the link here
832 : and also placed earlier into the link by lang-specs.h. Possibly
833 : this is needed because the m2pim,m2iso libraries are cross linked
834 : (--fixme-- combine all the m2 libraries into a single archive).
835 :
836 : We also add default scaffold linking options. */
837 :
838 : /* If we have not seen either uselist or gen_module_list and we need
839 : to link or compile a module list then we turn on -fgen_module_list=-
840 : as the default. */
841 19310 : if (!seen_uselist && !seen_gen_module_list
842 19310 : && (linking || scaffold_main))
843 6938 : append_option (OPT_fgen_module_list_, "-", 1);
844 :
845 : /* We checked that they were not both enabled above, if there was a set
846 : value (even iff that is 'off'), pass that to the FE. */
847 19310 : if (seen_scaffold_dynamic || scaffold_dynamic)
848 19310 : append_option (OPT_fscaffold_dynamic, NULL, scaffold_dynamic);
849 19310 : if (seen_scaffold_static)
850 22 : append_option (OPT_fscaffold_static, NULL, scaffold_static);
851 :
852 : /* If the user has set fscaffold-main specifically, use that. Otherwise, if
853 : we are linking then set it so that we generate the relevant code for the
854 : main module. */
855 19310 : if (seen_scaffold_main)
856 84 : append_option (OPT_fscaffold_main, NULL, scaffold_main);
857 19226 : else if (linking)
858 6884 : append_option (OPT_fscaffold_main, NULL, true);
859 :
860 19310 : if (allow_libraries)
861 : {
862 : /* If the libraries have not been specified by the user, select the
863 : appropriate libraries for the active dialect. */
864 2800 : if (libraries == NULL)
865 : {
866 2800 : if (strcmp (dialect, "iso") == 0)
867 310 : libraries = xstrdup ("m2iso,m2cor,m2pim,m2log");
868 : else
869 : /* Default to pim libraries otherwise. */
870 2490 : libraries = xstrdup ("m2cor,m2log,m2pim,m2iso");
871 : }
872 2800 : libraries = convert_abbreviations (libraries);
873 2800 : append_option (OPT_flibs_, xstrdup (libraries), 1);
874 : }
875 : else
876 16510 : append_option (OPT_flibs_, xstrdup ("-"), 0); /* no system libs. */
877 :
878 19310 : if (need_plugin)
879 197 : append_option (OPT_fplugin_, "m2rte", 1);
880 :
881 19310 : if (linking)
882 : {
883 6926 : if (allow_libraries)
884 : {
885 : #ifdef HAVE_LD_STATIC_DYNAMIC
886 2142 : if (!shared_libgm2)
887 0 : append_option (OPT_Wl_, LD_STATIC_OPTION, 1);
888 : #endif
889 2142 : added_libraries += add_default_libs (libraries);
890 : #ifdef HAVE_LD_STATIC_DYNAMIC
891 2142 : if (!shared_libgm2)
892 0 : append_option (OPT_Wl_, LD_DYNAMIC_OPTION, 1);
893 : #endif
894 : }
895 :
896 : /* Add `-lstdc++' if we haven't already done so. */
897 : #ifdef HAVE_LD_STATIC_DYNAMIC
898 6926 : if (library > 1 && !static_link)
899 0 : append_option (OPT_Wl_, LD_STATIC_OPTION, 1);
900 : #endif
901 6926 : if (which_library == USE_LIBCXX)
902 : {
903 0 : append_option (OPT_l, saw_profile_flag ? LIBCXX_PROFILE : LIBCXX, 1);
904 0 : added_libraries++;
905 0 : if (LIBCXXABI != NULL)
906 : {
907 0 : append_option (OPT_l, saw_profile_flag ? LIBCXXABI_PROFILE
908 : : LIBCXXABI, 1);
909 0 : added_libraries++;
910 : }
911 : }
912 : else
913 : {
914 6926 : append_option (OPT_l, saw_profile_flag ? LIBSTDCXX_PROFILE
915 : : LIBSTDCXX, 1);
916 6926 : added_libraries++;
917 : }
918 : /* Add target-dependent static library, if necessary. */
919 6926 : if ((static_link || library > 1) && LIBSTDCXX_STATIC != NULL)
920 : {
921 : append_option (OPT_l, LIBSTDCXX_STATIC, 1);
922 : added_libraries++;
923 : }
924 : #ifdef HAVE_LD_STATIC_DYNAMIC
925 6926 : if (library > 1 && !static_link)
926 0 : append_option (OPT_Wl_, LD_DYNAMIC_OPTION, 1);
927 : #endif
928 : }
929 19310 : if (need_math)
930 : {
931 16632 : append_option (OPT_l, saw_profile_flag ? MATH_LIBRARY_PROFILE :
932 : MATH_LIBRARY, 1);
933 16632 : added_libraries++;
934 : }
935 19310 : if (need_pthread)
936 : {
937 19310 : append_option (OPT_l, "pthread", 1);
938 19310 : added_libraries++;
939 : }
940 19310 : if (shared_libgcc && !static_link)
941 19310 : append_option (OPT_shared_libgcc, NULL, 1);
942 :
943 19310 : if (verbose && gm2_new_decoded_options != gm2_x_decoded_options)
944 : {
945 0 : fprintf (stderr, _("Driving:"));
946 0 : for (i = 0; i < gm2_newargc; i++)
947 0 : fprintf (stderr, " %s",
948 0 : gm2_new_decoded_options[i].orig_option_with_args_text);
949 0 : fprintf (stderr, "\n");
950 0 : fprintf (stderr, "new argc = %d, added_libraries = %d\n",
951 : gm2_newargc, added_libraries);
952 : }
953 :
954 19310 : *in_decoded_options_count = gm2_newargc;
955 19310 : *in_decoded_options = gm2_new_decoded_options;
956 19310 : *in_added_libraries = added_libraries;
957 : }
958 :
959 :
960 : /* Called before linking. Returns 0 on success and -1 on failure. */
961 : int
962 13276 : lang_specific_pre_link (void) /* Not used for M2. */
963 : {
964 13276 : return 0;
965 : }
966 :
967 : /* Number of extra output files that lang_specific_pre_link may generate. */
968 : int lang_specific_extra_outfiles = 0;
|