Studying note of GCC-3.4.6 source (124)

来源:互联网 发布:淘宝代理数据包下载 编辑:程序博客网 时间:2024/05/01 23:38

5.12.4.2.2.2.3.         Finish template-id

If template-name is an IDENTIFER_NODE, it maybe a member template;and if it is a TEMPLATE_DECL of class template, the template-id itself is aclass-name; and if it is FUNCTION_DECL, OVERLOAD or METHOD_DECL, thetemplate-id is a function-name.

So if template-name is a class template, the template-id may name anew class, for which case we should create corresponding class type by finish_template_type.It is a very complex procedure, later section will give an example to gothrough the function.

 

cp_parser_template_id (continue)

 

7991   /*Build a representation of the specialization. */

7992   if (TREE_CODE (template) ==IDENTIFIER_NODE)

7993     template_id = build_min_nt (TEMPLATE_ID_EXPR, template, arguments);

7994   else if(DECL_CLASS_TEMPLATE_P (template)

7995         ||DECL_TEMPLATE_TEMPLATE_PARM_P (template))

7996     template_id

7997       = finish_template_type (template, arguments,

7998                          cp_lexer_next_token_is (parser->lexer,

7999                                              CPP_SCOPE));

8000   else

8001   {

8002     /*If it's not a class-template or a template-template, it should be

8003       a function-template. */

8004     my_friendly_assert((DECL_FUNCTION_TEMPLATE_P (template)

8005                      ||TREE_CODE (template) == OVERLOAD

8006                      ||BASELINK_P (template)),

8007                      20010716);

8008      

8009     template_id = lookup_template_function (template,arguments);

8010   }

8011  

8012   /*Retrieve any deferred checks. Do not pop this access checks yet

8013     so thememory will not be reclaimed during token replacing below.  */

8014   access_check =get_deferred_access_checks ();

 

If template-name is an IDNETIFIER_NODE, the resultingTEMPLATE_ID_EXPR is built by build_min_nt. The function builds a tree nodeof tree_exp.

 

4069 tree

4070 build_min_nt (enumtree_code code, ...)                                                            intree.c

4071 {

4072   tree t;

4073   int length;

4074   int i;

4075   va_list p;

4076

4077   va_start (p, code);

4078

4079   t= make_node(code);

4080   length = TREE_CODE_LENGTH (code);

4081   TREE_COMPLEXITY (t) = input_line;

4082

4083   for (i = 0; i< length; i++)

4084   {

4085     tree x = va_arg (p, tree);

4086     TREE_OPERAND (t, i) = x;

4087   }

4088

4089   va_end (p);

4090   return t;

4091 }

 

If the template-name names a function template, the TEMPLATE_ID_EXPRnode is created by lookup_template_function. A BASELINK node is a reference to a memberfunction or member functions from a base class. Note that in this case in theTEMPLATE_ID_EXPR generated, its type is unknonw_type_node, which will force the front-endto invoke instantiate_typelater to resolve its type.

 

4069 tree

4070 lookup_template_function (tree fns, tree arglist)                                                  inpt.c

4071 {

4072   tree type;

4073

4074   if (fns == error_mark_node || arglist ==error_mark_node)

4075     returnerror_mark_node;

4076

4077   my_friendly_assert (!arglist || TREE_CODE(arglist) == TREE_VEC, 20030726);

4078   my_friendly_assert (fns && (is_overloaded_fn (fns)

4079                           || TREE_CODE (fns) ==IDENTIFIER_NODE),

4080                   20050608);

4081

4082   if (BASELINK_P (fns))

4083   {

4084     BASELINK_FUNCTIONS (fns) = build(TEMPLATE_ID_EXPR,

4085                                       unknown_type_node,

4086                                       BASELINK_FUNCTIONS(fns),

4087                                       arglist);

4088     return fns;

4089   }

4090

4091   type = TREE_TYPE (fns);

4092   if (TREE_CODE (fns) == OVERLOAD || !type)

4093     type = unknown_type_node;

4094   

4095   return build (TEMPLATE_ID_EXPR, type, fns, arglist);

4096 }

 

Then corresponding tokens are grouped as CPP_TEMPLATE_ID; similarlythere is another group - NESTED_NAME_SPECFIER.

 

cp_parser_template_id (continue)

 

8016   /* If parsingtentatively, replace the sequence of tokens that makes

8017     up thetemplate-id with a CPP_TEMPLATE_ID token. That way,

8018     should were-parse the token stream, we will not have to repeat

8019     the effortrequired to do the parse, nor will we issue duplicate

8020     error messagesabout problems during instantiation of the

8021     template.  */

8022   if (start_of_id >= 0)

