Studying note of GCC-3.4.6 source (135)

来源:互联网 发布:sql 的not in中的为空 编辑:程序博客网 时间:2024/06/05 22:30

5.12.5.2.2.2.1.3.2.           Instantiatebase class – finish

After processing the bases (they are chained tegother), in instantiate_class_templateat line 5452, xref_basetypeis called to fill the binfo part, in which parameter ref is the RECORD_TYPE of thederived, and base_listcontains 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 becompleted 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 alreadyissued an error.  */

153        returnNULL_TREE;

154      else if (!COMPLETE_TYPE_P (type))

155      {

156        cxx_incomplete_type_diagnostic (value,type, diag_type);

157        returnNULL_TREE;

158      }

159      else

160        returntype;

161    }

 

See complete_type is recursed at the beginning the function(we come here inside the complete_type calledfor the derived), in which also calls instantiate_class_template to instantiate thebase. If the base also derives from certain template class, this procedurewould be repeated till arrives at the bottom template class (we just see thefirst part of the instantiating, in the rear part the template will invoke finish_structto complete its RECORD_TYPE), or the bottom non-template class (such type hasinvoked finsih_struct,its RECORD_TYPE is complete). Here we just skip the detail of the handling ofthe base class in complete_type and assume this node ofRECORD_TYPE is completed after that.

The detail of xref_basetypecan be seen in previous section, for our case, real deep copy is executed asbase class is a node of RECORD_TYPE. And it gets following layout.

(Clickhere for open)

5.12.5.2.2.2.1.3.3.           Finish the derivedRECORD_TYPE –members subsititution

Now the instantiation of base class is ready, and the binfo of thederived is setup, following it needs fill in the member of the class as typehere is an empty RECORD_TYPE for the instantiation. Further the member of thederived class as some of them may depend on the template parameters, so theyneed be subsitituted by the arguments too. It’s worth our attention to see howto generate these types. The function though is lengthy but quite straightforward.

 

instantiate_class_template (continue)

 

5458     /* Now that ourbase classes are set up, enter the scope of the

5459       class, so that name lookupsinto base classes, etc. will work

5460       correctly. This is preciselyanalogous to what we do in

5461       begin_class_definition whendefining an ordinary non-template

5462       class.  */

5463     pushclass (type);

5464  

5465     /* Now members areprocessed 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 newCLASSTYPE_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 memberis a class template, then -- even after

5486             substituition -- theremay be dependent types in the

5487             template argument listfor the class. We increment

5488             PROCESSING_TEMPLATE_DECLso that dependent_type_p, as

5489             that function will assume that no typesare dependent

5490             when outside of atemplate.  */

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 classnested within a template class.)

5506                  This behavior isrequired for

5507                 maybe_process_partial_specialization to work

5508                  correctly, but isnot accurate in this case;

5509                  the TAG is not aninstantiation of anything.

5510                 (The correspondingTEMPLATE_DECL is an

5511                  instantiation, butthe TYPE is not.) */

5512               CLASSTYPE_USE_TEMPLATE (newtag) =0;

5513  

5514             /* Now, wecall pushtag to put this NEWTAG into the scope of

5515               TYPE. We first set up theIDENTIFIER_TYPE_VALUE to avoid

5516               pushtag callingpush_template_decl. We don't have to do

5517               this for enums becauseit 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 newTYPE_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 andline for this declaration, to

5548               assist in errormessage reporting. Since we

5549               calledpush_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. IfR is invalid, then it is

5578                 replaced byerror_mark_node so that it will not be

5579                 added toTYPE_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 isa TYPE_DECL for a class-scoped ENUMERAL_TYPE,

5592               such a thing willalready have been added to the field

5593               list by tsubst_enum infinish_member_declaration in the

5594               CLASSTYPE_NESTED_UTDScase 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 newCLASSTYPE_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 callto 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            /* Trickmake_friend_class into realizing that the friend

5635               we're adding is atemplate, not an ordinary class. It's

5636               important that we usemake_friend_class since it will

5637               perform someerror-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 newDECL_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 andline number information to whatever is given for

5664       the class itself. This putserror messages involving generated

5665       implicit functions at apredictable point, and the same point

5666       that would be used fornon-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 nodeof tree_list and chained in field of CLASSTYPE_DECL_LIST. In the tree_listnode, TREE_PURPOSE field records the class it belongs to (and NULL if it is thefriend declaration), and TREE_VALUE field holds the declaration itself.

Also see in previous sections, entities declared within the classtemplate are considered as template declarations too, with TEMPLATE_DECLgenerated. During instantiation, the real template arguments should substitutethe template parameters.

5.12.5.2.2.2.1.3.4.           Finish the derivedRECORD_TYPE – fixup inline methods

As RECORD_TYPE for the class template instantiation is a normalclass, at line 5671 finish_struct_1 must be invoked to finish thedefinition.

 

4997   void

4998   finish_struct_1 (tree t)                                                                             in class.c

4999   {

5001     tree x;

5002    /* A TREE_LIST. TheTREE_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 waspreviously laid out as a forward reference,

5018       make sure we lay it outagain.  */

