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

1.1.1. tree_code —— 树节点的ID

tree_node的定义中,结构体,象tree_typetree_decl 等,用于代表相应的语法成分。比如,tree_type用于类的定义,而type_decl用于声明。但如果需要进一步分别,比如tree_decl节点为何种声明,则我们需要用到在tree_node中的另一个位。这就是在tree_common定义中,第134行的code

 

31    #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) SYM,

32   

33    enum tree_code {                                                                                              in tree.h

34    #include "tree.def"

35   

36      LAST_AND_UNUSED_TREE_CODE    /* A convenient way to get a value for

37                                          NUM_TREE_CODE.  */

38    };

39   

40    #undef DEFTREECODE

 

另外在C++前端中,枚举类型(enumcplus_tree_code被附加到上述枚举定义的最后。

 

887  enum cplus_tree_code {                                                                              in cp-tree.h

888    CP_DUMMY_TREE_CODE = LAST_C_TREE_CODE,

889  #include "cp-tree.def"

890    LAST_CPLUS_TREE_CODE

891  };

 

文件tree.def定义了tree_code中前端通用的值。这个文件的内容是一系列的DEFTREECODE。而上面第31行,DEFTREECODE被定义成其中的一个域。这是GCC大量使用的技术。文件tree.def的内容显示在下面的表中。

节点码(tree code

 

类型

描述

ERROR_MARK

x

一个错误构造的解析。

IDENTIFIER_NODE

x

代表名字(例如,代表声明的节点的DECL_NAME 成员)。

TREE_LIST

x

tree_list的集合。

TREE_VEC

x

tree_vec节点

BLOCK

b

代码块

VOID_TYPE

t

Void类型

INTEGER_TYPE

t

所有语言的整数类型,包括C中的char

REAL_TYPE

t

Cfloatdouble

COMPLEX_TYPE

t

 

VECTOR_TYPE

t

 

ENUMERAL_TYPE

t

Cenum

BOOLEAN_TYPE

t

Pascalboolean类型(true或者false是唯一的值)。

CHAR_TYPE

t

PascalCHAR类型,不用于C

POINTER_TYPE

t

所有指针类型。

OFFSET_TYPE

t

偏移,相对于对象的指针。

REFERENCE_TYPE

t

C++的引用。

METHOD_TYPE

t

第一个参数不出现在参数列表,且指向“自己”的函数类型(C++中的类成员函数)。

FILE_TYPE

t

仅用于Pascal;

ARRAY_TYPE

t

 

SET_TYPE

t

Pascal中的sets类型。

RECORD_TYPE

t

C中的struct,或者Pascal中的record

UNION_TYPE

t

C中的union。和struct类似,但所有成员的偏移均为0

QUAL_UNION_TYPE

t

 

FUNCTION_TYPE

t

函数类型

LANG_TYPE

t

特定于语言的类型

INTEGER_CST

c

包含32位长的成员TREE_INT_CST_LOW TREE_INT_CST_HIGH , 可表示64位大小的常量。

REAL_CST

c

代表浮点常量。

COMPLEX_CST

c

表示复数常量

VECTOR_CST

c

表示vector类型常量

STRING_CST

c

表示字符串常量

FUNCTION_DECL

d

函数声明

LABEL_DECL

d

标示(label)声明

CONST_DECL

d

常量声明

TYPE_DECL

d

类型声明(例如:class A;

VAR_DECL

d

局部变量,全局变量,外部变量,静态变量的声明

PARM_DECL

d

函数参数声明

RESULT_DECL

d

函数返回值声明

FIELD_DECL

d

Struct/union/class的非方法(method)成员声明

NAMESPACE_DECL

d

名字空间声明

TRANSLATION_UNIT_DECL

d

编译单元,由GCC使用

COMPONENT_REF

r

Struct/union/class的非方法(method)成员的引用

BIT_FIELD_REF

r

Struct/union/class的位集(bit-field)成员的引用

INDIRECT_REF

r

C中的一元操作符*或者Pascal中的^

BUFFER_REF

r

Pascal中,用于文件的^

ARRAY_REF

r

通过索引指定的数组元素

ARRAY_RANGE_REF

r

通过索引指定的数组子集

VTABLE_REF

r

通过索引指定的虚表元素。带有虚表垃圾收集器需要的数据。其中操作数0是一个ARRAY_REF(或等效的表达式),操作数1是虚表的基地址(必须是VAR_DECL),操作数2是索引(必须为INTEGER_CST

CONSTRUCTOR

e

构造函数

COMPOUND_EXPR

e

复合表达式

MODIFY_EXPR

e

赋值表达式

INIT_EXPR

e

用于初始化的表达式。其中,操作数0是被初始化的变量,操作数1是初始值

TARGET_EXPR

e

其中,操作数0是初始化的目标,操作数1是初始值,操作数2,如果有,是清除操作。操作数3则是该节点展开后(亦即初始化执行后)所保存的初始值,这样我们可以反复展开这个节点。

COND_EXPR

e

条件表达式(C中为:... ? ... : ...)。其中,操作数0为条件。操作数1then的值。操作数2else的值。操作数0可以为任意类型。操作数1必须和整个表达式的类型相同,除非它无条件地抛出异常,而在这种情况下,它应该是void类型。对操作数2,有同样的要求。

BIND_EXPR

e

声明临时变量,包括生成对应的RTL对象及分配空间。操作数0是一串VAR_DECL节点。操作数1是使用这些变量的表达式,其值是BIND_EXPR的值。操作数3是对于的代码块,用于debug的目的。

CALL_EXPR

e

函数调用。操作数0是所调用的函数。操作数1是参数列表。

WITH_CLEANUP_EXPR

e

指定一个求值,连同相应的清除操作。操作数0为对应的表达式。操作数1是对应的清除操作。操作数2是最终代表这个值的RTL_EXPR

CLEANUP_POINT_EXPR

e

指定一个清除操作。操作数0是需要执行清除操作的表达式。在该表达式展开后,这些清除操作被执行。

PLACEHOLDER_EXPR

x

表示一个,在对该表达式求值时,由一个WITH_RECORD_EXPR 支持的recordGCC内部表示struct/union/class的结构)。该表达式的类型用于寻找替代它的record

WITH_RECORD_EXPR

x

提供引用了用于替代PLACEHOLDER_EXPRrecord的表达式。操作数1为要使用的record,它具有和PLACEHOLDER_EXPR的操作数0相同的类型。

PLUS_EXPR

2

加法表达式

MINUS_EXPR

2

减法表达式

MULT_EXPR

2

乘法表达式

TRUNC_DIV_EXPR

2

整数除法,商向0取整(丢弃小数位)。

CEIL_DIV_EXPR

2

整数除法,商向正无穷取整(丢弃小数位,加1)。

FLOOR_DIV_EXPR

2

整数除法,商向负无穷取整(丢弃小数位,减1)。

ROUND_DIV_EXPR

2

整数除法,商四舍五入。

TRUNC_MOD_EXPR

2

对应的余数

CEIL_MOD_EXPR

2

FLOOR_MOD_EXPR

2

ROUND_MOD_EXPR

2

RDIV_EXPR

2

浮点除法

EXACT_DIV_EXPR

2

假定不需要取整的除法。在C中用于指针相减。

FIX_TRUNC_EXPR

1

浮点到整型的转换。

FIX_CEIL_EXPR

1

FIX_FLOOR_EXPR

1

FIX_ROUND_EXPR

1

FLOAT_EXPR

1

整型到浮点的转换。

NEGATE_EXPR

1

一元取反操作符

MIN_EXPR

2

 

MAX_EXPR

2

 

ABS_EXPR

1

取绝对值

LSHIFT_EXPR

2

对于无符号值为逻辑移位,对有符号值为算术移位

RSHIFT_EXPR

2

LROTATE_EXPR

2

RROTATE_EXPR

2

BIT_IOR_EXPR

2

位操作表达式

BIT_XOR_EXPR

2

BIT_AND_EXPR

2

BIT_NOT_EXPR

2

TRUTH_ANDIF_EXPR

e

ANDIFORIF允许不计算第二个操作数,如果表达式的值可以从第一个操作数确定。ANDORXOR则永远对第二个操作数求值,不管它的值是否需要。操作数的类型应为BOOLEAN_TYPE或者INTEGER_TYPE

TRUTH_ORIF_EXPR

e

TRUTH_AND_EXPR

e

TRUTH_OR_EXPR

e

TRUTH_XOR_EXPR

e

TRUTH_NOT_EXPR

e

LT_EXPR

关系操作符表达式。其中EQ_EXPRNE_EXPR允许为任何类型。其他操作符只允许为整型(包括指针或枚举类型),或者浮点类型。在所有情况下,操作数必须有相同的类型,而表达式的类型为语言所定义的布尔类型。

LE_EXPR

GT_EXPR

GE_EXPR

EQ_EXPR

NE_EXPR

UNORDERED_EXPR

非序浮点数的比较操作符。

ORDERED_EXPR

UNLT_EXPR

非序关系表达式,由GCC使用。(GCC提供了内建的宏,进行C99浮点比较操作,以避免在碰到非序操作数时,抛出异常。NaN的浮点数就是非序的)。

UNLE_EXPR

UNGT_EXPR

UNGE_EXPR

UNEQ_EXPR

IN_EXPR

2

Pascalsets的操作。该版本GCC没有使用。

SET_LE_EXPR

CARD_EXPR

1

RANGE_EXPR

2

CONVERT_EXPR

1

表示对一个值的类型转换

NOP_EXPR

1

表示一个不需要额外产生代码的转换

NON_LVALUE_EXPR

1

非左值的表达式

VIEW_CONVERT_EXPR

1

代表把一个类型看作为另一个类型。对应于C中的用法:*(type2 *)&X

SAVE_EXPR

e

代表只能求值一次,却会被多次使用的结构(在GCC中,使用一般都会涉及求值,从而对子树进行简化)

UNSAVE_EXPR

e

表示诸如TARGET_EXPRsSAVE_EXPRsCALL_EXPRsRTL_EXPRs,这些被防止多次求值的表达式,需被重置。这样新的expand_expr函数调用将对它们重新求值(re-evaluated

RTL_EXPR

e

表示对应的RTL结构已被展开成一个序列,当该表达式被展开时,这个序列将被导出(emitted

ADDR_EXPR

e

C里的‘&

REFERENCE_EXPR

e

对一个对象的非左值引用或者指针

ENTRY_VALUE_EXPR

e

C++/C不用

FDESC_EXPR

e

 

COMPLEX_EXPR

2

复数表达式

CONJ_EXPR

1

共轭操作符表达式

REALPART_EXPR

1

实部表达式

IMAGPART_EXPR

1

虚部表达式

PREDECREMENT_EXPR

e

C里的++--。第二个操作数指明增加或减少的值。对于指针,则是指向对象的大小

PREINCREMENT_EXPR

e

POSTDECREMENT_EXPR

e

POSTINCREMENT_EXPR

e

VA_ARG_EXPR

e

用于实现va_arg

TRY_CATCH_EXPR

e

 

TRY_FINALLY_EXPR

e

 

GOTO_SUBROUTINE_EXPR

e

在编译器内部,用于实现TRY_FINALLY_EXPR时,需要的清除操作

LABEL_EXPR

s

被封装为语句的标示定义(A label definition,

GOTO_EXPR

s

 

RETURN_EXPR

s

 

EXIT_EXPR

s

有条件地退出最内层循环

LOOP_EXPR

s

循环

LABELED_BLOCK_EXPR

e

带标识的代码块

EXIT_BLOCK_EXPR

e

退出带标识的代码块,通常返回一个值

EXPR_WITH_FILE_LOCATION

e

用源代码位置信息诠释一个树节点(通常为比表达式)。包括文件名(EXPR_WFL_FILENAME);行号(EXPR_WFL_LINENO);和列号(EXPR_WFL_COLNO

SWITCH_EXPR

e

Switch表达式

EXC_PTR_EXPR

e

运行时的异常对象

1 tree.def中定义的树节点

 

在上表中的Type列,下列字母用作类识别码(class code),它们的含义如下:

Ø       'x'表示用于例外(不适合其它类别)。

Ø       't'表示用于类型对象。

Ø       'b'用于代码块。

Ø       'c'用于代表常量的节点

Ø       'd'用于代表声明的节点(同时用于临时变量的引用)。

Ø       'r'用于代表访问存储地址的节点。

Ø       '<'用于比较表达式。

Ø       '1'用于代表一元算术表达式的节点。

Ø       '2'用于代表二元算术表达式的节点。

Ø       's'用于代表“语句”(statement)的表达式的节点,该表达式有副作用(side-effects),但其值不被关注(例如,语句i=5;有值5,但这个值被忽略了)。

Ø       'e'用于代表其他类型表达式的节点。

对于re<12,和s类型的节点,它们对应于结构体tree_exp,在DEFTREECODE 的定义中,第四个元素为需要在tree_exp中分配的参数的个数。从而确定了节点对象的大小。而对于其他类型节点,结构体本身大小确定,这第四个元素必须为0。如果定义了特定于语言的xc类别的节点, 该语言的前端必须对langhooktree_size挂钩(hook)提供函数,以确定这些节点的大小。

对于C++前端,特定于C++的节点定义于文件cp-tree.def。它们的含义如下。

节点码(tree code

 

类型

描述

OFFSET_REF

r

OFFSET_REF节点用于下列两种情形:

1      形如A::m的表达式,其中 A是类(a class)而m是非静态成员(a non-static member)。在这种情况下,操作数0应该为对应于A的类型,操作数1可为FIELD_DECLBASELINK,,或TEMPLATE_ID_EXPR(对应于m)。

如果地址被使用,这个表达式为指向成员的指针(a pointer-to-member),但如果地址没有被使用,表达式仅表示对象的成员。

这个形式只用于解析阶段;当语义分析完成后,它便不复存在。

2      形如x.*p的表达式。在这种情况下,操作数0 是对应于x的表达式,而操作数1则是类型为指向成员指针的表达式。

PTRMEM_CST

c

指向成员的指针常量。对于指针常量X::Y,宏PTRMEM_CST_CLASS得到X对应的RECORD_TYPE,而PTRMEM_CST_MEMBER得到的是Y对应的声明。

NEW_EXPR

VEC_NEW_EXPR

e

e

对于NEW_EXPR,操作数0定位操作符中的定位地址(placement list)。操作数1new声明符(例如:new char[8])。操作数2是初始值。

DELETE_EXPR

VEC_DELETE_EXPR

e

e

对于DELETE_EXPR,操作数0是要被摧毁的存储区,操作数1是传给销毁函数的值,以指示是否回收存储区。

SCOPE_REF

r

引用特定的重载的类方法(particular overloaded class method)。操作数0是这个类,操作数1是方法。节点中的COMPLEXITY域指示类的层次(通常为0

MEMBER_REF

r

引用对象的数据成员。操作数0是对象。操作数1是数据成员(通常由解引用指针得到)

TYPE_EXPR

e

C++中的类型转换操作符。在节点中,TREE_TYPE是该转换符的目标类型。操作数0是要转换的表达式

AGGR_INIT_EXPR

e

在节点中,操作数0是执行初始化操作的函数,操作数1是函数的参数列表,操作数2是为该表达式分配的内存

THROW_EXPR

e

(异常)抛出表达式。操作数0是该表达式,如果该表达式存在,否则为NULL_TREEC++要求表达式必须出现,但需要考虑混合语言编程的情况)。

EMPTY_CLASS_EXPR

e

表示空的类对象。在节点中TREE_TYPE给出了类的类型。我们使用这种节点避免为空的类生成实例。

ALIAS_DECL

d

作为一个表达式的占位符的声明。用于实现非类域中的匿名union

BASELINK

x

表示从基类引用的成员函数。在节点中,BASELINK_FUNCTIONS给出对应的FUNCTION_DECL,或者TEMPLATE_DECL,或者OVERLOAD,或者TEMPLATE_ID_EXPR BASELINK_BINFO给出了定义该方法的基类,换而言之,当调用这个方法时,this指针需要被转换至的类型。BASELINK_ACCESS_BINFO则给出了最初定义这个方法的基类。

BASELINK代表一个表达式。它的TREE_TYPE给出了该表达式的类型。该类型或者是函数类型(FUNCTION_TYPE),获者是方法类型(METHOD_TYPE),或者是以unknown_type_node 代表的重载函数。

TEMPLATE_DECL

d

模板定义。以下节点中的域都有特定用途,虽然在cp-tree.h中,有其他宏会使用这些域。

DECL_ARGUMENTS – 模板参数vector

DECL_TEMPLATE_INFO – 模板特定的信息

DECL_VINDEX – 已具现的模板列表;该版本仅用于函数模板。

TREE_TYPE  -- 构建对象的类型

DECL_TEMPLATE_RESULT – 构建对象的声明(例如:对以具现函数模板的FUNCTION_DECL

TEMPLATE_PARM_INDEX

x

模板参数列表的索引。其中TEMPLATE_PARM_IDX 给出实参的索引(从0开始),而TEMPLATE_PARM_LEVEL给出模板参数的层次(从1开始)。例如:

   template <class T> // Index 0, Level 1.

   struct S

   {

      template <class U, // Index 0, Level 2.

                class V> // Index 1, Level 2.

      void f();

   };

TEMPLATE_PARM_DESCENDANTS是由该节点降阶(descend)后的TEMPLATE_PARM_INDEX节点组成的链表。链表中第一个节点将有相同的索引(IDX),但层次(LEVEL)少一级。链表中节点的TREE_CHAIN域将这些降阶的节点(descendants)链在一起。

TEMPLATE_PARM_DECL则对应这个模板参数的声明,它要么是个类型声明(TYPE_DECL)要么是个常量声明(CONST_DECL)。

TEMPLATE_PARM_ORIG_LEVEL则是最外层父节点的层次(the LEVEL of the most distant parent),也即最初声明这个模板参数时,对应的层次(the LEVEL that the parameter originally had when it was declared)。例如,如果我们具现S<int>,我们将得到:

 struct S<int>

 {

   template <class U, // Index 0, Level 1, Orig Level 2

           class V> // Index 1, Level 1, Orig Level 2

   void f();

 }; 

如果我们关注模板的类型,TEMPLATE_PARM_LEVEL表示模板参数的层次;如果我们关注具现,则TEMPLATE_PARM_ORIG_LEVEL是关联的层次。

TEMPLATE_TYPE_PARM

t

类型模板参数。对应的模板参数必须是类类型。而TYPE_FIELDS将包含一个TEMPLATE_PARM_INDEX节点。

TEMPLATE_TEMPLATE_PARM

t

模板模板参数。它必须是类类型。TYPE_FIELDS将包含一个TEMPLATE_PARM_INDEX节点。它不绑定任何模板实参,就像C<TT>中的TT

TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO 则是NULL_TREETYPE_NAME 则是对应的TEMPLATE_DECL

BOUND_TEMPLATE_TEMPLATE_PARM

t

类似TEMPLATE_TEMPLATE_PARM,但用于已绑定实参的模板参数,像TT<int>。在此情形下,TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO 包含模板名和绑定的实参。TYPE_NAME 是一个TYPE_DECL

TYPENAME_TYPE

t

由类似typename T::t指定的类型。  TYPE_CONTEXT对应T, TYPE_NAME是一个对应于tIDENTIFIER_NODE 。如果该类型通过template-id来命名, TYPENAME_TYPE_FULLNAME将持有 TEMPLATE_ID_EXPR节点。如果TREE_TYPE不为空,该类型由隐式的类型扩展生成(generated by the implicit typename extension),TREE_TYPE保存了T基类的类型节点(_TYPE from a baseclass of T)。

UNBOUND_CLASS_TEMPLATE

t

形如T::template C的模板模板实参。 TYPE_CONTEXT表示T,模板参数所依赖的对象。TYPE_NAME则是对应CIDENTIFIER_NODE 成员类模板。

TYPEOF_TYPE

t

代表由__typeof (expr)指出的类型。TYPE_FIELDS则是要询问的表达式(即例中的expr)。

USING_DECL

d

代表using声明。DECL_INITIAL指明指定的作用域(specified scope)。它不是别名(an alias),但随后它会被展开成多个别名。如果作用域(scope)是依赖的(dependent),该节点的类型是NULL_TYPE,否则就是void类型。

USING_STMT

e

代表using directive。它唯一的操作数是USING_STMT_NAMESPACE

DEFAULT_ARG

x

未被解析的缺省实参(un-parsed default argument)。域TREE_CHAIN用于保存那些,必须在此实参被解析时,已被具现好的函数实例(instantiations of functions that had to be instantiated before the argument was parsed)。注:用于模板

TEMPLATE_ID_EXPR

e

形如foo<int>template-id。其中第一个操作数是所对应的模板节点。如果没有显式的实参,则第二个操作数是NULL,否则就是代表实参的TREE_VEC。所对应的模板节点可以是FUNCTION_DECLTEMPLATE_DECL,或者OVERLOAD。而如果template-id表示一个成员模板(member template),所对应的模板节点可能是IDENTIFIER_NODE

OVERLOAD

x

用于链接候选的重载函数。

WRAPPER

x

用于封装非树节点结构,使其可以链如树结构。

MODOP_EXPR

e

 

CAST_EXPR

1

 

REINTERPRET_CAST_EXPR

1

 

CONST_CAST_EXPR

1

 

STATIC_CAST_EXPR

1

 

DYNAMIC_CAST_EXPR

1

 

DOTSTAR_EXPR

e

 

TYPEID_EXPR

e

 

PSEUDO_DTOR_EXPR

e

 

NON_DEPENDENT_EXPR

e

用于模板中非类型依赖表达式(expression that is not type-dependent)的展位符(placeholder)。当一个非类型依赖的表达式出现在另一个表达式中,我们必须计算这个更大的表达式的类型(compute the type of that larger expression)。这个计算通常会改变原有的表达式,如果那个表达式出现在模板实参列表,这会改变表达式的修饰名(the mangling of that expression)。在这种情况下,我们创建NON_DEPENDENT_EXPR节点来记录原始的表达式(take the place of the original expression)。这个表达式是唯一的操作数,它只用于诊断目的。

CTOR_INITIALIZER

e

 

TRY_BLOCK

e

 

EH_SPEC_BLOCK

e

 

HANDLER

e

HANDLER节点封装了一个对应catch句柄(catch handler)的HANDLER_TYPE节点。在HANDLER_PARMS 中是catch变量的声明,HANDLER_BODY则是catch

MUST_NOT_THROW_EXPR

e

MUST_NOT_THROW_EXPR封装的是不会抛出异常的表达式,如果这表达式抛出了异常,程序必须调用terminate结束。

TAG_DEFN

e

用于表示,在C++标准,[over.best.ics]节意义下的隐式转换序列。转换序列通过节点的第一个操作数链接在一起,链表中的转换以相反的次序执行。最里层的转换(亦即在链表尾端的节点)必须是代表自身变换(identity conversion)的IDENTITY_CONV)。

IDENTITY_CONV

e

LVALUE_CONV

e

QUAL_CONV

e

STD_CONV

e

PTR_CONV

e

PMEM_CONV

e

BASE_CONV

e

REF_BIND

e

USER_CONV

e

AMBIG_CONV

e

RVALUE_CONV

e

2 cp-tree.def中定义的树节点

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值