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

来源:互联网 发布:win10 iis php 配置 编辑:程序博客网 时间:2024/05/29 12:11

1.6. 为类型创建节点第一部分

1.6.1. 创建函数类型的节点

首先,看看FUNCTION_TYPE节点是个什么东西:

FUNCTION_TYPE[2]

²        用于表示普通函数和静态成员函数。域TREE_TYPE给出了函数的返回类型。域TYPE_ARG_TYPES是一个包含实参类型的TREE_LIST。其中每一节点的TREE_VALUE是对应实参的类型,TREE_PURPOSE如果非空,是默认参数值。如果链表结尾的节点是void_list_node(一个TREE_LIST节点,它的TREE_VALUEvoid_type_node),那么该函数类型不接受可变数量参数。否则,该函数类型接受可变数量参数。

注意在C(不是C++)中,一个被声明为类似void f()的函数是可接受可变数量参数的非原型函数,这种函数节点的TYPE_ARG_TYPESNULL

1.6.1.1.      由函数形参创建函数类型节点

函数build_function_type_list接受分立的形参节点,它主要被后端调用。

 

3876 tree

3877 build_function_type_list (tree return_type, ...)                                                    in tree.c

3878 {

3879   tree t, args, last;

3880   va_list p;

3881

3882   va_start (p, return_type);

3883

3884   t = va_arg (p, tree);

3885   for (args = NULL_TREE; t != NULL_TREE; t = va_arg (p, tree))

3886     args = tree_cons (NULL_TREE, t, args);

3887

3888   last = args;

3889   args = nreverse (args);

3890   TREE_CHAIN (last) = void_list_node;

3891   args = build_function_type (return_type, args);

3892

3893   va_end (p);

3894   return args;

3895 }

 

注意,形参节点以声明的次序传给build_function_type_list。在3889行,这些参数被反序(即汇编中参数被处理的次序)。

1.6.1.2.      由函数形参链表创建函数类型节点

前端更多地使用下面的函数来创建函数类型节点。函数的参数arg_types是一个tree_list,它把所有形参按声明次序的反序串在一起。

 

3845 tree

3846 build_function_type (tree value_type, tree arg_types)                                          in tree.c

3847 {

3848   tree t;

3849   unsigned int hashcode;

3850

3851   if (TREE_CODE (value_type) == FUNCTION_TYPE)

3852   {

3853     error ("function return type cannot be function");

3854     value_type = integer_type_node;

3855   }

3856

3857   /* Make a node of the sort we want.  */

3858   t = make_node (FUNCTION_TYPE);

3859   TREE_TYPE (t) = value_type;

3860   TYPE_ARG_TYPES (t) = arg_types;

3861

3862   /* If we already have such a type, use the old one and free this one.  */

3863   hashcode = TYPE_HASH (value_type) + type_hash_list (arg_types);

3864   t = type_hash_canon (hashcode, t);

3865

3866   if (!COMPLETE_TYPE_P (t))

3867     layout_type (t);

3868   return t;

3869 }

 

函数的类型由其返回值和形参列表决定,例如:int f (int, int)int g (int, int)的类型是相同的。为了确保类型节点和类型定义一一对应,所有的类型节点都被保存在哈希表type_hash_table中。

1.6.1.3.      对函数类型的布局

在目标文件中,函数定义被放于代码段中。同样出于访问效率,函数定义的起始地址是有对齐要求的。因此,函数类型也需要布局。

 

1528 void

1529 layout_type (tree type)                                                                       in stor-layout.c

1530 {

1531   if (type == 0)

1532     abort ();

1533

1534   /* Do nothing if type has been laid out before.  */

1535   if (TYPE_SIZE (type))

1536     return;

1537

1538   switch (TREE_CODE (type))

1539   {

        

1595     case FUNCTION_TYPE:

1596     case METHOD_TYPE:

1597       TYPE_MODE (type) = mode_for_size (2 * POINTER_SIZE, MODE_INT, 0);

1598       TYPE_SIZE (type) = bitsize_int (2 * POINTER_SIZE);

1599       TYPE_SIZE_UNIT (type) = size_int ((2 * POINTER_SIZE) / BITS_PER_UNIT);

1600       break;

         

1796   }

      

1801   if (TREE_CODE (type) != RECORD_TYPE

1802       && TREE_CODE (type) != UNION_TYPE

1803       && TREE_CODE (type) != QUAL_UNION_TYPE)

1804     finalize_type_size (type);

      

1818 }

 

从代码中可见,FUNCTION_TYPEMETHOD_TYPE都被定义为含有大小为2*POINTER_SIZE的整型模式。在finalize_type_size中类型的对齐量被设为指针的2倍。

1.6.2. 创建索引节点

这个函数所创建的整型节点将作为一个ARRAY_TYPE类型的TYPE_DOMAIN节点。参数maxval应该是最大边界值(数组长度减1)。

 

3724 tree

3725 build_index_type (tree maxval)                                                                          in tree.c

3726 {

3727   tree itype = make_node (INTEGER_TYPE);

3728

3729   TREE_TYPE (itype) = sizetype;

3730   TYPE_PRECISION (itype) = TYPE_PRECISION (sizetype);

3731   TYPE_MIN_VALUE (itype) = size_zero_node;

3732   TYPE_MAX_VALUE (itype) = convert (sizetype, maxval);

3733   TYPE_MODE (itype) = TYPE_MODE (sizetype);

3734   TYPE_SIZE (itype) = TYPE_SIZE (sizetype);

3735   TYPE_SIZE_UNIT (itype) = TYPE_SIZE_UNIT (sizetype);

3736   TYPE_ALIGN (itype) = TYPE_ALIGN (sizetype);

3737   TYPE_USER_ALIGN (itype) = TYPE_USER_ALIGN (sizetype);

3738

3739   if (host_integerp (maxval, 1))

3740     return type_hash_canon (tree_low_cst (maxval, 1), itype);

3741   else

3742     return itype;

3743 }

 

注意到索引节点的类型是size_t

原创粉丝点击