We have seen the procedure parser handles the template-class “SingleThreaded”, however, this example is quite simple in view of template declaration. Next we will see template declaration that derived from “SingleThreaded”, it can give us enlightment about how front-end processes template-template parameter, and inheritage. Here is the class-head we will hanlde:
template
<
template <class > class ThreadingModel = DEFAULT_THREADING,
std ::size_t chunkSize = DEFAULT_CHUNK_SIZE,
std ::size_t maxSmallObjectSize = MAX_SMALL_OBJECT_SIZE
>
class SmallObject : public ThreadingModel<
SmallObject<ThreadingModel, chunkSize, maxSmallObjectSize> >
In which DEFAULT_THREADING aliases to “::Loki::SingleThreaded”. The declaration obeys the rule:
template-declaration:
export [opt] template-parameter-list-seq decl-specifier-seq [opt] init-declarator [opt] ;
Like previous example, it undergoes the calls stack of cp_parser_template_declaration à cp_parser_template_declaration_after_export à begin_template_parm_list (inserts scope of sk_template_parms), cp_parser_template_parameter_list à cp_parser_template_parameter à cp_parser_type_parameter . Following code of cp_parser_type_parameter is run for the example.
7720 static tree
7721 cp_parser_type_parameter (cp_parser* parser) in parser.c
7722 {
7723 cp_token *token;
7724 tree parameter;
7725
7726 /* Look for a keyword to tell us what kind of parameter this is. */
7727 token = cp_parser_require (parser, CPP_KEYWORD,
7728 "`class', `typename', or `template'");
7729 if (!token)
7730 return error_mark_node;
7731
7732 switch (token->keyword)
7733 {
7734 case RID_CLASS:
7735 case RID_TYPENAME:
7736 {
...
7764 }
7765 break ;
7766
7767 case RID_TEMPLATE:
7768 {
7769 tree parameter_list;
7770 tree identifier;
7771 tree default_argument;
7772
7773 /* Look for the `<'. */
7774 cp_parser_require (parser, CPP_LESS, "`<'");
7775 /* Parse the template-parameter-list. */
7776 begin_template_parm_list ();
7777 parameter_list
7778 = cp_parser_template_parameter_list (parser);
7779 parameter_list = end_template_parm_list (parameter_list);
The first template parameter of our example is the template template parameter which begins with keyword template. This keyword template makes thing interesting now – a further scope of sk_template_parms is pushed in, and we will get following structure.
Figure 96 : before handling template template parameter
For the template template parameter, itself is a template declaration too. Here in the example, the template template parameter is: “template <class> class ThreadingModel”, and now the leading “template <” is consumed by parser. So in cp_parser_template_parameter (invoked by cp_parser_template_parameter_list at line 7778) following code is performed for the coming token “class”.
7654 static tree
7655 cp_parser_template_parameter (cp_parser* parser) in parser.c
7656 {
7657 cp_token *token;
7658
7659 /* Peek at the next token. */
7660 token = cp_lexer_peek_token (parser->lexer);
7661 /* If it is `class' or `template', we have a type-parameter. */
7662 if (token->keyword == RID_TEMPLATE)
7663 return cp_parser_type_parameter (parser);
7664 /* If it is `class' or `typename' we do not know yet whether it is a
7665 type parameter or a non-type parameter. Consider:
7666
7667 template <typename T, typename T::X X> ...
7668
7669 or:
7670
7671 template <class C, class D*> ...
7672
7673 Here, the first parameter is a type parameter, and the second is
7674 a non-type parameter. We can tell by looking at the token after
7675 the identifier -- if it is a `,', `=', or `>' then we have a type
7676 parameter. */
7677 if (token->keyword == RID_TYPENAME || token->keyword == RID_CLASS)
7678 {
7679 /* Peek at the token after `class' or `typename'. */
7680 token = cp_lexer_peek_nth_token (parser->lexer, 2);
7681 /* If it's an identifier, skip it. */
7682 if (token->type == CPP_NAME)
7683 token = cp_lexer_peek_nth_token (parser->lexer, 3);
7684 /* Now, see if the token looks like the end of a template
7685 parameter. */
7686 if (token->type == CPP_COMMA
7687 || token->type == CPP_EQ
7688 || token->type == CPP_GREATER)
7689 return cp_parser_type_parameter (parser);
7690 }
…
7703 }
Obviously, part “<class>” is the template parameter for the template template parameter; it is awkward-sounding, but shows the power of C++. Template can be nested to deep level – the standard defines that at least 12 levels should be allowed, in fact, every commercial compiler offers nesting level no less than 128.
For this template parameter “<class>”, cp_parser_type_parameter is recursed.
7720 static tree
7721 cp_parser_type_parameter (cp_parser* parser) in parser.c
7722 {
7723 cp_token *token;
7724 tree parameter;
7725
7726 /* Look for a keyword to tell us what kind of parameter this is. */
7727 token = cp_parser_require (parser, CPP_KEYWORD,
7728 "`class', `typename', or `template'");
7729 if (!token)
7730 return error_mark_node;
7731
7732 switch (token->keyword)
7733 {
7734 case RID_CLASS:
7735 case RID_TYPENAME:
7736 {
7737 tree identifier;
7738 tree default_argument;
7739
7740 /* If the next token is an identifier, then it names the
7741 parameter. */
7742 if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
7743 identifier = cp_parser_identifier (parser);
7744 else
7745 identifier = NULL_TREE;
7746
7747 /* Create the parameter. */
7748 parameter = finish_template_type_parm (class_type_node, identifier);
7749
7750 /* If the next token is an `=', we have a default argument. */
7751 if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
7752 {
...
7757 }
7758 else
7759 default_argument = NULL_TREE;
7760
7761 /* Create the combined representation of the parameter and the
7762 default argument. */
7763 parameter = build_tree_list (default_argument, parameter);
7764 }
7765 break ;
…
7848 }
7849
7850 return parameter;
7851 }
Above finish_template_type_parm creates a tree_list for the paramete; and further integrating into another tree_list at line 7763. Then parameter refers to nodes as below as the parameter is nameless and hasn’t default value.
Figure 97 : parameter node for template template parameter
Then back into cp_parser_template_parameter_list , process_template_parm packs template parameters. And note that it is the template parameter for the template template parameter! The argument next just refers to the node 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 {
…
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 {
...
2226 }
2227 else
2228 {
2229 t = make_aggr_type (TEMPLATE_TYPE_PARM);
2230 /* parm is either IDENTIFIER_NODE or NULL_TREE. */
2231 decl = build_decl (TYPE_DECL, parm, t);
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 }
Here begin_template_parm_list has been invoked twice so far, then processing_template_decl is 2. Note that TYPE_DECL of TEMPLATE_TPYE_PARM is nameless, so in pushdecl below, this TYPE_DECL is linked into names field of the relevant cxx_scope by add_decl_to_level .
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 {
…
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 }
Then back outer cp_parser_type_parameter from cp_parser_template_parameter_list , end_template_parm_list following prepares current_template_parms . And parameter_list returned is that in below figure.
(Click here for open )
Figure 98 : parameter list for template parameter of template template parameter
The following token must be “> class identifier [opt]”. By these tokens, the template template parameter comes into being.
cp_parser_type_parameter (continue)
7780 /* Look for the `>'. */
7781 cp_parser_require (parser, CPP_GREATER, "`>'");
7782 /* Look for the `class' keyword. */
7783 cp_parser_require_keyword (parser, RID_CLASS, "`class'");
7784 /* If the next token is an `=', then there is a
7785 default-argument. If the next token is a `>', we are at
7786 the end of the parameter-list. If the next token is a `,',
7787 then we are at the end of this parameter. */
7788 if (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ)
7789 && cp_lexer_next_token_is_not (parser->lexer, CPP_GREATER)
7790 && cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
7791 {
7792 identifier = cp_parser_identifier (parser);
7793 /* Treat invalid names as if the parameter were nameless. */
7794 if (identifier == error_mark_node)
7795 identifier = NULL_TREE;
7796 }
7797 else
7798 identifier = NULL_TREE;
7799
7800 /* Create the template parameter. */
7801 parameter = finish_template_template_parm (class_type_node ,
7802 identifier);
The template template parameter is a template declaration used in template parameter, it should be associated with a TEMPLATE_DECL to stand for this template declaration.
1943 tree
1944 finish_template_template_parm (tree aggr, tree identifier) in semantics.c
1945 {
1946 tree decl = build_decl (TYPE_DECL, identifier, NULL_TREE);
1947 tree tmpl = build_lang_decl (TEMPLATE_DECL, identifier, NULL_TREE);
1948 DECL_TEMPLATE_PARMS (tmpl) = current_template_parms ;
1949 DECL_TEMPLATE_RESULT (tmpl) = decl;
1950 DECL_ARTIFICIAL (decl) = 1;
1951 end_template_decl ();
1952
1953 my_friendly_assert (DECL_TEMPLATE_PARMS (tmpl), 20010110);
1954
1955 return finish_template_type_parm (aggr, tmpl);
1956 }
As this template declaration is closed when the optional identifier is read, end_template_decl must be invoked to decrease processing_template_decl and jump out of the binding scope of the declaration (see it is the sk_template_parms). Further finish_template_type_parm packs the TEMPLATE_DECL into the template parameter for the host template declaraion. So before parsing the optional default value, we can get following figure.
( Click here for open )
Figure 99 : template template parameter created