GCC-3.4.6源代码学习笔记(29)

4.1.2. 设置Lexer控制参数

下面,flag_inline_trees,是0如果不执行内联,是1如果以树形式展开内联函数调用,是2如果所有函数被视为内联的候选。

flag_inline_functions,如果为非0值,允许编译器在调用点,选择某些简单的内联函数将其内联。这个变量自动被-O3打开,除非指定了-fno-inline-functions。另flag_no_inline如果为非0值,则促使编译器忽略关键字inline。再者,flag_really_no_inline,如果为非0值,表示出于-fno-inline,我们不希望内联,而不是由于树内联器(tree inliner)把内联关闭(即编译器决定不内联声明为inline的函数)。

显然,如果flag_really_no_inline为非0,除非使用属性always_inline,内联函数都不被内联。但如果flag_no_inline为非0,而且在flag_inline_functions为非0,编译器将决定内联的对象。

 

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);

 

如果我们不期望仅执行预处理后即退出,那么在1151行,开始初始化词法分析器。

 

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   }

 

上面的84行,创建了splay树(自适应二叉搜索树)。这个树用于记录文件的编译时间。

上面的95行的cpp_get_callbacks获取cpp_readercb域的地址,这个结构绑定与语言相关的句柄。

我们已经看过了cpp_options的定义,它是控制除词法分析器行为的标识符集。因此在c_common_post_option1161行,cpp_post_options调整这些标识符。

 

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    }

 

下面的623行,cpp_reader中的traditional域由-traditional-cpp选项设定(默认值为0),非0即启动传统的预处理器。

 

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    }

 

只要使用C++,就要设置operator_names。函数mark_named_operatorsC++的操作符插入cpp_readerhash_table

 

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    }

 

而在325行,operator_array是所谓的内建类型(builtin type),内建类型记录了内建函数的字面名(literal name)及附属的枚举值。C++的内建操作符有:andand_eqbitandbitorcomplnotnot_eqoror_eqxorxor_eqbuiltin中的valueTTYPE_TABLE定义,这个值用作了内建对象的识别符。

 

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

 

上面329行的cpp_lookup将节点插入cpp_reader中的hash_table表内,表中的元素要求为ht_identifier类型(但实际插入的是cpp_hashnode)。

 

你可能感兴趣的:(struct,tree,编译器,output,Warnings,filenames)