4.3. 语言相关的初始化
回到do_compile,下一个被调用的是lang_dependent_init。
do_compile (continue)
4650 /* Language-dependent initialization. Returns true on success. */
4651 if (lang_dependent_init (main_input_filename))
4652 {
4653 if (flag_unit_at_a_time)
4654 {
4655 open_dump_file (DFI_cgraph, NULL);
4656 cgraph_dump_file = rtl_dump_file;
4657 rtl_dump_file = NULL;
4658 }
注意到参数name指向main_input_filename,该值在handle_options中被设置。
4525 static int
4526 lang_dependent_init (const char *name) in toplev.c
4527 {
4528 if (dump_base_name == 0)
4529 dump_base_name = name ? name : "gccdump";
4530
4531 /* Other front-end initialization. */
4532 if ((*lang_hooks.init) () == 0)
4533 return 0;
4.3.1. 前端部分的初始化
对于C++,lang_hooks的init钩子是cxx_init。正如其名,它执行C++所需的初始化工作。
384 bool
386 {
387 static const enum tree_code stmt_codes[] = {
388 c_common_stmt_codes,
389 cp_stmt_codes
390 };
391
392 INIT_STATEMENT_CODES (stmt_codes);
4.3.1.1. stmt_codes
在上面的388行,c_common_stmt_codes具有如下定义,它表示通用的C语句类型。
1150 #define c_common_stmt_codes / in c-common.h
1151 CLEANUP_STMT, EXPR_STMT, COMPOUND_STMT, /
1152 DECL_STMT, IF_STMT, FOR_STMT, /
1153 WHILE_STMT, DO_STMT, RETURN_STMT, /
1154 BREAK_STMT, CONTINUE_STMT, SCOPE_STMT, /
1155 SWITCH_STMT, GOTO_STMT, LABEL_STMT, /
1156 ASM_STMT, FILE_STMT, CASE_LABEL
而cp_stmt_codes则有如下定义,这是特定于C++的。
895 #define cp_stmt_codes / in cp-tree.h
896 CTOR_INITIALIZER, TRY_BLOCK, HANDLER, /
897 EH_SPEC_BLOCK, USING_STMT, TAG_DEFN
在388行,INIT_STATEMENT_CODES根据可用语句的编码来设置stmt_codes。
1164 #define INIT_STATEMENT_CODES(STMT_CODES) /
1165 do { /
1166 unsigned int i; /
1167 memset (&statement_code_p, 0, sizeof (statement_code_p)); /
1168 for (i = 0; i < ARRAY_SIZE (STMT_CODES); i++) /
1169 statement_code_p[STMT_CODES[i]] = true; /
1170 } while (0)
4.3.1.2. 为C++初始化关键字
对于C++,特定的字符串被保留用于为语言携带特定的语义。通常为了使词法分析更方便高效,输入的字符串将首先被检查是否是保留字,而不是使用有限状态机(DFA)来识别关键字。
cxx_init (continue)
394 /* We cannot just assign to input_filename because it has already
395 been initialized and will be used later as an N_BINCL for stabs+
396 debugging. */
397 push_srcloc ("<internal>", 0);
398
399 init_reswords ();
首先push_srcloc在input_file_stack中压入节点“<internal>”。
349 void
350 init_reswords (void) in lex.c
351 {
352 unsigned int i;
353 tree id;
354 int mask = ((flag_no_asm ? D_ASM : 0)
355 | (flag_no_gnu_keywords ? D_EXT : 0));
356
357 ridpointers = ggc_calloc ((int) RID_MAX, sizeof (tree));
358 for (i = 0; i < ARRAY_SIZE (reswords); i++)
359 {
360 id = get_identifier (reswords[i].word);
361 C_RID_CODE (id) = reswords[i].rid;
362 ridpointers [(int) reswords[i].rid] = id;
363 if (! (reswords[i].disable & mask))
364 C_IS_RESERVED_WORD (id) = 1;
365 }
366 }
这里ridpointers是“reserved id pointers”的缩写,它是一个rtx对象数组。reswords的类型是resword。
231 struct resword in lex.c
232 {
233 const char *const word;
234 ENUM_BITFIELD(rid) const rid : 16;
235 const unsigned int disable : 16;
236 };
用于C++的保留字定义如下:
245 static const struct resword reswords[] = in lex.c
246 {
247 { "_Complex", RID_COMPLEX, 0 },
248 { "__FUNCTION__", RID_FUNCTION_NAME, 0 },
249 { "__PRETTY_FUNCTION__", RID_PRETTY_FUNCTION_NAME, 0 },
250 { "__alignof", RID_ALIGNOF, 0 },
251 { "__alignof__", RID_ALIGNOF, 0 },
252 { "__asm", RID_ASM, 0 },
253 { "__asm__", RID_ASM, 0 },
254 { "__attribute", RID_ATTRIBUTE, 0 },
255