Studying note of GCC-3.4.6 source (131)

5.12.5.2.2.2.1.1.2.            Replace rest default arguments

The second parameter is the node pointed by the red pointer in below figure. As the third parameter is similar, we just skip it in below.

(Click here for open )

Then at line 3835 in coerce_template_parms , when invoking tsubst_template_arg , node of tree_list referred by the purpose field of the second parameter above is passed as first argument. Within tsubst_template_arg , tsubst_expr is called, which invokes tsubst_copy_and_build for non-statement. Then in tsubst_copy_and_build , tsubst_copy is invoked and returns the node of INTEGER_CST kept in the purpose field. And this node is returned up to tsubst_template_arg .

Then convert_template_argument is invoked to generate appropriate argument. Here parm is the node referred by value field and arg is the purpose field of the tree_list pointed by the red pointer in above figure.

 

3636   static tree

3637   convert_template_argument (tree parm,                                                            in pt.c

3638                           tree arg,

3639                           tree args,

3640                           tsubst_flags_t complain,

3641                           int i,

3642                           tree in_decl)

3643   {

3644     tree val;

3645     tree inner_args;

3646     int is_type, requires_type, is_tmpl_type, requires_tmpl_type;

3647    

3648     inner_args = INNERMOST_TEMPLATE_ARGS (args);

 

3722     if (is_type)

3723     {

         

3762     }

3763     else

3764     {

3765       tree t = tsubst (TREE_TYPE (parm), args, complain, in_decl);

3766  

3767       if (invalid_nontype_parm_type_p (t, complain))

3768         return error_mark_node;

3769        

3770       if (!uses_template_parms (arg) && !uses_template_parms (t))

3771         /* We used to call digest_init here. However, digest_init

3772           will report errors, which we don't want when complain

3773           is zero. More importantly, digest_init will try too

3774           hard to convert things: for example, `0' should not be

3775           converted to pointer type at this point according to

3776           the standard. Accepting this is not merely an

3777           extension, since deciding whether or not these

3778           conversions can occur is part of determining which

3779           function template to call, or whether a given explicit

3780           argument specification is valid.  */

3781         val = convert_nontype_argument (t, arg);

3782       else

3783         val = arg;

3784  

3785       if (val == NULL_TREE)

3786         val = error_mark_node;

3787       else if (val == error_mark_node && (complain & tf_error))

3788         error ("could not convert template argument `%E' to `%T'",

3789               arg, t);

3790     }

3791  

3792     return val;

3793   }

 

TREE_TYPE of parm is the node of INTEGER_TYPE which is returned by tsubst without processing, and as arg points to node of INTEGER_CST, convert_nontype_argument at line 3781 can’t simplify arg any more. So as last we just get the node pointed by arg as the final argument.

5.12.5.2.2.2.1.1.3.            Generate the nodes

Below template_type refers to the node of RECORD_TYPE of “SmallObject”, and arglist is the tree_vec in below (the third argument is omitted).

(Click here for open )

 

lookup_template_class (continue)

 

4356       /* In the scope of a template class, explicit references to the

4357         template class refer to the type of the template, not any

4358         instantiation of it. For example, in:

4359       

4360         template <class T> class C { void f(C<T>); }

4361  

4362         the `C<T>' is just the same as `C'. Outside of the

4363         class, however, such a reference is an instantiation.  */

4364       if (comp_template_args (TYPE_TI_ARGS (template_type),

4365                           arglist))

4366       {

4367         found = template_type;

4368         

4369         if (!entering_scope && PRIMARY_TEMPLATE_P (template))

4370         {

4371           tree ctx;

4372             

4373           for (ctx = current_class_type ;

4374               ctx && TREE_CODE (ctx) != NAMESPACE_DECL;

4375               ctx = (TYPE_P (ctx)

4376                     ? TYPE_CONTEXT (ctx)

4377                     : DECL_CONTEXT (ctx)))

4378             if (TYPE_P (ctx) && same_type_p (ctx, template_type))

4379               goto found_ctx;

4380             

4381           /* We're not in the scope of the class, so the

4382             TEMPLATE_TYPE is not the type we want after all.  */

4383           found = NULL_TREE;

4384       found_ctx:;

4385         }

4386       }