8023   {

8024     cp_token *token;

8025

8026     /* Find the tokenthat corresponds to the start of the

8027       template-id.  */

8028     token = cp_lexer_advance_token(parser->lexer,

8029                                 parser->lexer->first_token,

8030                                 start_of_id);

8031

8032     /* Reset thecontents of the START_OF_ID token.  */

8033     token->type = CPP_TEMPLATE_ID;

8034     token->value = build_tree_list(access_check, template_id);

8035     token->keyword = RID_MAX;

8036     /* Purge allsubsequent tokens.  */

8037     cp_lexer_purge_tokens_after(parser->lexer, token);

8038

8039     /* ??? Can weactually assume that, if template_id ==

8040       error_mark_node, we will have issued adiagnostic to the

8041       user, asopposed to simply marking the tentative parse as

8042       failed?  */

8043     if (cp_parser_error_occurred (parser)&& template_id != error_mark_node)

8044       error ("parse error in templateargument list");

8045   }

8046

8047   pop_deferring_access_checks();

8048   returntemplate_id;

8049 }

5.12.4.2.2.3. Finish lookup class name

When get decl for the identifier, as indicated by the grammar, it mustbe an identifier or template-id. If argument typename_p is true, it meanskeyword typenamehas been seen. So invoke make_typename_type to resolve “typenameCONTEXT::NAME" and return appropriate type.

 

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 aTYPENAME_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::templateX<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     returnerror_mark_node;

11843   }

11844

11845   returndecl;

11846 }

 

Refer to maybe_get_template_decl_from_type_declthat invoked in cp_parser_template_id, it can betterunderstand cp_parser_maybe_treat_template_as_class.Argument tag_name_pif true, declindicates the class being defined in a class-head, or declared in an elaborated-type-specifier.

 

13901 static tree

13902 cp_parser_maybe_treat_template_as_class (tree decl, bool tag_name_p)              in parser.c

13903 {

13904   /*If the TEMPLATE_DECL is being declared as part of a class-head,

13905     thetranslation from TEMPLATE_DECL to TYPE_DECL occurs:

13906

13907       struct A {

13908         template <typename T> struct B;

13909        };

13910

13911       template <typename T> struct A::B {};

13912   

13913    Similarly, in a elaborated-type-specifier:

13914

13915       namespace N { struct X{}; }

13916

13917       struct A {

13918         template <typename T> friend struct N::X;

13919        };

13920

13921    However, if the DECL refers to a class type, and we are in

13922     thescope of the class, then the name lookup automatically

13923     findsthe TYPE_DECL created by build_self_reference rather

13924     than aTEMPLATE_DECL. For example, in:

13925

13926       template <class T> struct S {

13927          Ss;

13928        };

13929

13930     thereis no need to handle such case.  */

13931

13932   if (DECL_CLASS_TEMPLATE_P(decl) && tag_name_p)

13933     returnDECL_TEMPLATE_RESULT (decl);

13934

13935   returndecl;

13936 }

 

The effect of the routine is if decl isa TEMPLATE_DECL that can be treated like a TYPE_DECL in the current context,returns the TYPE_DECL.

Below if name is a template class (by CLASSTYPE_IS_TEMPLATE) or a template instantiation or specialization (by CLASSTYPE_USE_TEMPLATE), a TMEPLATE_ID_EXPR is built. Its processinginvolves lookup_template_classwhich is a complex function and we will see it later with example.

 

2608 tree

2609 make_typename_type (tree context, treename, tsubst_flags_t complain)               in decl.c

