]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/opts-common.c
Correct a function pre/postcondition [PR102403].
[thirdparty/gcc.git] / gcc / opts-common.c
CommitLineData
14c7833c 1/* Command line option handling.
99dee823 2 Copyright (C) 2006-2021 Free Software Foundation, Inc.
14c7833c
L
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
9dcd6f09 8Software Foundation; either version 3, or (at your option) any later
14c7833c
L
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
9dcd6f09
NC
17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
14c7833c
L
19
20#include "config.h"
21#include "system.h"
22#include "intl.h"
23#include "coretypes.h"
24#include "opts.h"
1916bcb5 25#include "options.h"
5f20c657 26#include "diagnostic.h"
70f25790 27#include "spellcheck.h"
14c7833c 28
60cf253a
JM
29static void prune_options (struct cl_decoded_option **, unsigned int *);
30
9ed32e27
AO
31/* An option that is undocumented, that takes a joined argument, and
32 that doesn't fit any of the classes of uses (language/common,
33 driver, target) is assumed to be a prefix used to catch
34 e.g. negated options, and stop them from being further shortened to
35 a prefix that could use the negated option as an argument. For
36 example, we want -gno-statement-frontiers to be taken as a negation
37 of -gstatement-frontiers, but without catching the gno- prefix and
38 signaling it's to be used for option remapping, it would end up
39 backtracked to g with no-statemnet-frontiers as the debug level. */
40
41static bool
42remapping_prefix_p (const struct cl_option *opt)
43{
44 return opt->flags & CL_UNDOCUMENTED
45 && opt->flags & CL_JOINED
46 && !(opt->flags & (CL_DRIVER | CL_TARGET | CL_COMMON | CL_LANG_ALL));
47}
48
14c7833c 49/* Perform a binary search to find which option the command-line INPUT
6e2f1956
JM
50 matches. Returns its index in the option array, and
51 OPT_SPECIAL_unknown on failure.
14c7833c
L
52
53 This routine is quite subtle. A normal binary search is not good
54 enough because some options can be suffixed with an argument, and
55 multiple sub-matches can occur, e.g. input of "-pedantic" matching
56 the initial substring of "-pedantic-errors".
57
58 A more complicated example is -gstabs. It should match "-g" with
59 an argument of "stabs". Suppose, however, that the number and list
60 of switches are such that the binary search tests "-gen-decls"
61 before having tested "-g". This doesn't match, and as "-gen-decls"
62 is less than "-gstabs", it will become the lower bound of the
63 binary search range, and "-g" will never be seen. To resolve this
af47e6ac 64 issue, 'optc-gen.awk' makes "-gen-decls" point, via the back_chain member,
14c7833c
L
65 to "-g" so that failed searches that end between "-gen-decls" and
66 the lexicographically subsequent switch know to go back and see if
67 "-g" causes a match (which it does in this example).
68
69 This search is done in such a way that the longest match for the
70 front end in question wins. If there is no match for the current
71 front end, the longest match for a different front end is returned
72 (or N_OPTS if none) and the caller emits an error message. */
73size_t
eb50f63a 74find_opt (const char *input, unsigned int lang_mask)
14c7833c 75{
e200444e 76 size_t mn, mn_orig, mx, md, opt_len;
14c7833c
L
77 size_t match_wrong_lang;
78 int comp;
79
80 mn = 0;
81 mx = cl_options_count;
82
83 /* Find mn such this lexicographical inequality holds:
84 cl_options[mn] <= input < cl_options[mn + 1]. */
85 while (mx - mn > 1)
86 {
87 md = (mn + mx) / 2;
88 opt_len = cl_options[md].opt_len;
89 comp = strncmp (input, cl_options[md].opt_text + 1, opt_len);
90
91 if (comp < 0)
92 mx = md;
93 else
94 mn = md;
95 }
96
e200444e
JM
97 mn_orig = mn;
98
14c7833c 99 /* This is the switch that is the best match but for a different
6e2f1956
JM
100 front end, or OPT_SPECIAL_unknown if there is no match at all. */
101 match_wrong_lang = OPT_SPECIAL_unknown;
14c7833c
L
102
103 /* Backtrace the chain of possible matches, returning the longest
104 one, if any, that fits best. With current GCC switches, this
105 loop executes at most twice. */
106 do
107 {
108 const struct cl_option *opt = &cl_options[mn];
109
110 /* Is the input either an exact match or a prefix that takes a
111 joined argument? */
112 if (!strncmp (input, opt->opt_text + 1, opt->opt_len)
113 && (input[opt->opt_len] == '\0' || (opt->flags & CL_JOINED)))
114 {
115 /* If language is OK, return it. */
116 if (opt->flags & lang_mask)
117 return mn;
118
9ed32e27
AO
119 if (remapping_prefix_p (opt))
120 return OPT_SPECIAL_unknown;
121
14c7833c
L
122 /* If we haven't remembered a prior match, remember this
123 one. Any prior match is necessarily better. */
6e2f1956 124 if (match_wrong_lang == OPT_SPECIAL_unknown)
14c7833c
L
125 match_wrong_lang = mn;
126 }
127
128 /* Try the next possibility. This is cl_options_count if there
129 are no more. */
130 mn = opt->back_chain;
131 }
132 while (mn != cl_options_count);
133
e200444e
JM
134 if (match_wrong_lang == OPT_SPECIAL_unknown && input[0] == '-')
135 {
136 /* Long options, starting "--", may be abbreviated if the
137 abbreviation is unambiguous. This only applies to options
138 not taking a joined argument, and abbreviations of "--option"
139 are permitted even if there is a variant "--option=". */
140 size_t mnc = mn_orig + 1;
141 size_t cmp_len = strlen (input);
142 while (mnc < cl_options_count
143 && strncmp (input, cl_options[mnc].opt_text + 1, cmp_len) == 0)
144 {
145 /* Option matching this abbreviation. OK if it is the first
146 match and that does not take a joined argument, or the
147 second match, taking a joined argument and with only '='
148 added to the first match; otherwise considered
149 ambiguous. */
150 if (mnc == mn_orig + 1
151 && !(cl_options[mnc].flags & CL_JOINED))
152 match_wrong_lang = mnc;
153 else if (mnc == mn_orig + 2
154 && match_wrong_lang == mn_orig + 1
155 && (cl_options[mnc].flags & CL_JOINED)
156 && (cl_options[mnc].opt_len
157 == cl_options[mn_orig + 1].opt_len + 1)
158 && strncmp (cl_options[mnc].opt_text + 1,
159 cl_options[mn_orig + 1].opt_text + 1,
160 cl_options[mn_orig + 1].opt_len) == 0)
161 ; /* OK, as long as there are no more matches. */
162 else
163 return OPT_SPECIAL_unknown;
164 mnc++;
165 }
166 }
167
6e2f1956 168 /* Return the best wrong match, or OPT_SPECIAL_unknown if none. */
14c7833c
L
169 return match_wrong_lang;
170}
171
00abf86c
MS
172/* If ARG is a non-negative decimal or hexadecimal integer representable
173 in HOST_WIDE_INT return its value, otherwise return -1. If ERR is not
174 null set *ERR to zero on success or to EINVAL or to the value of errno
175 otherwise. */
5d4b393f 176
00abf86c
MS
177HOST_WIDE_INT
178integral_argument (const char *arg, int *err, bool byte_size_suffix)
5d4b393f 179{
00abf86c
MS
180 if (!err)
181 err = &errno;
182
183 if (!ISDIGIT (*arg))
184 {
185 *err = EINVAL;
186 return -1;
187 }
188
189 *err = 0;
190 errno = 0;
5d4b393f 191
00abf86c
MS
192 char *end = NULL;
193 unsigned HOST_WIDE_INT unit = 1;
194 unsigned HOST_WIDE_INT value = strtoull (arg, &end, 10);
5d4b393f 195
00abf86c
MS
196 /* If the value is too large to be represented use the maximum
197 representable value that strtoull sets VALUE to (setting
198 errno to ERANGE). */
5d4b393f 199
00abf86c 200 if (end && *end)
317c1849 201 {
00abf86c
MS
202 if (!byte_size_suffix)
203 {
204 errno = 0;
205 value = strtoull (arg, &end, 0);
206 if (*end)
207 {
7ad99f7d
RZ
208 if (errno)
209 *err = errno;
210 else
211 *err = EINVAL;
00abf86c
MS
212 return -1;
213 }
214
215 return value;
216 }
217
218 /* Numeric option arguments are at most INT_MAX. Make it
219 possible to specify a larger value by accepting common
220 suffixes. */
221 if (!strcmp (end, "kB"))
222 unit = 1000;
223 else if (!strcasecmp (end, "KiB") || !strcmp (end, "KB"))
224 unit = 1024;
225 else if (!strcmp (end, "MB"))
226 unit = HOST_WIDE_INT_UC (1000) * 1000;
227 else if (!strcasecmp (end, "MiB"))
228 unit = HOST_WIDE_INT_UC (1024) * 1024;
229 else if (!strcasecmp (end, "GB"))
230 unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000;
231 else if (!strcasecmp (end, "GiB"))
232 unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024;
233 else if (!strcasecmp (end, "TB"))
234 unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000;
235 else if (!strcasecmp (end, "TiB"))
236 unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024;
237 else if (!strcasecmp (end, "PB"))
238 unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000 * 1000;
239 else if (!strcasecmp (end, "PiB"))
240 unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024 * 1024;
241 else if (!strcasecmp (end, "EB"))
242 unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000 * 1000
243 * 1000;
244 else if (!strcasecmp (end, "EiB"))
245 unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024 * 1024
246 * 1024;
247 else
248 {
249 /* This could mean an unknown suffix or a bad prefix, like
250 "+-1". */
251 *err = EINVAL;
252 return -1;
253 }
254 }
317c1849 255
00abf86c
MS
256 if (unit)
257 {
258 unsigned HOST_WIDE_INT prod = value * unit;
259 value = prod < value ? HOST_WIDE_INT_M1U : prod;
317c1849
CLT
260 }
261
00abf86c 262 return value;
5d4b393f
JM
263}
264
d9d16a19
JM
265/* Return whether OPTION is OK for the language given by
266 LANG_MASK. */
267static bool
268option_ok_for_language (const struct cl_option *option,
269 unsigned int lang_mask)
270{
271 if (!(option->flags & lang_mask))
272 return false;
273 else if ((option->flags & CL_TARGET)
274 && (option->flags & (CL_LANG_ALL | CL_DRIVER))
275 && !(option->flags & (lang_mask & ~CL_COMMON & ~CL_TARGET)))
276 /* Complain for target flag language mismatches if any languages
277 are specified. */
278 return false;
279 return true;
280}
281
e6d4b984
JM
282/* Return whether ENUM_ARG is OK for the language given by
283 LANG_MASK. */
284
285static bool
286enum_arg_ok_for_language (const struct cl_enum_arg *enum_arg,
287 unsigned int lang_mask)
288{
289 return (lang_mask & CL_DRIVER) || !(enum_arg->flags & CL_ENUM_DRIVER_ONLY);
290}
291
292/* Look up ARG in ENUM_ARGS for language LANG_MASK, returning true and
293 storing the value in *VALUE if found, and returning false without
294 modifying *VALUE if not found. */
295
296static bool
297enum_arg_to_value (const struct cl_enum_arg *enum_args,
00abf86c
MS
298 const char *arg, HOST_WIDE_INT *value,
299 unsigned int lang_mask)
e6d4b984
JM
300{
301 unsigned int i;
302
303 for (i = 0; enum_args[i].arg != NULL; i++)
304 if (strcmp (arg, enum_args[i].arg) == 0
305 && enum_arg_ok_for_language (&enum_args[i], lang_mask))
306 {
307 *value = enum_args[i].value;
308 return true;
309 }
310
311 return false;
312}
313
8023568e
JM
314/* Look up ARG in the enum used by option OPT_INDEX for language
315 LANG_MASK, returning true and storing the value in *VALUE if found,
316 and returning false without modifying *VALUE if not found. */
317
318bool
00abf86c
MS
319opt_enum_arg_to_value (size_t opt_index, const char *arg,
320 int *value, unsigned int lang_mask)
8023568e
JM
321{
322 const struct cl_option *option = &cl_options[opt_index];
323
324 gcc_assert (option->var_type == CLVC_ENUM);
325
00abf86c
MS
326 HOST_WIDE_INT wideval;
327 if (enum_arg_to_value (cl_enums[option->var_enum].values, arg,
328 &wideval, lang_mask))
329 {
330 *value = wideval;
331 return true;
332 }
333
334 return false;
8023568e
JM
335}
336
e6d4b984
JM
337/* Look of VALUE in ENUM_ARGS for language LANG_MASK and store the
338 corresponding string in *ARGP, returning true if the found string
339 was marked as canonical, false otherwise. If VALUE is not found
340 (which may be the case for uninitialized values if the relevant
341 option has not been passed), set *ARGP to NULL and return
342 false. */
343
344bool
345enum_value_to_arg (const struct cl_enum_arg *enum_args,
346 const char **argp, int value, unsigned int lang_mask)
347{
348 unsigned int i;
349
350 for (i = 0; enum_args[i].arg != NULL; i++)
351 if (enum_args[i].value == value
352 && (enum_args[i].flags & CL_ENUM_CANONICAL)
353 && enum_arg_ok_for_language (&enum_args[i], lang_mask))
354 {
355 *argp = enum_args[i].arg;
356 return true;
357 }
358
359 for (i = 0; enum_args[i].arg != NULL; i++)
360 if (enum_args[i].value == value
361 && enum_arg_ok_for_language (&enum_args[i], lang_mask))
362 {
363 *argp = enum_args[i].arg;
364 return false;
365 }
366
367 *argp = NULL;
368 return false;
369}
5de8299c
JM
370
371/* Fill in the canonical option part of *DECODED with an option
372 described by OPT_INDEX, ARG and VALUE. */
373
374static void
00abf86c
MS
375generate_canonical_option (size_t opt_index, const char *arg,
376 HOST_WIDE_INT value,
5de8299c
JM
377 struct cl_decoded_option *decoded)
378{
379 const struct cl_option *option = &cl_options[opt_index];
380 const char *opt_text = option->opt_text;
381
382 if (value == 0
300d83d9 383 && !option->cl_reject_negative
9ed32e27
AO
384 && (opt_text[1] == 'W' || opt_text[1] == 'f'
385 || opt_text[1] == 'g' || opt_text[1] == 'm'))
5de8299c 386 {
dc357798 387 char *t = XOBNEWVEC (&opts_obstack, char, option->opt_len + 5);
5de8299c
JM
388 t[0] = '-';
389 t[1] = opt_text[1];
390 t[2] = 'n';
391 t[3] = 'o';
392 t[4] = '-';
393 memcpy (t + 5, opt_text + 2, option->opt_len);
394 opt_text = t;
395 }
396
397 decoded->canonical_option[2] = NULL;
398 decoded->canonical_option[3] = NULL;
399
400 if (arg)
401 {
d1583032 402 if ((option->flags & CL_SEPARATE)
300d83d9 403 && !option->cl_separate_alias)
5de8299c
JM
404 {
405 decoded->canonical_option[0] = opt_text;
406 decoded->canonical_option[1] = arg;
407 decoded->canonical_option_num_elements = 2;
408 }
409 else
410 {
411 gcc_assert (option->flags & CL_JOINED);
dc357798 412 decoded->canonical_option[0] = opts_concat (opt_text, arg, NULL);
5de8299c
JM
413 decoded->canonical_option[1] = NULL;
414 decoded->canonical_option_num_elements = 1;
415 }
416 }
417 else
418 {
419 decoded->canonical_option[0] = opt_text;
420 decoded->canonical_option[1] = NULL;
421 decoded->canonical_option_num_elements = 1;
422 }
423}
424
e200444e
JM
425/* Structure describing mappings from options on the command line to
426 options to look up with find_opt. */
427struct option_map
428{
429 /* Prefix of the option on the command line. */
430 const char *opt0;
431 /* If two argv elements are considered to be merged into one option,
432 prefix for the second element, otherwise NULL. */
433 const char *opt1;
434 /* The new prefix to map to. */
435 const char *new_prefix;
436 /* Whether at least one character is needed following opt1 or opt0
437 for this mapping to be used. (--optimize= is valid for -O, but
438 --warn- is not valid for -W.) */
439 bool another_char_needed;
440 /* Whether the original option is a negated form of the option
441 resulting from this map. */
442 bool negated;
443};
444static const struct option_map option_map[] =
445 {
446 { "-Wno-", NULL, "-W", false, true },
447 { "-fno-", NULL, "-f", false, true },
9ed32e27 448 { "-gno-", NULL, "-g", false, true },
e200444e
JM
449 { "-mno-", NULL, "-m", false, true },
450 { "--debug=", NULL, "-g", false, false },
451 { "--machine-", NULL, "-m", true, false },
452 { "--machine-no-", NULL, "-m", false, true },
453 { "--machine=", NULL, "-m", false, false },
454 { "--machine=no-", NULL, "-m", false, true },
455 { "--machine", "", "-m", false, false },
456 { "--machine", "no-", "-m", false, true },
457 { "--optimize=", NULL, "-O", false, false },
458 { "--std=", NULL, "-std=", false, false },
459 { "--std", "", "-std=", false, false },
460 { "--warn-", NULL, "-W", true, false },
461 { "--warn-no-", NULL, "-W", false, true },
462 { "--", NULL, "-f", true, false },
463 { "--no-", NULL, "-f", false, true }
464 };
465
61789eed
DM
466/* Helper function for gcc.c's driver::suggest_option, for populating the
467 vec of suggestions for misspelled options.
468
469 option_map above provides various prefixes for spelling command-line
470 options, which decode_cmdline_option uses to map spellings of options
471 to specific options. We want to do the reverse: to find all the ways
472 that a user could validly spell an option.
473
603107fb
DM
474 Given valid OPT_TEXT (with a leading dash) for OPTION, add it and all
475 of its valid variant spellings to CANDIDATES, each without a leading
476 dash.
61789eed
DM
477
478 For example, given "-Wabi-tag", the following are added to CANDIDATES:
479 "Wabi-tag"
480 "Wno-abi-tag"
481 "-warn-abi-tag"
482 "-warn-no-abi-tag".
483
484 The added strings must be freed using free. */
485
486void
487add_misspelling_candidates (auto_vec<char *> *candidates,
603107fb 488 const struct cl_option *option,
61789eed
DM
489 const char *opt_text)
490{
491 gcc_assert (candidates);
603107fb 492 gcc_assert (option);
61789eed 493 gcc_assert (opt_text);
9ed32e27
AO
494 if (remapping_prefix_p (option))
495 return;
61789eed
DM
496 candidates->safe_push (xstrdup (opt_text + 1));
497 for (unsigned i = 0; i < ARRAY_SIZE (option_map); i++)
498 {
499 const char *opt0 = option_map[i].opt0;
500 const char *new_prefix = option_map[i].new_prefix;
501 size_t new_prefix_len = strlen (new_prefix);
502
603107fb
DM
503 if (option->cl_reject_negative && option_map[i].negated)
504 continue;
505
61789eed
DM
506 if (strncmp (opt_text, new_prefix, new_prefix_len) == 0)
507 {
508 char *alternative = concat (opt0 + 1, opt_text + new_prefix_len,
509 NULL);
510 candidates->safe_push (alternative);
511 }
512 }
8cc5fcaf
ML
513
514 /* For all params (e.g. --param=key=value),
515 include also '--param key=value'. */
516 const char *prefix = "--param=";
517 if (strstr (opt_text, prefix) == opt_text)
518 {
519 char *param = xstrdup (opt_text + 1);
520 gcc_assert (param[6] == '=');
521 param[6] = ' ';
522 candidates->safe_push (param);
523 }
61789eed
DM
524}
525
5d4b393f 526/* Decode the switch beginning at ARGV for the language indicated by
603349bf
JM
527 LANG_MASK (including CL_COMMON and CL_TARGET if applicable), into
528 the structure *DECODED. Returns the number of switches
529 consumed. */
5d4b393f 530
6e2f1956 531static unsigned int
129a1319 532decode_cmdline_option (const char *const *argv, unsigned int lang_mask,
5d4b393f
JM
533 struct cl_decoded_option *decoded)
534{
535 size_t opt_index;
e200444e 536 const char *arg = 0;
00abf86c 537 HOST_WIDE_INT value = 1;
c8967d95 538 unsigned int result = 1, i, extra_args, separate_args = 0;
e200444e 539 int adjust_len = 0;
eea13ead
JM
540 size_t total_len;
541 char *p;
5d4b393f
JM
542 const struct cl_option *option;
543 int errors = 0;
2d2bd949 544 const char *warn_message = NULL;
c878765b
JM
545 bool separate_arg_flag;
546 bool joined_arg_flag;
d1583032 547 bool have_separate_arg = false;
5d4b393f 548
e200444e 549 extra_args = 0;
5d4b393f 550
2df89b66
ML
551 const char *opt_value = argv[0] + 1;
552 opt_index = find_opt (opt_value, lang_mask);
e200444e
JM
553 i = 0;
554 while (opt_index == OPT_SPECIAL_unknown
555 && i < ARRAY_SIZE (option_map))
5d4b393f 556 {
e200444e
JM
557 const char *opt0 = option_map[i].opt0;
558 const char *opt1 = option_map[i].opt1;
559 const char *new_prefix = option_map[i].new_prefix;
560 bool another_char_needed = option_map[i].another_char_needed;
561 size_t opt0_len = strlen (opt0);
562 size_t opt1_len = (opt1 == NULL ? 0 : strlen (opt1));
563 size_t optn_len = (opt1 == NULL ? opt0_len : opt1_len);
564 size_t new_prefix_len = strlen (new_prefix);
565
566 extra_args = (opt1 == NULL ? 0 : 1);
567 value = !option_map[i].negated;
568
569 if (strncmp (argv[0], opt0, opt0_len) == 0
570 && (opt1 == NULL
571 || (argv[1] != NULL && strncmp (argv[1], opt1, opt1_len) == 0))
572 && (!another_char_needed
573 || argv[extra_args][optn_len] != 0))
574 {
575 size_t arglen = strlen (argv[extra_args]);
576 char *dup;
577
578 adjust_len = (int) optn_len - (int) new_prefix_len;
579 dup = XNEWVEC (char, arglen + 1 - adjust_len);
580 memcpy (dup, new_prefix, new_prefix_len);
581 memcpy (dup + new_prefix_len, argv[extra_args] + optn_len,
582 arglen - optn_len + 1);
583 opt_index = find_opt (dup + 1, lang_mask);
584 free (dup);
585 }
586 i++;
5d4b393f
JM
587 }
588
6e2f1956
JM
589 if (opt_index == OPT_SPECIAL_unknown)
590 {
591 arg = argv[0];
e200444e
JM
592 extra_args = 0;
593 value = 1;
6e2f1956
JM
594 goto done;
595 }
5d4b393f
JM
596
597 option = &cl_options[opt_index];
598
599 /* Reject negative form of switches that don't take negatives as
600 unrecognized. */
300d83d9 601 if (!value && option->cl_reject_negative)
5d4b393f 602 {
6e2f1956 603 opt_index = OPT_SPECIAL_unknown;
184eb658 604 errors |= CL_ERR_NEGATIVE;
6e2f1956 605 arg = argv[0];
5d4b393f
JM
606 goto done;
607 }
608
00abf86c
MS
609 /* Clear the initial value for size options (it will be overwritten
610 later based on the Init(value) specification in the opt file. */
611 if (option->var_type == CLVC_SIZE)
612 value = 0;
613
e200444e 614 result = extra_args + 1;
2d2bd949
JM
615 warn_message = option->warn_message;
616
5d4b393f 617 /* Check to see if the option is disabled for this configuration. */
300d83d9 618 if (option->cl_disabled)
5d4b393f
JM
619 errors |= CL_ERR_DISABLED;
620
c878765b 621 /* Determine whether there may be a separate argument based on
c243beb0
JM
622 whether this option is being processed for the driver, and, if
623 so, how many such arguments. */
c878765b 624 separate_arg_flag = ((option->flags & CL_SEPARATE)
300d83d9 625 && !(option->cl_no_driver_arg
c878765b 626 && (lang_mask & CL_DRIVER)));
c243beb0 627 separate_args = (separate_arg_flag
300d83d9 628 ? option->cl_separate_nargs + 1
c243beb0 629 : 0);
c878765b
JM
630 joined_arg_flag = (option->flags & CL_JOINED) != 0;
631
5d4b393f 632 /* Sort out any argument the switch takes. */
c878765b 633 if (joined_arg_flag)
5d4b393f
JM
634 {
635 /* Have arg point to the original switch. This is because
636 some code, such as disable_builtin_function, expects its
637 argument to be persistent until the program exits. */
e200444e 638 arg = argv[extra_args] + cl_options[opt_index].opt_len + 1 + adjust_len;
5d4b393f 639
300d83d9 640 if (*arg == '\0' && !option->cl_missing_ok)
5d4b393f 641 {
c878765b 642 if (separate_arg_flag)
5d4b393f 643 {
e200444e
JM
644 arg = argv[extra_args + 1];
645 result = extra_args + 2;
5d4b393f 646 if (arg == NULL)
e200444e 647 result = extra_args + 1;
d1583032
JM
648 else
649 have_separate_arg = true;
5d4b393f
JM
650 }
651 else
652 /* Missing argument. */
653 arg = NULL;
654 }
655 }
c878765b 656 else if (separate_arg_flag)
5d4b393f 657 {
e200444e 658 arg = argv[extra_args + 1];
c243beb0
JM
659 for (i = 0; i < separate_args; i++)
660 if (argv[extra_args + 1 + i] == NULL)
661 {
662 errors |= CL_ERR_MISSING_ARG;
663 break;
664 }
665 result = extra_args + 1 + i;
666 if (arg != NULL)
d1583032 667 have_separate_arg = true;
5d4b393f
JM
668 }
669
5de8299c
JM
670 if (arg == NULL && (separate_arg_flag || joined_arg_flag))
671 errors |= CL_ERR_MISSING_ARG;
672
2d2bd949
JM
673 /* Is this option an alias (or an ignored option, marked as an alias
674 of OPT_SPECIAL_ignore)? */
d1583032 675 if (option->alias_target != N_OPTS
300d83d9 676 && (!option->cl_separate_alias || have_separate_arg))
5de8299c
JM
677 {
678 size_t new_opt_index = option->alias_target;
5de8299c 679
c0c12356 680 if (new_opt_index == OPT_SPECIAL_ignore
68a57628 681 || new_opt_index == OPT_SPECIAL_warn_removed)
5de8299c 682 {
2d2bd949
JM
683 gcc_assert (option->alias_arg == NULL);
684 gcc_assert (option->neg_alias_arg == NULL);
685 opt_index = new_opt_index;
686 arg = NULL;
5de8299c 687 }
2d2bd949 688 else
5de8299c 689 {
2d2bd949 690 const struct cl_option *new_option = &cl_options[new_opt_index];
5de8299c 691
2d2bd949 692 /* The new option must not be an alias itself. */
e200444e 693 gcc_assert (new_option->alias_target == N_OPTS
300d83d9 694 || new_option->cl_separate_alias);
5de8299c 695
2d2bd949
JM
696 if (option->neg_alias_arg)
697 {
698 gcc_assert (option->alias_arg != NULL);
699 gcc_assert (arg == NULL);
300d83d9 700 gcc_assert (!option->cl_negative_alias);
2d2bd949
JM
701 if (value)
702 arg = option->alias_arg;
703 else
704 arg = option->neg_alias_arg;
705 value = 1;
706 }
707 else if (option->alias_arg)
708 {
709 gcc_assert (value == 1);
710 gcc_assert (arg == NULL);
300d83d9 711 gcc_assert (!option->cl_negative_alias);
2d2bd949
JM
712 arg = option->alias_arg;
713 }
5de8299c 714
300d83d9 715 if (option->cl_negative_alias)
666a21a2
JM
716 value = !value;
717
2d2bd949
JM
718 opt_index = new_opt_index;
719 option = new_option;
5de8299c 720
2d2bd949 721 if (value == 0)
300d83d9 722 gcc_assert (!option->cl_reject_negative);
2d2bd949
JM
723
724 /* Recompute what arguments are allowed. */
725 separate_arg_flag = ((option->flags & CL_SEPARATE)
300d83d9 726 && !(option->cl_no_driver_arg
2d2bd949
JM
727 && (lang_mask & CL_DRIVER)));
728 joined_arg_flag = (option->flags & CL_JOINED) != 0;
729
300d83d9 730 if (separate_args > 1 || option->cl_separate_nargs)
c243beb0 731 gcc_assert (separate_args
300d83d9 732 == (unsigned int) option->cl_separate_nargs + 1);
c243beb0 733
2d2bd949
JM
734 if (!(errors & CL_ERR_MISSING_ARG))
735 {
736 if (separate_arg_flag || joined_arg_flag)
e200444e 737 {
300d83d9 738 if (option->cl_missing_ok && arg == NULL)
e200444e
JM
739 arg = "";
740 gcc_assert (arg != NULL);
741 }
2d2bd949
JM
742 else
743 gcc_assert (arg == NULL);
744 }
5de8299c 745
2d2bd949
JM
746 /* Recheck for warnings and disabled options. */
747 if (option->warn_message)
748 {
749 gcc_assert (warn_message == NULL);
750 warn_message = option->warn_message;
751 }
300d83d9 752 if (option->cl_disabled)
2d2bd949
JM
753 errors |= CL_ERR_DISABLED;
754 }
5de8299c
JM
755 }
756
5d4b393f 757 /* Check if this is a switch for a different front end. */
d9d16a19 758 if (!option_ok_for_language (option, lang_mask))
5d4b393f 759 errors |= CL_ERR_WRONG_LANG;
2df89b66
ML
760 else if (strcmp (option->opt_text, "-Werror=") == 0
761 && strchr (opt_value, ',') == NULL)
762 {
763 /* Verify that -Werror argument is a valid warning
764 for a language. */
765 char *werror_arg = xstrdup (opt_value + 6);
766 werror_arg[0] = 'W';
767
768 size_t warning_index = find_opt (werror_arg, lang_mask);
bc6087c5 769 free (werror_arg);
2df89b66
ML
770 if (warning_index != OPT_SPECIAL_unknown)
771 {
772 const struct cl_option *warning_option
773 = &cl_options[warning_index];
774 if (!option_ok_for_language (warning_option, lang_mask))
775 errors |= CL_ERR_WRONG_LANG;
776 }
777 }
5d4b393f 778
413519ae
JM
779 /* Convert the argument to lowercase if appropriate. */
780 if (arg && option->cl_tolower)
781 {
782 size_t j;
783 size_t len = strlen (arg);
dc357798 784 char *arg_lower = XOBNEWVEC (&opts_obstack, char, len + 1);
413519ae
JM
785
786 for (j = 0; j < len; j++)
787 arg_lower[j] = TOLOWER ((unsigned char) arg[j]);
788 arg_lower[len] = 0;
789 arg = arg_lower;
790 }
791
00abf86c
MS
792 /* If the switch takes an integer argument, convert it. */
793 if (arg && (option->cl_uinteger || option->cl_host_wide_int))
5d4b393f 794 {
00abf86c
MS
795 int error = 0;
796 value = *arg ? integral_argument (arg, &error, option->cl_byte_size) : 0;
797 if (error)
5d4b393f 798 errors |= CL_ERR_UINT_ARG;
63010089
ML
799
800 /* Reject value out of a range. */
801 if (option->range_max != -1
802 && (value < option->range_min || value > option->range_max))
803 errors |= CL_ERR_INT_RANGE_ARG;
5d4b393f
JM
804 }
805
e6d4b984
JM
806 /* If the switch takes an enumerated argument, convert it. */
807 if (arg && (option->var_type == CLVC_ENUM))
808 {
809 const struct cl_enum *e = &cl_enums[option->var_enum];
810
811 gcc_assert (value == 1);
812 if (enum_arg_to_value (e->values, arg, &value, lang_mask))
813 {
814 const char *carg = NULL;
815
816 if (enum_value_to_arg (e->values, &carg, value, lang_mask))
817 arg = carg;
818 gcc_assert (carg != NULL);
819 }
820 else
821 errors |= CL_ERR_ENUM_ARG;
822 }
823
5d4b393f 824 done:
5d4b393f
JM
825 decoded->opt_index = opt_index;
826 decoded->arg = arg;
827 decoded->value = value;
828 decoded->errors = errors;
2d2bd949 829 decoded->warn_message = warn_message;
eea13ead
JM
830
831 if (opt_index == OPT_SPECIAL_unknown)
c243beb0 832 gcc_assert (result == 1);
eea13ead
JM
833
834 gcc_assert (result >= 1 && result <= ARRAY_SIZE (decoded->canonical_option));
835 decoded->canonical_option_num_elements = result;
836 total_len = 0;
837 for (i = 0; i < ARRAY_SIZE (decoded->canonical_option); i++)
838 {
839 if (i < result)
840 {
7fcf46f5 841 size_t len;
5de8299c
JM
842 if (opt_index == OPT_SPECIAL_unknown)
843 decoded->canonical_option[i] = argv[i];
844 else
845 decoded->canonical_option[i] = NULL;
7fcf46f5
JZ
846 len = strlen (argv[i]);
847 /* If the argument is an empty string, we will print it as "" in
848 orig_option_with_args_text. */
849 total_len += (len != 0 ? len : 2) + 1;
eea13ead
JM
850 }
851 else
852 decoded->canonical_option[i] = NULL;
853 }
c0c12356 854 if (opt_index != OPT_SPECIAL_unknown && opt_index != OPT_SPECIAL_ignore
68a57628 855 && opt_index != OPT_SPECIAL_warn_removed)
c243beb0
JM
856 {
857 generate_canonical_option (opt_index, arg, value, decoded);
858 if (separate_args > 1)
859 {
860 for (i = 0; i < separate_args; i++)
861 {
862 if (argv[extra_args + 1 + i] == NULL)
863 break;
864 else
865 decoded->canonical_option[1 + i] = argv[extra_args + 1 + i];
866 }
867 gcc_assert (result == 1 + i);
868 decoded->canonical_option_num_elements = result;
869 }
870 }
dc357798
JJ
871 decoded->orig_option_with_args_text
872 = p = XOBNEWVEC (&opts_obstack, char, total_len);
eea13ead
JM
873 for (i = 0; i < result; i++)
874 {
875 size_t len = strlen (argv[i]);
876
7fcf46f5
JZ
877 /* Print the empty string verbally. */
878 if (len == 0)
879 {
880 *p++ = '"';
881 *p++ = '"';
882 }
883 else
884 memcpy (p, argv[i], len);
eea13ead
JM
885 p += len;
886 if (i == result - 1)
887 *p++ = 0;
888 else
889 *p++ = ' ';
890 }
891
5d4b393f
JM
892 return result;
893}
894
a5d1569a
JJ
895/* Obstack for option strings. */
896
897struct obstack opts_obstack;
898
899/* Like libiberty concat, but allocate using opts_obstack. */
900
901char *
902opts_concat (const char *first, ...)
903{
904 char *newstr, *end;
905 size_t length = 0;
906 const char *arg;
907 va_list ap;
908
909 /* First compute the size of the result and get sufficient memory. */
910 va_start (ap, first);
911 for (arg = first; arg; arg = va_arg (ap, const char *))
912 length += strlen (arg);
913 newstr = XOBNEWVEC (&opts_obstack, char, length + 1);
914 va_end (ap);
915
916 /* Now copy the individual pieces to the result string. */
917 va_start (ap, first);
918 for (arg = first, end = newstr; arg; arg = va_arg (ap, const char *))
919 {
920 length = strlen (arg);
921 memcpy (end, arg, length);
922 end += length;
923 }
924 *end = '\0';
925 va_end (ap);
926 return newstr;
927}
928
6e2f1956
JM
929/* Decode command-line options (ARGC and ARGV being the arguments of
930 main) into an array, setting *DECODED_OPTIONS to a pointer to that
931 array and *DECODED_OPTIONS_COUNT to the number of entries in the
932 array. The first entry in the array is always one for the program
933 name (OPT_SPECIAL_program_name). LANG_MASK indicates the language
603349bf
JM
934 flags applicable for decoding (including CL_COMMON and CL_TARGET if
935 those options should be considered applicable). Do not produce any
936 diagnostics or set state outside of these variables. */
6e2f1956
JM
937
938void
939decode_cmdline_options_to_array (unsigned int argc, const char **argv,
940 unsigned int lang_mask,
941 struct cl_decoded_option **decoded_options,
942 unsigned int *decoded_options_count)
943{
2be55a25 944 unsigned int n, i;
6e2f1956
JM
945 struct cl_decoded_option *opt_array;
946 unsigned int num_decoded_options;
947
129a1319
LH
948 int opt_array_len = argc;
949 opt_array = XNEWVEC (struct cl_decoded_option, opt_array_len);
6e2f1956
JM
950
951 opt_array[0].opt_index = OPT_SPECIAL_program_name;
2d2bd949 952 opt_array[0].warn_message = NULL;
6e2f1956
JM
953 opt_array[0].arg = argv[0];
954 opt_array[0].orig_option_with_args_text = argv[0];
eea13ead 955 opt_array[0].canonical_option_num_elements = 1;
7a9bf9a4
JM
956 opt_array[0].canonical_option[0] = argv[0];
957 opt_array[0].canonical_option[1] = NULL;
eea13ead
JM
958 opt_array[0].canonical_option[2] = NULL;
959 opt_array[0].canonical_option[3] = NULL;
6e2f1956
JM
960 opt_array[0].value = 1;
961 opt_array[0].errors = 0;
962 num_decoded_options = 1;
963
964 for (i = 1; i < argc; i += n)
965 {
966 const char *opt = argv[i];
967
968 /* Interpret "-" or a non-switch as a file name. */
969 if (opt[0] != '-' || opt[1] == '\0')
970 {
d9d16a19 971 generate_option_input_file (opt, &opt_array[num_decoded_options]);
6e2f1956
JM
972 num_decoded_options++;
973 n = 1;
974 continue;
975 }
976
76c26af9
ML
977 /* Interpret "--param" "key=name" as "--param=key=name". */
978 const char *needle = "--param";
979 if (i + 1 < argc && strcmp (opt, needle) == 0)
980 {
981 const char *replacement
982 = opts_concat (needle, "=", argv[i + 1], NULL);
983 argv[++i] = replacement;
984 }
985
129a1319
LH
986 /* Expand -fdiagnostics-plain-output to its constituents. This needs
987 to happen here so that prune_options can handle -fdiagnostics-color
988 specially. */
989 if (!strcmp (opt, "-fdiagnostics-plain-output"))
990 {
991 /* If you have changed the default diagnostics output, and this new
992 output is not appropriately "plain" (e.g., the change needs to be
993 undone in order for the testsuite to work properly), then please do
994 the following:
995 1. Add the necessary option to undo the new behavior to
996 the array below.
997 2. Update the documentation for -fdiagnostics-plain-output
998 in invoke.texi. */
999 const char *const expanded_args[] = {
1000 "-fno-diagnostics-show-caret",
1001 "-fno-diagnostics-show-line-numbers",
1002 "-fdiagnostics-color=never",
1003 "-fdiagnostics-urls=never",
7345c89e 1004 "-fdiagnostics-path-format=separate-events",
129a1319
LH
1005 };
1006 const int num_expanded = ARRAY_SIZE (expanded_args);
1007 opt_array_len += num_expanded - 1;
1008 opt_array = XRESIZEVEC (struct cl_decoded_option,
1009 opt_array, opt_array_len);
1010 for (int j = 0, nj; j < num_expanded; j += nj)
1011 {
1012 nj = decode_cmdline_option (expanded_args + j, lang_mask,
1013 &opt_array[num_decoded_options]);
1014 num_decoded_options++;
1015 }
1016
1017 n = 1;
1018 continue;
1019 }
1020
6e2f1956
JM
1021 n = decode_cmdline_option (argv + i, lang_mask,
1022 &opt_array[num_decoded_options]);
1023 num_decoded_options++;
1024 }
1025
6e2f1956
JM
1026 *decoded_options = opt_array;
1027 *decoded_options_count = num_decoded_options;
60cf253a 1028 prune_options (decoded_options, decoded_options_count);
6e2f1956
JM
1029}
1030
14c7833c
L
1031/* Return true if NEXT_OPT_IDX cancels OPT_IDX. Return false if the
1032 next one is the same as ORIG_NEXT_OPT_IDX. */
1033
1034static bool
1035cancel_option (int opt_idx, int next_opt_idx, int orig_next_opt_idx)
1036{
1037 /* An option can be canceled by the same option or an option with
1038 Negative. */
1039 if (cl_options [next_opt_idx].neg_index == opt_idx)
1040 return true;
1041
1042 if (cl_options [next_opt_idx].neg_index != orig_next_opt_idx)
1043 return cancel_option (opt_idx, cl_options [next_opt_idx].neg_index,
1044 orig_next_opt_idx);
b8698a0f 1045
14c7833c
L
1046 return false;
1047}
1048
1049/* Filter out options canceled by the ones after them. */
1050
60cf253a
JM
1051static void
1052prune_options (struct cl_decoded_option **decoded_options,
1053 unsigned int *decoded_options_count)
14c7833c 1054{
60cf253a
JM
1055 unsigned int old_decoded_options_count = *decoded_options_count;
1056 struct cl_decoded_option *old_decoded_options = *decoded_options;
1057 unsigned int new_decoded_options_count;
1058 struct cl_decoded_option *new_decoded_options
1059 = XNEWVEC (struct cl_decoded_option, old_decoded_options_count);
1060 unsigned int i;
14c7833c 1061 const struct cl_option *option;
35632122 1062 unsigned int fdiagnostics_color_idx = 0;
14c7833c
L
1063
1064 /* Remove arguments which are negated by others after them. */
60cf253a
JM
1065 new_decoded_options_count = 0;
1066 for (i = 0; i < old_decoded_options_count; i++)
14c7833c 1067 {
60cf253a
JM
1068 unsigned int j, opt_idx, next_opt_idx;
1069
1070 if (old_decoded_options[i].errors & ~CL_ERR_WRONG_LANG)
1071 goto keep;
14c7833c 1072
60cf253a
JM
1073 opt_idx = old_decoded_options[i].opt_index;
1074 switch (opt_idx)
14c7833c 1075 {
60cf253a
JM
1076 case OPT_SPECIAL_unknown:
1077 case OPT_SPECIAL_ignore:
68a57628 1078 case OPT_SPECIAL_warn_removed:
60cf253a
JM
1079 case OPT_SPECIAL_program_name:
1080 case OPT_SPECIAL_input_file:
1081 goto keep;
1082
35632122
MLI
1083 /* Do not save OPT_fdiagnostics_color_, just remember the last one. */
1084 case OPT_fdiagnostics_color_:
1085 fdiagnostics_color_idx = i;
1086 continue;
1087
60cf253a
JM
1088 default:
1089 gcc_assert (opt_idx < cl_options_count);
1090 option = &cl_options[opt_idx];
1091 if (option->neg_index < 0)
1092 goto keep;
1093
1094 /* Skip joined switches. */
aebe10d4
L
1095 if ((option->flags & CL_JOINED)
1096 && (!option->cl_reject_negative
1097 || (unsigned int) option->neg_index != opt_idx))
60cf253a
JM
1098 goto keep;
1099
1100 for (j = i + 1; j < old_decoded_options_count; j++)
14c7833c 1101 {
60cf253a
JM
1102 if (old_decoded_options[j].errors & ~CL_ERR_WRONG_LANG)
1103 continue;
1104 next_opt_idx = old_decoded_options[j].opt_index;
1105 if (next_opt_idx >= cl_options_count)
1106 continue;
1107 if (cl_options[next_opt_idx].neg_index < 0)
1108 continue;
aebe10d4
L
1109 if ((cl_options[next_opt_idx].flags & CL_JOINED)
1110 && (!cl_options[next_opt_idx].cl_reject_negative
1111 || ((unsigned int) cl_options[next_opt_idx].neg_index
1112 != next_opt_idx)))
1113 continue;
60cf253a 1114 if (cancel_option (opt_idx, next_opt_idx, next_opt_idx))
14c7833c
L
1115 break;
1116 }
60cf253a
JM
1117 if (j == old_decoded_options_count)
1118 {
14c7833c 1119keep:
60cf253a
JM
1120 new_decoded_options[new_decoded_options_count]
1121 = old_decoded_options[i];
1122 new_decoded_options_count++;
1123 }
1124 break;
14c7833c
L
1125 }
1126 }
1127
6525fb87 1128 if (fdiagnostics_color_idx >= 1)
35632122
MLI
1129 {
1130 /* We put the last -fdiagnostics-color= at the first position
1131 after argv[0] so it can take effect immediately. */
1132 memmove (new_decoded_options + 2, new_decoded_options + 1,
1133 sizeof (struct cl_decoded_option)
1134 * (new_decoded_options_count - 1));
1135 new_decoded_options[1] = old_decoded_options[fdiagnostics_color_idx];
1136 new_decoded_options_count++;
1137 }
1138
60cf253a
JM
1139 free (old_decoded_options);
1140 new_decoded_options = XRESIZEVEC (struct cl_decoded_option,
1141 new_decoded_options,
1142 new_decoded_options_count);
1143 *decoded_options = new_decoded_options;
1144 *decoded_options_count = new_decoded_options_count;
14c7833c 1145}
5f20c657 1146
481e1176 1147/* Handle option DECODED for the language indicated by LANG_MASK,
d4d24ba4
JM
1148 using the handlers in HANDLERS and setting fields in OPTS and
1149 OPTS_SET. KIND is the diagnostic_t if this is a diagnostics
a4d8c676
JM
1150 option, DK_UNSPECIFIED otherwise, and LOC is the location of the
1151 option for options from the source file, UNKNOWN_LOCATION
1152 otherwise. GENERATED_P is true for an option generated as part of
1153 processing another option or otherwise generated internally, false
b9822443
JJ
1154 for one explicitly passed by the user. control_warning_option
1155 generated options are considered explicitly passed by the user.
1156 Returns false if the switch was invalid. DC is the diagnostic
1157 context for options affecting diagnostics state, or NULL. */
5f20c657 1158
a4d8c676 1159static bool
46625112 1160handle_option (struct gcc_options *opts,
d4d24ba4 1161 struct gcc_options *opts_set,
46625112 1162 const struct cl_decoded_option *decoded,
a4d8c676 1163 unsigned int lang_mask, int kind, location_t loc,
d4d24ba4 1164 const struct cl_option_handlers *handlers,
1ebe4b4f 1165 bool generated_p, diagnostic_context *dc)
5f20c657 1166{
481e1176
JM
1167 size_t opt_index = decoded->opt_index;
1168 const char *arg = decoded->arg;
00abf86c 1169 HOST_WIDE_INT value = decoded->value;
5f20c657 1170 const struct cl_option *option = &cl_options[opt_index];
46625112 1171 void *flag_var = option_flag_var (opt_index, opts);
5f20c657
JM
1172 size_t i;
1173
46625112 1174 if (flag_var)
d4d24ba4 1175 set_option (opts, (generated_p ? NULL : opts_set),
a4d8c676 1176 opt_index, value, arg, kind, loc, dc);
5f20c657
JM
1177
1178 for (i = 0; i < handlers->num_handlers; i++)
1179 if (option->flags & handlers->handlers[i].mask)
1180 {
d4d24ba4 1181 if (!handlers->handlers[i].handler (opts, opts_set, decoded,
a4d8c676 1182 lang_mask, kind, loc,
130fcab0
ML
1183 handlers, dc,
1184 handlers->target_option_override_hook))
5f20c657 1185 return false;
5f20c657
JM
1186 }
1187
1188 return true;
1189}
1190
481e1176
JM
1191/* Like handle_option, but OPT_INDEX, ARG and VALUE describe the
1192 option instead of DECODED. This is used for callbacks when one
1193 option implies another instead of an option being decoded from the
1194 command line. */
1195
1196bool
d4d24ba4
JM
1197handle_generated_option (struct gcc_options *opts,
1198 struct gcc_options *opts_set,
00abf86c 1199 size_t opt_index, const char *arg, HOST_WIDE_INT value,
a4d8c676 1200 unsigned int lang_mask, int kind, location_t loc,
1ebe4b4f 1201 const struct cl_option_handlers *handlers,
b9822443 1202 bool generated_p, diagnostic_context *dc)
481e1176 1203{
481e1176
JM
1204 struct cl_decoded_option decoded;
1205
d9d16a19 1206 generate_option (opt_index, arg, value, lang_mask, &decoded);
a4d8c676 1207 return handle_option (opts, opts_set, &decoded, lang_mask, kind, loc,
b9822443 1208 handlers, generated_p, dc);
d9d16a19
JM
1209}
1210
1211/* Fill in *DECODED with an option described by OPT_INDEX, ARG and
1212 VALUE for a front end using LANG_MASK. This is used when the
1213 compiler generates options internally. */
1214
1215void
00abf86c 1216generate_option (size_t opt_index, const char *arg, HOST_WIDE_INT value,
d9d16a19
JM
1217 unsigned int lang_mask, struct cl_decoded_option *decoded)
1218{
1219 const struct cl_option *option = &cl_options[opt_index];
1220
1221 decoded->opt_index = opt_index;
2d2bd949 1222 decoded->warn_message = NULL;
d9d16a19 1223 decoded->arg = arg;
d9d16a19
JM
1224 decoded->value = value;
1225 decoded->errors = (option_ok_for_language (option, lang_mask)
1226 ? 0
1227 : CL_ERR_WRONG_LANG);
481e1176 1228
5de8299c
JM
1229 generate_canonical_option (opt_index, arg, value, decoded);
1230 switch (decoded->canonical_option_num_elements)
481e1176 1231 {
5de8299c
JM
1232 case 1:
1233 decoded->orig_option_with_args_text = decoded->canonical_option[0];
1234 break;
1235
1236 case 2:
1237 decoded->orig_option_with_args_text
dc357798
JJ
1238 = opts_concat (decoded->canonical_option[0], " ",
1239 decoded->canonical_option[1], NULL);
5de8299c
JM
1240 break;
1241
1242 default:
1243 gcc_unreachable ();
481e1176 1244 }
d9d16a19 1245}
481e1176 1246
d9d16a19
JM
1247/* Fill in *DECODED with an option for input file FILE. */
1248
1249void
1250generate_option_input_file (const char *file,
1251 struct cl_decoded_option *decoded)
1252{
1253 decoded->opt_index = OPT_SPECIAL_input_file;
2d2bd949 1254 decoded->warn_message = NULL;
d9d16a19
JM
1255 decoded->arg = file;
1256 decoded->orig_option_with_args_text = file;
1257 decoded->canonical_option_num_elements = 1;
1258 decoded->canonical_option[0] = file;
1259 decoded->canonical_option[1] = NULL;
1260 decoded->canonical_option[2] = NULL;
1261 decoded->canonical_option[3] = NULL;
1262 decoded->value = 1;
1263 decoded->errors = 0;
481e1176
JM
1264}
1265
14bce257
JJ
1266/* Helper function for listing valid choices and hint for misspelled
1267 value. CANDIDATES is a vector containing all valid strings,
1268 STR is set to a heap allocated string that contains all those
1269 strings concatenated, separated by spaces, and the return value
1270 is the closest string from those to ARG, or NULL if nothing is
1271 close enough. Callers should XDELETEVEC (STR) after using it
1272 to avoid memory leaks. */
1273
1274const char *
1275candidates_list_and_hint (const char *arg, char *&str,
1276 const auto_vec <const char *> &candidates)
1277{
1278 size_t len = 0;
1279 int i;
1280 const char *candidate;
1281 char *p;
1282
1283 FOR_EACH_VEC_ELT (candidates, i, candidate)
1284 len += strlen (candidate) + 1;
1285
1286 str = p = XNEWVEC (char, len);
1287 FOR_EACH_VEC_ELT (candidates, i, candidate)
1288 {
1289 len = strlen (candidate);
1290 memcpy (p, candidate, len);
1291 p[len] = ' ';
1292 p += len + 1;
1293 }
1294 p[-1] = '\0';
1295 return find_closest_string (arg, &candidates);
1296}
1297
63bbf46d
JJ
1298/* Perform diagnostics for read_cmdline_option and control_warning_option
1299 functions. Returns true if an error has been diagnosed.
1300 LOC and LANG_MASK arguments like in read_cmdline_option.
1301 OPTION is the option to report diagnostics for, OPT the name
1302 of the option as text, ARG the argument of the option (for joined
1303 options), ERRORS is bitmask of CL_ERR_* values. */
5f20c657 1304
63bbf46d
JJ
1305static bool
1306cmdline_handle_error (location_t loc, const struct cl_option *option,
1307 const char *opt, const char *arg, int errors,
1308 unsigned int lang_mask)
5f20c657 1309{
63bbf46d 1310 if (errors & CL_ERR_DISABLED)
5f20c657 1311 {
0ecf545c 1312 error_at (loc, "command-line option %qs"
63bbf46d
JJ
1313 " is not supported by this configuration", opt);
1314 return true;
5f20c657
JM
1315 }
1316
63bbf46d 1317 if (errors & CL_ERR_MISSING_ARG)
5f20c657
JM
1318 {
1319 if (option->missing_argument_error)
a4d8c676 1320 error_at (loc, option->missing_argument_error, opt);
5f20c657 1321 else
a4d8c676 1322 error_at (loc, "missing argument to %qs", opt);
63bbf46d 1323 return true;
5f20c657
JM
1324 }
1325
63bbf46d 1326 if (errors & CL_ERR_UINT_ARG)
5f20c657 1327 {
00abf86c
MS
1328 if (option->cl_byte_size)
1329 error_at (loc, "argument to %qs should be a non-negative integer "
1330 "optionally followed by a size unit",
1331 option->opt_text);
1332 else
1333 error_at (loc, "argument to %qs should be a non-negative integer",
1334 option->opt_text);
63bbf46d 1335 return true;
5f20c657
JM
1336 }
1337
63010089
ML
1338 if (errors & CL_ERR_INT_RANGE_ARG)
1339 {
1340 error_at (loc, "argument to %qs is not between %d and %d",
1341 option->opt_text, option->range_min, option->range_max);
1342 return true;
1343 }
1344
63bbf46d 1345 if (errors & CL_ERR_ENUM_ARG)
e6d4b984
JM
1346 {
1347 const struct cl_enum *e = &cl_enums[option->var_enum];
1348 unsigned int i;
14bce257 1349 char *s;
e6d4b984 1350
097f82ec 1351 auto_diagnostic_group d;
e6d4b984 1352 if (e->unknown_error)
63bbf46d 1353 error_at (loc, e->unknown_error, arg);
e6d4b984
JM
1354 else
1355 error_at (loc, "unrecognized argument in option %qs", opt);
1356
70f25790 1357 auto_vec <const char *> candidates;
e6d4b984
JM
1358 for (i = 0; e->values[i].arg != NULL; i++)
1359 {
85d91a6b
DV
1360 if (!enum_arg_ok_for_language (&e->values[i], lang_mask))
1361 continue;
70f25790 1362 candidates.safe_push (e->values[i].arg);
e6d4b984 1363 }
14bce257 1364 const char *hint = candidates_list_and_hint (arg, s, candidates);
70f25790
DM
1365 if (hint)
1366 inform (loc, "valid arguments to %qs are: %s; did you mean %qs?",
1367 option->opt_text, s, hint);
1368 else
1369 inform (loc, "valid arguments to %qs are: %s", option->opt_text, s);
14bce257 1370 XDELETEVEC (s);
70f25790 1371
63bbf46d
JJ
1372 return true;
1373 }
1374
1375 return false;
1376}
1377
1378/* Handle the switch DECODED (location LOC) for the language indicated
1379 by LANG_MASK, using the handlers in *HANDLERS and setting fields in
1380 OPTS and OPTS_SET and using diagnostic context DC (if not NULL) for
1381 diagnostic options. */
1382
1383void
1384read_cmdline_option (struct gcc_options *opts,
1385 struct gcc_options *opts_set,
1386 struct cl_decoded_option *decoded,
1387 location_t loc,
1388 unsigned int lang_mask,
1389 const struct cl_option_handlers *handlers,
1390 diagnostic_context *dc)
1391{
1392 const struct cl_option *option;
1393 const char *opt = decoded->orig_option_with_args_text;
1394
1395 if (decoded->warn_message)
1396 warning_at (loc, 0, decoded->warn_message, opt);
1397
1398 if (decoded->opt_index == OPT_SPECIAL_unknown)
1399 {
1400 if (handlers->unknown_option_callback (decoded))
0ecf545c 1401 error_at (loc, "unrecognized command-line option %qs", decoded->arg);
e6d4b984
JM
1402 return;
1403 }
1404
63bbf46d
JJ
1405 if (decoded->opt_index == OPT_SPECIAL_ignore)
1406 return;
1407
68a57628 1408 if (decoded->opt_index == OPT_SPECIAL_warn_removed)
c0c12356
ML
1409 {
1410 /* Warn only about positive ignored options. */
1411 if (decoded->value)
1412 warning_at (loc, 0, "switch %qs is no longer supported", opt);
1413 return;
1414 }
1415
63bbf46d
JJ
1416 option = &cl_options[decoded->opt_index];
1417
1418 if (decoded->errors
1419 && cmdline_handle_error (loc, option, opt, decoded->arg,
1420 decoded->errors, lang_mask))
1421 return;
1422
4df47bca
JM
1423 if (decoded->errors & CL_ERR_WRONG_LANG)
1424 {
1425 handlers->wrong_lang_callback (decoded, lang_mask);
1426 return;
1427 }
1428
5f20c657
JM
1429 gcc_assert (!decoded->errors);
1430
d4d24ba4 1431 if (!handle_option (opts, opts_set, decoded, lang_mask, DK_UNSPECIFIED,
a4d8c676 1432 loc, handlers, false, dc))
0ecf545c 1433 error_at (loc, "unrecognized command-line option %qs", opt);
5f20c657
JM
1434}
1435
d4d24ba4 1436/* Set any field in OPTS, and OPTS_SET if not NULL, for option
a4d8c676
JM
1437 OPT_INDEX according to VALUE and ARG, diagnostic kind KIND,
1438 location LOC, using diagnostic context DC if not NULL for
1439 diagnostic classification. */
5f20c657
JM
1440
1441void
d4d24ba4 1442set_option (struct gcc_options *opts, struct gcc_options *opts_set,
00abf86c 1443 int opt_index, HOST_WIDE_INT value, const char *arg, int kind,
a4d8c676 1444 location_t loc, diagnostic_context *dc)
5f20c657
JM
1445{
1446 const struct cl_option *option = &cl_options[opt_index];
46625112 1447 void *flag_var = option_flag_var (opt_index, opts);
d4d24ba4 1448 void *set_flag_var = NULL;
5f20c657 1449
46625112 1450 if (!flag_var)
5f20c657
JM
1451 return;
1452
3ba421e8
MLI
1453 if ((diagnostic_t) kind != DK_UNSPECIFIED && dc != NULL)
1454 diagnostic_classify_diagnostic (dc, opt_index, (diagnostic_t) kind, loc);
1455
d4d24ba4
JM
1456 if (opts_set != NULL)
1457 set_flag_var = option_flag_var (opt_index, opts_set);
1458
5f20c657
JM
1459 switch (option->var_type)
1460 {
1461 case CLVC_BOOLEAN:
00abf86c
MS
1462 if (option->cl_host_wide_int)
1463 {
1464 *(HOST_WIDE_INT *) flag_var = value;
1465 if (set_flag_var)
1466 *(HOST_WIDE_INT *) set_flag_var = 1;
1467 }
1468 else
1469 {
5c5eb7e4
ML
1470 if (value > INT_MAX)
1471 error_at (loc, "argument to %qs is bigger than %d",
1472 option->opt_text, INT_MAX);
1473 else
1474 {
1475 *(int *) flag_var = value;
1476 if (set_flag_var)
1477 *(int *) set_flag_var = 1;
1478 }
00abf86c
MS
1479 }
1480
1481 break;
1482
1483 case CLVC_SIZE:
1484 if (option->cl_host_wide_int)
1485 {
1486 *(HOST_WIDE_INT *) flag_var = value;
1487 if (set_flag_var)
1488 *(HOST_WIDE_INT *) set_flag_var = value;
1489 }
1490 else
1491 {
1492 *(int *) flag_var = value;
1493 if (set_flag_var)
1494 *(int *) set_flag_var = value;
1495 }
1496
5f20c657
JM
1497 break;
1498
1499 case CLVC_EQUAL:
00abf86c
MS
1500 if (option->cl_host_wide_int)
1501 {
1502 *(HOST_WIDE_INT *) flag_var = (value
1503 ? option->var_value
1504 : !option->var_value);
1505 if (set_flag_var)
1506 *(HOST_WIDE_INT *) set_flag_var = 1;
1507 }
99114bbf 1508 else
00abf86c
MS
1509 {
1510 *(int *) flag_var = (value
1511 ? option->var_value
1512 : !option->var_value);
1513 if (set_flag_var)
1514 *(int *) set_flag_var = 1;
1515 }
5f20c657
JM
1516 break;
1517
1518 case CLVC_BIT_CLEAR:
1519 case CLVC_BIT_SET:
1520 if ((value != 0) == (option->var_type == CLVC_BIT_SET))
99114bbf
L
1521 {
1522 if (option->cl_host_wide_int)
1523 *(HOST_WIDE_INT *) flag_var |= option->var_value;
1524 else
1525 *(int *) flag_var |= option->var_value;
1526 }
5f20c657 1527 else
99114bbf
L
1528 {
1529 if (option->cl_host_wide_int)
1530 *(HOST_WIDE_INT *) flag_var &= ~option->var_value;
1531 else
1532 *(int *) flag_var &= ~option->var_value;
1533 }
d4d24ba4 1534 if (set_flag_var)
99114bbf
L
1535 {
1536 if (option->cl_host_wide_int)
1537 *(HOST_WIDE_INT *) set_flag_var |= option->var_value;
1538 else
1539 *(int *) set_flag_var |= option->var_value;
1540 }
5f20c657
JM
1541 break;
1542
1543 case CLVC_STRING:
46625112 1544 *(const char **) flag_var = arg;
d4d24ba4
JM
1545 if (set_flag_var)
1546 *(const char **) set_flag_var = "";
5f20c657 1547 break;
21bf1558 1548
e6d4b984
JM
1549 case CLVC_ENUM:
1550 {
1551 const struct cl_enum *e = &cl_enums[option->var_enum];
1552
1553 e->set (flag_var, value);
1554 if (set_flag_var)
1555 e->set (set_flag_var, 1);
1556 }
1557 break;
1558
21bf1558
JM
1559 case CLVC_DEFER:
1560 {
9771b263
DN
1561 vec<cl_deferred_option> *v
1562 = (vec<cl_deferred_option> *) *(void **) flag_var;
f32682ca 1563 cl_deferred_option p = {opt_index, arg, value};
9771b263
DN
1564 if (!v)
1565 v = XCNEW (vec<cl_deferred_option>);
1566 v->safe_push (p);
1567 *(void **) flag_var = v;
21bf1558 1568 if (set_flag_var)
9771b263 1569 *(void **) set_flag_var = v;
21bf1558
JM
1570 }
1571 break;
5f20c657 1572 }
5f20c657 1573}
46625112
JM
1574
1575/* Return the address of the flag variable for option OPT_INDEX in
1576 options structure OPTS, or NULL if there is no flag variable. */
1577
1578void *
1579option_flag_var (int opt_index, struct gcc_options *opts)
1580{
1581 const struct cl_option *option = &cl_options[opt_index];
1582
1583 if (option->flag_var_offset == (unsigned short) -1)
1584 return NULL;
1585 return (void *)(((char *) opts) + option->flag_var_offset);
1586}
c5fa0890 1587
c98cd5bf
JM
1588/* Return 1 if option OPT_IDX is enabled in OPTS, 0 if it is disabled,
1589 or -1 if it isn't a simple on-off switch. */
1590
1591int
fa5baeed 1592option_enabled (int opt_idx, unsigned lang_mask, void *opts)
c98cd5bf
JM
1593{
1594 const struct cl_option *option = &(cl_options[opt_idx]);
fa5baeed
MS
1595
1596 /* A language-specific option can only be considered enabled when it's
1597 valid for the current language. */
e2eee239
MS
1598 if (!(option->flags & CL_COMMON)
1599 && (option->flags & CL_LANG_ALL)
1600 && !(option->flags & lang_mask))
fa5baeed
MS
1601 return 0;
1602
c98cd5bf
JM
1603 struct gcc_options *optsg = (struct gcc_options *) opts;
1604 void *flag_var = option_flag_var (opt_idx, optsg);
1605
1606 if (flag_var)
1607 switch (option->var_type)
1608 {
1609 case CLVC_BOOLEAN:
00abf86c
MS
1610 if (option->cl_host_wide_int)
1611 return *(HOST_WIDE_INT *) flag_var != 0;
1612 else
1613 return *(int *) flag_var != 0;
c98cd5bf
JM
1614
1615 case CLVC_EQUAL:
99114bbf
L
1616 if (option->cl_host_wide_int)
1617 return *(HOST_WIDE_INT *) flag_var == option->var_value;
1618 else
1619 return *(int *) flag_var == option->var_value;
c98cd5bf
JM
1620
1621 case CLVC_BIT_CLEAR:
99114bbf
L
1622 if (option->cl_host_wide_int)
1623 return (*(HOST_WIDE_INT *) flag_var & option->var_value) == 0;
1624 else
1625 return (*(int *) flag_var & option->var_value) == 0;
c98cd5bf
JM
1626
1627 case CLVC_BIT_SET:
99114bbf
L
1628 if (option->cl_host_wide_int)
1629 return (*(HOST_WIDE_INT *) flag_var & option->var_value) != 0;
1630 else
1631 return (*(int *) flag_var & option->var_value) != 0;
c98cd5bf 1632
00abf86c
MS
1633 case CLVC_SIZE:
1634 if (option->cl_host_wide_int)
1635 return *(HOST_WIDE_INT *) flag_var != -1;
1636 else
1637 return *(int *) flag_var != -1;
1638
c98cd5bf 1639 case CLVC_STRING:
e6d4b984 1640 case CLVC_ENUM:
c98cd5bf
JM
1641 case CLVC_DEFER:
1642 break;
1643 }
1644 return -1;
1645}
1646
1647/* Fill STATE with the current state of option OPTION in OPTS. Return
1648 true if there is some state to store. */
1649
1650bool
1651get_option_state (struct gcc_options *opts, int option,
1652 struct cl_option_state *state)
1653{
1654 void *flag_var = option_flag_var (option, opts);
1655
1656 if (flag_var == 0)
1657 return false;
1658
1659 switch (cl_options[option].var_type)
1660 {
1661 case CLVC_BOOLEAN:
1662 case CLVC_EQUAL:
00abf86c 1663 case CLVC_SIZE:
c98cd5bf 1664 state->data = flag_var;
99114bbf
L
1665 state->size = (cl_options[option].cl_host_wide_int
1666 ? sizeof (HOST_WIDE_INT)
1667 : sizeof (int));
c98cd5bf
JM
1668 break;
1669
1670 case CLVC_BIT_CLEAR:
1671 case CLVC_BIT_SET:
fa5baeed 1672 state->ch = option_enabled (option, -1, opts);
c98cd5bf
JM
1673 state->data = &state->ch;
1674 state->size = 1;
1675 break;
1676
1677 case CLVC_STRING:
1678 state->data = *(const char **) flag_var;
1679 if (state->data == 0)
1680 state->data = "";
1681 state->size = strlen ((const char *) state->data) + 1;
1682 break;
1683
e6d4b984
JM
1684 case CLVC_ENUM:
1685 state->data = flag_var;
1686 state->size = cl_enums[cl_options[option].var_enum].var_size;
1687 break;
1688
c98cd5bf
JM
1689 case CLVC_DEFER:
1690 return false;
1691 }
1692 return true;
1693}
1694
c5fa0890
JM
1695/* Set a warning option OPT_INDEX (language mask LANG_MASK, option
1696 handlers HANDLERS) to have diagnostic kind KIND for option
1697 structures OPTS and OPTS_SET and diagnostic context DC (possibly
63bbf46d
JJ
1698 NULL), at location LOC (UNKNOWN_LOCATION for -Werror=). ARG is the
1699 argument of the option for joined options, or NULL otherwise. If IMPLY,
c5fa0890
JM
1700 the warning option in question is implied at this point. This is
1701 used by -Werror= and #pragma GCC diagnostic. */
1702
1703void
63bbf46d
JJ
1704control_warning_option (unsigned int opt_index, int kind, const char *arg,
1705 bool imply, location_t loc, unsigned int lang_mask,
c5fa0890
JM
1706 const struct cl_option_handlers *handlers,
1707 struct gcc_options *opts,
1708 struct gcc_options *opts_set,
1709 diagnostic_context *dc)
1710{
1711 if (cl_options[opt_index].alias_target != N_OPTS)
54d62f51
JJ
1712 {
1713 gcc_assert (!cl_options[opt_index].cl_separate_alias
1714 && !cl_options[opt_index].cl_negative_alias);
1715 if (cl_options[opt_index].alias_arg)
1716 arg = cl_options[opt_index].alias_arg;
1717 opt_index = cl_options[opt_index].alias_target;
1718 }
68a57628 1719 if (opt_index == OPT_SPECIAL_ignore || opt_index == OPT_SPECIAL_warn_removed)
c5fa0890
JM
1720 return;
1721 if (dc)
1722 diagnostic_classify_diagnostic (dc, opt_index, (diagnostic_t) kind, loc);
1723 if (imply)
1724 {
63bbf46d
JJ
1725 const struct cl_option *option = &cl_options[opt_index];
1726
c5fa0890 1727 /* -Werror=foo implies -Wfoo. */
00abf86c
MS
1728 if (option->var_type == CLVC_BOOLEAN
1729 || option->var_type == CLVC_ENUM
1730 || option->var_type == CLVC_SIZE)
63bbf46d 1731 {
00abf86c 1732 HOST_WIDE_INT value = 1;
63bbf46d
JJ
1733
1734 if (arg && *arg == '\0' && !option->cl_missing_ok)
1735 arg = NULL;
1736
1737 if ((option->flags & CL_JOINED) && arg == NULL)
1738 {
1739 cmdline_handle_error (loc, option, option->opt_text, arg,
1740 CL_ERR_MISSING_ARG, lang_mask);
1741 return;
1742 }
1743
00abf86c
MS
1744 /* If the switch takes an integer argument, convert it. */
1745 if (arg && (option->cl_uinteger || option->cl_host_wide_int))
63bbf46d 1746 {
00abf86c
MS
1747 int error = 0;
1748 value = *arg ? integral_argument (arg, &error,
1749 option->cl_byte_size) : 0;
1750 if (error)
63bbf46d
JJ
1751 {
1752 cmdline_handle_error (loc, option, option->opt_text, arg,
1753 CL_ERR_UINT_ARG, lang_mask);
1754 return;
1755 }
1756 }
1757
1758 /* If the switch takes an enumerated argument, convert it. */
1759 if (arg && option->var_type == CLVC_ENUM)
1760 {
1761 const struct cl_enum *e = &cl_enums[option->var_enum];
1762
1763 if (enum_arg_to_value (e->values, arg, &value, lang_mask))
1764 {
1765 const char *carg = NULL;
1766
1767 if (enum_value_to_arg (e->values, &carg, value, lang_mask))
1768 arg = carg;
1769 gcc_assert (carg != NULL);
1770 }
1771 else
1772 {
1773 cmdline_handle_error (loc, option, option->opt_text, arg,
1774 CL_ERR_ENUM_ARG, lang_mask);
1775 return;
1776 }
1777 }
1778
1779 handle_generated_option (opts, opts_set,
1780 opt_index, arg, value, lang_mask,
b9822443 1781 kind, loc, handlers, false, dc);
63bbf46d 1782 }
c5fa0890
JM
1783 }
1784}
f1a681a1
PK
1785
1786/* Parse options in COLLECT_GCC_OPTIONS and push them on ARGV_OBSTACK.
1787 Store number of arguments into ARGC_P. */
1788
1789void
1790parse_options_from_collect_gcc_options (const char *collect_gcc_options,
1791 obstack *argv_obstack,
1792 int *argc_p)
1793{
1794 char *argv_storage = xstrdup (collect_gcc_options);
1795 int j, k;
1796
1797 for (j = 0, k = 0; argv_storage[j] != '\0'; ++j)
1798 {
1799 if (argv_storage[j] == '\'')
1800 {
1801 obstack_ptr_grow (argv_obstack, &argv_storage[k]);
1802 ++j;
1803 do
1804 {
1805 if (argv_storage[j] == '\0')
1806 fatal_error (input_location,
1807 "malformed %<COLLECT_GCC_OPTIONS%>");
6ba3079d 1808 else if (startswith (&argv_storage[j], "'\\''"))
f1a681a1
PK
1809 {
1810 argv_storage[k++] = '\'';
1811 j += 4;
1812 }
1813 else if (argv_storage[j] == '\'')
1814 break;
1815 else
1816 argv_storage[k++] = argv_storage[j++];
1817 }
1818 while (1);
1819 argv_storage[k++] = '\0';
1820 }
1821 }
1822
1823 obstack_ptr_grow (argv_obstack, NULL);
1824 *argc_p = obstack_object_size (argv_obstack) / sizeof (void *) - 1;
1825}
1826
1827/* Prepend -Xassembler for each option in COLLECT_AS_OPTIONS,
1828 and push on O. */
1829
1830void prepend_xassembler_to_collect_as_options (const char *collect_as_options,
1831 obstack *o)
1832{
1833 obstack opts_obstack;
1834 int opts_count;
1835
1836 obstack_init (&opts_obstack);
1837 parse_options_from_collect_gcc_options (collect_as_options,
1838 &opts_obstack, &opts_count);
1839 const char **assembler_opts = XOBFINISH (&opts_obstack, const char **);
1840
1841 for (int i = 0; i < opts_count; i++)
1842 {
1843 obstack_grow (o, " '-Xassembler' ",
1844 strlen (" '-Xassembler' "));
1845 const char *opt = assembler_opts[i];
1846 obstack_1grow (o, '\'');
1847 obstack_grow (o, opt, strlen (opt));
1848 obstack_1grow (o, '\'');
1849 }
1850}