4387       if (found)

4388         POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, found);

 

The comment above explains the purpose of above code clearly. For the example given in the comment, method f is also built with TEMPLATE_DECL, but as it is method of template class, its parameter-list is generated by current_template_args . And parameter of f “C<T>” is a template-id. No doubt, this argument-list “T” is the same as its enclosing template class parameter-list.

First comp_template_args ensures both lists are same. Further entering_scope at line 4369 is nonzero only when we are about to enter the scope of the class we are looking up (then at f’s processing, it is 0). So FOR block at line 4373 verifies that template_type is the enclosing one. If so, it is the type we are looking for.

 

3899   int

3900   comp_template_args (tree oldargs, tree newargs)                                              in pt.c

3901   {

3902     int ;

3903  

3904     if (TREE_VEC_LENGTH (oldargs) != TREE_VEC_LENGTH (newargs))

3905       return 0;

3906  

3907     for (i = 0; i < TREE_VEC_LENGTH (oldargs); ++i)

3908     {

3909       tree nt = TREE_VEC_ELT (newargs, i);

3910       tree ot = TREE_VEC_ELT (oldargs, i);

3911  

3912       if (! template_args_equal (ot, nt))

3913         return 0;

3914     }

3915     return 1;

3916   }

 

Checking the equation of the template parameter follows the same way of checking equation between tree nodes.

 

3879   static int

3880   template_args_equal (tree ot, tree nt)                                                                 in pt.c

3881   {

3882     if (nt == ot)

3883       return 1;

3884  

3885     if (TREE_CODE (nt) == TREE_VEC)

3886       /* For member templates */

3887       return TREE_CODE (ot) == TREE_VEC && comp_template_args (ot, nt);

3888     else if (TYPE_P (nt))

3889       return TYPE_P (ot) && same_type_p (ot, nt);

3890     else if (TREE_CODE (ot) == TREE_VEC || TYPE_P (ot))

3891       return 0;

3892     else

3893       return cp_tree_equal (ot, nt);

3894   }

 

Above code handles non-instantiation case, closes at the return statement at line 4388. Then for instantation case, it first needs to check if such instantation has been processed (it was recorded within chain of DECL_TEMPLATE_INSTANTIATIONS as soon as processed).

 

lookup_template_class (continue)

 

4390       for (tp = &DECL_TEMPLATE_INSTANTIATIONS (template);

4391          *tp;

4392          tp = &TREE_CHAIN (*tp))

4393         if (comp_template_args (TREE_PURPOSE (*tp), arglist))

4394         {

             

4405         }

4406  

4407       /* This type is a "partial instantiation" if any of the template

4408         arguments still involve template parameters. Note that we set

4409         IS_PARTIAL_INSTANTIATION for partial specializations as

4410         well.  */

4411       is_partial_instantiation = uses_template_parms (arglist);

4412  

4413       /* If the deduced arguments are invalid, then the binding

4414         failed.  */

4415       if (!is_partial_instantiation

4416          && check_instantiated_args (template,

4417                                  INNERMOST_TEMPLATE_ARGS (arglist),

4418                                  complain))

4419         POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);

4420       

4421       if (!is_partial_instantiation

4422          && !PRIMARY_TEMPLATE_P (template)

4423          && TREE_CODE (CP_DECL_CONTEXT (template)) == NAMESPACE_DECL)

4424       {

           

4429       }

4430        

4431       context = tsubst (DECL_CONTEXT (template), arglist,

4432                     complain, in_decl);

4433       if (!context)

4434         context = global_namespace ;

 

At line 4412, uses_template_args returns 0 to indicate a template instantiation. At instantiation, for type-parameter, it must not be variable size one, as statement likes:

struct S { int i[f()]; }

