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

4.3.1.7.3.            类型信息树节点

回到 cxx_init_decl_processing ,接下来 GCC 将最终确定的内联函数的选项置入 flag_inline_trees 2983 行的 ptrmemfunc_vbit_in_pfn 是枚举类型 ptrmemfunc_vbit_where_t

 

2048   enum ptrmemfunc_vbit_where_t                                                                              in tree.h

2049   {

2050     ptrmemfunc_vbit_in_pfn,

2051     ptrmemfunc_vbit_in_delta

2052   };

 

它之所以需要,是因为 GCC 需要编译使用了不同语言的程序,因此在系统中一个指向方法的指针看上去就像:

     struct {

       __P __pfn;

       ptrdiff_t __delta;

     };

如果 __pfn NULL ,那么它是一个为 NULL 的方法指针。(因为 vtable 总是对象中位于第一的,我们不需要它的偏移。)如果函数是虚函数,那么 PFN 1 加上 2 倍其在 vtable 中的索引( PFN 为距 vtable 头的“偏移”,其最低位将是 1 );否则就是指向函数的指针(通常,函数地址有对齐要求,其最低位将是 0 ,这样由这个最低位就可以知道函数是否是虚函数)。

不过,这样使用 PFN 的最低位在不要求函数地址对齐的机器上不能奏效;或者,例如使用最低位来区分不同的指令集架构( ISA )。对于这样的机器,我们使用 DELTA 的最低位,而不是 PFN 的,并且 DELTA 的值将加倍。

毫无疑问宏 TARGET_PTRMEMFUNC_VBIT_LOCATION 即记录了这个区分虚函数与普通函数的比特位在何处。对于 x86 ,这个宏就是 ptrmemfunc_vbit_in_pfn 。全局变量 force_align_functions_log 则记录了对函数地址对齐的强制要求(以 2 为底的对数)。显然如果它为 0 ,则没有对齐要求,那些需要将其调整至 1 (对齐至偶数字节处)。

 

cxx_init_decl_processing (continue)

 

2967     /* Adjust various flags based on command-line settings.  */

2968     if (!flag_permissive )

2969       flag_pedantic_errors = 1;

2970     if (!flag_no_inline )

2971     {

2972       flag_inline_trees = 1;

2973       flag_no_inline = 1;

2974     }

2975     if (flag_inline_functions )

2976     {

2977       flag_inline_trees = 2;

2978       flag_inline_functions = 0;

2979     }

2980  

2981     /* Force minimum function alignment if using the least significant

2982       bit of function pointers to store the virtual bit.  */

2983     if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn

2984         && force_align_functions_log < 1)

2985       force_align_functions_log = 1;

2986  

2987     /* Initially, C.  */

2988     current_lang_name = lang_name_c;

2989  

2990     build_common_tree_nodes (flag_signed_char );

2991  

2992     error_mark_list = build_tree_list (error_mark_node, error_mark_node);

2993     TREE_TYPE (error_mark_list ) = error_mark_node;

 

内建类型的树节点 一节,已经看过相关内建类型节点的创建。这些节点正是在下面的函数中构建的。

 

4834   void

4835   build_common_tree_nodes (int signed_char)                                                     in tree.c

