GCC-3.4.6源代码学习笔记
文章平均质量分 90
wuhui_gdnt
这个作者很懒,什么都没留下…
展开
-
GCC-3.4.6源代码学习笔记(1)
大约4年前,我加入了GDNT - 北电网络在中国的合资企业,参与3G UMTS无线接入网的研发工作。与GCC有了第一次亲密的接触(之前使用的是MS的VC)。彼时,北电在其诸如,UMTS、CDMA、及自行开发的众多工具等项目中(此后,在4G项目,Wimax及Lte中),将GCC作为标准编译器来使用。每周我都需要进行数次的loadbuild,编译出load文件进行测试,以验证我对一些bug的修正代码。原创 2010-02-21 14:43:00 · 8021 阅读 · 15 评论 -
GCC-3.4.6源代码学习笔记(4)
1.2. 树节点的构造上面make_node提供了构造树节点的方法,但它比较初级,节点由0填充。为了更好地为表达式,语句等语法成分构造树节点,GCC定义了一系列函数。我们先看一部分。1.2.2. 机器模式的概念[2]机器模式描述了一个数据对象的大小和它的表示方式。在GCC中,机器模式由定义在machmode.def文件中的枚举类型enum machine_mode来表示(准确地说,ma原创 2010-02-23 11:40:00 · 2513 阅读 · 0 评论 -
GCC-3.4.6源代码学习笔记(2)
1.1.1. tree_code —— 树节点的ID在tree_node的定义中,结构体,象tree_type,tree_decl 等,用于代表相应的语法成分。比如,tree_type用于类的定义,而type_decl用于声明。但如果需要进一步分别,比如tree_decl节点为何种声明,则我们需要用到在tree_node中的另一个位。这就是在tree_common定义中,第134行的code。原创 2010-02-21 14:49:00 · 3564 阅读 · 0 评论 -
GCC-3.4.6源代码学习笔记(3)
1.1.3. 树节点的内存分配1.1.3.1. 节点大小的确定树节点由下面的make_node函数来分配。函数中的参数code,在上面的表中给出,注意它也是由.def文件定义的。 202 tree203 make_node (enum tree_code code)原创 2010-02-22 11:40:00 · 1706 阅读 · 0 评论 -
GCC-3.4.6源代码学习笔记(5)
1.2.2. 内建类型的树节点对于语言中的内建类型,例如,C/C++中的int,unsigned short等,编译器在启动时便会为这些类型创建节点。1.2.2.1. 初始化临时的size_t节点在创建内建类型的节点前,先要创建临时的size_t节点(一个用作size_t,另一个用作bitsize_t。size_t是sizeof的返回类型,bitsize_t由前端原创 2010-02-24 11:40:00 · 1830 阅读 · 0 评论 -
GCC-3.4.6源代码学习笔记(7)
1.2.4. 与地址相关节点的构造在C++中,指针、引用和地址在一定程度上可以混用。语言允许通过指针或者引用直接改变地址所在的内容。而函数调用,事实上是通过跳转到相应的地址来实现。另外在语言中,数组名也代表数组的首地址。因此,编译器可能需要首先创建与地址相关的节点,再由这个节点出发构建其它节点。比如,构建函数或数组节点。1.2.4.1. 指针类型节点的构造1.2.4.1.1.原创 2010-02-26 11:48:00 · 1318 阅读 · 0 评论 -
GCC-3.4.6源代码学习笔记(6)
1.2.3. 创建浮点常量节点在GCC中表示浮点常量的节点是下面所示的tree_real_cst。1.2.3.1. tree_real_cst节点 702 struct tree_real_cst GTY(()) in原创 2010-02-25 11:47:00 · 1417 阅读 · 0 评论 -
GCC-3.4.6源代码学习笔记(9)
1.4. 为一元表达式创建节点函数build1类似于build,但用于一元操作符。它用于代替相当一部分的build调用。减少对于RISC机器来说相当昂贵的可变参量的使用。 2411 tree2412 build1 (enum tree_code code, tree type, tree node)原创 2010-03-02 12:06:00 · 1027 阅读 · 0 评论 -
GCC-3.4.6源代码学习笔记(8)
1.3. 为非一元表达式创建节点函数build可被用于为表达式创建节点。但它只接受表达式作为参数,把它们合成为更为复杂的表达式。它不可以被用于创建第一级的表达式(也就是由解析器解析出的语法成分,合成出表达式。这些步骤需要远为复杂的函数来处理,在后面我们可以看到一些代码片断)。尽管如此,build还是被广泛使用,因为在C/C++程序中,表达式的表现力在于它的嵌套能力及它能出现的地方。把简单表达式原创 2010-03-01 11:50:00 · 1359 阅读 · 0 评论 -
GCC-3.4.6源代码学习笔记(10)
1.6. 为类型创建节点 – 第一部分1.6.1. 创建函数类型的节点首先,看看FUNCTION_TYPE节点是个什么东西:FUNCTION_TYPE[2]² 用于表示普通函数和静态成员函数。域TREE_TYPE给出了函数的返回类型。域TYPE_ARG_TYPES是一个包含实参类型的TREE_LIST。其中每一节点的TREE_VALUE是对应实参的类型,TREE_PU原创 2010-03-04 11:49:00 · 941 阅读 · 0 评论 -
GCC-3.4.6源代码学习笔记(10续3)
1.6.3.1.1.1.4. 加法和减法回到int_const_binop,接下来的操作是加法和减法。 int_const_binop (continue) 1239 case PLUS_EXPR:1240 overflow = add_double (int1l, int1h, int2l, int2h, &low, &hi)原创 2010-03-05 12:39:00 · 1063 阅读 · 0 评论 -
GCC-3.4.6源代码学习笔记(10续4)
1.6.3.1.1.2. 获取结果而在int_const_binop的余下部分,计算结果已经存放在low和hi中,这个结果将被合成为相应的树节点对象并检查溢出情况。下面的notrunc如果非零,表明不做值截取,而overflow则记录了计算过程中是否发生溢出,no_overflow如果非零,表明计算不会导致溢出。 int_const_binop (continue) 1331原创 2010-03-05 12:51:00 · 860 阅读 · 0 评论 -
GCC-3.4.6源代码学习笔记(11)
2. 编译器的初始化编译器的核心始于YOUR-GCC-SOURCE-DIR/gcc目录下,文件main.c中的main函数。该函数立即调用函数toplev_main。 4684 int4685 toplev_main (unsigned int argc, const char **argv) i原创 2010-03-08 12:56:00 · 1823 阅读 · 0 评论 -
GCC-3.4.6源代码学习笔记(10续2)
1.6.3.1.1.1.2. 右移右移的操作是类似的。同样在下面的函数中,参数ll是被移位数的低位部分,而hl是高位部分,count则是要移动的位数,必须为正数,计算结果存放在lv和hv中,arith非零指明是进行算术右移,否则为逻辑右移。 428 void429 rshift_double (unsigned HOST_WIDE_INT l1, HO原创 2010-03-05 12:34:00 · 980 阅读 · 0 评论 -
GCC-3.4.6源代码学习笔记(10续1)
1.6.3. 创建数组类型节点当调用build_array_type时,第二个参数index_type应该是由上一节所创建的索引节点。注意C++中没有函数数组类型,因为C++函数拥有常量地址。 3790 tree3791 build_array_type (tree elt_type, tree index_type)原创 2010-03-05 12:08:00 · 990 阅读 · 0 评论 -
GCC-3.4.6源代码学习笔记(13)
2.2.3.1.5. 聚集类型的信息2.2.3.1.5.1. 概览[2]一个类类型由一个RECORD_TYPE节点或者UNION_TYPE节点来表示。声明为union 的类由UNION_TYPE来表示,而声明为struct或者class的类由RECORD_TYPE来表示。你可以使用宏CLASSTYPE_DECLARED_CLASS来辨别特定的类是class还是str原创 2010-03-10 12:08:00 · 1240 阅读 · 0 评论 -
GCC-3.4.6源代码学习笔记(12)
2.2. 类型哈希表的初始化完成标识符哈希表的初始化后,general_init调用init_ttree来初始化类型哈希表。 116 void117 init_ttree (void) i原创 2010-03-09 11:54:00 · 1023 阅读 · 0 评论 -
GCC-3.4.6源代码学习笔记(14)
2.2.3.1.5.2.2.5. UNION的布局在上面854行,rli->t是正在被布局的类的树节点,能到这里,field一定是一个FIELD_DECL。如果rli->t不是一个RECORD_TYPE,在C++里,它一定是一个代表union的节点。它有和class及struct不同的布局方案。 778 static void779 place_union原创 2010-03-16 11:32:00 · 1262 阅读 · 0 评论 -
GCC-3.4.6源代码学习笔记(15)
2.2.3.1.5.2.2.6. RECORD_TYPE中的FIELD_DECL上面已经提到FIELD_DECL用于表示非静态成员,具体的描述如下:FIELD_DECL[2]² 这些节点表示类的非静态成员。其DECL_SIZE和DECL_ALIGN的行为与VAR_DECL节点的相同。而DECL_FIELD_BITPOS给出了该域使用的第一个比特,它是一个IN原创 2010-03-17 11:43:00 · 1915 阅读 · 0 评论 -
GCC-3.4.6源代码学习笔记(17)
2.4. 初始化优化参数回到general_init,4264行的add_params把数组lang_independent_params的内容存入数组compiler_params。compiler_params保存编译器的参数及当前值。lang_independent_params由params.def以如下方式展开得到。 1022 static const param_info原创 2010-03-19 11:44:00 · 1292 阅读 · 0 评论 -
GCC-3.4.6源代码学习笔记(18)
3. 对命令行选项的处理3.1. 为语言准备的钩子回到toplev_main,就像我们以前提到过的,前端最好能设计成使新语言的引入变得容易。在GCC中,前端为语言提供了一个框架,在这个框架中,所有语言相关的处理都被定义为回调(callback),而且这些回调被捆绑至以下的结构中。 212 struct lang_hooks原创 2010-03-22 11:58:00 · 1114 阅读 · 0 评论 -
GCC-3.4.6源代码学习笔记(16)
2.3. 初始化寄存器集接下来,跟着init_ttree,general_init调用init_reg_sets。对于大多数机器,某些寄存器具有特殊的用途。例如,在x86机器上,esp总是保存栈顶的地址,它不能用于传递函数参数。而在函数调用过程中,根据特定的惯例,其他一些寄存器需要被保存及恢复;而其他则不需要。显然这些都是与机器有关的。这里init_reg_sets收集芯片系列的通用信原创 2010-03-18 15:17:00 · 1369 阅读 · 0 评论 -
GCC-3.4.6源代码学习笔记(19)
3.2.1. 创建cpp_reader在上面的205行,cpp_create_reader尝试创建一个cpp_reader对象。对于象C,C++这样需要预处理机制的语言,一般来说,编译器需要提供一个预处理遍,对源程序进行预处理操作。而当前版本的GCC,应用cpp_reader对象,实现了在线的预处理展开,不再需要预处理遍。因为这个目的,cpp_reader的定义也变得相当复杂。在以后有关词原创 2010-03-23 11:47:00 · 1895 阅读 · 0 评论 -
GCC-3.4.6源代码学习笔记(19续)
cpp_reader中的域op_stack用于多次包含优化(multiple-include optimization,即将#include指示加入#if !defined和#endif对中),它将缓存#if或#elseif表达式的符号。 cpp_create_reader (continue) 199 /* The expression parser stack. */原创 2010-03-23 11:55:00 · 1346 阅读 · 0 评论 -
GCC-3.4.6源代码学习笔记(20)
3.2.2. 准备处理编译命令选项在创建了cpp_reader对象后,c_common_init_options最后确认要编译的语言,并初始化相关的数据结构。这个函数最终将确认的语言返回。 c_common_init_options (continue) 210 cpp_opts = cpp_get_options (parse_in);211 cpp_opts原创 2010-03-24 11:37:00 · 874 阅读 · 0 评论 -
GCC-3.4.6源代码学习笔记(21)
3.3. 处理编译选项3.3.1. 与优化有关的选项回到decode_options,在480行,对于C++,lang_hooks中的钩子initialize_diagnostics引用cxx_initialize_diagnostics。它设立诊断设施,用于给出足够详细、正确的出错消息。这里我们跳过它,因为它与真正的编译关系不大。 decode_options (continue原创 2010-03-25 11:32:00 · 2037 阅读 · 0 评论 -
GCC-3.4.6源代码学习笔记(22)
3.3.2. 初始化与目标平台相关选项在上面605行, set_target_switch处理与目标平台相关的选项。所有这些选项都以“-m”开头。 3829 void3830 set_target_switch (const char *name) in toplev.原创 2010-03-30 11:46:00 · 1391 阅读 · 0 评论 -
GCC-3.4.6源代码学习笔记(26续2)
common_handle_option (continue) 1179 case OPT_fprofile:1180 profile_flag = value;1181 break;11821183 case OPT_fprofile_arcs:1184 profile_arc_flag_set = true;1原创 2010-04-13 12:27:00 · 1393 阅读 · 0 评论 -
GCC-3.4.6源代码学习笔记(23)
3.3.3. 处理其他选项一切准备好后,可以开始处理除-O优化选项外的编译命令行选项了。 decode_options (continue) 618 handle_options (argc, argv, lang_mask);619 620 if (flag_pie)621 flag_pic = flag_pie;622 if (原创 2010-03-31 11:44:00 · 1074 阅读 · 0 评论 -
GCC-3.4.6源代码学习笔记(27)
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,fl原创 2010-04-14 09:19:00 · 1299 阅读 · 0 评论 -
Studying note of GCC-3.4.6 source (24 cont)
-foptimize-sibling-callsRefer to flag_optimize_sibling_callsCL_COMMON-foptional-diagsEnable optional diagnosticsCL_CXX | CL_ObjCXX-fpack-struct原创 2010-04-01 12:26:00 · 1025 阅读 · 0 评论 -
GCC-3.4.6源代码学习笔记(24)
3.3.3.1. 可用的选项这个数组在options.c文件中初始化,其初始化值在下表中给出。这是个很长的列表。更详细的描述,可参见【8】,【6】。注意,选项是按名字排序的。选项 描述标识集--help显示帮助信息CL_COMMON--output-pch=参见pc原创 2010-04-01 12:12:00 · 1380 阅读 · 0 评论 -
GCC-3.4.6源代码学习笔记(24续)
-fnonansi-builtins参见flag_no_nonansi_builtinCL_CXX | CL_ObjCXX-fnonnull-objects已过时,不支持CL_CXX | CL_ObjCXX-fold-unroll-all-loops参见flag_old_unroll原创 2010-04-01 12:16:00 · 1273 阅读 · 0 评论 -
GCC-3.4.6源代码学习笔记(26续1)
common_handle_option (continue) 909 case OPT_fcall_used_:910 fix_register (arg, 0, 1);911 break;912 913 case OPT_fcall_saved_:914 fix_register (arg, 0, 0)原创 2010-04-13 12:09:00 · 2036 阅读 · 0 评论 -
GCC-3.4.6源代码学习笔记(28)
4.1.1. 完成查找路径设置GCC在多个不同的地方查找头文件。在一个普通的Unix系统上,如果不另外指示,由`#include 请求的文件将在以下目录中查找: /usr/local/include LIBDIR/gcc/TARGET/VERSION/include /usr/TARGET/include /usr/include对于C++原创 2010-04-15 09:41:00 · 1231 阅读 · 0 评论 -
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如果原创 2010-04-16 09:46:00 · 940 阅读 · 0 评论 -
GCC-3.4.6源代码学习笔记(31)
4.1.3.1.1.1. 验证PCH文件如果PCH文件找到了,需确保它是有效的。 1257 static bool1258 validate_pch (cpp_reader *pfile, _cpp_file *file, const char *pchname) in cppfiles.c1259 {1260 const char *sav原创 2010-04-20 09:22:00 · 1174 阅读 · 0 评论 -
GCC-3.4.6源代码学习笔记(30)
4.1.3. 读入源代码现在cpp_reader已经就绪,是时候读入源文件了。在下面,宏input_line访问全局变量input_location的line域。这个全局变量记录了当前文件名及当前处理行号。 c_common_post_option (continue) 1162 saved_lineno = input_line;1163 input_line =原创 2010-04-19 10:07:00 · 1168 阅读 · 0 评论 -
GCC-3.4.6源代码学习笔记(32)
4.1.3.1.2. 读入文件上面439行,如果文件找到并成功打开,_cpp_find_file将对应的_cpp_file对象返回,交由pfile->main_file保存。由此,可以开始读入文件的内容。 cpp_read_main_file (continue) 473 _cpp_stack_file (pfile, pfile->main_f原创 2010-04-21 09:21:00 · 1209 阅读 · 0 评论 -
GCC-3.4.6源代码学习笔记(25)
3.3.3.1.1. C++的选项对于C,C++或者obj-C,lang_hooks的handle_options都是c_common_handle_option。下面的OPT_*用作cl_options数组的索引。 251 int252 c_common_handle_option (size_t scode, const char *arg, int原创 2010-04-07 11:13:00 · 1711 阅读 · 0 评论