3.3.4. Finish the handling
When return from handle_options, decode_options updates other flags accordingly. Orinigal value of flag_no_inline and flag_really_no_inline are 2. If appropriate, flag_no_inline will be set as 1 in common_handle_option to stand for no inline (see line 1060 in the function). In below, we see that the final value will be 0 for both if inline is possible. And if optimize is zero, flag_no_inline will be 1, but flag_really_no_inline may be 0 to indicate inline is turned off by tree inliner, and may be 1 to indicate inline is turned off by -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. Pre-source-parsing
After decode_options processing compiler switches, returns back to toplev_main, following randomize is invoked to initialize random seeds. Next, if real compilation is expected, the hard work will begin in 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. Options aftertreatment
Though options are parsed and recorded by handle_options in decode_options, it needs verify that those options are valid for the language and target. It also may adjust them if necessary. At the same time it needs set up the compiler according to those options too.
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);
Above, at line 4276, debug_hooks and do_nothing_debug_hooks are of gcc_debug_hooks type which contains hooks for the debug information output functions. Originally, debug_hooks set as do_nothing_debug_hooks which is do-nothing debug hooks.
At line 4282, callback post_options of lang_hooks, for C/C++, is 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);
The compile unit of C, C++ is one source file and related header files, the name and path of these files are passed by command options. In handle_options, at line 453, in_frames saves these filenames. And at line 1074, out_frame holds the name of output file designated by –o switch.
If -dN, -dM, -dD, -dI are not specified, environment variable DEPENDENCIES_OUTPUT or SUNPRO_DEPENDENCIES is checked.
Setting DEPENDENCIES_OUTPUT to a file name will cause the preprocessor to write a dependency-based makefile rule to the file. But System header file names are not included. While for SUNPRO_DEPENDENCIES, system header file names are included. If the environment variable is set to a single name, it is taken to be the name of the file, and the name on the dependency rule is taken from the name of the source file. If there are two names in the definition, the second name is the name of the target used on the dependency rule. The result of setting this environment variable is the same as using a combination of options -MM, -MF, and -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 {
1309 cpp_opts->deps.style = DEPS_SYSTEM;
1310 cpp_opts->deps.ignore_main_file = true;
1311 }
1312 }
1313
1314 if (spec)
1315 {
1316 /* Find the space before the DEPS_TARGET, if there is one. */
1317 char *s = strchr (spec, ' ');
1318 if (s)
1319 {
1320 /* Let the caller perform MAKE quoting. */
1321 defer_opt (OPT_MT, s + 1);
1322 *s = '/0';
1323 }
1324
1325 /* Command line -MF overrides environment variables and default. */
1326 if (!deps_file)
1327 deps_file = spec;
1328
1329 deps_append = 1;
1330 }
1331 }
Previous, it has seen that option –MT or –MQ needs be cached to be deferred for processing. Then, at line 1080, these deffered options can be handled.
1334 static void
1335 handle_deferred_opts (void) in c-opts.c
1336 {
1337 size_t i;
1338
1339 for (i = 0; i < deferred_count; i++)
1340 {
1341 struct deferred_opt *opt = &deferred_opts[i];
1342
1343 if (opt->code == OPT_MT || opt->code == OPT_MQ)
1344 cpp_add_dependency_target (parse_in, opt->arg, opt->code == OPT_MQ);
1345 }
1346 }
As –MT or -MQ changes the target of the rule emitted by dependency generation, the target is added by cpp_add_dependency_target.
430 void
431 cpp_add_dependency_target (cpp_reader *pfile, const char *target, int quote) in cppinit.c
432 {
433 if (!pfile->deps)
434 pfile->deps = deps_init ();
435
436 deps_add_target (pfile->deps, target, quote);
437 }
deps at line 433 is defined as following.
27 /* Keep this structure local to this file, so clients don't find it
28 easy to start making assumptions. */
30 {
31 const char **targetv;
32 unsigned int ntargets; /* number of slots actually occupied */
33 unsigned int targets_size; /* amt of allocated space - in words */
34
35 const char **depv;
36 unsigned int ndeps;
37 unsigned int deps_size;
38 };
This object is initialized by deps_init, and target name is added by deps_add_target, in which parameter quote indiactes the need to quote special characters in the name.
Then after this processing of deferred options, sanitize_cpp_opts is invoked to do some sanity check.
1350 static void
1351 sanitize_cpp_opts (void) in c-opts.c
1352 {
1353 /* If we don't know what style of dependencies to output, complain
1354 if any other dependency switches have been given. */
1355 if (deps_seen && cpp_opts->deps.style == DEPS_NONE)
1356 error ("to generate dependencies you must specify either -M or -MM");
1357
1358 /* -dM and dependencies suppress normal output; do it here so that
1359 the last -d[MDN] switch overrides earlier ones. */
1360 if (flag_dump_macros == 'M')
1361 flag_no_output = 1;
1362
1363 /* Disable -dD, -dN and -dI if normal output is suppressed. Allow
1364 -dM since at least glibc relies on -M -dM to work. */
1365 /* Also, flag_no_output implies flag_no_line_commands, always. */
1366 if (flag_no_output)
1367 {
1368 if (flag_dump_macros != 'M')
1369 flag_dump_macros = 0;
1370 flag_dump_includes = 0;
1371 flag_no_line_commands = 1;
1372 }
1373
1374 cpp_opts->unsigned_char = !flag_signed_char;
1375 cpp_opts->stdc_0_in_system_headers = STDC_0_IN_SYSTEM_HEADERS;
1376
1377 /* We want -Wno-long-long to override -pedantic -std=non-c99
1378 and/or -Wtraditional, whatever the ordering. */
1379 cpp_opts->warn_long_long
1380 = warn_long_long && ((!flag_isoc99 && pedantic) || warn_traditional);
1381
1382 /* If we're generating preprocessor output, emit current directory
1383 if explicitly requested or if debugging information is enabled.
1384 ??? Maybe we should only do it for debugging formats that
1385 actually output the current directory? */
1386 if (flag_working_directory == -1)
1387 flag_working_directory = (debug_info_level != DINFO_LEVEL_NONE);
1388 }
Above at line 1360, flag_dump_macro is set in handle_OPT_d, which if is ‘M’ only macros are dumped. Then at line 1361, flag_no_output, if nonzero, causes -E output not to be done, but directives such as #define that have side effects are still obeyed.