Studying note of GCC-3.4.6 source (135)

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.

 

你可能感兴趣的:(tree,Class,processing,Constructor,destructor,Instantiation)