关闭

Studying note of GCC-3.4.6 source (143)

444人阅读 评论(0) 收藏 举报

5.12.5.2.2.2.1.4.    Finish instantiation

Now continue to process our template instantiation example, in section Front-end initialization , we have seen when using the -frepo command-line option, init_repo would generate a .rpo file or read in an already existed .rpo file. Below repo_template_used will record the usage of the template instantiation in corresponding .rpo file for compiler and collect2 using later.

 

instantiate_class_template (continue)

 

5473     /* Clear this now so repo_template_used is happy.  */

5474     TYPE_BEING_DEFINED (type) = 0;

5475     repo_template_used (type);

5476  

5477     /* Now that the class is complete, instantiate default arguments for

5478       any member functions. We don't do this earlier because the

5479       default arguments may reference members of the class.  */

5480     if (!PRIMARY_TEMPLATE_P (template))

5481       for (t = TYPE_METHODS (type); t; t = TREE_CHAIN (t))

5482         if (TREE_CODE (t) == FUNCTION_DECL

5483            /* Implicitly generated member functions will not have template

5484              information; they are not instantiations, but instead are

5485              created "fresh" for each instantiation.  */

5486            && DECL_TEMPLATE_INFO (t))

5487           tsubst_default_arguments (t);

5488  

5489     popclass ();

5490     pop_from_top_level ();

5491     pop_deferring_access_checks ();

5492     pop_tinst_level ();

5493  

5494     if (TYPE_CONTAINS_VPTR_P (type))

5495       keyed_classes = tree_cons (NULL_TREE, type, keyed_classes);

5496  

5497     return type;

5498   }

 

Next remember to leave the scope of the class by popclass ; then restore original binding scope by pop_from_top_level . Also decreases tinst_depth and updates current_tinst_level by pop_tinst_level , which is the node of EXPR_WITH_FILE_LOCATION. See as the class contains vtable, it is regarded as keyed class.

Getting out of instantiate_class_template , we return back complete_type , then layout_var_decl . The template is instantiated within function main , so current_function_decl refers to the binding scope of the function, then at line 4100 in layout_var_decl , push_local_name pushes this variable into the function scope.

 

948    static void

949    push_local_name (tree decl)                                                                            in decl.c

950    {

951      size_t i, nelts;

952      tree t, name;

953   

954      timevar_push (TV_NAME_LOOKUP);

955      if (!local_names)

956        VARRAY_TREE_INIT (local_names, 8, "local_names");

957   

958      name = DECL_NAME (decl);

959   

960      nelts = VARRAY_ACTIVE_SIZE (local_names);

961      for (i = 0; i < nelts; i++)

962      {

963        t = VARRAY_TREE (local_names, i);

964        if (DECL_NAME (t) == name)

965        {

966           if (!DECL_LANG_SPECIFIC (decl))

967             retrofit_lang_decl (decl);

968           DECL_LANG_SPECIFIC (decl)->decl_flags.u2sel = 1;

969           if (DECL_LANG_SPECIFIC (t))

970             DECL_DISCRIMINATOR (decl) = DECL_DISCRIMINATOR (t) + 1;

971           else

972             DECL_DISCRIMINATOR (decl) = 1;

973   

974           VARRAY_TREE (local_names, i) = decl;

975           timevar_pop (TV_NAME_LOOKUP);

976           return ;

977        }

978      }

979   

980      VARRAY_PUSH_TREE (local_names, decl);

981      timevar_pop (TV_NAME_LOOKUP);

982    }

 

Above local_names is a macro accesses slot x_local_names in language part of cfun , which is a variable array to save the local names declared within the function specified by cfun .

5.12.5.2.2.2.1.5.    Finish VAR_DECL

Now we back into cp_finish_decl , dawn is in front!

 

cp_finish_decl (continue)

 

4962     /* Output the assembler code and/or RTL code for variables and functions,

4963       unless the type is an undefined structure or union.

4964       If not, it will get done when the type is completed.  */

4965     if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)

