一切准备好后,可以开始处理除-O优化选项外的编译命令行选项了。
decode_options (continue)
618 handle_options (argc, argv, lang_mask);
619
620 if (flag_pie)
621 flag_pic = flag_pie;
622 if (flag_pic && ! flag_pie)
623 flag_shlib = 1;
624
625 if (flag_no_inline == 2)
626 flag_no_inline = 0;
627 else
628 flag_really_no_inline = flag_no_inline;
629
630 /* Set flag_no_inline before the post_options () hook. The C front
631 ends use it to determine tree inlining defaults. FIXME: such
632 code should be lang-independent when all front ends use tree
633 inlining, in which case it, and this condition, should be moved
634 to the top of process_options() instead. */
635 if (optimize == 0)
636 {
637 /* Inlining does not work if not optimizing,
638 so force it not to be done. */
639 flag_no_inline = 1;
640 warn_inline = 0;
641
642 /* The c_decode_option function and decode_option hook set
643 this to `2' if -Wall is used, so we can avoid giving out
644 lots of errors for people who don't realize what -Wall does. */
645 if (warn_uninitialized == 1)
646 warning ("-Wuninitialized is not supported without -O");
647 }
648
649 if (flag_really_no_inline == 2)
650 flag_really_no_inline = flag_no_inline;
651 }
在618行处理了选项后,相应的需要同步某些选项。
flag_pie,为非0值,如果我们正在编译位置无关代码(position independent code,pic)的可执行文件。如果是“小”pic,其值为1;如果为“大”pic,其值为2。
flag_pic,为非0值,如果我们正在编译纯代码(共享代码)。如果是“小”pic,其值为1;如果为“大”pic,其值为2。
flag_shlib,为非0值,如果我们为共享库编译代码;为0,如果编译执行文件。
flag_no_inline(-fno-inline),如果为非0值,促使编译器忽略关键字inline。
flag_really_no_inline,如果为非0值,表示出于-fno-inline,我们不希望内联,而不是由于树内联器(tree inliner)把内联关闭。
注意到,在618行,lang_mask从c_common_init_options得到它的值,它是枚举值CL_C,CL_ObjC,CL_CXX和CL_ObjCXX之一。
439 static void
440 handle_options (unsigned int argc, const char **argv, unsigned int lang_mask) in opts.c
441 {
442 unsigned int n, i;
443
444 for (i = 1; i < argc; i += n)
445 {
446 const char *opt = argv[i];
447
448 /* Interpret "-" or a non-switch as a file name. */
449 if (opt[0] != '-' || opt[1] == '/0')
450 {
451 if (main_input_filename == NULL)
452 main_input_filename = opt;
453 add_input_filename (opt);
454 n = 1;
455 continue;
456 }
457
458 n = handle_option (argv + i, lang_mask);
459
460 if (!n)
461 {
462 n = 1;
463 error ("unrecognized command line option /"%s/"", opt);
464 }
465 }
466 }
在这个函数的448行的handle_option,它解析编译命令行并返回“消化”的选项个数。在命令行中,选项“-”表示从标准输入(通常是控制台)获取输入,而不以“-”的选项被视为普通的输入文件。看到输入文件在handle_option之前被识别,因此我们可以这样写命令:g++ test –o test.c,也可以这样写:g++ -o test.c test。
327 static unsigned int
328 handle_option (const char **argv, unsigned int lang_mask) in opts.c
329 {
330 size_t opt_index;
331 const char *opt, *arg = 0;
332 char *dup = 0;
333 int value = 1;
334 unsigned int result = 0;
335 const struct cl_option *option;
336
337 opt = argv[0];
338
339 /* Drop the "no-" from negative switches. */
340 if ((opt[1] == 'W' || opt[1] == 'f')
341 && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-')
342 {
343 size_t len = strlen (opt) - 3;
344
345 dup = xmalloc (len + 1);
346 dup[0] = '-';
347 dup[1] = opt[1];
348 memcpy (dup + 2, opt + 5, len - 2 + 1);
349 opt = dup;
350 value = 0;
351 }
352
353 opt_index = find_opt (opt + 1, lang_mask | CL_COMMON);
354 if (opt_index == cl_options_count)
355 goto done;
356
357 option = &cl_options[opt_index];
358
359 /* Reject negative form of switches that don't take negatives as
360 unrecognized. */
361 if (!value && (option->flags & CL_REJECT_NEGATIVE))
362 goto done;
340 ~ 351行,从–[Wf]no-*移去“no-”部分,并且设置value为0以表示否定的选项(negative switch)。在357行,cl_options是以下定义的cl_option类型,它包含了C/C++语言的相关选项。
27 struct cl_option in opts.h
28 {
29 const char *opt_text;
30 const char *help;
31 unsigned short back_chain;
32 unsigned char opt_len;
33 unsigned int flags;
34 };
在353行的函数find_opt即是使用这个数组来找出选项对应的下标。注意到由c_common_init_options返回的lang_mask表示了应用该选项的语言,因此,find_opt会检查选项是否适用于指定的语言,但即便选项和语言不相配,它一样会把选项的索引返回。