Below, flag_inline_trees, it is 0 if we should not perform inlining, 1 if we should expand functions calls inline at the tree level, and 2 if we should consider all functions to be inline candidates.
And flag_inline_functions if nonzero, the compiler is allowed to select certain simple functions to be expanded in line at the point of the function call. This variable is automatically set by -O3 unless the -fno-inline-functions flag is specified. Next, flag_no_inline if nonzero, causes the compiler to ignore the inline keyword. Further flag_really_no_inline, if nonzero, means that we don't want inlining by virtue of -fno-inline, not just because the tree inliner turned us off.
Obvious, if flag_really_no_inline is nonzero, unless using attribute “always_inline”, inline functions won’t be expanded. But if lag_no_inline and flag_inline_functions both are nonzero, the compiler will determine which to be expanded.
c_common_post_option (continue)
1087 flag_inline_trees = 1;
1088
1089 /* Use tree inlining if possible. Function instrumentation is only
1090 done in the RTL level, so we disable tree inlining. */
1091 if (flag_instrument_function_entry_exit)
1092 {
1093 flag_no_inline = 1;
1094 flag_really_no_inline = 1;
1095 }
1096 else
1097 {
1098 if (!flag_no_inline)
1099 flag_no_inline = 1;
1100 if (flag_inline_functions)
1101 {
1102 flag_inline_trees = 2;
1103 flag_inline_functions = 0;
1104 }
1105 }
1106
1107 /* -Wextra implies -Wsign-compare, but not if explicitly
1108 overridden. */
1109 if (warn_sign_compare == -1)
1110 warn_sign_compare = extra_warnings;
1111
1112 /* Special format checking options don't work without -Wformat; warn if
1113 they are used. */
1114 if (warn_format_y2k && !warn_format)
1115 warning ("-Wformat-y2k ignored without -Wformat");
1116 if (warn_format_extra_args && ! warn_format)
1117 warning ("-Wformat-extra-args ignored without -Wformat");
1118 if (warn_format_zero_length && ! warn_format)
1119 warning ("-Wformat-zero-length ignored without -Wformat");
1120 if (warn_format_nonliteral && ! warn_format)
1121 warning ("-Wformat-nonliteral ignored without -Wformat");
1122 if (warn_format_security && ! warn_format)
1123 warning ("-Wformat-security ignored without -Wformat");
1124 if (warn_missing_format_attribute && ! warn_format)
1125 warning ("-Wmissing-format-attribute ignored without -Wformat");
1126
1127 if (flag_preprocess_only)
1128 {
1129 /* Open the output now. We must do so even if flag_no_output is
1130 on, because there may be other output than from the actual
1131 preprocessing (e.g. from -dM). */
1132 if (out_fname [0] == '/0')
1133 out_fname = stdout;
1134 else
1135 out_fname = fopen (out_fname, "w");
1136
1137 if (out_fname == NULL)
1138 {
1139 fatal_error ("opening output file %s: %m", out_fname);
1140 return false;
1141 }
1142
1143 if (num_in_fnames > 1)
1144 error ("too many filenames given. Type %s --help for usage",
1145 progname);
1146
1147 init_pp_output (out_fname);
1148 }
1149 else
1150 {
1151 init_c_lex ();
1152
1153 /* Yuk. WTF is this? I do know ObjC relies on it somewhere. */
1154 input_line = 0;
1155 }
1156
1157 cb = cpp_get_callbacks (parse_in);
1158 cb->file_change = cb_file_change;
1159 cb->dir_change = cb_dir_change;
1160 cpp_post_options (parse_in);
If we don’t require just preprocessing and then stop, thus line 1151 above does the initialization related to lex stage.
77 void
78 init_c_lex (void) in c-lex.c
79 {
80 struct cpp_callbacks *cb;
81 struct c_fileinfo *toplevel;
82
83 /* Set up filename timing. Must happen before cpp_read_main_file. */
84 file_info_tree = splay_tree_new ((splay_tree_compare_fn)strcmp,
85 0,
86 (splay_tree_delete_value_fn)free);
87 toplevel = get_fileinfo ("<top level>");
88 if (flag_detailed_statistics)
89 {
90 header_time = 0;
91 body_time = get_run_time ();
92 toplevel->time = body_time;
93 }
94
95 cb = cpp_get_callbacks (parse_in);
96
97 cb->line_change = cb_line_change;
98 cb->ident = cb_ident;
99 cb->def_pragma = cb_def_pragma;
100 cb->valid_pch = c_common_valid_pch;
101 cb->read_pch = c_common_read_pch;
102
103 /* Set the debug callbacks if we can use them. */
104 if (debug_info_level == DINFO_LEVEL_VERBOSE
105 && (write_symbols == DWARF_DEBUG || write_symbols == DWARF2_DEBUG
106 || write_symbols == VMS_AND_DWARF2_DEBUG))
107 {
108 cb->define = cb_define;
109 cb->undef = cb_undef;
110 }
111 }
Above, at line 84, creates a root node for splay-tree (self adjusting binary searching tree). This tree is used to records time of file in compiling.
cpp_get_callbacks, at line 95 above, fetches the address of cb field of cpp_reader, which bundles language dependent handlers here.
We have seen the definition of cpp_options, it is the collection of flags that controls the behavior of the lexer. At line 1161 in c_common_post_option, cpp_post_options adjusts these flags.
441 void
442 cpp_post_options (cpp_reader *pfile) in cpppinit.c
443 {
444 sanity_checks (pfile);
445
446 post_options (pfile);
447
448 /* Mark named operators before handling command line macros. */
449 if (CPP_OPTION (pfile, cplusplus) && CPP_OPTION (pfile, operator_names))
450 mark_named_operators (pfile);
451 }
Below at line 623, field traditional in cpp_reader is set by option -traditional-cpp (default value is 0), if nonzero, means using traditional preprocessor.
605 static void
606 post_options (cpp_reader *pfile) in cpppinit.c
607 {
608 /* -Wtraditional is not useful in C++ mode. */
609 if (CPP_OPTION (pfile, cplusplus))
610 CPP_OPTION (pfile, warn_traditional) = 0;
611
612 /* Permanently disable macro expansion if we are rescanning
613 preprocessed text. Read preprocesed source in ISO mode. */
614 if (CPP_OPTION (pfile, preprocessed))
615 {
616 pfile->state.prevent_expansion = 1;
617 CPP_OPTION (pfile, traditional) = 0;
618 }
619
620 if (CPP_OPTION (pfile, warn_trigraphs) == 2)
621 CPP_OPTION (pfile, warn_trigraphs) = !CPP_OPTION (pfile, trigraphs);
622
623 if (CPP_OPTION (pfile, traditional))
624 {
625 CPP_OPTION (pfile, cplusplus_comments) = 0;
626
627 /* Traditional CPP does not accurately track column information. */
628 CPP_OPTION (pfile, show_column) = 0;
629 CPP_OPTION (pfile, trigraphs) = 0;
630 CPP_OPTION (pfile, warn_trigraphs) = 0;
631 }
632 }
As long as using C++, operator_names will also be set, mark_named_operators inserts C++ operators into hash_table of cpp_reader.
320 static void
321 mark_named_operators (cpp_reader *pfile) in cpppinit.c
322 {
323 const struct builtin *b;
324
325 for (b = operator_array;
326 b < (operator_array + ARRAY_SIZE (operator_array));
327 b++)
328 {
329 cpp_hashnode *hp = cpp_lookup (pfile, b->name, b->len);
330 hp->flags |= NODE_OPERATOR;
331 hp->is_directive = 0;
332 hp->directive_index = b->value;
333 }
334 }
Above at line 325, operator_array is of type builtin which is just records the literal name of the builtin funciton and its enum value associated. The builtin operators of C++ are: and, and_eq, bitand, bitor, compl, not, not_eq, or, or_eq, xor, xor_eq. The value of builtin is defined in TTYPE_TABLE, which is the identifer for the builtin object.
281 struct builtin in cpppinit.c
282 {
283 const uchar *name;
284 unsigned short len;
285 unsigned short value;
286 };
288 #define B(n, t) { DSC(n), t }
303 static const struct builtin operator_array[] =
304 {
305 B("and", CPP_AND_AND),
306 B("and_eq", CPP_AND_EQ),
307 B("bitand", CPP_AND),
308 B("bitor", CPP_OR),
309 B("compl", CPP_COMPL),
310 B("not", CPP_NOT),
311 B("not_eq", CPP_NOT_EQ),
312 B("or", CPP_OR_OR),
313 B("or_eq", CPP_OR_EQ),
314 B("xor", CPP_XOR),
315 B("xor_eq", CPP_XOR_EQ)
316 };
317 #undef B
Above cpp_lookup at line 329 will insert the node into hash_table of cpp_reader which has element of type ht_identifier (but cpp_hashnode indeed).