4966     {

4967       if (TREE_CODE (decl) == VAR_DECL)

4968         maybe_commonize_var (decl);

4969  

4970       make_rtl_for_nonlocal_decl (decl, init, asmspec);

4971  

4972       if (TREE_CODE (type) == FUNCTION_TYPE

4973          || TREE_CODE (type) == METHOD_TYPE)

4974        abstract_virtuals_error (decl,

4975                           strip_array_types (TREE_TYPE (type)));

4976       else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)

4977       {

           

4986       }

4987       else

4988         abstract_virtuals_error (decl, type);

4989  

4990       if (TREE_CODE (decl) == FUNCTION_DECL

4991          || TREE_TYPE (decl) == error_mark_node)

4992         /* No initialization required.  */

4993         ;

4994       else if (DECL_EXTERNAL (decl)

4995             && ! (DECL_LANG_SPECIFIC (decl)

4996                  && DECL_NOT_REALLY_EXTERN (decl)))

4997       {

4998         if (init)

4999           DECL_INITIAL (decl) = init;

5000       }

5001       else

5002       {

5003         /* A variable definition.  */

5004         if (DECL_FUNCTION_SCOPE_P (decl))

5005         {

5006           /* This is a local declaration.  */

5007           maybe_inject_for_scope_var (decl);

5008           /* Initialize the local variable.  */

5009           if (processing_template_decl)

5010           {

5011             if (init || DECL_INITIAL (decl) == error_mark_node)

5012               DECL_INITIAL (decl) = init;

5013           }

5014           else if (!TREE_STATIC (decl))

5015             initialize_local_var (decl, init);

5016         }

5017  

5018         /* If a variable is defined, and then a subsequent

5019           definintion with external linkage is encountered, we will

5020           get here twice for the same variable. We want to avoid

5021           calling expand_static_init more than once. For variables

5022           that are not static data members, we can call

5023           expand_static_init only when we actually process the

5024           initializer. It is not legal to redeclare a static data

5025           member, so this issue does not arise in that case.  */

5026         if (var_definition_p && TREE_STATIC (decl))

5027           expand_static_init (decl, init);

5028       }

5029   finish_end0:

5030  

5031       /* Undo call to `pushclass' that was done in `start_decl'

5032          due to initialization of qualified member variable.

5033          i.e., Foo::x = 10;  */

5034       {

5035         tree context = CP_DECL_CONTEXT (decl);

5036         if (context

5037            && TYPE_P (context)

5038            && (TREE_CODE (decl) == VAR_DECL

5039                /* We also have a pushclass done that we need to undo here

5040                     if we're at top level and declare a method.  */

5041                || TREE_CODE (decl) == FUNCTION_DECL)

5042            /* If size hasn't been set, we're still defining it,

5043               and therefore inside the class body; don't pop

5044                the binding level..  */

5045            && COMPLETE_TYPE_P (context)

5046            && context == current_class_type )

5047           pop_nested_class ();

5048       }

5049     }

5050  

5051     /* If a CLEANUP_STMT was created to destroy a temporary bound to a

5052       reference, insert it in the statement-tree now.  */

5053     if (cleanup)

5054       add_stmt (cleanup);

5055  

5056   finish_end:

5057  

5058     if (was_readonly)

5059       TREE_READONLY (decl) = 1;

5060  

5061     /* If this was marked 'used', be sure it will be output.  */

5062     if (lookup_attribute ("used", DECL_ATTRIBUTES (decl)))

5063       mark_referenced (DECL_ASSEMBLER_NAME (decl));

5064   }

 

In the rest code of the function, to handle the template instantiation obj_ as local variable, initialize_local_var at line 5015 is invoked.

 

698    static void

4699   initialize_local_var (tree decl, tree init)                                                              in decl.c