5019     TYPE_SIZE (t) = NULL_TREE;

5020     CLASSTYPE_PRIMARY_BINFO (t) = NULL_TREE;

5021  

5022     fixup_inline_methods(t);

5023    

5024     /* Make assumptionsabout 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-classsemantic processing: checking the validity of the

5031       bases and members and addimplicitly generated methods.  */

5032     check_bases_and_members(t);

 

Also, remember that for inline method, the associated FUNCTION_DECLnode has its template_infofield filled with the template information. The member subsititution abovesubsititues the arguments for methods appropriately, but some relations arestill 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 memberfunctions.  */

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 withinDECL_PENDING_INLINE_INFO. For arguments of the inline method, they have beensubsititued with those at instantiating, but the context field remains untouched, itneeds updated for the inline method after subsititution (the new nodescreated).

 

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 derivedRECORD_TYPE – verify base classes

At this point, the base class, and the members are subsitituted withargument appropriately, but no semantic checking at the class level isperformed for the template instantiation. This semantic checking should betaken as soon as possible. Here is the most early point the semantic checkingcan be performed.

 

4145   static void

4146   check_bases_and_members (tree t)                                                           in class.c

4147   {

4148     /* Nonzero if weare not allowed to generate a default constructor

4149       for this case.  */

4150     int cant_have_default_ctor;

4151    /* Nonzero if theimplicitly generated copy constructor should take

4152       a non-const reference argument.  */

4153     int cant_have_const_ctor;

4154     /* Nonzero if thethe implicitly generated assignment operator

4155       should take a non-constreference argument.  */

4156     int no_const_asn_ref;

4157     tree access_decls;

4158  

4159     /* By default, weuse 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 thebase-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 thebase classes may be class template too, see our example of “SmallObject”), itis 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 aggregatecannot 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 outwhat base we're looking at.  */

1133      base_binfo = TREE_VEC_ELT (binfos, i);

1134       basetype = TREE_TYPE (base_binfo);

1135  

1136       /* If the type ofbasetype 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 pretendthat 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 ofvirtual functions but non-virtual

1156         dtor is handled infinish_struct_1.  */

1157       if (warn_ecpp && ! TYPE_POLYMORPHIC_P(basetype)

1158          && TYPE_HAS_DESTRUCTOR(basetype))

1159         warning ("base class `%#T' has anon-virtual destructor",

1160                  basetype);

1161  

1162       /* If the baseclass doesn't have copy constructors or

1163         assignment operators thattake const references, then the

1164         derived class cannot have sucha 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, ifthe base class doesn't have a default

1172         constructor, then thederived class won't have an

1173         automatically generateddefault 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 virtualbase 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 ifthere is more than one nearly empty base, then the

1190             derived class is notnearly empty either.  */

1191           CLASSTYPE_NEARLY_EMPTY_P (t) = 0;

1192         else

1193           /* Rememberwe've seen one.  */

1194           seen_non_virtual_nearly_empty_base_p =1;

1195       }

1196       else if (!is_empty_class (basetype))

1197         /* If the baseclass is not empty or nearly empty, then this

1198           class cannot be nearlyempty.  */

1199         CLASSTYPE_NEARLY_EMPTY_P (t) = 0;

1200  

1201       /* A lot ofproperties 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 ifbase classes have no default constructor, cant_have_const_ctor is nonzero if base classeshave no copy constructor that takes constant reference, and no_const_asn_refis nonzero if base classes have no assignment operator that takes constantreference.

 

原创粉丝点击