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

Studying note of GCC-3.4.6 source (64)

2013年01月14日 ⁄ 综合 ⁄ 共 5526字 ⁄ 字号 评论关闭
4.3.1.7.8.            Finish initialization

Below abort_fndecl represents function abort, and function build_library_fn_ptr like build_library_fn, but takes a C string instead of an IDENTIFIER_NODE.

 

cxx_init_decl_processing (continue)

 

3115     abort_fndecl

3116       = build_library_fn_ptr ("__cxa_pure_virtual", void_ftype);

3117

3118     /* Perform other language dependent initializations.  */

3119     init_class_processing ();

3120     init_search_processing ();

3121     init_rtti_processing ();

3122  

3123     if (flag_exceptions)

3124       init_exception_processing ();

3125  

3126     if (! supports_one_only ())

3127       flag_weak = 0;

3128  

3129     make_fname_decl = cp_make_fname_decl;

3130     start_fname_decls ();

3131  

3132     /* Show we use EH for cleanups.  */

3133     using_eh_for_cleanups ();

3134  

3135     /* Maintain consistency. Perhaps we should just complain if they

3136     say -fwritable-strings?  */

3137     if (flag_writable_strings)

3138       flag_const_strings = 0;

3139   }

4.3.1.7.8.1.      Initialize class processing

During handling class declaration, GCC uses following global variables to control the process. Among them, current_class_depth indicates the level of the nesting, and the classes nesting form a stack current_class_stack, which uses current_class_stack_size to tell the size. GNU C++ has an extension, allows class being defined within function body, which can only be visible there. To discriminate the class from others, the class is saved by local_classes.

 

5424   void

5425   init_class_processing (void)                                                                      in class.c

5426   {

5427     current_class_depth = 0;

5428     current_class_stack_size = 10;

5429     current_class_stack

5430       = xmalloc (current_class_stack_size * sizeof (struct class_stack_node));

5431     VARRAY_TREE_INIT (local_classes, 8, "local_classes");

5432  

5433     ridpointers[(int) RID_PUBLIC] = access_public_node;

5434     ridpointers[(int) RID_PRIVATE] = access_private_node;

5435     ridpointers[(int) RID_PROTECTED] = access_protected_node;

5436   }

 

And search_obstack initialized below is useless in current version, and has been removed in V4.

 

2346   void

2347   init_search_processing (void)                                                                   in search.c

2348   {

2349     gcc_obstack_init (&search_obstack);

2350   }

4.3.1.7.8.2.      Runtime type identification (RTTI)

4.3.1.7.8.2.1.              Create TYPE_DECL

To support RTTI (runtime type identification) which allows programs that manipulate objects as pointers or references to base classes to retrieve the actual derived types of the objects to which these pointers or references refer, GCC offers two operators: dynamic_cast and typeid. The returned type of typeid is type_info, and the definition of type_info is implement dependent. Here in the initialization of RTTI, unlike std::bad_alloc, full definition will be created as this type is expected by runtime environment.

 

115     void

116     init_rtti_processing (void)                                                                               in rtti.c

117     {

118       tree const_type_info_type;

119    

120      push_namespace (std_identifier);

121      type_info_type_node

122        = xref_tag (class_type, get_identifier ("type_info"),

123                 true, false);

124      pop_namespace ();

125      const_type_info_type = build_qualified_type (type_info_type_node,

126                                            TYPE_QUAL_CONST);

127      type_info_ptr_type = build_pointer_type (const_type_info_type);

128      type_info_ref_type = build_reference_type (const_type_info_type);

129   

130      VARRAY_TREE_INIT (unemitted_tinfo_decls, 10, "RTTI decls");

131   

132      create_tinfo_types ();

133    }

 

Now xref_tag tries to get the struct, enum or union (tag_code says which) with name. Defines the tag as a forward-reference if it is not defined.

If argument globalize is false, it means the identifier name is a definition. In C++, it first allows to define types of same name in different binding scope; second, in the same binding scope, different types of same name is an error unless the definitions are identical. At line 9476, lookup_tag tries to find out the type definition specified by code and name within binding scope referred by b. We will see the detail of the function later.

While if globalize is true, the tag is just type declaration. In C++, we can use the reference of an undefined user defining types restrictly by just declare it. For example,

class A;

A* pa = NULL;

Within GCC, when it finds that nothing can be found, it will create a fake type (remember std::bad_alloc), then declares implicit typedef for it and pushes TYPE_DECL created by implicit typedef within specified binding scope. Thus the forward declaration in fact refers to this TYPE_DECL, then later when the real definition encountered, the corresponding type node (of RECORD_TYPE/UNION_TYPE/ ENUMERAL_TYPE) is updated accordingly. And while GCC finds existing type declaration (no fake type), special handling is needed when the declaration relates to generic programing, we will see it shortly.

 

9443   tree

9444   xref_tag (enum tag_types tag_code, tree name,                                                         in decl.c

9445          bool globalize, bool template_header_p)

9446   {

9447     enum tree_code code;

9448     tree t;

9449     struct cp_binding_level *b = current_binding_level;

9450     tree context = NULL_TREE;

9451  

9452     timevar_push (TV_NAME_LOOKUP);

9453  

9454     my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 0);

9455  

9456     switch (tag_code)

9457     {

9458       case record_type:

9459       case class_type:

9460         code = RECORD_TYPE;

9461         break;

9462       case union_type:

9463         code = UNION_TYPE;

9464         break;

9465       case enum_type:

9466         code = ENUMERAL_TYPE;

9467         break;

9468       default:

9469         abort ();

9470     }

9471  

9472     if (! globalize)

9473     {

9474       /* If we know we are defining this tag, only look it up in

9475         this scope and don't try to find it as a type.  */

9476       t = lookup_tag (code, name, b, 1);

9477     }

9478     else

9479     {

9480       tree decl = lookup_name (name, 2);

 

Here globalize is true, it uses

抱歉!评论已关闭.