4700   {

4701     tree type = TREE_TYPE (decl);

4702     tree cleanup;

4703  

4704     my_friendly_assert (TREE_CODE (decl) == VAR_DECL

4705                       || TREE_CODE (decl) == RESULT_DECL,

4706                      20021010);

4707     my_friendly_assert (!TREE_STATIC (decl), 20021010);

4708  

4709     if (DECL_SIZE (decl) == NULL_TREE)

4710     {

4711       /* If we used it already as memory, it must stay in memory.  */

4712       DECL_INITIAL (decl) = NULL_TREE;

4713       TREE_ADDRESSABLE (decl) = TREE_USED (decl);

4714     }

4715  

4716     if (DECL_SIZE (decl) && type != error_mark_node)

4717     {

4718       int already_used;

4719  

4720        /* Compute and store the initial value.  */

4721       already_used = TREE_USED (decl) || TREE_USED (type);

4722  

4723       /* Perform the initialization.  */

4724       if (init)

4725       {

4726         int saved_stmts_are_full_exprs_p;

4727  

4728         my_friendly_assert (building_stmt_tree (), 20000906);

4729         saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();

4730         current_stmt_tree ()->stmts_are_full_exprs_p = 1;

4731         finish_expr_stmt (init);

4732         current_stmt_tree ()->stmts_are_full_exprs_p =

4733            saved_stmts_are_full_exprs_p;

4734          }

4735  

4736       /* Set this to 0 so we can tell whether an aggregate which was

4737         initialized was ever used. Don't do this if it has a

4738         destructor, so we don't complain about the 'resource

4739         allocation is initialization' idiom. Now set

4740         attribute((unused)) on types so decls of that type will be

4741         marked used. (see TREE_USED, above.)  */

4742       if (TYPE_NEEDS_CONSTRUCTING (type)

4743          && ! already_used

4744          && TYPE_HAS_TRIVIAL_DESTRUCTOR (type)

4745          && DECL_NAME (decl))

4746         TREE_USED (decl) = 0;

4747       else if (already_used)

4748         TREE_USED (decl) = 1;

4749     }

4750  

4751     /* Generate a cleanup, if necessary.  */

4752     cleanup = cxx_maybe_build_cleanup (decl);

4753     if (DECL_SIZE (decl) && cleanup)

4754       finish_decl_cleanup (decl, cleanup);

4755   }

 

Here argument init comes from the part following “=” in declarator, which is the initializer specified by programmer instead of compiler as we see in previous section. Of course, for our example, init is NULL.

Next see cxx_maybe_build_cleanup at line 4752. Compiler may insert code to cleanup the local variable at exitting its binding scope.

 

11215 tree

11216 cxx_maybe_build_cleanup (tree decl)                                                               in decl.c

11217 {

11218   tree type = TREE_TYPE (decl);

11219

11220   if (type != error_mark_node && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))

11221   {

11222     int flags = LOOKUP_NORMAL|LOOKUP_DESTRUCTOR;

11223     tree rval;

11224

11225     if (TREE_CODE (type) == ARRAY_TYPE)

11226       rval = decl;

11227     else

11228     {

11229       cxx_mark_addressable (decl);

11230       rval = build_unary_op (ADDR_EXPR, decl, 0);

11231     }

11232

11233     /* Optimize for space over speed here.  */

11234     if (! TYPE_USES_VIRTUAL_BASECLASSES (type)

11235         || flag_expensive_optimizations )

11236       flags |= LOOKUP_NONVIRTUAL;

11237

11238     rval = build_delete (TREE_TYPE (rval), rval,

11239                     sfk_complete_destructor, flags, 0);

11240

11241     if (TYPE_USES_VIRTUAL_BASECLASSES (type)

11242         && ! TYPE_HAS_DESTRUCTOR (type))

11243       rval = build_compound_expr (rval, build_vbase_delete (type, decl));

11244

11245     return rval;

11246   }

11247   return NULL_TREE;

11248 }

 

Predicate TYPE_HAS_NONTRIVIAL_DESTRUCTOR is true, if the type’s destructor is not trivial (if we don’t define destructor, and TYPE_HAS_NONTRIVIAL_DESTRUCTOR is false for all bases and non-static members, TYPE_HAS_NONTRIVIAL_DESTRUCTOR is false for the class).

