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

来源:互联网 发布:局域网传输软件 编辑:程序博客网 时间:2024/06/10 17:41

5.13.4.2.             迭代发布tinfo

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

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

tmp

 

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      returninit; 

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 theNTBS 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 nameof the string containing the type's name has a

764          specialname.  */

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 sawa definition of this type, so we need to

785            tell thecompiler that this is an exported class, as

786           indeed all ofthe __*_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 topoint 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,该函数为这个类型的tinfovtable构建VAR_DECL,并把这个VRA_DECL标记为外部,但其中的cp_finish_decl不为其做任何事。

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

t2

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