值得注意的是,GCC并没有所谓的预处理遍,因为cpp_get_token这样的函数,直接就可以获取经过预处理的符号。显然,这个函数也是词法分析器的重要部分。作为源文件解析的第一步,首先准备解析器及附属的词法分析器。...
值得注意的是,GCC并没有所谓的预处理遍,因为cpp_get_token这样的函数,直接就可以获取经过预处理的符号。显然,这个函数也是词法分析器的重要部分。作为源文件解析的第一步,首先准备解析器及附属的词法分析器。...
2.2.3.1.5.2.2.6. RECORD_TYPE中的FIELD_DECL上面已经提到FIELD_DECL用于表示非静态成员,具体的描述如下:FIELD_DECL[2]² 这些节点表示类的非静态成员。其DECL_SIZE和DECL_ALIGN的行为与VAR_DECL节点的相同。...
5.12.3. 第二条语句– TEMPLATE_DECL 第二条语句是模板声明,其简要语法树如下。第一条规则是类模板声明,其下是函数模板声明。现在我们正在定义类模板。 template-declaration ├export ...
对于指令生成,编译器尝试打开已编码的RTL代码(如果是开放编码的(open-coded),没有进行真正的函数调用,只是在同等代码的展开;而封闭编码的(close-coded)则导致函数的调用。在编译器界(compiler circles),...
4.3.1.7.8.2.2. 构建type_info的定义 下面就是构建这个type_info类型系列。首先是基类。 1251 static void 1252 create_tinfo_types (void) in rtti.c 1253 {
4.3.1.7.2.4. 全局名字空间对象 全局名字空间的标识符是global_scope_name,其对应的树节点的编码是NAMESPACE_DECL,名字空间本身没有类型信息,是故下面的参数type为void_type_node。 687 tree...
5.12.3.1.2. 处理模板参数 现在我们从cp_parser_parameter_declaration返回,然后从cp_parser_template_parameter回到cp_parser_template_parameter_list。在这个函数中,变量parameter保存上图所示的树节点。...
5.3.1.2. 宏调用 对于我们的案例,这下一个符号是“FUN”。对于这个节点,它的类型无疑是NT_MACRO。只要它不是失能的宏,并且不是在禁止宏展开的环境下(即,在处理断言、pragma、#if系列指示,解析宏参数、...
5.9.3.错误恢复 错误恢复是一个重要而又相当困难的议题。当遇到错误时,如何使解析器可以在错误点后的有效符号处重新解析,从来都不是一个简单的事。在C++的前端中,尝试性解析器提供了一个优雅的方法,当我们...
4.2.7.准备重装遍4.2.7.1. 概览 从init_loop返回后,在backend_init中,接下来调用init_reload来为重装遍做准备。 重装遍做什么用呢? 重装遍使用所分配的物理寄存器的编号,重新编号对应的伪寄存器...
5.6.1.1.2. 数字 预处理器除了知道什么是数字外,并不尝试去解读它。对于预处理器来说,这样并无不可,而且这样可以使得预处理器更灵活。但是当从预处理器处得到数字序列时,词法分析器需要知道如何解读它。...
5.9.2.1. 是否从当前类访问 如果current_class_type不是NULL,表明当前的作用域是一个类,而且我们正在这个类定义中。首先检查decl是否在这棵派生树里,并且为当前类节点可访问。...
4.2.1.2. 初始化哈希表与前端相似,后端亦对常用、共享的对象使用哈希表。在以后的章节,结合编译过程,我们再来看这些哈希表中,元素的意义。接着在init_emit_once,5474到5494行,找出适合字节类型,字类型及...
4.2.3.3. 支持自动增/减寄存器的信息回到init_regs,其次调用init_reg_autoinc。对于x86机器这个函数将对所有的寄存器设置forbidden_inc_dec_class,因为x86没有任何自增取址(auto increment addressing)。...
5.4.由-include包含的头文件 根据【6】,由选项–include包含的头文件应该在源文件中所包含的头文件之前被引入,但要在被–macro指定的文件处理完成后,才能被处理。如果给出了多个-include选项,那么文件要按...
4.3.1.7.5.4. 内建函数类型节点 从这里开始,我们将多次看到FUNCTION_DECL及FUNCTION_TYPE。正如我们所了解的,在C/C++中,函数具有类型。例如,“int a (int A);”及“int b (int B);”,这2个函数具有相同的...
同样的,这次我们仍然需要定义一个宏,从定义文件– builtins.def 来产生代码。 c_common_nodes_and_builtins (continue) 3431 #define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE,...
4.2.10. 评估算术操作的代价 4.2.10.1. 创建伪函数上下文 回到backend_init,下来是init_dummy_function_start。它初始化了rtl的展开机制,因而我们可以进行一些简单序列的生成。...
4.3.1.7.4. 创建std名字空间4.3.1.7.4.1. 加入全局名字空间 std名字空间是C++标准的一部分。这一名字空间亦是C++的运行时环境的一部分,例如:异常机制、运行时类型识别、标准库等都出自此处。...
4.3.1.7.5.6.5.2. 处理format属性 对于printf,scanf等类型的函数,真正的检查要在调用处进行。在其声明中,只进行少许检查,由handle_format_attribute执行。现在参数args是节点ATTR_PRINTF_1_0,而...
为了更好地为表达式,语句等语法成分构造树节点,GCC定义了一系列函数。我们先看一部分。1.2.2. 机器模式的概念[2]机器模式描述了一个数据对象的大小和它的表示方式。在GCC中,机器模式由定义在machmode.def文件中的...
4.2.3.3. 确定寄存器间移动数据的代价接下来,init_reg_sets_1评估不同类别寄存器间移动数据的代价,而后是评估寄存器和内存之间。 init_reg_sets_1 (continue) 477 /* Initialize the move cost table....
<br /> grokdeclarator (continue) 8163 { 8164 tree decl; 8165 8166 if (decl_context == PARM) 8167 { 8168 ...cp_build_parm_decl ...
#pragma interface及#pragma implementation作为GCC提供的一个C++的扩展,【6】解释了#pragma interface “filename” (op) 及#pragma implementation “filename” (op)。 6.3 模糊链接性(Vague Linkage)在C++...
c_common_handle_option (continue) 657 case OPT_Wwrite_strings:658 if (!c_dialect_cxx ())659 flag_const_strings = value;660 else661 warn_write_strings =
4.1.3. 读入源代码现在cpp_reader已经就绪,是时候读入源文件了。在下面,宏input_line访问全局变量input_location的line域。这个全局变量记录了当前文件名及当前处理行号。 c_common_post_option (continue) 1162...
4.3.1.7. 初始化声明处理机制 声明是C++最重要的一部分。正是函数声明、类型声明、名字空间声明、变量声明等,构成了C++强大灵活的特性。C++编译器中这部分机制的初始化显得十分重要而复杂,这个机制还生成了...
1.2.3. 创建浮点常量节点在GCC中表示浮点常量的节点是下面所示的tree_real_cst。1.2.3.1. tree_real_cst节点 702 struct tree_real_cst GTY(()) in
2.2.3.1.5.2.2.5. UNION的布局在上面854行,rli->t是正在被布局的类的树节点,能到这里,field一定是一个FIELD_DECL。如果rli->t不是一个RECORD_TYPE,在C++里,它一定是一个代表union的节点。...
4.2. 初始化后端处理完命令行选项后,do_compile将初始化后端。 do_compile (continue) 4638 /* Dont do any more if an error has already occurred. */4639 if (!errorcount)4640 {4641 /* This must be run