]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/opts-common.c
re PR c++/48969 (ICE with -std=c++0x)
[thirdparty/gcc.git] / gcc / opts-common.c
CommitLineData
14c7833c 1/* Command line option handling.
eb50f63a 2 Copyright (C) 2006, 2007, 2008, 2010, 2011 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"
a75bfaa6 25#include "flags.h"
5f20c657 26#include "diagnostic.h"
14c7833c 27
60cf253a
JM
28static void prune_options (struct cl_decoded_option **, unsigned int *);
29
14c7833c 30/* Perform a binary search to find which option the command-line INPUT
6e2f1956
JM
31 matches. Returns its index in the option array, and
32 OPT_SPECIAL_unknown on failure.
14c7833c
L
33
34 This routine is quite subtle. A normal binary search is not good
35 enough because some options can be suffixed with an argument, and
36 multiple sub-matches can occur, e.g. input of "-pedantic" matching
37 the initial substring of "-pedantic-errors".
38
39 A more complicated example is -gstabs. It should match "-g" with
40 an argument of "stabs". Suppose, however, that the number and list
41 of switches are such that the binary search tests "-gen-decls"
42 before having tested "-g". This doesn't match, and as "-gen-decls"
43 is less than "-gstabs", it will become the lower bound of the
44 binary search range, and "-g" will never be seen. To resolve this
af47e6ac 45 issue, 'optc-gen.awk' makes "-gen-decls" point, via the back_chain member,
14c7833c
L
46 to "-g" so that failed searches that end between "-gen-decls" and
47 the lexicographically subsequent switch know to go back and see if
48 "-g" causes a match (which it does in this example).
49
50 This search is done in such a way that the longest match for the
51 front end in question wins. If there is no match for the current
52 front end, the longest match for a different front end is returned
53 (or N_OPTS if none) and the caller emits an error message. */
54size_t
eb50f63a 55find_opt (const char *input, unsigned int lang_mask)
14c7833c 56{
e200444e 57 size_t mn, mn_orig, mx, md, opt_len;
14c7833c
L
58 size_t match_wrong_lang;
59 int comp;
60
61 mn = 0;
62 mx = cl_options_count;
63
64 /* Find mn such this lexicographical inequality holds:
65 cl_options[mn] <= input < cl_options[mn + 1]. */
66 while (mx - mn > 1)
67 {
68 md = (mn + mx) / 2;
69 opt_len = cl_options[md].opt_len;
70 comp = strncmp (input, cl_options[md].opt_text + 1, opt_len);
71
72 if (comp < 0)
73 mx = md;
74 else
75 mn = md;
76 }
77
e200444e
JM
78 mn_orig = mn;
79
14c7833c 80 /* This is the switch that is the best match but for a different
6e2f1956
JM
81 front end, or OPT_SPECIAL_unknown if there is no match at all. */
82 match_wrong_lang = OPT_SPECIAL_unknown;
14c7833c
L
83
84 /* Backtrace the chain of possible matches, returning the longest
85 one, if any, that fits best. With current GCC switches, this
86 loop executes at most twice. */
87 do
88 {
89 const struct cl_option *opt = &cl_options[mn];
90
91 /* Is the input either an exact match or a prefix that takes a
92 joined argument? */
93 if (!strncmp (input, opt->opt_text + 1, opt->opt_len)
94 && (input[opt->opt_len] == '\0' || (opt->flags & CL_JOINED)))
95 {
96 /* If language is OK, return it. */
97 if (opt->flags & lang_mask)
98 return mn;
99
100 /* If we haven't remembered a prior match, remember this
101 one. Any prior match is necessarily better. */
6e2f1956 102 if (match_wrong_lang == OPT_SPECIAL_unknown)
14c7833c
L
103 match_wrong_lang = mn;
104 }
105
106 /* Try the next possibility. This is cl_options_count if there
107 are no more. */
108 mn = opt->back_chain;
109 }
110 while (mn != cl_options_count);
111
e200444e
JM
112 if (match_wrong_lang == OPT_SPECIAL_unknown && input[0] == '-')
113 {
114 /* Long options, starting "--", may be abbreviated if the
115 abbreviation is unambiguous. This only applies to options
116 not taking a joined argument, and abbreviations of "--option"
117 are permitted even if there is a variant "--option=". */
118 size_t mnc = mn_orig + 1;
119 size_t cmp_len = strlen (input);
120 while (mnc < cl_options_count
121 && strncmp (input, cl_options[mnc].opt_text + 1, cmp_len) == 0)
122 {
123 /* Option matching this abbreviation. OK if it is the first
124 match and that does not take a joined argument, or the
125 second match, taking a joined argument and with only '='
126 added to the first match; otherwise considered
127 ambiguous. */
128 if (mnc == mn_orig + 1
129 && !(cl_options[mnc].flags & CL_JOINED))
130 match_wrong_lang = mnc;
131 else if (mnc == mn_orig + 2
132 && match_wrong_lang == mn_orig + 1
133 && (cl_options[mnc].flags & CL_JOINED)
134 && (cl_options[mnc].opt_len
135 == cl_options[mn_orig + 1].opt_len + 1)
136 && strncmp (cl_options[mnc].opt_text + 1,
137 cl_options[mn_orig + 1].opt_text + 1,
138 cl_options[mn_orig + 1].opt_len) == 0)
139 ; /* OK, as long as there are no more matches. */
140 else
141 return OPT_SPECIAL_unknown;
142 mnc++;
143 }
144 }
145
6e2f1956 146 /* Return the best wrong match, or OPT_SPECIAL_unknown if none. */
14c7833c
L
147 return match_wrong_lang;
148}
149
5d4b393f
JM
150/* If ARG is a non-negative integer made up solely of digits, return its
151 value, otherwise return -1. */
152
153int
154integral_argument (const char *arg)
155{
156 const char *p = arg;
157
158 while (*p && ISDIGIT (*p))
159 p++;
160
161 if (*p == '\0')
162 return atoi (arg);
163
164 return -1;
165}
166
d9d16a19
JM
167/* Return whether OPTION is OK for the language given by
168 LANG_MASK. */
169static bool
170option_ok_for_language (const struct cl_option *option,
171 unsigned int lang_mask)
172{
173 if (!(option->flags & lang_mask))
174 return false;
175 else if ((option->flags & CL_TARGET)
176 && (option->flags & (CL_LANG_ALL | CL_DRIVER))
177 && !(option->flags & (lang_mask & ~CL_COMMON & ~CL_TARGET)))
178 /* Complain for target flag language mismatches if any languages
179 are specified. */
180 return false;
181 return true;
182}
183
e6d4b984
JM
184/* Return whether ENUM_ARG is OK for the language given by
185 LANG_MASK. */
186
187static bool
188enum_arg_ok_for_language (const struct cl_enum_arg *enum_arg,
189 unsigned int lang_mask)
190{
191 return (lang_mask & CL_DRIVER) || !(enum_arg->flags & CL_ENUM_DRIVER_ONLY);
192}
193
194/* Look up ARG in ENUM_ARGS for language LANG_MASK, returning true and
195 storing the value in *VALUE if found, and returning false without
196 modifying *VALUE if not found. */
197
198static bool
199enum_arg_to_value (const struct cl_enum_arg *enum_args,
200 const char *arg, int *value, unsigned int lang_mask)
201{
202 unsigned int i;
203
204 for (i = 0; enum_args[i].arg != NULL; i++)
205 if (strcmp (arg, enum_args[i].arg) == 0
206 && enum_arg_ok_for_language (&enum_args[i], lang_mask))
207 {
208 *value = enum_args[i].value;
209 return true;
210 }
211
212 return false;
213}
214
215/* Look of VALUE in ENUM_ARGS for language LANG_MASK and store the
216 corresponding string in *ARGP, returning true if the found string
217 was marked as canonical, false otherwise. If VALUE is not found
218 (which may be the case for uninitialized values if the relevant
219 option has not been passed), set *ARGP to NULL and return
220 false. */
221
222bool
223enum_value_to_arg (const struct cl_enum_arg *enum_args,
224 const char **argp, int value, unsigned int lang_mask)
225{
226 unsigned int i;
227
228 for (i = 0; enum_args[i].arg != NULL; i++)
229 if (enum_args[i].value == value
230 && (enum_args[i].flags & CL_ENUM_CANONICAL)
231 && enum_arg_ok_for_language (&enum_args[i], lang_mask))
232 {
233 *argp = enum_args[i].arg;
234 return true;
235 }
236
237 for (i = 0; enum_args[i].arg != NULL; i++)
238 if (enum_args[i].value == value
239 && enum_arg_ok_for_language (&enum_args[i], lang_mask))
240 {
241 *argp = enum_args[i].arg;
242 return false;
243 }
244
245 *argp = NULL;
246 return false;
247}
5de8299c
JM
248
249/* Fill in the canonical option part of *DECODED with an option
250 described by OPT_INDEX, ARG and VALUE. */
251
252static void
253generate_canonical_option (size_t opt_index, const char *arg, int value,
254 struct cl_decoded_option *decoded)
255{
256 const struct cl_option *option = &cl_options[opt_index];
257 const char *opt_text = option->opt_text;
258
259 if (value == 0
300d83d9 260 && !option->cl_reject_negative
5de8299c
JM
261 && (opt_text[1] == 'W' || opt_text[1] == 'f' || opt_text[1] == 'm'))
262 {
263 char *t = XNEWVEC (char, option->opt_len + 5);
264 t[0] = '-';
265 t[1] = opt_text[1];
266 t[2] = 'n';
267 t[3] = 'o';
268 t[4] = '-';
269 memcpy (t + 5, opt_text + 2, option->opt_len);
270 opt_text = t;
271 }
272
273 decoded->canonical_option[2] = NULL;
274 decoded->canonical_option[3] = NULL;
275
276 if (arg)
277 {
d1583032 278 if ((option->flags & CL_SEPARATE)
300d83d9 279 && !option->cl_separate_alias)
5de8299c
JM
280 {
281 decoded->canonical_option[0] = opt_text;
282 decoded->canonical_option[1] = arg;
283 decoded->canonical_option_num_elements = 2;
284 }
285 else
286 {
287 gcc_assert (option->flags & CL_JOINED);
288 decoded->canonical_option[0] = concat (opt_text, arg, NULL);
289 decoded->canonical_option[1] = NULL;
290 decoded->canonical_option_num_elements = 1;
291 }
292 }
293 else
294 {
295 decoded->canonical_option[0] = opt_text;
296 decoded->canonical_option[1] = NULL;
297 decoded->canonical_option_num_elements = 1;
298 }
299}
300
e200444e
JM
301/* Structure describing mappings from options on the command line to
302 options to look up with find_opt. */
303struct option_map
304{
305 /* Prefix of the option on the command line. */
306 const char *opt0;
307 /* If two argv elements are considered to be merged into one option,
308 prefix for the second element, otherwise NULL. */
309 const char *opt1;
310 /* The new prefix to map to. */
311 const char *new_prefix;
312 /* Whether at least one character is needed following opt1 or opt0
313 for this mapping to be used. (--optimize= is valid for -O, but
314 --warn- is not valid for -W.) */
315 bool another_char_needed;
316 /* Whether the original option is a negated form of the option
317 resulting from this map. */
318 bool negated;
319};
320static const struct option_map option_map[] =
321 {
322 { "-Wno-", NULL, "-W", false, true },
323 { "-fno-", NULL, "-f", false, true },
324 { "-mno-", NULL, "-m", false, true },
325 { "--debug=", NULL, "-g", false, false },
326 { "--machine-", NULL, "-m", true, false },
327 { "--machine-no-", NULL, "-m", false, true },
328 { "--machine=", NULL, "-m", false, false },
329 { "--machine=no-", NULL, "-m", false, true },
330 { "--machine", "", "-m", false, false },
331 { "--machine", "no-", "-m", false, true },
332 { "--optimize=", NULL, "-O", false, false },
333 { "--std=", NULL, "-std=", false, false },
334 { "--std", "", "-std=", false, false },
335 { "--warn-", NULL, "-W", true, false },
336 { "--warn-no-", NULL, "-W", false, true },
337 { "--", NULL, "-f", true, false },
338 { "--no-", NULL, "-f", false, true }
339 };
340
5d4b393f 341/* Decode the switch beginning at ARGV for the language indicated by
603349bf
JM
342 LANG_MASK (including CL_COMMON and CL_TARGET if applicable), into
343 the structure *DECODED. Returns the number of switches
344 consumed. */
5d4b393f 345
6e2f1956 346static unsigned int
5d4b393f
JM
347decode_cmdline_option (const char **argv, unsigned int lang_mask,
348 struct cl_decoded_option *decoded)
349{
350 size_t opt_index;
e200444e 351 const char *arg = 0;
5d4b393f 352 int value = 1;
c8967d95 353 unsigned int result = 1, i, extra_args, separate_args = 0;
e200444e 354 int adjust_len = 0;
eea13ead
JM
355 size_t total_len;
356 char *p;
5d4b393f
JM
357 const struct cl_option *option;
358 int errors = 0;
2d2bd949 359 const char *warn_message = NULL;
c878765b
JM
360 bool separate_arg_flag;
361 bool joined_arg_flag;
d1583032 362 bool have_separate_arg = false;
5d4b393f 363
e200444e 364 extra_args = 0;
5d4b393f 365
e200444e
JM
366 opt_index = find_opt (argv[0] + 1, lang_mask);
367 i = 0;
368 while (opt_index == OPT_SPECIAL_unknown
369 && i < ARRAY_SIZE (option_map))
5d4b393f 370 {
e200444e
JM
371 const char *opt0 = option_map[i].opt0;
372 const char *opt1 = option_map[i].opt1;
373 const char *new_prefix = option_map[i].new_prefix;
374 bool another_char_needed = option_map[i].another_char_needed;
375 size_t opt0_len = strlen (opt0);
376 size_t opt1_len = (opt1 == NULL ? 0 : strlen (opt1));
377 size_t optn_len = (opt1 == NULL ? opt0_len : opt1_len);
378 size_t new_prefix_len = strlen (new_prefix);
379
380 extra_args = (opt1 == NULL ? 0 : 1);
381 value = !option_map[i].negated;
382
383 if (strncmp (argv[0], opt0, opt0_len) == 0
384 && (opt1 == NULL
385 || (argv[1] != NULL && strncmp (argv[1], opt1, opt1_len) == 0))
386 && (!another_char_needed
387 || argv[extra_args][optn_len] != 0))
388 {
389 size_t arglen = strlen (argv[extra_args]);
390 char *dup;
391
392 adjust_len = (int) optn_len - (int) new_prefix_len;
393 dup = XNEWVEC (char, arglen + 1 - adjust_len);
394 memcpy (dup, new_prefix, new_prefix_len);
395 memcpy (dup + new_prefix_len, argv[extra_args] + optn_len,
396 arglen - optn_len + 1);
397 opt_index = find_opt (dup + 1, lang_mask);
398 free (dup);
399 }
400 i++;
5d4b393f
JM
401 }
402
6e2f1956
JM
403 if (opt_index == OPT_SPECIAL_unknown)
404 {
405 arg = argv[0];
e200444e
JM
406 extra_args = 0;
407 value = 1;
6e2f1956
JM
408 goto done;
409 }
5d4b393f
JM
410
411 option = &cl_options[opt_index];
412
413 /* Reject negative form of switches that don't take negatives as
414 unrecognized. */
300d83d9 415 if (!value && option->cl_reject_negative)
5d4b393f 416 {
6e2f1956 417 opt_index = OPT_SPECIAL_unknown;
184eb658 418 errors |= CL_ERR_NEGATIVE;
6e2f1956 419 arg = argv[0];
5d4b393f
JM
420 goto done;
421 }
422
e200444e 423 result = extra_args + 1;
2d2bd949
JM
424 warn_message = option->warn_message;
425
5d4b393f 426 /* Check to see if the option is disabled for this configuration. */
300d83d9 427 if (option->cl_disabled)
5d4b393f
JM
428 errors |= CL_ERR_DISABLED;
429
c878765b 430 /* Determine whether there may be a separate argument based on
c243beb0
JM
431 whether this option is being processed for the driver, and, if
432 so, how many such arguments. */
c878765b 433 separate_arg_flag = ((option->flags & CL_SEPARATE)
300d83d9 434 && !(option->cl_no_driver_arg
c878765b 435 && (lang_mask & CL_DRIVER)));
c243beb0 436 separate_args = (separate_arg_flag
300d83d9 437 ? option->cl_separate_nargs + 1
c243beb0 438 : 0);
c878765b
JM
439 joined_arg_flag = (option->flags & CL_JOINED) != 0;
440
5d4b393f 441 /* Sort out any argument the switch takes. */
c878765b 442 if (joined_arg_flag)
5d4b393f
JM
443 {
444 /* Have arg point to the original switch. This is because
445 some code, such as disable_builtin_function, expects its
446 argument to be persistent until the program exits. */
e200444e 447 arg = argv[extra_args] + cl_options[opt_index].opt_len + 1 + adjust_len;
5d4b393f 448
300d83d9 449 if (*arg == '\0' && !option->cl_missing_ok)
5d4b393f 450 {
c878765b 451 if (separate_arg_flag)
5d4b393f 452 {
e200444e
JM
453 arg = argv[extra_args + 1];
454 result = extra_args + 2;
5d4b393f 455 if (arg == NULL)
e200444e 456 result = extra_args + 1;
d1583032
JM
457 else
458 have_separate_arg = true;
5d4b393f
JM
459 }
460 else
461 /* Missing argument. */
462 arg = NULL;
463 }
464 }
c878765b 465 else if (separate_arg_flag)
5d4b393f 466 {
e200444e 467 arg = argv[extra_args + 1];
c243beb0
JM
468 for (i = 0; i < separate_args; i++)
469 if (argv[extra_args + 1 + i] == NULL)
470 {
471 errors |= CL_ERR_MISSING_ARG;
472 break;
473 }
474 result = extra_args + 1 + i;
475 if (arg != NULL)
d1583032 476 have_separate_arg = true;
5d4b393f
JM
477 }
478
5de8299c
JM
479 if (arg == NULL && (separate_arg_flag || joined_arg_flag))
480 errors |= CL_ERR_MISSING_ARG;
481
2d2bd949
JM
482 /* Is this option an alias (or an ignored option, marked as an alias
483 of OPT_SPECIAL_ignore)? */
d1583032 484 if (option->alias_target != N_OPTS
300d83d9 485 && (!option->cl_separate_alias || have_separate_arg))
5de8299c
JM
486 {
487 size_t new_opt_index = option->alias_target;
5de8299c 488
2d2bd949 489 if (new_opt_index == OPT_SPECIAL_ignore)
5de8299c 490 {
2d2bd949
JM
491 gcc_assert (option->alias_arg == NULL);
492 gcc_assert (option->neg_alias_arg == NULL);
493 opt_index = new_opt_index;
494 arg = NULL;
5de8299c
JM
495 value = 1;
496 }
2d2bd949 497 else
5de8299c 498 {
2d2bd949 499 const struct cl_option *new_option = &cl_options[new_opt_index];
5de8299c 500
2d2bd949 501 /* The new option must not be an alias itself. */
e200444e 502 gcc_assert (new_option->alias_target == N_OPTS
300d83d9 503 || new_option->cl_separate_alias);
5de8299c 504
2d2bd949
JM
505 if (option->neg_alias_arg)
506 {
507 gcc_assert (option->alias_arg != NULL);
508 gcc_assert (arg == NULL);
300d83d9 509 gcc_assert (!option->cl_negative_alias);
2d2bd949
JM
510 if (value)
511 arg = option->alias_arg;
512 else
513 arg = option->neg_alias_arg;
514 value = 1;
515 }
516 else if (option->alias_arg)
517 {
518 gcc_assert (value == 1);
519 gcc_assert (arg == NULL);
300d83d9 520 gcc_assert (!option->cl_negative_alias);
2d2bd949
JM
521 arg = option->alias_arg;
522 }
5de8299c 523
300d83d9 524 if (option->cl_negative_alias)
666a21a2
JM
525 value = !value;
526
2d2bd949
JM
527 opt_index = new_opt_index;
528 option = new_option;
5de8299c 529
2d2bd949 530 if (value == 0)
300d83d9 531 gcc_assert (!option->cl_reject_negative);
2d2bd949
JM
532
533 /* Recompute what arguments are allowed. */
534 separate_arg_flag = ((option->flags & CL_SEPARATE)
300d83d9 535 && !(option->cl_no_driver_arg
2d2bd949
JM
536 && (lang_mask & CL_DRIVER)));
537 joined_arg_flag = (option->flags & CL_JOINED) != 0;
538
300d83d9 539 if (separate_args > 1 || option->cl_separate_nargs)
c243beb0 540 gcc_assert (separate_args
300d83d9 541 == (unsigned int) option->cl_separate_nargs + 1);
c243beb0 542
2d2bd949
JM
543 if (!(errors & CL_ERR_MISSING_ARG))
544 {
545 if (separate_arg_flag || joined_arg_flag)
e200444e 546 {
300d83d9 547 if (option->cl_missing_ok && arg == NULL)
e200444e
JM
548 arg = "";
549 gcc_assert (arg != NULL);
550 }
2d2bd949
JM
551 else
552 gcc_assert (arg == NULL);
553 }
5de8299c 554
2d2bd949
JM
555 /* Recheck for warnings and disabled options. */
556 if (option->warn_message)
557 {
558 gcc_assert (warn_message == NULL);
559 warn_message = option->warn_message;
560 }
300d83d9 561 if (option->cl_disabled)
2d2bd949
JM
562 errors |= CL_ERR_DISABLED;
563 }
5de8299c
JM
564 }
565
5d4b393f 566 /* Check if this is a switch for a different front end. */
d9d16a19 567 if (!option_ok_for_language (option, lang_mask))
5d4b393f 568 errors |= CL_ERR_WRONG_LANG;
5d4b393f 569
413519ae
JM
570 /* Convert the argument to lowercase if appropriate. */
571 if (arg && option->cl_tolower)
572 {
573 size_t j;
574 size_t len = strlen (arg);
575 char *arg_lower = XNEWVEC (char, len + 1);
576
577 for (j = 0; j < len; j++)
578 arg_lower[j] = TOLOWER ((unsigned char) arg[j]);
579 arg_lower[len] = 0;
580 arg = arg_lower;
581 }
582
5d4b393f 583 /* If the switch takes an integer, convert it. */
300d83d9 584 if (arg && option->cl_uinteger)
5d4b393f
JM
585 {
586 value = integral_argument (arg);
587 if (value == -1)
588 errors |= CL_ERR_UINT_ARG;
589 }
590
e6d4b984
JM
591 /* If the switch takes an enumerated argument, convert it. */
592 if (arg && (option->var_type == CLVC_ENUM))
593 {
594 const struct cl_enum *e = &cl_enums[option->var_enum];
595
596 gcc_assert (value == 1);
597 if (enum_arg_to_value (e->values, arg, &value, lang_mask))
598 {
599 const char *carg = NULL;
600
601 if (enum_value_to_arg (e->values, &carg, value, lang_mask))
602 arg = carg;
603 gcc_assert (carg != NULL);
604 }
605 else
606 errors |= CL_ERR_ENUM_ARG;
607 }
608
5d4b393f 609 done:
5d4b393f
JM
610 decoded->opt_index = opt_index;
611 decoded->arg = arg;
612 decoded->value = value;
613 decoded->errors = errors;
2d2bd949 614 decoded->warn_message = warn_message;
eea13ead
JM
615
616 if (opt_index == OPT_SPECIAL_unknown)
c243beb0 617 gcc_assert (result == 1);
eea13ead
JM
618
619 gcc_assert (result >= 1 && result <= ARRAY_SIZE (decoded->canonical_option));
620 decoded->canonical_option_num_elements = result;
621 total_len = 0;
622 for (i = 0; i < ARRAY_SIZE (decoded->canonical_option); i++)
623 {
624 if (i < result)
625 {
7fcf46f5 626 size_t len;
5de8299c
JM
627 if (opt_index == OPT_SPECIAL_unknown)
628 decoded->canonical_option[i] = argv[i];
629 else
630 decoded->canonical_option[i] = NULL;
7fcf46f5
JZ
631 len = strlen (argv[i]);
632 /* If the argument is an empty string, we will print it as "" in
633 orig_option_with_args_text. */
634 total_len += (len != 0 ? len : 2) + 1;
eea13ead
JM
635 }
636 else
637 decoded->canonical_option[i] = NULL;
638 }
2d2bd949 639 if (opt_index != OPT_SPECIAL_unknown && opt_index != OPT_SPECIAL_ignore)
c243beb0
JM
640 {
641 generate_canonical_option (opt_index, arg, value, decoded);
642 if (separate_args > 1)
643 {
644 for (i = 0; i < separate_args; i++)
645 {
646 if (argv[extra_args + 1 + i] == NULL)
647 break;
648 else
649 decoded->canonical_option[1 + i] = argv[extra_args + 1 + i];
650 }
651 gcc_assert (result == 1 + i);
652 decoded->canonical_option_num_elements = result;
653 }
654 }
eea13ead
JM
655 decoded->orig_option_with_args_text = p = XNEWVEC (char, total_len);
656 for (i = 0; i < result; i++)
657 {
658 size_t len = strlen (argv[i]);
659
7fcf46f5
JZ
660 /* Print the empty string verbally. */
661 if (len == 0)
662 {
663 *p++ = '"';
664 *p++ = '"';
665 }
666 else
667 memcpy (p, argv[i], len);
eea13ead
JM
668 p += len;
669 if (i == result - 1)
670 *p++ = 0;
671 else
672 *p++ = ' ';
673 }
674
5d4b393f
JM
675 return result;
676}
677
6e2f1956
JM
678/* Decode command-line options (ARGC and ARGV being the arguments of
679 main) into an array, setting *DECODED_OPTIONS to a pointer to that
680 array and *DECODED_OPTIONS_COUNT to the number of entries in the
681 array. The first entry in the array is always one for the program
682 name (OPT_SPECIAL_program_name). LANG_MASK indicates the language
603349bf
JM
683 flags applicable for decoding (including CL_COMMON and CL_TARGET if
684 those options should be considered applicable). Do not produce any
685 diagnostics or set state outside of these variables. */
6e2f1956
JM
686
687void
688decode_cmdline_options_to_array (unsigned int argc, const char **argv,
689 unsigned int lang_mask,
690 struct cl_decoded_option **decoded_options,
691 unsigned int *decoded_options_count)
692{
2be55a25 693 unsigned int n, i;
6e2f1956
JM
694 struct cl_decoded_option *opt_array;
695 unsigned int num_decoded_options;
696
697 opt_array = XNEWVEC (struct cl_decoded_option, argc);
698
699 opt_array[0].opt_index = OPT_SPECIAL_program_name;
2d2bd949 700 opt_array[0].warn_message = NULL;
6e2f1956
JM
701 opt_array[0].arg = argv[0];
702 opt_array[0].orig_option_with_args_text = argv[0];
eea13ead 703 opt_array[0].canonical_option_num_elements = 1;
7a9bf9a4
JM
704 opt_array[0].canonical_option[0] = argv[0];
705 opt_array[0].canonical_option[1] = NULL;
eea13ead
JM
706 opt_array[0].canonical_option[2] = NULL;
707 opt_array[0].canonical_option[3] = NULL;
6e2f1956
JM
708 opt_array[0].value = 1;
709 opt_array[0].errors = 0;
710 num_decoded_options = 1;
711
712 for (i = 1; i < argc; i += n)
713 {
714 const char *opt = argv[i];
715
716 /* Interpret "-" or a non-switch as a file name. */
717 if (opt[0] != '-' || opt[1] == '\0')
718 {
d9d16a19 719 generate_option_input_file (opt, &opt_array[num_decoded_options]);
6e2f1956
JM
720 num_decoded_options++;
721 n = 1;
722 continue;
723 }
724
725 n = decode_cmdline_option (argv + i, lang_mask,
726 &opt_array[num_decoded_options]);
727 num_decoded_options++;
728 }
729
6e2f1956
JM
730 *decoded_options = opt_array;
731 *decoded_options_count = num_decoded_options;
60cf253a 732 prune_options (decoded_options, decoded_options_count);
6e2f1956
JM
733}
734
14c7833c
L
735/* Return true if NEXT_OPT_IDX cancels OPT_IDX. Return false if the
736 next one is the same as ORIG_NEXT_OPT_IDX. */
737
738static bool
739cancel_option (int opt_idx, int next_opt_idx, int orig_next_opt_idx)
740{
741 /* An option can be canceled by the same option or an option with
742 Negative. */
743 if (cl_options [next_opt_idx].neg_index == opt_idx)
744 return true;
745
746 if (cl_options [next_opt_idx].neg_index != orig_next_opt_idx)
747 return cancel_option (opt_idx, cl_options [next_opt_idx].neg_index,
748 orig_next_opt_idx);
b8698a0f 749
14c7833c
L
750 return false;
751}
752
753/* Filter out options canceled by the ones after them. */
754
60cf253a
JM
755static void
756prune_options (struct cl_decoded_option **decoded_options,
757 unsigned int *decoded_options_count)
14c7833c 758{
60cf253a
JM
759 unsigned int old_decoded_options_count = *decoded_options_count;
760 struct cl_decoded_option *old_decoded_options = *decoded_options;
761 unsigned int new_decoded_options_count;
762 struct cl_decoded_option *new_decoded_options
763 = XNEWVEC (struct cl_decoded_option, old_decoded_options_count);
764 unsigned int i;
14c7833c 765 const struct cl_option *option;
14c7833c
L
766
767 /* Remove arguments which are negated by others after them. */
60cf253a
JM
768 new_decoded_options_count = 0;
769 for (i = 0; i < old_decoded_options_count; i++)
14c7833c 770 {
60cf253a
JM
771 unsigned int j, opt_idx, next_opt_idx;
772
773 if (old_decoded_options[i].errors & ~CL_ERR_WRONG_LANG)
774 goto keep;
14c7833c 775
60cf253a
JM
776 opt_idx = old_decoded_options[i].opt_index;
777 switch (opt_idx)
14c7833c 778 {
60cf253a
JM
779 case OPT_SPECIAL_unknown:
780 case OPT_SPECIAL_ignore:
781 case OPT_SPECIAL_program_name:
782 case OPT_SPECIAL_input_file:
783 goto keep;
784
785 default:
786 gcc_assert (opt_idx < cl_options_count);
787 option = &cl_options[opt_idx];
788 if (option->neg_index < 0)
789 goto keep;
790
791 /* Skip joined switches. */
792 if ((option->flags & CL_JOINED))
793 goto keep;
794
795 for (j = i + 1; j < old_decoded_options_count; j++)
14c7833c 796 {
60cf253a
JM
797 if (old_decoded_options[j].errors & ~CL_ERR_WRONG_LANG)
798 continue;
799 next_opt_idx = old_decoded_options[j].opt_index;
800 if (next_opt_idx >= cl_options_count)
801 continue;
802 if (cl_options[next_opt_idx].neg_index < 0)
803 continue;
804 if ((cl_options[next_opt_idx].flags & CL_JOINED))
805 continue;
806 if (cancel_option (opt_idx, next_opt_idx, next_opt_idx))
14c7833c
L
807 break;
808 }
60cf253a
JM
809 if (j == old_decoded_options_count)
810 {
14c7833c 811keep:
60cf253a
JM
812 new_decoded_options[new_decoded_options_count]
813 = old_decoded_options[i];
814 new_decoded_options_count++;
815 }
816 break;
14c7833c
L
817 }
818 }
819
60cf253a
JM
820 free (old_decoded_options);
821 new_decoded_options = XRESIZEVEC (struct cl_decoded_option,
822 new_decoded_options,
823 new_decoded_options_count);
824 *decoded_options = new_decoded_options;
825 *decoded_options_count = new_decoded_options_count;
14c7833c 826}
5f20c657 827
481e1176 828/* Handle option DECODED for the language indicated by LANG_MASK,
d4d24ba4
JM
829 using the handlers in HANDLERS and setting fields in OPTS and
830 OPTS_SET. KIND is the diagnostic_t if this is a diagnostics
a4d8c676
JM
831 option, DK_UNSPECIFIED otherwise, and LOC is the location of the
832 option for options from the source file, UNKNOWN_LOCATION
833 otherwise. GENERATED_P is true for an option generated as part of
834 processing another option or otherwise generated internally, false
835 for one explicitly passed by the user. Returns false if the switch
836 was invalid. DC is the diagnostic context for options affecting
837 diagnostics state, or NULL. */
5f20c657 838
a4d8c676 839static bool
46625112 840handle_option (struct gcc_options *opts,
d4d24ba4 841 struct gcc_options *opts_set,
46625112 842 const struct cl_decoded_option *decoded,
a4d8c676 843 unsigned int lang_mask, int kind, location_t loc,
d4d24ba4 844 const struct cl_option_handlers *handlers,
1ebe4b4f 845 bool generated_p, diagnostic_context *dc)
5f20c657 846{
481e1176
JM
847 size_t opt_index = decoded->opt_index;
848 const char *arg = decoded->arg;
849 int value = decoded->value;
5f20c657 850 const struct cl_option *option = &cl_options[opt_index];
46625112 851 void *flag_var = option_flag_var (opt_index, opts);
5f20c657
JM
852 size_t i;
853
46625112 854 if (flag_var)
d4d24ba4 855 set_option (opts, (generated_p ? NULL : opts_set),
a4d8c676 856 opt_index, value, arg, kind, loc, dc);
5f20c657
JM
857
858 for (i = 0; i < handlers->num_handlers; i++)
859 if (option->flags & handlers->handlers[i].mask)
860 {
d4d24ba4 861 if (!handlers->handlers[i].handler (opts, opts_set, decoded,
a4d8c676
JM
862 lang_mask, kind, loc,
863 handlers, dc))
5f20c657
JM
864 return false;
865 else
481e1176 866 handlers->post_handling_callback (decoded,
5f20c657
JM
867 handlers->handlers[i].mask);
868 }
869
870 return true;
871}
872
481e1176
JM
873/* Like handle_option, but OPT_INDEX, ARG and VALUE describe the
874 option instead of DECODED. This is used for callbacks when one
875 option implies another instead of an option being decoded from the
876 command line. */
877
878bool
d4d24ba4
JM
879handle_generated_option (struct gcc_options *opts,
880 struct gcc_options *opts_set,
881 size_t opt_index, const char *arg, int value,
a4d8c676 882 unsigned int lang_mask, int kind, location_t loc,
1ebe4b4f
JM
883 const struct cl_option_handlers *handlers,
884 diagnostic_context *dc)
481e1176 885{
481e1176
JM
886 struct cl_decoded_option decoded;
887
d9d16a19 888 generate_option (opt_index, arg, value, lang_mask, &decoded);
a4d8c676
JM
889 return handle_option (opts, opts_set, &decoded, lang_mask, kind, loc,
890 handlers, true, dc);
d9d16a19
JM
891}
892
893/* Fill in *DECODED with an option described by OPT_INDEX, ARG and
894 VALUE for a front end using LANG_MASK. This is used when the
895 compiler generates options internally. */
896
897void
898generate_option (size_t opt_index, const char *arg, int value,
899 unsigned int lang_mask, struct cl_decoded_option *decoded)
900{
901 const struct cl_option *option = &cl_options[opt_index];
902
903 decoded->opt_index = opt_index;
2d2bd949 904 decoded->warn_message = NULL;
d9d16a19 905 decoded->arg = arg;
d9d16a19
JM
906 decoded->value = value;
907 decoded->errors = (option_ok_for_language (option, lang_mask)
908 ? 0
909 : CL_ERR_WRONG_LANG);
481e1176 910
5de8299c
JM
911 generate_canonical_option (opt_index, arg, value, decoded);
912 switch (decoded->canonical_option_num_elements)
481e1176 913 {
5de8299c
JM
914 case 1:
915 decoded->orig_option_with_args_text = decoded->canonical_option[0];
916 break;
917
918 case 2:
919 decoded->orig_option_with_args_text
920 = concat (decoded->canonical_option[0], " ",
921 decoded->canonical_option[1], NULL);
922 break;
923
924 default:
925 gcc_unreachable ();
481e1176 926 }
d9d16a19 927}
481e1176 928
d9d16a19
JM
929/* Fill in *DECODED with an option for input file FILE. */
930
931void
932generate_option_input_file (const char *file,
933 struct cl_decoded_option *decoded)
934{
935 decoded->opt_index = OPT_SPECIAL_input_file;
2d2bd949 936 decoded->warn_message = NULL;
d9d16a19
JM
937 decoded->arg = file;
938 decoded->orig_option_with_args_text = file;
939 decoded->canonical_option_num_elements = 1;
940 decoded->canonical_option[0] = file;
941 decoded->canonical_option[1] = NULL;
942 decoded->canonical_option[2] = NULL;
943 decoded->canonical_option[3] = NULL;
944 decoded->value = 1;
945 decoded->errors = 0;
481e1176
JM
946}
947
a4d8c676
JM
948/* Handle the switch DECODED (location LOC) for the language indicated
949 by LANG_MASK, using the handlers in *HANDLERS and setting fields in
950 OPTS and OPTS_SET and using diagnostic context DC (if not NULL) for
1ebe4b4f 951 diagnostic options. */
5f20c657
JM
952
953void
46625112 954read_cmdline_option (struct gcc_options *opts,
d4d24ba4 955 struct gcc_options *opts_set,
46625112 956 struct cl_decoded_option *decoded,
a4d8c676 957 location_t loc,
5f20c657 958 unsigned int lang_mask,
1ebe4b4f
JM
959 const struct cl_option_handlers *handlers,
960 diagnostic_context *dc)
5f20c657
JM
961{
962 const struct cl_option *option;
2d2bd949
JM
963 const char *opt = decoded->orig_option_with_args_text;
964
965 if (decoded->warn_message)
a4d8c676 966 warning_at (loc, 0, decoded->warn_message, opt);
5f20c657
JM
967
968 if (decoded->opt_index == OPT_SPECIAL_unknown)
969 {
481e1176 970 if (handlers->unknown_option_callback (decoded))
a4d8c676 971 error_at (loc, "unrecognized command line option %qs", decoded->arg);
5f20c657
JM
972 return;
973 }
974
2d2bd949
JM
975 if (decoded->opt_index == OPT_SPECIAL_ignore)
976 return;
977
5f20c657 978 option = &cl_options[decoded->opt_index];
5f20c657
JM
979
980 if (decoded->errors & CL_ERR_DISABLED)
981 {
a4d8c676
JM
982 error_at (loc, "command line option %qs"
983 " is not supported by this configuration", opt);
5f20c657
JM
984 return;
985 }
986
5f20c657
JM
987 if (decoded->errors & CL_ERR_MISSING_ARG)
988 {
989 if (option->missing_argument_error)
a4d8c676 990 error_at (loc, option->missing_argument_error, opt);
5f20c657 991 else
a4d8c676 992 error_at (loc, "missing argument to %qs", opt);
5f20c657
JM
993 return;
994 }
995
996 if (decoded->errors & CL_ERR_UINT_ARG)
997 {
a4d8c676
JM
998 error_at (loc, "argument to %qs should be a non-negative integer",
999 option->opt_text);
5f20c657
JM
1000 return;
1001 }
1002
e6d4b984
JM
1003 if (decoded->errors & CL_ERR_ENUM_ARG)
1004 {
1005 const struct cl_enum *e = &cl_enums[option->var_enum];
1006 unsigned int i;
1007 size_t len;
1008 char *s, *p;
1009
1010 if (e->unknown_error)
1011 error_at (loc, e->unknown_error, decoded->arg);
1012 else
1013 error_at (loc, "unrecognized argument in option %qs", opt);
1014
1015 len = 0;
1016 for (i = 0; e->values[i].arg != NULL; i++)
1017 len += strlen (e->values[i].arg) + 1;
1018
1019 s = XALLOCAVEC (char, len);
1020 p = s;
1021 for (i = 0; e->values[i].arg != NULL; i++)
1022 {
1023 size_t arglen = strlen (e->values[i].arg);
1024 memcpy (p, e->values[i].arg, arglen);
1025 p[arglen] = ' ';
1026 p += arglen + 1;
1027 }
1028 p[-1] = 0;
1029 inform (loc, "valid arguments to %qs are: %s", option->opt_text, s);
1030 return;
1031 }
1032
4df47bca
JM
1033 if (decoded->errors & CL_ERR_WRONG_LANG)
1034 {
1035 handlers->wrong_lang_callback (decoded, lang_mask);
1036 return;
1037 }
1038
5f20c657
JM
1039 gcc_assert (!decoded->errors);
1040
d4d24ba4 1041 if (!handle_option (opts, opts_set, decoded, lang_mask, DK_UNSPECIFIED,
a4d8c676
JM
1042 loc, handlers, false, dc))
1043 error_at (loc, "unrecognized command line option %qs", opt);
5f20c657
JM
1044}
1045
d4d24ba4 1046/* Set any field in OPTS, and OPTS_SET if not NULL, for option
a4d8c676
JM
1047 OPT_INDEX according to VALUE and ARG, diagnostic kind KIND,
1048 location LOC, using diagnostic context DC if not NULL for
1049 diagnostic classification. */
5f20c657
JM
1050
1051void
d4d24ba4 1052set_option (struct gcc_options *opts, struct gcc_options *opts_set,
1ebe4b4f 1053 int opt_index, int value, const char *arg, int kind,
a4d8c676 1054 location_t loc, diagnostic_context *dc)
5f20c657
JM
1055{
1056 const struct cl_option *option = &cl_options[opt_index];
46625112 1057 void *flag_var = option_flag_var (opt_index, opts);
d4d24ba4 1058 void *set_flag_var = NULL;
5f20c657 1059
46625112 1060 if (!flag_var)
5f20c657
JM
1061 return;
1062
d4d24ba4
JM
1063 if (opts_set != NULL)
1064 set_flag_var = option_flag_var (opt_index, opts_set);
1065
5f20c657
JM
1066 switch (option->var_type)
1067 {
1068 case CLVC_BOOLEAN:
46625112 1069 *(int *) flag_var = value;
d4d24ba4
JM
1070 if (set_flag_var)
1071 *(int *) set_flag_var = 1;
5f20c657
JM
1072 break;
1073
1074 case CLVC_EQUAL:
46625112
JM
1075 *(int *) flag_var = (value
1076 ? option->var_value
1077 : !option->var_value);
d4d24ba4
JM
1078 if (set_flag_var)
1079 *(int *) set_flag_var = 1;
5f20c657
JM
1080 break;
1081
1082 case CLVC_BIT_CLEAR:
1083 case CLVC_BIT_SET:
1084 if ((value != 0) == (option->var_type == CLVC_BIT_SET))
46625112 1085 *(int *) flag_var |= option->var_value;
5f20c657 1086 else
46625112 1087 *(int *) flag_var &= ~option->var_value;
d4d24ba4
JM
1088 if (set_flag_var)
1089 *(int *) set_flag_var |= option->var_value;
5f20c657
JM
1090 break;
1091
1092 case CLVC_STRING:
46625112 1093 *(const char **) flag_var = arg;
d4d24ba4
JM
1094 if (set_flag_var)
1095 *(const char **) set_flag_var = "";
5f20c657 1096 break;
21bf1558 1097
e6d4b984
JM
1098 case CLVC_ENUM:
1099 {
1100 const struct cl_enum *e = &cl_enums[option->var_enum];
1101
1102 e->set (flag_var, value);
1103 if (set_flag_var)
1104 e->set (set_flag_var, 1);
1105 }
1106 break;
1107
21bf1558
JM
1108 case CLVC_DEFER:
1109 {
1110 VEC(cl_deferred_option,heap) *vec
1111 = (VEC(cl_deferred_option,heap) *) *(void **) flag_var;
1112 cl_deferred_option *p;
1113
1114 p = VEC_safe_push (cl_deferred_option, heap, vec, NULL);
1115 p->opt_index = opt_index;
1116 p->arg = arg;
1117 p->value = value;
1118 *(void **) flag_var = vec;
1119 if (set_flag_var)
1120 *(void **) set_flag_var = vec;
1121 }
1122 break;
5f20c657
JM
1123 }
1124
1ebe4b4f
JM
1125 if ((diagnostic_t) kind != DK_UNSPECIFIED
1126 && dc != NULL)
a4d8c676 1127 diagnostic_classify_diagnostic (dc, opt_index, (diagnostic_t) kind, loc);
5f20c657 1128}
46625112
JM
1129
1130/* Return the address of the flag variable for option OPT_INDEX in
1131 options structure OPTS, or NULL if there is no flag variable. */
1132
1133void *
1134option_flag_var (int opt_index, struct gcc_options *opts)
1135{
1136 const struct cl_option *option = &cl_options[opt_index];
1137
1138 if (option->flag_var_offset == (unsigned short) -1)
1139 return NULL;
1140 return (void *)(((char *) opts) + option->flag_var_offset);
1141}
c5fa0890 1142
c98cd5bf
JM
1143/* Return 1 if option OPT_IDX is enabled in OPTS, 0 if it is disabled,
1144 or -1 if it isn't a simple on-off switch. */
1145
1146int
1147option_enabled (int opt_idx, void *opts)
1148{
1149 const struct cl_option *option = &(cl_options[opt_idx]);
1150 struct gcc_options *optsg = (struct gcc_options *) opts;
1151 void *flag_var = option_flag_var (opt_idx, optsg);
1152
1153 if (flag_var)
1154 switch (option->var_type)
1155 {
1156 case CLVC_BOOLEAN:
1157 return *(int *) flag_var != 0;
1158
1159 case CLVC_EQUAL:
1160 return *(int *) flag_var == option->var_value;
1161
1162 case CLVC_BIT_CLEAR:
1163 return (*(int *) flag_var & option->var_value) == 0;
1164
1165 case CLVC_BIT_SET:
1166 return (*(int *) flag_var & option->var_value) != 0;
1167
1168 case CLVC_STRING:
e6d4b984 1169 case CLVC_ENUM:
c98cd5bf
JM
1170 case CLVC_DEFER:
1171 break;
1172 }
1173 return -1;
1174}
1175
1176/* Fill STATE with the current state of option OPTION in OPTS. Return
1177 true if there is some state to store. */
1178
1179bool
1180get_option_state (struct gcc_options *opts, int option,
1181 struct cl_option_state *state)
1182{
1183 void *flag_var = option_flag_var (option, opts);
1184
1185 if (flag_var == 0)
1186 return false;
1187
1188 switch (cl_options[option].var_type)
1189 {
1190 case CLVC_BOOLEAN:
1191 case CLVC_EQUAL:
1192 state->data = flag_var;
1193 state->size = sizeof (int);
1194 break;
1195
1196 case CLVC_BIT_CLEAR:
1197 case CLVC_BIT_SET:
1198 state->ch = option_enabled (option, opts);
1199 state->data = &state->ch;
1200 state->size = 1;
1201 break;
1202
1203 case CLVC_STRING:
1204 state->data = *(const char **) flag_var;
1205 if (state->data == 0)
1206 state->data = "";
1207 state->size = strlen ((const char *) state->data) + 1;
1208 break;
1209
e6d4b984
JM
1210 case CLVC_ENUM:
1211 state->data = flag_var;
1212 state->size = cl_enums[cl_options[option].var_enum].var_size;
1213 break;
1214
c98cd5bf
JM
1215 case CLVC_DEFER:
1216 return false;
1217 }
1218 return true;
1219}
1220
c5fa0890
JM
1221/* Set a warning option OPT_INDEX (language mask LANG_MASK, option
1222 handlers HANDLERS) to have diagnostic kind KIND for option
1223 structures OPTS and OPTS_SET and diagnostic context DC (possibly
1224 NULL), at location LOC (UNKNOWN_LOCATION for -Werror=). If IMPLY,
1225 the warning option in question is implied at this point. This is
1226 used by -Werror= and #pragma GCC diagnostic. */
1227
1228void
1229control_warning_option (unsigned int opt_index, int kind, bool imply,
1230 location_t loc, unsigned int lang_mask,
1231 const struct cl_option_handlers *handlers,
1232 struct gcc_options *opts,
1233 struct gcc_options *opts_set,
1234 diagnostic_context *dc)
1235{
1236 if (cl_options[opt_index].alias_target != N_OPTS)
1237 opt_index = cl_options[opt_index].alias_target;
1238 if (opt_index == OPT_SPECIAL_ignore)
1239 return;
1240 if (dc)
1241 diagnostic_classify_diagnostic (dc, opt_index, (diagnostic_t) kind, loc);
1242 if (imply)
1243 {
1244 /* -Werror=foo implies -Wfoo. */
1245 if (cl_options[opt_index].var_type == CLVC_BOOLEAN)
1246 handle_generated_option (opts, opts_set,
1247 opt_index, NULL, 1, lang_mask,
1248 kind, loc, handlers, dc);
1249 }
1250}