That is why don’t define a destructor if it does nothing. Though compiler will add an implicit one for you, it will be tagged as trivial as long as its bases and non-static members have trivial destructor too. As result, no code for cleanup will be generated here.

If cleanup is expected, it first needs build the ADDR_EXPR from decl of local variable as delete operator always works upon pointer. In case programmer uses register to force variable being placed into register, cxx_mark_addressable will revise the code generated so as to indicate to place this local variable within stack.

 

2866   tree

2867   build_delete (tree type, tree addr, special_function_kind auto_delete,                    in init.c

2868              int flags, int use_global_delete)

2869   {

2870     tree expr;

2871  

2872     if (addr == error_mark_node)

2873       return error_mark_node;

2874  

2875     /* Can happen when CURRENT_EXCEPTION_OBJECT gets its type

2876       set to `error_mark_node' before it gets properly cleaned up.  */

2877     if (type == error_mark_node)

2878       return error_mark_node;

2879  

2880     type = TYPE_MAIN_VARIANT (type);

2881  

2882     if (TREE_CODE (type) == POINTER_TYPE)

2883     {

         

2918     }

2919     else if (TREE_CODE (type) == ARRAY_TYPE)

2920     {

         

2930     }

2931     else

2932     {

2933       /* Don't check PROTECT here; leave that decision to the

2934          destructor. If the destructor is accessible, call it,

2935          else report error.  */

2936       addr = build_unary_op (ADDR_EXPR, addr, 0);

2937       if (TREE_SIDE_EFFECTS (addr))

2938         addr = save_expr (addr);

2939  

2940       addr = convert_force (build_pointer_type (type), addr, 0);

2941     }

2942  

2943     my_friendly_assert (IS_AGGR_TYPE (type), 220);

2944  

2945     if (TYPE_HAS_TRIVIAL_DESTRUCTOR (type))

2946     {

2947       if (auto_delete != sfk_deleting_destructor)

2948         return void_zero_node;

2949  

2950       return build_op_delete_call

2951              (DELETE_EXPR, addr, cxx_sizeof_nowarn (type),

2952               LOOKUP_NORMAL | (use_global_delete * LOOKUP_GLOBAL),

2953               NULL_TREE);

2954     }

2955     else

2956     {

2957       tree do_delete = NULL_TREE;

2958       tree ifexp;

2959  

2960       my_friendly_assert (TYPE_HAS_DESTRUCTOR (type), 20011213);

2961  

2962       /* For `::delete x', we must not use the deleting destructor

2963          since then we would not be sure to get the global `operator

2964          delete'.  */

2965       if (use_global_delete && auto_delete == sfk_deleting_destructor)

2966       {

2967         /* We will use ADDR multiple times so we must save it.  */

2968         addr = save_expr (addr);

2969         /* Delete the object.  */

2970         do_delete = build_builtin_delete_call (addr);

2971         /* Otherwise, treat this like a complete object destructor

2972              call.  */

2973         auto_delete = sfk_complete_destructor;

2974       }

2975       /* If the destructor is non-virtual, there is no deleting

2976         variant. Instead, we must explicitly call the appropriate

2977          `operator delete' here.  */

2978       else if (!DECL_VIRTUAL_P (CLASSTYPE_DESTRUCTORS (type))

2979             && auto_delete == sfk_deleting_destructor)

2980       {

2981          /* We will use ADDR multiple times so we must save it.  */

2982         addr = save_expr (addr);

2983         /* Build the call.  */

2984         do_delete = build_op_delete_call (DELETE_EXPR,

2985                                     addr,

2986                                      cxx_sizeof_nowarn (type),

2987                                     LOOKUP_NORMAL,

2988                                     NULL_TREE);

2989         /* Call the complete object destructor.  */

2990         auto_delete = sfk_complete_destructor;

2991       }

2992       else if (auto_delete == sfk_deleting_destructor

2993             && TYPE_GETS_REG_DELETE (type))

2994       {

2995         /* Make sure we have access to the member op delete, even though

2996            we'll actually be calling it from the destructor.  */

2997         build_op_delete_call (DELETE_EXPR, addr, cxx_sizeof_nowarn (type),

2998                           LOOKUP_NORMAL, NULL_TREE);

2999       }

3000  

3001       expr = build_dtor_call (build_indirect_ref (addr, NULL),

3002                            auto_delete, flags);

3003       if (do_delete)

3004         expr = build (COMPOUND_EXPR, void_type_node, expr, do_delete);

3005  

3006       if (flags & LOOKUP_DESTRUCTOR)

3007         /* Explicit destructor call; don't check for null pointer.  */

3008         ifexp = integer_one_node;

3009       else

3010         /* Handle deleting a null pointer.  */

3011         ifexp = fold (cp_build_binary_op (NE_EXPR, addr, integer_zero_node));

3012  

3013       if (ifexp != integer_one_node)

3014         expr = build (COND_EXPR, void_type_node,

3015                    ifexp, expr, void_zero_node);

3016  

3017       return expr;

3018     }

3019   }

 

