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

    技术2025-03-19  47

    5.13.4.2.              迭代 发布 tinfo

    现在所有需要代码发布的 tinfo 已经被串入 unemitted_tinfo_decls 中。接着在 finish_file 2628 行, emit_tinfo_decl 确定 decl tinfo 是否需要发布,如果需要,则返回 true 。下面,看到之前在 finish_file 2571 行调用的 emit_support_tinfos 中, doing_runtime 被设为 1

    那么在调用 class_initializer 这一点上( emit_tinfo_decl à get_pseudo_ti_init ),参数 trail 将是下图所示的树。注意到基类的 tinfo VAR_DECL 已经产生了初始值( desc 是当前类的 tinfo VAR_DECL )。

     

    951    static tree

    952    class_initializer (tree desc, tree target, tree trail)                                                  in rtti.c

    953    {

    954      tree init = tinfo_base_init (desc, target);

    955     

    956      TREE_CHAIN (init) = trail;

    957      init = build_constructor (NULL_TREE, init);

    958      TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;

    959      return init; 

    960    }

     

    看到在类 type_info 中,有一个“ const char * ”的域 name ,在 745 行开始的代码块为这个域产生修饰名及初始化代码。

     

    738    static tree

    739    tinfo_base_init (tree desc, tree target)                                                                in rtti.c

    740    {

    741      tree init = NULL_TREE;

    742      tree name_decl;

    743      tree vtable_ptr;

    744     

    745      {

    746        tree name_name;

    747       

    748        /* Generate the NTBS array variable.  */

    749        tree name_type = build_cplus_array_type

    750                       (build_qualified_type (char_type_node, TYPE_QUAL_CONST),

    751                        NULL_TREE);

    752        tree name_string = tinfo_name (target);

    753   

    754        name_name = mangle_typeinfo_string_for_type (target);

    755        name_decl = build_lang_decl (VAR_DECL, name_name, name_type);

    756       

    757        DECL_ARTIFICIAL (name_decl) = 1;

    758         TREE_READONLY (name_decl) = 1;

    759        TREE_STATIC (name_decl) = 1;

    760        DECL_EXTERNAL (name_decl) = 0;

    761        TREE_PUBLIC (name_decl) = 1;

    762        import_export_tinfo (name_decl, target, typeinfo_in_lib_p (target));

    763        /* External name of the string containing the type's name has a

    764          special name.  */

    765        SET_DECL_ASSEMBLER_NAME (name_decl,

    766                                       mangle_typeinfo_string_for_type (target));

    767        DECL_INITIAL (name_decl) = name_string;

    768        mark_used (name_decl);

    769        pushdecl_top_level_and_finish (name_decl, name_string);

    770      }

    771   

    772      vtable_ptr = TINFO_VTABLE_DECL (desc);

    773      if (!vtable_ptr)

    774      {

    775        tree real_type;

    776     

    777        push_nested_namespace (abi_node);

    778        real_type = xref_tag (class_type, TINFO_REAL_NAME (desc),

    779                           true, false);

    780        pop_nested_namespace (abi_node);

    781     

    782        if (!COMPLETE_TYPE_P (real_type))

    783        {

    784          /* We never saw a definition of this type, so we need to

    785            tell the compiler that this is an exported class, as

    786            indeed all of the __*_type_info classes are.  */

    787          SET_CLASSTYPE_INTERFACE_KNOWN (real_type);

    788          CLASSTYPE_INTERFACE_ONLY (real_type) = 1;

    789        }

    790   

    791        vtable_ptr = get_vtable_decl (real_type, /*complete=*/ 1);

    792        vtable_ptr = build_unary_op (ADDR_EXPR, vtable_ptr, 0);

    793   

    794        /* We need to point into the middle of the vtable.  */

    795        vtable_ptr = build

    796                   (PLUS_EXPR, TREE_TYPE (vtable_ptr), vtable_ptr,

    797                    size_binop (MULT_EXPR,

    798                        size_int (2 * TARGET_VTABLE_DATA_ENTRY_DISTANCE),

    799                        TYPE_SIZE_UNIT (vtable_entry_type )));

    800        TREE_CONSTANT (vtable_ptr) = 1;

    801   

    802        TINFO_VTABLE_DECL (desc) = vtable_ptr;

    803      }

    804   

    805      init = tree_cons (NULL_TREE, vtable_ptr, init);

    806     

    807      init = tree_cons (NULL_TREE, decay_conversion (name_decl), init);

    808     

    809      init = build_constructor (NULL_TREE, nreverse (init));

    810      TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;

    811       init = tree_cons (NULL_TREE, init, NULL_TREE);

    812     

    813      return init;

    814    }

     

    注意在上面 791 行, get_vtable_decl 的最后一个参数是 1 ,该函数为这个类型的 tinfo vtable 构建 VAR_DECL ,并把这个 VRA_DECL 标记为外部,但其中的 cp_finish_decl 不为其做任何事。

    最后,在 emit_tinfo_decl 1452 行, var_init 是如下的树。并且 var_init 将被用作这个 tinfo 的初始值。而在 emit_tinfo_decl 1461 行, decl tinfo VAR_DECL ,正如我们在前面的章节所见, cp_finish_decl 没有作任何事。

    如果 emit_tinfo_decl 成功返回,这意味着正在处理的中间树发生了变化,强制再次迭代 2573 行的 DO…WHILE 循环。

    最新回复(0)