2610 {

2611   tree fullname;

2612

2613   if (name == error_mark_node

2614       || context == NULL_TREE

2615       || context == error_mark_node)

2616     returnerror_mark_node;

2617

2618   if (TYPE_P (name))

2619   {

2620     if (!(TYPE_LANG_SPECIFIC (name)

2621         && (CLASSTYPE_IS_TEMPLATE(name)

2622             || CLASSTYPE_USE_TEMPLATE (name))))

2623       name= TYPE_IDENTIFIER (name);

2624     else

2625       /* Create a TEMPLATE_ID_EXPR for the type.  */

2626       name= build_nt (TEMPLATE_ID_EXPR,

2627                      CLASSTYPE_TI_TEMPLATE(name),

2628                      CLASSTYPE_TI_ARGS (name));

2629   }

2630   else if (TREE_CODE (name) == TYPE_DECL)

2631     name = DECL_NAME (name);

2632

2633   fullname = name;

2634

2635   if (TREE_CODE (name) == TEMPLATE_ID_EXPR)

2636   {

2637     name = TREE_OPERAND (name, 0);

2638     if (TREE_CODE (name) == TEMPLATE_DECL)

2639       name= TREE_OPERAND (fullname, 0) = DECL_NAME (name);

2640   }

2641   if (TREE_CODE (name) == TEMPLATE_DECL)

2642   {

2643     error ("`%D' used without templateparameters", name);

2644     returnerror_mark_node;

2645   }

2646   my_friendly_assert (TREE_CODE (name) ==IDENTIFIER_NODE, 20030802);

2647   my_friendly_assert (TYPE_P (context),20050905);

2648

2649   if (!dependent_type_p(context)

2650       ||currently_open_class (context))

2651   {

2652     if (TREE_CODE (fullname) ==TEMPLATE_ID_EXPR)

2653     {

2654       tree tmpl = NULL_TREE;

2655       if (IS_AGGR_TYPE (context))

2656         tmpl = lookup_field(context, name, 0, false);

2657       if (!tmpl || !DECL_CLASS_TEMPLATE_P(tmpl))

2658       {

2659         if (complain & tf_error)

2660           error ("no class template named `%#T' in`%#T'",

2661                 name, context);

2662         returnerror_mark_node;

2663       }

2664

2665       if (complain & tf_error)

2666         perform_or_defer_access_check(TYPE_BINFO (context), tmpl);

2667

2668       return lookup_template_class (tmpl,

2669                                TREE_OPERAND (fullname, 1),

2670                                NULL_TREE, context,

2671                                /*entering_scope=*/0,

2672                                tf_error | tf_warning| tf_user);

2673     }

2674     else

2675     {

2676       tree t;

2677

2678       if(!IS_AGGR_TYPE (context))

2679       {

2680         if (complain & tf_error)

2681           error ("no type named `%#T' in`%#T'", name, context);

2682         returnerror_mark_node;

2683       }

2684

2685       t =lookup_field (context, name, 0, true);

2686       if(t)

2687       {

2688         if (TREE_CODE (t) != TYPE_DECL)

2689         {

2690           if (complain & tf_error)

2691             error ("no type named `%#T' in`%#T'", name, context);

2692           returnerror_mark_node;

2693         }

2694

2695         if (complain & tf_error)

2696           perform_or_defer_access_check(TYPE_BINFO (context), t);

2697

2698         if (DECL_ARTIFICIAL (t) || !(complain &tf_keep_type_decl))

2699           t = TREE_TYPE (t);

2700      

2701         returnt;

2702       }

2703     }

2704   }

2705

2706   /* If the CONTEXTis not a template type, then either the field is

2707     there now or itsnever going to be.  */

2708   if (!dependent_type_p(context))

2709   {

2710     if (complain & tf_error)

2711       error ("no type named `%#T' in `%#T'",name, context);

2712     returnerror_mark_node;

2713   }

2714

2715   return build_typename_type (context, name, fullname);

2716 }

 

And for expression “typenameCONTEXT::NAME”, if CONTEXT is non-dependent, or is currently opened class, NAMEis first looked up within the class by lookup_field.

 

1372 tree

1373 lookup_field(tree xbasetype, tree name, int protect, bool want_type)             in search.c

1374 {

1375   tree rval = lookup_member(xbasetype, name, protect, want_type);

1376   

1377   /* Ignorefunctions.  */

1378   if (rval && BASELINK_P (rval))

1379     returnNULL_TREE;

1380

1381   return rval;

1382 }

 

See that argument want_typein invocation at line 2656 is false for template-id; and invocation at line2685 is true for normal type. And want_type is true, indicates we only acceptTYPE_DECL.

If nothing found and the scope isdependent, it must build a placeholder for the type. It is the node of TYPENAME_TYPE.

 

2566 static tree

2567 build_typename_type (tree context, tree name, tree fullname)                        in decl.c

2568 {

2569   tree t;

2570   tree d;

2571   void **e;

2572

2573   if (typename_htab == NULL)

2574   {

2575     typename_htab = htab_create_ggc(61, &typename_hash,

2576                                  &typename_compare,NULL);

2577   }

2578

2579   /*Build the TYPENAME_TYPE.  */

2580   t = make_aggr_type(TYPENAME_TYPE);

2581   TYPE_CONTEXT (t) = FROB_CONTEXT (context);

2582   TYPENAME_TYPE_FULLNAME (t) =fullname;

2583

2584   /*Build the corresponding TYPE_DECL.  */

2585   d = build_decl(TYPE_DECL, name, t);

2586   TYPE_NAME (TREE_TYPE (d)) =d;

2587   TYPE_STUB_DECL (TREE_TYPE(d)) = d;

2588   DECL_CONTEXT (d) =FROB_CONTEXT (context);

2589   DECL_ARTIFICIAL (d) = 1;

2590

2591   /*See if we already have this type.  */

2592   e = htab_find_slot (typename_htab,t, INSERT);

2593   if (*e)

2594     t = (tree) *e;

2595   else

2596     *e = t;

2597

2598   returnt;

2599 }

 

Node of TYPENAME_TYPE represents structure “typenameT::t”. In the node, its TYPE_CONTEXT is `T', TYPE_NAME is an IDENTIFIER_NODEfor `t'. If the type was named via template-id, TYPENAME_TYPE_FULLNAME willhold the TEMPLATE_ID_EXPR.

Note that handling “typename T::t”here, ‘T’ has been resolved in previous step, it may be a template or templateparameter, and with a subtree already built. So in fact “typename T::t” underdifferent context ‘T’ stands for different structure. To ensure unique instanceof such structure within the translation-unit, these nodes are stored withinthe hashtable of typename_htab.

 

原创粉丝点击