现在的位置: 首页 > 综合 > 正文

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

2013年07月06日 ⁄ 综合 ⁄ 共 3945字 ⁄ 字号 评论关闭

4.3.1.7.8.2.2.              构建type­_info的定义

下面就是构建这个type_info类型系列。首先是基类。

 

1251   static void

1252   create_tinfo_types (void)                                                                                 in rtti.c

1253   {

1254     my_friendly_assert (!ti_desc_type_node, 20020609);

1255  

1256     push_nested_namespace (abi_node);

 

如果我们需要将不是被当前名字空间所包含的名字空间,作为当前名字空间(例如,当前是A::B,现在我们需要A::D),那么我们应该使用push_nested_namespace,而不是push_namespace。这个函数通过递归,首先回溯到全局名字空间,由push_to_top_level将当前名字空间到全局名字空间之间的内容缓存,然后由push_namespace逐个加入从全局名字空间到所希望名字空间之间的内容(参考进入全局名字空间)。

 

3143   void

3144   push_nested_namespace (tree ns)                                                       in name-lookup.c

3145   {

3146     if (ns == global_namespace)

3147       push_to_top_level ();

3148     else

3149     {

3150       push_nested_namespace (CP_DECL_CONTEXT (ns));

3151       push_namespace (DECL_NAME (ns));

3152     }

3153   }

 

push_nested_namespace的反向操作是pop_nested_namespace。它恢复所有被缓存的内容(参考从全局名字空间返回)。

 

3158   void

3159   pop_nested_namespace (tree ns)                                                         in name-lookup.c

3160   {

3161     timevar_push (TV_NAME_LOOKUP);

3162     while (ns != global_namespace)

3163     {

3164       pop_namespace ();

3165       ns = CP_DECL_CONTEXT (ns);

3166     }

3167  

3168     pop_from_top_level ();

3169     timevar_pop (TV_NAME_LOOKUP);

3170   }

 

现在我们在名字空间__cxxabiv1里了。在“gcc-3.4.6/libstdc++-v3/libsupc++”目录下,GCC有文件cxxabi.h。这个文件就是Linux系统include目录中的“c++/`version`/cxxabi.h”,而其代码生成在libstdc++.so.`ver`库文件里。编译器将按这个文件的内容来生成类定义。

__cxxabiv1名字空间里的类定义都是std::type_info的派生类。因此,首先应该构建这个基类。但是注意下面,这个基类构建在__cxxabiv1名字空间里,且名字是“type_info_pseduo”。事实上,在GCC内部并没有生成std::type_info的定义。在下面std::type_info的定义中,我们可以看到这个类不能单独使用,只能作为基类,而且它具有平凡析构函数(虽然是虚函数)。真正被使用的是__cxxabiv1中的type_info派生类。那么我们偷梁换柱,用type_info_pseduo来替换std::type_info亦无不可,只要我们用到方法、成员都一样的声明,并且不使用基类指针(编译器保证这一点)。下面可以看到type_info_pseduo类是被大大简化了的。

 

create_tinfo_types (continue)

 

1258     /* Create the internal type_info structure. This is used as a base for

1259       the other structures.  */

1260     {

1261       tree field, fields;

1262  

1263       ti_desc_type_node = make_aggr_type (RECORD_TYPE);

1264       field = build_decl (FIELD_DECL, NULL_TREE, const_ptr_type_node);

1265       fields = field;

1266      

1267       field = build_decl (FIELD_DECL, NULL_TREE, const_string_type_node);

1268       TREE_CHAIN (field) = fields;

1269       fields = field;

1270      

1271       finish_builtin_struct (ti_desc_type_node, "__type_info_pseudo",

1272                        fields, NULL_TREE);

1273       TYPE_HAS_CONSTRUCTOR (ti_desc_type_node) = 1;

1274     }

 

type_info_pseduo具有2个匿名成员,一个具有类型“const void*”,另一个是类型“const char*”。这是为了让type_info_pseduostd::type_info具有相同的大小(注意std::type_info有虚函数表,其大小就是const void*)。函数finish_builtin_struct完成这个结构体。

 

1476   void

1477   finish_builtin_struct (tree type, const char *name, tree fields,                      in stor-layout.c

1478                      tree align_type)

1479   {

1480     tree tail, next;

1481  

1482     for (tail = NULL_TREE; fields; tail = fields, fields = next)

1483     {

1484       DECL_FIELD_CONTEXT (fields) = type;

1485       next = TREE_CHAIN (fields);

1486       TREE_CHAIN (fields) = tail;

1487     }

1488     TYPE_FIELDS (type) = tail;

1489  

1490     if (align_type)

1491     {

1492       TYPE_ALIGN (type) = TYPE_ALIGN (align_type);

1493       TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (align_type);

1494     }

1495  

1496     layout_type (type);

1497   #if 0 /* not yet, should get fixed properly later */

1498     TYPE_NAME (type) = make_type_decl (get_identifier (name), type);

1499   #else

1500     TYPE_NAME (type) = build_decl (TYPE_DECL, get_identifier (name), type);

1501   #endif

1502     TYPE_STUB_DECL (type) = TYPE_NAME (type);

1503     layout_decl (TYPE_NAME (type), 0);

1504   }

 

下面将std::type_info的定义列出。作为对比,type_info_pseduo没有定义任何方法,而且只有不可用的匿名成员。为什么会这样呢?

 

63      class type_info                                                                                        in typeinfo

64      {

65        public:

66          /** Destructor. Being the first non-inline virtual function, this

67           *  controls in which translation unit the vtable is emitted. The

68           *  compiler makes use of that information to know where to emit

69           *  the runtime-mandated type_info structures in the new-abi.  */

70     

抱歉!评论已关闭.