5.12.5.2.2.2.1.3.2. Instantiate base class – finish
After processing the bases (they are chained tegother), in instantiate_class_template at line 5452, xref_basetype is called to fill the binfo part, in which parameter ref is the RECORD_TYPE of the derived, and base_list contains the RECORD_TYPE of the bases and their accessbility.
The RECORD_TYPE of base is incomplete as the type field is empty, so it needs be completed first by complete_type_or_else at line 9645 in xref_basetype .
4210 #define complete_type_or_else (T,V) (complete_type_or_diagnostic ((T), (V), 0))
147 tree
148 complete_type_or_diagnostic (tree type, tree value, int diag_type) in typeck.c
149 {
150 type = complete_type (type);
151 if (type == error_mark_node)
152 /* We already issued an error. */
153 return NULL_TREE;
154 else if (!COMPLETE_TYPE_P (type))
155 {
156 cxx_incomplete_type_diagnostic (value, type, diag_type);
157 return NULL_TREE;
158 }
159 else
160 return type;
161 }
See complete_type is recursed at the beginning the function (we come here inside the complete_type called for the derived), in which also calls instantiate_class_template to instantiate the base. If the base also derives from certain template class, this procedure would be repeated till arrives at the bottom template class (we just see the first part of the instantiating, in the rear part the template will invoke finish_struct to complete its RECORD_TYPE), or the bottom non-template class (such type has invoked finsih_struct , its RECORD_TYPE is complete). Here we just skip the detail of the handling of the base class in complete_type and assume this node of RECORD_TYPE is completed after that.
The detail of xref_basetype can be seen in previous section, for our case, real deep copy is executed as base class is a node of RECORD_TYPE. And it gets following layout.
(Click here for open )
5.12.5.2.2.2.1.3.3. Finish the derived RECORD_TYPE –members subsititution
Now the instantiation of base class is ready, and the binfo of the derived is setup, following it needs fill in the member of the class as type here is an empty RECORD_TYPE for the instantiation. Further the member of the derived class as some of them may depend on the template parameters, so they need be subsitituted by the arguments too. It’s worth our attention to see how to generate these types. The function though is lengthy but quite straight forward.
instantiate_class_template (continue)
5458 /* Now that our base classes are set up, enter the scope of the
5459 class, so that name lookups into base classes, etc. will work
5460 correctly. This is precisely analogous to what we do in
5461 begin_class_definition when defining an ordinary non-template
5462 class. */
5463 pushclass (type);
5464
5465 /* Now members are processed in the order of declaration. */
5466 for (member = CLASSTYPE_DECL_LIST (pattern);
5467 member; member = TREE_CHAIN (member))
5468 {
5469 tree t = TREE_VALUE (member);
5470
5471 if (TREE_PURPOSE (member))
5472 {
5473 if (TYPE_P (t))
5474 {
5475 /* Build new CLASSTYPE_NESTED_UTDS. */
5476
5477 tree tag = t;
5478 tree name = TYPE_IDENTIFIER (tag);
5479 tree newtag;
5480 bool class_template_p;
5481
5482 class_template_p = (TREE_CODE (tag) != ENUMERAL_TYPE
5483 && TYPE_LANG_SPECIFIC (tag)
5484 && CLASSTYPE_IS_TEMPLATE (tag));
5485 /* If the member is a class template, then -- even after
5486 substituition -- there may be dependent types in the
5487 template argument list for the class. We increment
5488 PROCESSING_TEMPLATE_DECL so that dependent_type_p, as
5489 that function will assume that no types are dependent
5490 when outside of a template. */
5491 if (class_template_p)
5492 ++processing_template_decl;
5493 newtag = tsubst (tag, args, tf_error, NULL_TREE);
5494 if (class_template_p)
5495 --processing_template_decl;
5496 if (newtag == error_mark_node)
5497 continue ;
5498
5499 if (TREE_CODE (newtag) != ENUMERAL_TYPE)
5500 {
5501 if (class_template_p)
5502 /* Unfortunately, lookup_template_class sets
5503 CLASSTYPE_IMPLICIT_INSTANTIATION for a partial
5504 instantiation (i.e., for the type of a member
5505 template class nested within a template class.)
5506 This behavior is required for
5507 maybe_process_partial_specialization to work
5508 correctly, but is not accurate in this case;
5509 the TAG is not an instantiation of anything.
5510 (The corresponding TEMPLATE_DECL is an
5511 instantiation, but the TYPE is not.) */
5512 CLASSTYPE_USE_TEMPLATE (newtag) = 0;
5513
5514 /* Now, we call pushtag to put this NEWTAG into the scope of
5515 TYPE. We first set up the IDENTIFIER_TYPE_VALUE to avoid
5516 pushtag calling push_template_decl. We don't have to do
5517 this for enums because it will already have been done in
5518 tsubst_enum. */
5519 if (name)
5520 SET_IDENTIFIER_TYPE_VALUE (name, newtag);
5521 pushtag (name, newtag, /*globalize=*/ 0);
5522 }
5523 } // end if (TYPE_P (t))
5524 else if (TREE_CODE (t) == FUNCTION_DECL
5525 || DECL_FUNCTION_TEMPLATE_P (t))
5526 {
5527 /* Build new TYPE_METHODS. */
5528 tree r;
5529
5530 if (TREE_CODE (t) == TEMPLATE_DECL)
5531 ++processing_template_decl;
5532 r = tsubst (t, args, tf_error, NULL_TREE);
5533 if (TREE_CODE (t) == TEMPLATE_DECL)
5534 --processing_template_decl;
5535 set_current_access_from_decl (r);
5536 grok_special_member_properties (r);
5537 finish_member_declaration (r);
5538 }
5539 else
5540 {
5541 /* Build new TYPE_FIELDS. */
5542
5543 if (TREE_CODE (t) != CONST_DECL)
5544 {
5545 tree r;
5546
5547 /* The the file and line for this declaration, to
5548 assist in error message reporting. Since we
5549 called push_tinst_level above, we don't need to
5550 restore these. */
5551 input_location = DECL_SOURCE_LOCATION (t);
5552
5553 if (TREE_CODE (t) == TEMPLATE_DECL)
5554 ++processing_template_decl;
5555 r = tsubst (t, args, tf_error | tf_warning, NULL_TREE);
5556 if (TREE_CODE (t) == TEMPLATE_DECL)
5557 --processing_template_decl;
5558 if (TREE_CODE (r) == VAR_DECL)
5559 {
5560 tree init;
5561
5562 if (DECL_INITIALIZED_IN_CLASS_P (r))
5563 init = tsubst_expr (DECL_INITIAL (t), args,
5564 tf_error | tf_warning, NULL_TREE);
5565 else
5566 init = NULL_TREE;
5567
5568 finish_static_data_member_decl
5569 (r, init, /*asmspec_tree=*/ NULL_TREE, /*flags=*/ 0);
5570
5571 if (DECL_INITIALIZED_IN_CLASS_P (r))
5572 check_static_variable_definition (r, TREE_TYPE (r));
5573 }
5574 else if (TREE_CODE (r) == FIELD_DECL)
5575 {
5576 /* Determine whether R has a valid type and can be
5577 completed later. If R is invalid, then it is
5578 replaced by error_mark_node so that it will not be
5579 added to TYPE_FIELDS. */
5580 tree rtype = TREE_TYPE (r);
5581 if (can_complete_type_without_circularity (rtype))
5582 complete_type (rtype);
5583
5584 if (!COMPLETE_TYPE_P (rtype))
5585 {
5586 cxx_incomplete_type_error (r, rtype);
5587 r = error_mark_node;
5588 }
5589 }
5590
5591 /* If it is a TYPE_DECL for a class-scoped ENUMERAL_TYPE,
5592 such a thing will already have been added to the field
5593 list by tsubst_enum in finish_member_declaration in the
5594 CLASSTYPE_NESTED_UTDS case above. */
5595 if (!(TREE_CODE (r) == TYPE_DECL
5596 && TREE_CODE (TREE_TYPE (r)) == ENUMERAL_TYPE
5597 && DECL_ARTIFICIAL (r)))
5598 {
5599 set_current_access_from_decl (r);
5600 finish_member_declaration (r);
5601 }
5602 }
5603 }
5604 } // if (TREE_PURPOSE (member))
5605 else
5606 {
5607 if (TYPE_P (t) || DECL_CLASS_TEMPLATE_P (t))
5608 {
5609 /* Build new CLASSTYPE_FRIEND_CLASSES. */
5610
5611 tree friend_type = t;
5612 tree new_friend_type;
5613
5614 if (TREE_CODE (friend_type) == TEMPLATE_DECL)
5615 new_friend_type = tsubst_friend_class (friend_type, args);
5616 else if (uses_template_parms (friend_type))
5617 new_friend_type = tsubst (friend_type, args,
5618 tf_error | tf_warning, NULL_TREE);
5619 else if (CLASSTYPE_USE_TEMPLATE (friend_type))
5620 new_friend_type = friend_type;
5621 else
5622 {
5623 tree ns = decl_namespace_context (TYPE_MAIN_DECL (friend_type));
5624
5625 /* The call to xref_tag_from_type does injection for friend
5626 classes. */
5627 push_nested_namespace (ns);
5628 new_friend_type =
5629 xref_tag_from_type (friend_type, NULL_TREE, 1);
5630 pop_nested_namespace (ns);
5631 }
5632
5633 if (TREE_CODE (friend_type) == TEMPLATE_DECL)
5634 /* Trick make_friend_class into realizing that the friend
5635 we're adding is a template, not an ordinary class. It's
5636 important that we use make_friend_class since it will
5637 perform some error-checking and output cross-reference
5638 information. */
5639 ++processing_template_decl;
5640
5641 if (new_friend_type != error_mark_node)
5642 make_friend_class (type, new_friend_type,
5643 /*complain=*/ false);
5644
5645 if (TREE_CODE (friend_type) == TEMPLATE_DECL)
5646 --processing_template_decl;
5647 }
5648 else
5649 {
5650 /* Build new DECL_FRIENDLIST. */
5651 tree r;
5652
5653 if (TREE_CODE (t) == TEMPLATE_DECL)
5654 ++processing_template_decl;
5655 r = tsubst_friend_function (t, args);
5656 if (TREE_CODE (t) == TEMPLATE_DECL)
5657 --processing_template_decl;
5658 add_friend (type, r, /*complain=*/ false);
5659 }
5660 }
5661 }
5662
5663 /* Set the file and line number information to whatever is given for
5664 the class itself. This puts error messages involving generated
5665 implicit functions at a predictable point, and the same point
5666 that would be used for non-template classes. */
5667 typedecl = TYPE_MAIN_DECL (type);
5668 input_location = DECL_SOURCE_LOCATION (typedecl);
5669
5670 unreverse_member_declarations (type);
5671 finish_struct_1 (type);
Notice that members declared within the class are recorded by node of tree_list and chained in field of CLASSTYPE_DECL_LIST. In the tree_list node, TREE_PURPOSE field records the class it belongs to (and NULL if it is the friend declaration), and TREE_VALUE field holds the declaration itself.
Also see in previous sections, entities declared within the class template are considered as template declarations too, with TEMPLATE_DECL generated. During instantiation, the real template arguments should substitute the template parameters.
5.12.5.2.2.2.1.3.4. Finish the derived RECORD_TYPE – fixup inline methods
As RECORD_TYPE for the class template instantiation is a normal class, at line 5671 finish_struct_1 must be invoked to finish the definition.
4997 void
4998 finish_struct_1 (tree t) in class.c
4999 {
5001 tree x;
5002 /* A TREE_LIST. The TREE_VALUE of each node is a FUNCTION_DECL. */
5003 tree virtuals = NULL_TREE;
5004 int n_fields = 0;
5005 tree vfield;
5006
5007 if (COMPLETE_TYPE_P (t))
5008 {
5009 if (IS_AGGR_TYPE (t))
5010 error ("redefinition of `%#T'", t);
5011 else
5012 abort ();
5013 popclass ();
5014 return ;
5015 }
5016
5017 /* If this type was previously laid out as a forward reference,
5018 make sure we lay it out again. */
5019 TYPE_SIZE (t) = NULL_TREE;
5020 CLASSTYPE_PRIMARY_BINFO (t) = NULL_TREE;
5021
5022 fixup_inline_methods (t);
5023
5024 /* Make assumptions about the class; we'll reset the flags if
5025 necessary. */
5026 CLASSTYPE_EMPTY_P (t) = 1;
5027 CLASSTYPE_NEARLY_EMPTY_P (t) = 1;
5028 CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 0;
5029
5030 /* Do end-of-class semantic processing: checking the validity of the
5031 bases and members and add implicitly generated methods. */
5032 check_bases_and_members (t);
Also, remember that for inline method, the associated FUNCTION_DECL node has its template_info field filled with the template information. The member subsititution above subsititues the arguments for methods appropriately, but some relations are still not updated accordingly.
4323 static void
4324 fixup_inline_methods (tree type) in class.
4325 {
4326 tree method = TYPE_METHODS (type);
4327
4328 if (method && TREE_CODE (method) == TREE_VEC)
4329 {
4330 if (TREE_VEC_ELT (method, 1))
4331 method = TREE_VEC_ELT (method, 1);
4332 else if (TREE_VEC_ELT (method, 0))
4333 method = TREE_VEC_ELT (method, 0);
4334 else
4335 method = TREE_VEC_ELT (method, 2);
4336 }
4337
4338 /* Do inline member functions. */
4339 for (; method; method = TREE_CHAIN (method))
4340 fixup_pending_inline (method);
4341
4342 /* Do friends. */
4343 for (method = CLASSTYPE_INLINE_FRIENDS (type);
4344 method;
4345 method = TREE_CHAIN (method))
4346 fixup_pending_inline (TREE_VALUE (method));
4347 CLASSTYPE_INLINE_FRIENDS (type) = NULL_TREE;
4348 }
Remember the body of inline method is cached within DECL_PENDING_INLINE_INFO. For arguments of the inline method, they have been subsititued with those at instantiating, but the context field remains untouched, it needs updated for the inline method after subsititution (the new nodes created).
4306 static void
4307 fixup_pending_inline (tree fn) in class.
4308 {
4309 if (DECL_PENDING_INLINE_INFO (fn))
4310 {
4311 tree args = DECL_ARGUMENTS (fn);
4312 while (args)
4313 {
4314 DECL_CONTEXT (args) = fn;
4315 args = TREE_CHAIN (args);
4316 }
4317 }
4318 }
5.12.5.2.2.2.1.3.5. Finish the derived RECORD_TYPE – verify base classes
At this point, the base class, and the members are subsitituted with argument appropriately, but no semantic checking at the class level is performed for the template instantiation. This semantic checking should be taken as soon as possible. Here is the most early point the semantic checking can be performed.
4145 static void
4146 check_bases_and_members (tree t) in class.c
4147 {
4148 /* Nonzero if we are not allowed to generate a default constructor
4149 for this case. */
4150 int cant_have_default_ctor;
4151 /* Nonzero if the implicitly generated copy constructor should take
4152 a non-const reference argument. */
4153 int cant_have_const_ctor;
4154 /* Nonzero if the the implicitly generated assignment operator
4155 should take a non-const reference argument. */
4156 int no_const_asn_ref;
4157 tree access_decls;
4158
4159 /* By default, we use const reference arguments and generate default
4160 constructors. */
4161 cant_have_default_ctor = 0;
4162 cant_have_const_ctor = 0;
4163 no_const_asn_ref = 0;
4164
4165 /* Check all the base-classes. */
4166 check_bases (t, &cant_have_default_ctor, &cant_have_const_ctor,
4167 &no_const_asn_ref);
If the class template contains (derives) base classes (remember the base classes may be class template too, see our example of “SmallObject”), it is time to see there is any flaw between the class and the base classes.
1109 static void
1110 check_bases (tree t, in class.c
1111 int* cant_have_default_ctor_p,
1112 int* cant_have_const_ctor_p,
1113 int* no_const_asn_ref_p)
1114 {
1115 int n_baseclasses;
1116 int i;
1117 int seen_non_virtual_nearly_empty_base_p;
1118 tree binfos;
1119
1120 binfos = TYPE_BINFO_BASETYPES (t);
1121 n_baseclasses = CLASSTYPE_N_BASECLASSES (t);
1122 seen_non_virtual_nearly_empty_base_p = 0;
1123
1124 /* An aggregate cannot have baseclasses. */
1125 CLASSTYPE_NON_AGGREGATE (t) |= (n_baseclasses != 0);
1126
1127 for (i = 0; i < n_baseclasses; ++i)
1128 {
1129 tree base_binfo;
1130 tree basetype;
1131
1132 /* Figure out what base we're looking at. */
1133 base_binfo = TREE_VEC_ELT (binfos, i);
1134 basetype = TREE_TYPE (base_binfo);
1135
1136 /* If the type of basetype is incomplete, then we already
1137 complained about that fact (and we should have fixed it up as
1138 well). */
1139 if (!COMPLETE_TYPE_P (basetype))
1140 {
1141 int j;
1142 /* The base type is of incomplete type. It is
1143 probably best to pretend that it does not
1144 exist. */
1145 if (i == n_baseclasses-1)
1146 TREE_VEC_ELT (binfos, i) = NULL_TREE;
1147 TREE_VEC_LENGTH (binfos) -= 1;
1148 n_baseclasses -= 1;
1149 for (j = i; j+1 < n_baseclasses; j++)
1150 TREE_VEC_ELT (binfos, j) = TREE_VEC_ELT (binfos, j+1);
1151 continue ;
1152 }
1153
1154 /* Effective C++ rule 14. We only need to check TYPE_POLYMORPHIC_P
1155 here because the case of virtual functions but non-virtual
1156 dtor is handled in finish_struct_1. */
1157 if (warn_ecpp && ! TYPE_POLYMORPHIC_P (basetype)
1158 && TYPE_HAS_DESTRUCTOR (basetype))
1159 warning ("base class `%#T' has a non-virtual destructor",
1160 basetype);
1161
1162 /* If the base class doesn't have copy constructors or
1163 assignment operators that take const references, then the
1164 derived class cannot have such a member automatically
1165 generated. */
1166 if (! TYPE_HAS_CONST_INIT_REF (basetype))
1167 *cant_have_const_ctor_p = 1;
1168 if (TYPE_HAS_ASSIGN_REF (basetype)
1169 && !TYPE_HAS_CONST_ASSIGN_REF (basetype))
1170 *no_const_asn_ref_p = 1;
1171 /* Similarly, if the base class doesn't have a default
1172 constructor, then the derived class won't have an
1173 automatically generated default constructor. */
1174 if (TYPE_HAS_CONSTRUCTOR (basetype)
1175 && ! TYPE_HAS_DEFAULT_CONSTRUCTOR (basetype))
1176 {
1177 *cant_have_default_ctor_p = 1;
1178 if (! TYPE_HAS_CONSTRUCTOR (t))
1179 pedwarn ("base `%T' with only non-default constructor in class without a constructor",
1180 basetype);
1181 }
1182
1183 if (TREE_VIA_VIRTUAL (base_binfo))
1184 /* A virtual base does not effect nearly emptiness. */
1185 ;
1186 else if (CLASSTYPE_NEARLY_EMPTY_P (basetype))
1187 {
1188 if (seen_non_virtual_nearly_empty_base_p)
1189 /* And if there is more than one nearly empty base, then the
1190 derived class is not nearly empty either. */
1191 CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
1192 else
1193 /* Remember we've seen one. */
1194 seen_non_virtual_nearly_empty_base_p = 1;
1195 }
1196 else if (!is_empty_class (basetype))
1197 /* If the base class is not empty or nearly empty, then this
1198 class cannot be nearly empty. */
1199 CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
1200
1201 /* A lot of properties from the bases also apply to the derived
1202 class. */
1203 TYPE_NEEDS_CONSTRUCTING (t) |= TYPE_NEEDS_CONSTRUCTING (basetype);
1204 TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
1205 |= TYPE_HAS_NONTRIVIAL_DESTRUCTOR (basetype);
1206 TYPE_HAS_COMPLEX_ASSIGN_REF (t)
1207 |= TYPE_HAS_COMPLEX_ASSIGN_REF (basetype);
1208 TYPE_HAS_COMPLEX_INIT_REF (t) |= TYPE_HAS_COMPLEX_INIT_REF (basetype);
1209 TYPE_POLYMORPHIC_P (t) |= TYPE_POLYMORPHIC_P (basetype);
1210 CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t)
1211 |= CLASSTYPE_CONTAINS_EMPTY_CLASS_P (basetype);
1212 }
1213 }
Among the arguments in the invocation, cant_have_default_ctor is nonzero if base classes have no default constructor, cant_have_const_ctor is nonzero if base classes have no copy constructor that takes constant reference, and no_const_asn_ref is nonzero if base classes have no assignment operator that takes constant reference.