3.3.4. 完成处理
当从handle_options符号时,decode_options相应地更新其他标识。flag_no_inline和flag_really_no_inline初始是2。如果合适,flag_no_inline将被common_handle_option 设为1(见该函数的1060行)。在下面,可以看到,如果内联是可能的,这2个变量均是0。而且如果optimize是0,flag_no_inline将是1,但flag_really_no_inline可能是0,以表示树内联器(tree inliner)关闭了内联;也可能是1,以表示内联由-fno-inline关闭。
decode_options (continue)
620 if (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 }
4. 预备源码解析
在decode_options完成编译选项处理后,回到toplev_main,接下来调用randomize初始化随机种子(random seeds)。进而,如果期望真正的编译,艰苦的工作由do_compile肇始。
4638 static void
4639 do_compile (void) in toplev.c
4640 {
4641 /* Initialize timing first. The C front ends read the main file in
4642 the post_options hook, and C++ does file timings. */
4643 if (time_report || !quiet_flag || flag_detailed_statistics)
4644 timevar_init ();
4645 timevar_start (TV_TOTAL);
4646
4647 process_options ();
4.1. 选项的后处理
虽然选项已由decode_options中的handle_options解析和记录,这里仍需要确认这些选项对于语言和目标平台是有效的。如果需要,还要进行调整。同时,还要根据这些选项设置编译器。
4271 static void
4272 process_options (void) in toplev.c
4273 {
4274 /* Just in case lang_hooks.post_options ends up calling a debug_hook.
4275 This can happen with incorrect pre-processed input. */
4276 debug_hooks = &do_nothing_debug_hooks;
4277
4278 /* Allow the front end to perform consistency checks and do further
4279 initialization based on the command line options. This hook also
4280 sets the original filename if appropriate (e.g. foo.i -> foo.c)
4281 so we can correctly initialize debug output. */
4282 no_backend = (*lang_hooks.post_options) (&main_input_filename);
上面,在4276行,debug_hooks及do_nothing_debug_hooks都是gcc_debug_hooks类型,该类型包含了调试信息输出函数的构子。起初,debug_hooks设为do_nothing_debug_hooks,它是不作任何事的钩子。
在4636行,lang_hooks的回调钩子post_options,对于C/C++,是c_common_post_options。
1060 bool
1061 c_common_post_options (const char **pfilename) in c-opts.c
1062 {
1063 struct cpp_callbacks *cb;
1064
1065 /* Canonicalize the input and output filenames. */
1066 if (in_fnames == NULL)
1067 {
1068 in_fnames = xmalloc (sizeof (in_fnames[0]));
1069 in_fnames[0] = "";
1070 }
1071 else if (strcmp (in_fnames[0], "-") == 0)
1072 in_fnames[0] = "";
1073
1074 if (out_fname == NULL || !strcmp (out_fname, "-"))
1075 out_fname = "";
1076
1077 if (cpp_opts->deps.style == DEPS_NONE)
1078 check_deps_environment_vars ();
1079
1080 handle_deferred_opts ();
1081
1082 sanitize_cpp_opts ();
1083
1084 register_include_chains (parse_in, sysroot, iprefix,
1085 std_inc, std_cxx_inc && c_dialect_cxx (), verbose);
C,C++的编译单元是一个源文件加上相关的头文件,这些文件名及路径由命令行选项传入。在handle_options,在453行,in_frames保存了这些文件名。
而在1074行,out_frame持有由-o选项指定的输出文件名。
如果没有使用-dN,-dM,-dD,-dI,就要检查环境变量DEPENDENCIES_OUTPUT或SUNPRO_DEPENDENCIES。
把DEPENDENCIES_OUTPUT设置为一文件名,会导致预处理器把基于依赖的(dependency-based)makefile规则至这个文件。但系统头文件名不包括在内。而对于SUNPRO_DEPENDENCIES,系统头文件亦被包括。如果这些环境变量被设为单个名字,它被认为是该输出文件名,而依赖规则的名字从源文件名获取。如果环境变量被设为2个名字,第二个名字即是依赖规则的目标名。设置这些环境变量的结果,等同于同时使用-MM,-MF和-MT。
1296 static void
1297 check_deps_environment_vars (void) in c-opts.c
1298 {
1299 char *spec;
1300
1301 GET_ENVIRONMENT (spec, "DEPENDENCIES_OUTPUT");
1302 if (spec)
1303 cpp_opts->deps.style = DEPS_USER;
1304 else
1305 {
1306 GET_ENVIRONMENT (spec, "SUNPRO_DEPENDENCIES");
1307 if (spec)
1308