4836   {

4837     error_mark_node = make_node (ERROR_MARK);

4838     TREE_TYPE (error_mark_node) = error_mark_node;

4839  

4840     initialize_sizetypes ();

4841  

4842     /* Define both `signed char' and `unsigned char'.  */

4843     signed_char_type_node = make_signed_type (CHAR_TYPE_SIZE);

4844     unsigned_char_type_node = make_unsigned_type (CHAR_TYPE_SIZE);

4845  

4846     /* Define `char', which is like either `signed char' or `unsigned char'

4847       but not the same as either.  */

4848     char_type_node

4849       = (signed_char

4850          ? make_signed_type (CHAR_TYPE_SIZE)

4851          : make_unsigned_type (CHAR_TYPE_SIZE));

4852  

4853     short_integer_type_node = make_signed_type (SHORT_TYPE_SIZE);

4854     short_unsigned_type_node = make_unsigned_type (SHORT_TYPE_SIZE);

4855     integer_type_node = make_signed_type (INT_TYPE_SIZE);

4856     unsigned_type_node = make_unsigned_type (INT_TYPE_SIZE);

4857     long_integer_type_node = make_signed_type (LONG_TYPE_SIZE);

4858     long_unsigned_type_node = make_unsigned_type (LONG_TYPE_SIZE);

4859     long_long_integer_type_node = make_signed_type (LONG_LONG_TYPE_SIZE);

4860     long_long_unsigned_type_node = make_unsigned_type (LONG_LONG_TYPE_SIZE);

4861  

4862     /* Define a boolean type. This type only represents boolean values but

4863       may be larger than char depending on the value of BOOL_TYPE_SIZE.

4864       Front ends which want to override this size (i.e. Java) can redefine

4865       boolean_type_node before calling build_common_tree_nodes_2.  */

4866     boolean_type_node = make_unsigned_type (BOOL_TYPE_SIZE);

4867     TREE_SET_CODE (boolean_type_node, BOOLEAN_TYPE);

4868     TYPE_MAX_VALUE (boolean_type_node) = build_int_2 (1, 0);

4869     TREE_TYPE (TYPE_MAX_VALUE (boolean_type_node)) = boolean_type_node;

4870     TYPE_PRECISION (boolean_type_node) = 1;

4871  

4872     /* Fill in the rest of the sized types. Reuse existing type nodes

4873       when possible.  */

4874     intQI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (QImode), 0);

4875     intHI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (HImode), 0);

4876     intSI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (SImode), 0);

4877     intDI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (DImode), 0);

4878     intTI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (TImode), 0);

4879  

4880     unsigned_intQI_type_node =make_or_reuse_type(GET_MODE_BITSIZE (QImode), 1);

4881     unsigned_intHI_type_node =make_or_reuse_type(GET_MODE_BITSIZE (HImode), 1);

4882     unsigned_intSI_type_node = make_or_reuse_type(GET_MODE_BITSIZE (SImode), 1);

4883     unsigned_intDI_type_node =make_or_reuse_type(GET_MODE_BITSIZE (DImode), 1);

4884     unsigned_intTI_type_node = make_or_reuse_type(GET_MODE_BITSIZE (TImode), 1);

4885  

4886     access_public_node = get_identifier ("public");

4887     access_protected_node = get_identifier ("protected");

4888     access_private_node = get_identifier ("private");

4889   }

 

C++ 中,内建类型 short unsighed short int 等,其大小与所运行的平台有关。因此,在编译器的实现中,需要把这些类型的节点与标准尺寸节点关联。这些标准尺寸节点就是上面的 intQI_type_node intHI_type_node 等。关联由 make_or_reuse_type 建立。其意义在于能快速确定内建类型的模式(即其内存使用),例如,如果知道 short_integer_type_node intHI_type_node ,即可知 short HI 模式。

 

4809   static tree

4810   make_or_reuse_type (unsigned size, int unsignedp)                                            in tree.c

4811   {

4812     if (size == INT_TYPE_SIZE)

4813       return unsignedp ? unsigned_type_node : integer_type_node;

4814     if (size == CHAR_TYPE_SIZE)

4815       return unsignedp ? unsigned_char_type_node : signed_char_type_node;

4816     if (size == SHORT_TYPE_SIZE)

4817       return unsignedp ? short_unsigned_type_node : short_integer_type_node;

4818     if (size == LONG_TYPE_SIZE)

4819       return unsignedp ? long_unsigned_type_node : long_integer_type_node;

4820     if (size == LONG_LONG_TYPE_SIZE)

4821       return (unsignedp ? long_long_unsigned_type_node

4822               : long_long_integer_type_node);

4823  

4824     if (unsignedp)

4825       return make_unsigned_type (size);

4826     else

4827       return make_signed_type (size);

4828   }

 

另, 4886 行至 4888 行创建的是关键字: public protected private 的树节点。

 

 

你可能感兴趣的:(GCC-3.4.6源代码学习笔记(54))