Studying note of GCC-3.4.6 source (118)

5.12.4.1.1.1.  Process template-template parameter

Similarly, after parsing the template template parameter, extra nodes are needed for the sub-tree of template template parameter. It is the task of process_template_parm . Notice that argument next refers to parameter in above figure.

 

2161   tree

2162   process_template_parm (tree list, tree next)                                                       in pt.c

2163   {

2164     tree parm;

2165     tree decl = 0;

2166     tree defval;

2167     int is_type, idx;

2168  

2169     parm = next;

2170     my_friendly_assert (TREE_CODE (parm) == TREE_LIST, 259);

2171     defval = TREE_PURPOSE (parm);

2172     parm = TREE_VALUE (parm);

2173     is_type = TREE_PURPOSE (parm) == class_type_node;

2174  

2175     if (list)

2176     {

2177       tree p = TREE_VALUE (tree_last (list));

2178  

2179       if (TREE_CODE (p) == TYPE_DECL || TREE_CODE (p) == TEMPLATE_DECL)

2180         idx = TEMPLATE_TYPE_IDX (TREE_TYPE (p));

2181       else

2182         idx = TEMPLATE_PARM_IDX (DECL_INITIAL (p));

2183       ++idx;

2184     }

2185     else

2186       idx = 0;

2187  

2188     if (!is_type)

2189     {

         

2212     }

2213     else

2214     {

2215       tree t;

2216       parm = TREE_VALUE (parm);

2217        

2218       if (parm && TREE_CODE (parm) == TEMPLATE_DECL)

2219       {

2220         t = make_aggr_type (TEMPLATE_TEMPLATE_PARM);

2221         /* This is for distinguishing between real templates and template

2222            template parameters */

2223         TREE_TYPE (parm) = t;

2224         TREE_TYPE (DECL_TEMPLATE_RESULT (parm)) = t;

2225         decl = parm;

2226       }

2227       else

2228       {

           

2232       }

2233          

2234       TYPE_NAME (t) = decl;

2235        TYPE_STUB_DECL (t) = decl;

2236       parm = decl;

2237       TEMPLATE_TYPE_PARM_INDEX (t)

2238            = build_template_parm_index (idx, processing_template_decl,

2239                                     processing_template_decl,

2240                                     decl, TREE_TYPE (parm));

2241     }

2242     DECL_ARTIFICIAL (decl) = 1;

2243     SET_DECL_TEMPLATE_PARM_P (decl);

2244     pushdecl (decl);

2245     parm = build_tree_list (defval, parm);

2246     return chainon (list, parm);

2247   }

 

Notice that idx is 0, and processing_template_decl now is 1 which means it is the first parameter at top level. Tree node of TEMPLATE_TYPE_PARM_INDEX records this informaiton. Then pushdecl will insert this sub-tree into the intermediate tree again.

 

566    tree

567    pushdecl (tree x)                                                                                     in name-lookup.c

568    {

569      tree t;

570      tree name;

571      int need_new_binding;

572   

573      timevar_push (TV_NAME_LOOKUP);

574   

575      need_new_binding = 1;

576   

577      if (DECL_TEMPLATE_PARM_P (x))

578        /* Template parameters have no context; they are not X::T even

579          when declared within a class or namespace.  */

580        ;

581      else

582      {

         

602      }

603   

604      name = DECL_NAME (x);

605      if (name)

606      {

607        int different_binding_level = 0;

         

615        /* In case this decl was explicitly namespace-qualified, look it

616          up in its namespace context.  */

617        if (DECL_NAMESPACE_SCOPE_P (x) && namespace_bindings_p ())

618          t = namespace_binding (name, DECL_CONTEXT (x));

619        else

620          t = lookup_name_current_level (name);

         

743        check_template_shadow (x);

         

828         /* This name is new in its binding level.

829          Install the new declaration and return it.  */

830        if (namespace_bindings_p ())

831        {

           

872        }

873        else

874        {

875          /* Here to install a non-global value.  */

876          tree oldlocal = IDENTIFIER_VALUE (name);

877          tree oldglobal = IDENTIFIER_NAMESPACE_VALUE (name);

878   

879          if (need_new_binding)

880          {

881            push_local_binding (name, x, 0);

882            /* Because push_local_binding will hook X on to the

883              current_binding_level's name list, we don't want to

884              do that again below.  */

885            need_new_binding = 0;

886          }

           

1003       }

1004  

1005       if (TREE_CODE (x) == VAR_DECL)

1006         maybe_register_incomplete_var (x);

1007     }

1008  

1009     if (need_new_binding)

1010       add_decl_to_level (x,

1011                       DECL_NAMESPACE_SCOPE_P (x)

1012                       ? NAMESPACE_LEVEL (CP_DECL_CONTEXT (x))

1013                       : current_binding_level);

1014  

1015     POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);

1016   }

 

After pushdecl executed, the relevant part of the intermediate tree will have below structure.

 

(Click here for open )

Figure 103 : push the template template parameter

Back from pushdecl , the rest of process_template_parm re-arranges parm and strips useless nodes as below figure indicates.

(Click here for open )

Figure 104 : template template parameter finished

 

你可能感兴趣的:(list,tree,processing,templates,binding,Parsing)