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 }