is valid in GNU C. While for non-type parameter, it must be an integer or enum constant. This condition is verified by check_instantiated_args .

 

8705   static bool

8706   check_instantiated_args (tree tmpl, tree args, tsubst_flags_t complain)                in pt.c

8707   {

8708     int ix, len = DECL_NTPARMS (tmpl);

8709     bool result = false;

8710  

8711     for (ix = 0; ix != len; ix++)

8712     {

8713       tree t = TREE_VEC_ELT (args, ix);

8714      

8715       if (TYPE_P (t))

8716       {

8717          /* [basic.link]: A name with no linkage (notably, the name

8718           of a class or enumeration declared in a local scope)

8719           shall not be used to declare an entity with linkage.

8720           This implies that names with no linkage cannot be used as

8721           template arguments.  */

8722         tree nt = no_linkage_check (t);

8723  

8724         if (nt)

8725         {

8726           if (!(complain & tf_error))

8727              /*OK*/;

8728           else if (TYPE_ANONYMOUS_P (nt))

8729             error ("`%T' uses anonymous type", t);

8730           else

8731             error ("`%T' uses local type `%T'", t, nt);

8732           result = true;

8733         }

8734         /* In order to avoid all sorts of complications, we do not

8735           allow variably-modified types as template arguments.  */

8736         else if (variably_modified_type_p (t))

8737         {

8738           if (complain & tf_error)

8739             error ("`%T' is a variably modified type", t);

8740           result = true;

8741         }

8742       }

8743       /* A non-type argument of integral or enumerated type must be a

8744         constant.  */

8745       else if (TREE_TYPE (t)

8746             && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (t))

8747             && !TREE_CONSTANT (t))

8748       {

8749         if (complain & tf_error)

8750           error ("integral expression `%E' is not constant", t);

8751         result = true;

8752       }

8753     }

8754     if (result && complain & tf_error)

8755       error ("  trying to instantiate `%D'", tmpl);

8756     return result;

8757   }

 

At line 8722 no_linkage_check returns a type that depends on a type with no linkage; otherwise returns NULL. And for such type, it can’t be used as template inistantiated argument. Whether a type has variable size is checked by variably_modified_type_p as below.

 

4316   bool

4317   variably_modified_type_p (tree type)                                                                in tree.c

4318   {

4319     tree t;

4320  

4321     if (type == error_mark_node)

4322       return false;

4323  

4324     /* If TYPE itself has variable size, it is variably modified.

4325  

4326       We do not yet have a representation of the C99 '[*]' syntax.

4327       When a representation is chosen, this function should be modified

4328       to test for that case as well.  */

4329     t = TYPE_SIZE (type);

4330     if (t && t != error_mark_node && TREE_CODE (t) != INTEGER_CST)

4331       return true;

4332  

4333     switch (TREE_CODE (type))

4334     {

4335       case POINTER_TYPE:

4336       case REFERENCE_TYPE:

4337       case ARRAY_TYPE:

4338         /* If TYPE is a pointer or reference, it is variably modified if

4339            the type pointed to is variably modified. Similarly for arrays;

4340            note that VLAs are handled by the TYPE_SIZE check above.  */

4341         return variably_modified_type_p (TREE_TYPE (type));

4342  

4343       case FUNCTION_TYPE:

4344       case METHOD_TYPE:

4345         /* If TYPE is a function type, it is variably modified if any of the

4346           parameters or the return type are variably modified.  */

4347         {

4348           tree parm;

4349  

4350           if (variably_modified_type_p (TREE_TYPE (type)))

4351             return true;

4352           for (parm = TYPE_ARG_TYPES (type);

4353               parm && parm != void_list_node;

4354               parm = TREE_CHAIN (parm))

4355             if (variably_modified_type_p (TREE_VALUE (parm)))

4356               return true;

4357         }

4358         break ;

4359  

4360       case INTEGER_TYPE:

4361          /* Scalar types are variably modified if their end points

4362           aren't constant.  */

4363          t = TYPE_MIN_VALUE (type);

4364         if (t && t != error_mark_node && TREE_CODE (t) != INTEGER_CST)

4365           return true;

4366         t = TYPE_MAX_VALUE (type);

4367         if (t && t != error_mark_node && TREE_CODE (t) != INTEGER_CST)

4368           return true;

4369         return false;

4370  

4371       default :

4372         break ;

4373     }

4374  

4375     /* The current language may have other cases to check, but in general,

4376       all other types are not variably modified.  */

4377     return (*lang_hooks .tree_inlining.var_mod_type_p ) (type);

4378   }

 