Indicator sfk_complete_destructor means destory the object but not claim the memory, and sfk_deleting_destructor requires to take back the memory of the object. If type is a class, delete operator can be overloaded within it (predicate TYPE_GETS_REG_DELETE at line 2993 tells it).

There is a special treatment for trivial destructor at line 2945. Note that this function is not only invoked to cleanup local variable getting out of its binding scope, but invoked to release object allocated upon heap by delete expression. If no memory needs be taken back, nothing will be done (void_zero_node returned instead), otherwise only builds nodes for delete expression (the class may overload delete operator, build_op_delete_call will find out the appropriate operator to use).

Then before invoking build_dtor_call at line 3001, argument auto_delete should be setup appropriately first. See it is set as sfk_complete_destructor at line 2973 and 2990 which will indicate build_dtor_call to find a destructor that destories the whole object including virtual bases, but doesn’t delete the object. And at same time do_delete refers to the delete expression. Note that predicate TYPE_GETS_REG_DELETE only tells if there is overrided delete operator within the heirarchy tree; it may be defined in base, and if this delete operator is declared as private, it is not accessible from its derived classes, so at line 2997, build_op_delete_call will do this checking.

Back in cxx_maybe_build_cleanup , if a class contains virutal bases but doesn’t define destructor, it would not destory these virtual bases. But it must, so the corresponding destructing operation is constructed by build_vbase_delete at line 11243.

 

3108   tree

3109   build_vbase_delete (tree type, tree decl)                                                             in init.c

3110   {

3111     tree vbases = CLASSTYPE_VBASECLASSES (type);

3112     tree result;

3113     tree addr = build_unary_op (ADDR_EXPR, decl, 0);

3114  

3115     my_friendly_assert (addr != error_mark_node, 222);

3116  

3117     for (result = convert_to_void (integer_zero_node, NULL);

3118         vbases; vbases = TREE_CHAIN (vbases))

3119     {

3120       tree base_addr = convert_force

3121             (build_pointer_type (BINFO_TYPE (TREE_VALUE (vbases))), addr, 0);

3122       tree base_delete = build_delete

3123              TREE_TYPE (base_addr), base_addr, sfk_base_destructor,

3124              LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0);

3125        

3126       result = build_compound_expr (result, base_delete);

3127     }

3128     return result;

3129   }

 

See again, if we don’t define the destructors or the destructors are trivial, nothing will be generated for us except the memory reclaiming action. And if something is generated, it is built in a CLEANUP_STMT and inserted into statement tree under constructing.

 

1164   void

1165   finish_decl_cleanup (tree decl, tree cleanup)                                        in semantics.c

1166   {

1167     add_stmt (build_stmt (CLEANUP_STMT, decl, cleanup));

1168   }

 

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:670101次
    • 积分:13066
    • 等级:
    • 排名:第1014名
    • 原创:578篇
    • 转载:0篇
    • 译文:78篇
    • 评论:47条
    最新评论