Whether a type has variable size is indicated by its TYPE_SIZE field. If this field is an INTEGER_CST it is the invariable size type. So for types may contain variable size type, they need be looked into level by level. For C++ language, method is the extra type needs be considered, hook var_mod_type_p at line 4377 covers the case for the language. And it invokes cp_var_mod_type_p in below.

 

381    static bool

382    cp_var_mod_type_p (tree type)                                                                       in cp-lang.c

383    {

384      /* If TYPE is a pointer-to-member, it is variably modified if either

385        the class or the member are variably modified.  */

386      if (TYPE_PTR_TO_MEMBER_P (type))

387        return (variably_modified_type_p (TYPE_PTRMEM_CLASS_TYPE (type))

388              || variably_modified_type_p(TYPE_PTRMEM_POINTED_TO_TYPE (type)));

389   

390      /* All other types are not variably modified.  */

391      return false;

392    }

 

For the template instantiation arguments of our case, they pass the test successfully.

At line 4431, template refers to the TEMPLATE_DECL of “SmallObject” which is contained within namespace “Loki”. So tsubst at line 4431 just returns the NAMESPACE_DECL without handling.

 

lookup_template_class (continue)

 

4436       /* Create the type.  */

4437       if (TREE_CODE (template_type) == ENUMERAL_TYPE)

4438       {

           

4450       }

4451       else

4452       {

4453         t = make_aggr_type (TREE_CODE (template_type));

4454         CLASSTYPE_DECLARED_CLASS (t)

4455             = CLASSTYPE_DECLARED_CLASS (template_type);

4456         SET_CLASSTYPE_IMPLICIT_INSTANTIATION (t);

4457         TYPE_FOR_JAVA (t) = TYPE_FOR_JAVA (template_type);

4458  

4459         /* A local class. Make sure the decl gets registered properly.  */

4460         if (context == current_function_decl )

4461           pushtag (DECL_NAME (template), t, 0);

4462       }

4463  

4464        /* If we called start_enum or pushtag above, this information

4465         will already be set up.  */

4466       if (!TYPE_NAME (t))

4467       {

4468         TYPE_CONTEXT (t) = FROB_CONTEXT (context);

4469         

4470         type_decl = create_implicit_typedef (DECL_NAME (template), t);

4471         DECL_CONTEXT (type_decl) = TYPE_CONTEXT (t);

4472         TYPE_STUB_DECL (t) = type_decl;

4473         DECL_SOURCE_LOCATION (type_decl)

4474            = DECL_SOURCE_LOCATION (TYPE_STUB_DECL (template_type));

4475       }

4476       else

4477         type_decl = TYPE_NAME (t);

4478  

4479       TREE_PRIVATE (type_decl)

4480          = TREE_PRIVATE (TYPE_STUB_DECL (template_type));

4481       TREE_PROTECTED (type_decl)

4482          = TREE_PROTECTED (TYPE_STUB_DECL (template_type));

4483  

4484       /* Set up the template information. We have to figure out which

4485         template is the immediate parent if this is a full

4486         instantiation.  */

4487       if (parm_depth == 1 || is_partial_instantiation

4488          || !PRIMARY_TEMPLATE_P (template))

4489         /* This case is easy; there are no member templates involved.  */

4490         found = template;

4491       else

4492       {

           

4544       }

4545  

4546       SET_TYPE_TEMPLATE_INFO (t, tree_cons (found, arglist, NULL_TREE)); 

4547       DECL_TEMPLATE_INSTANTIATIONS (template)

4548            = tree_cons (arglist, t,

4549                       DECL_TEMPLATE_INSTANTIATIONS (template));

4550  

4551       if (TREE_CODE (t) == ENUMERAL_TYPE

4552          && !is_partial_instantiation)

4553         /* Now that the type has been registered on the instantiations

4554           list, we set up the enumerators. Because the enumeration

4555           constants may involve the enumeration type itself, we make

4556           sure to register the type first, and then create the

4557           constants. That way, doing tsubst_expr for the enumeration

4558           constants won't result in recursive calls here; we'll find

4559           the instantiation and exit above.  */

4560         tsubst_enum (template_type, t, arglist);

4561  

4562       /* Reset the name of the type, now that CLASSTYPE_TEMPLATE_INFO

4563         is set up.  */

4564       if (TREE_CODE (t) != ENUMERAL_TYPE)

4565         DECL_NAME (type_decl) = classtype_mangled_name (t);

4566       if (is_partial_instantiation)

4567          /* If the type makes use of template parameters, the

4568           code that generates debugging information will crash.  */

4569         DECL_IGNORED_P (TYPE_STUB_DECL (t)) = 1;

4570  

4571       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);

4572     }

4573     timevar_pop (TV_NAME_LOOKUP);

4574   }

 

For new instantiation (as our case), a RECORD_TYPE and associated nodes are created, as every time a new instantiation introduces a new type. To prevent duplicate definitions, every instantiation is recorded by DECL_TEMPLATE_INSTANTIATIONS at line 4547; however it only works in the same translation-unit. Duplicate definitions can’t be avoided across translation-unit by this way, but linker can do the help. At exit point of the function, we get following intermediate tree (the new nodes are in blue color).

(Click here for open )

The RECORD_TYPE in above figure is returned by lookup_template_class , and then TYPE_DECL accessed via its chain field is returned by finish_template_type . This TYPE_DECL is used as the result of template_id in cp_parser_template_id at line 7997 and then returned as below decl in cp_parser_class_name .

 

cp_parser_class_name (continue)

 

11812   decl = cp_parser_maybe_treat_template_as_class (decl, class_head_p);

11813

11814   /* If this is a typename, create a TYPENAME_TYPE.  */

11815   if (typename_p && decl != error_mark_node)

11816   {

11817     decl = make_typename_type (scope, decl, /*complain=*/ 1);

11818     if (decl != error_mark_node)

11819       decl = TYPE_NAME (decl);

11820   }

11821

11822   /* Check to see that it is really the name of a class.  */

11823   if (TREE_CODE (decl) == TEMPLATE_ID_EXPR

11824      && TREE_CODE (TREE_OPERAND (decl, 0)) == IDENTIFIER_NODE

11825      && cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))

11826     /* Situations like this:

11827

11828       template <typename T> struct A {

11829         typename T::template X<int>::I i;

11830       };

11831

11832       are problematic. Is `T::template X<int>' a class-name? The

11833       standard does not seem to be definitive, but there is no other

11834       valid interpretation of the following `::'. Therefore, those

11835       names are considered class-names.  */

11836     decl = TYPE_NAME (make_typename_type (scope, decl, tf_error));

11837   else if (decl == error_mark_node

11838         || TREE_CODE (decl) != TYPE_DECL

11839         || !IS_AGGR_TYPE (TREE_TYPE (decl)))

11840   {

11841     cp_parser_error (parser, "expected class-name");

11842     return error_mark_node;

11843   }

11844

11845   return decl;

11846 }

 

At line 11812, cp_parser_maybe_treat_template_as_class does nothing for the passed in TYPE_DECL, but returns associated TYPE_DECL if it’s TEMPALTE_DECL. So decl is returned by cp_parser_class_name too. In fact this TYPE_DECL is what we find for type-specifier in decl-specifier-seq. This node climbs up the call-stack into cp_parser_simple_declaration .

 

你可能感兴趣的:(Studying note of GCC-3.4.6 source (131))