Now we return from cp_parser_parameter_declaration, then cp_parser_template_parameter back to cp_parser_template_parameter_list, in which, variable parameter holds the tree node illustrated by 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;
In above function, parameter list is the list of already processed template parameter. In this chain to quickly find out who is who, every parameter is indexed and the sequential number is saved within the node too. So it first needs to find out the last used number then the first unused number.
As for type template parameter, the type slot of tree_common part (accessed by TREE_TYPE); and initial slot of tree_decl (accessed by DECL_INITIAL, which is unused for common parm-decl) are of type template_parm_index which has following definition.
241 typedef struct template_parm_index_s GTY(()) in cp-tree.h
242 {
243 struct tree_common common;
244 HOST_WIDE_INT index;
245 HOST_WIDE_INT level;
246 HOST_WIDE_INT orig_level;
247 tree decl;
248 } template_parm_index;
And a series of macros have been defined for accessing related fields. Some of them are defined as below.
3443 #define TEMPLATE_PARM_INDEX_CAST(NODE) / in cp-tree.h
3444 ((template_parm_index*)TEMPLATE_PARM_INDEX_CHECK (NODE))
3445 #define TEMPLATE_PARM_IDX(NODE) (TEMPLATE_PARM_INDEX_CAST (NODE)->index)
3446 #define TEMPLATE_PARM_LEVEL(NODE) (TEMPLATE_PARM_INDEX_CAST (NODE)->level)
3447 #define TEMPLATE_PARM_DESCENDANTS(NODE) (TREE_CHAIN (NODE))
3448 #define TEMPLATE_PARM_ORIG_LEVEL(NODE) (TEMPLATE_PARM_INDEX_CAST (NODE)->orig_level)
3449 #define TEMPLATE_PARM_DECL(NODE) (TEMPLATE_PARM_INDEX_CAST (NODE)->decl)
The TEMPLATE_PARM_IDX gives the index (from 0) of the parameter, while the TEMPLATE_PARM_LEVEL gives the level (from 1) of the parameter. Here's an example:
template <class T> // Index 0, Level 1, Orig Level 1.
struct S {
template <class U, // Index 0, Level 2, Orig Level 2.
class V> // Index 1, Level 2, Orig Level 2.
void f();
};
TEMPLATE_PARM_DESCENDANTS will be a chain of template_parm_index descended from above one. The first descendant will have the same IDX, but its LEVEL will be 1 less. The descendants are chained together by TREE_CHAIN. TEMPLATE_PARM_DECL is the parameter declaration, either TYPE_DECL or CONST_DECL. TEMPLATE_PARM_ORIG_LEVEL is the level of the most distant parent, i.e., the level that the parameter originally had when it was declared. For example, if we instantiate S<int>, we will have:
struct S<int> // N/A {
template <class U, // Index 0, Level 1, Orig Level 2
class V> // Index 1, Level 1, Orig Level 2
void f();
};
The LEVEL is the level of the parameter when we are worrying about the types of things; the ORIG_LEVEL is the level when we are worrying about instantiating things.
process_template_parm (continue)
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 }
Now our parameter “Host” is not a template declaration itself, a simple class type will be created for this parameter, it is regarded as a TYPE_DECL.
2104 static tree
2105 build_template_parm_index (int index, in pt.c
2106 int level,
2107 int orig_level,
2108 tree decl,
2109 tree type)
2110 {
2111 tree t = make_node (TEMPLATE_PARM_INDEX);
2112 TEMPLATE_PARM_IDX (t) = index;
2113 TEMPLATE_PARM_LEVEL (t) = level;
2114 TEMPLATE_PARM_ORIG_LEVEL (t) = orig_level;
2115 TEMPLATE_PARM_DECL (t) = decl;
2116 TREE_TYPE (t) = type;
2117 TREE_CONSTANT (t) = TREE_CONSTANT (decl);
2118 TREE_READONLY (t) = TREE_READONLY (decl);
2119
2120 return t;
2121 }
TEMPLATE_PARM_INDEX is a special tree node that of type template_parm_index. And it will never be created by user, but generated by front-end (DECL_ARTIFICIAL indicates this).
The template parameter is effective in scope of sk_template_parms. It should be added into the scope.
556 tree
557 pushdecl (tree x) in name-lookup.c
558 {
559 tree t;
560 tree name;
561 int need_new_binding;
562
563 timevar_push (TV_NAME_LOOKUP);
564
565 need_new_binding = 1;
566
567 if (DECL_TEMPLATE_PARM_P (x))
568 /* Template parameters have no context; they are not X::T even
569 when declared within a class or namespace. */
570 ;
…
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);
Now cuurent scope is sk_template_parms, condition at line 617 is not satisfied so it tries to check if this identifier has been declared or not only at current binding level. Here we get NULL as result from lookup_name_current_level.
4019 static tree
4020 lookup_name_current_level (tree name) in name-lookup.c
4021 {
4022 struct cp_binding_level *b;
4023 tree t = NULL_TREE;
4024
4025 timevar_push (TV_NAME_LOOKUP);
4026 b = innermost_nonclass_level ();
4027
4028 if (b->kind == sk_namespace)
4029 {
4030 t = IDENTIFIER_NAMESPACE_VALUE (name);
4031
4032 /* extern "C" function() */
4033 if (t != NULL_TREE && TREE_CODE (t) == TREE_LIST)
4034 t = TREE_VALUE (t);
4035 }
4036 else if (IDENTIFIER_BINDING (name)
4037 && LOCAL_BINDING_P (IDENTIFIER_BINDING (name)))
4038 {
4039 while (1)
4040 {
4041 if (IDENTIFIER_BINDING (name)->scope == b)
4042 POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, IDENTIFIER_VALUE (name));
4043
4044 if (b->kind == sk_cleanup)
4045 b = b->level_chain;
4046 else
4047 break;
4048 }
4049 }
4050
4051 POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
4052 }
Then this new declaration is installed within the scope by set_identifier_type_value at line 800. And at line 830, namespace_binding_p returns false, as the innermost non-class scope from current binding level is sk_template_parms.
pushdecl (continue)
772 /* If declaring a type as a typedef, copy the type (unless we're
773 at line 0), and install this TYPE_DECL as the new type's typedef
774 name. See the extensive comment in ../c-decl.c (pushdecl). */
775 if (TREE_CODE (x) == TYPE_DECL)
776 {
777 tree type = TREE_TYPE (x);
…
797 if (type != error_mark_node
798 && TYPE_NAME (type)
799 && TYPE_IDENTIFIER (type))
800 set_identifier_type_value (DECL_NAME (x), x);
801 }
…
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 }
887
888 /* If this is a TYPE_DECL, push it into the type value slot. */
889 if (TREE_CODE (x) == TYPE_DECL)
890 set_identifier_type_value (name, x);
…
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}
For identifier, IDENTIFIER_VALUE field records the non-namespace binding scopes have the name defined, while IDNETIFIER_NAMESPACE_VALUE records the namespaces have the name defined. As “Host” is the new identifier, above, oldlocal and oldglobal are both NULL.
1052 void
1053 push_local_binding (tree id, tree decl, int flags) in name-lookup.c
1054 {
1055 struct cp_binding_level *b;
1056
1057 /* Skip over any local classes. This makes sense if we call
1058 push_local_binding with a friend decl of a local class. */
1059 b = innermost_nonclass_level ();
1060
1061 if (lookup_name_current_level (id))
1062 {
1063 /* Supplement the existing binding. */
1064 if (!supplement_binding (IDENTIFIER_BINDING (id), decl))
1065 /* It didn't work. Something else must be bound at this
1066 level. Do not add DECL to the list of things to pop
1067 later. */
1068 return;
1069 }
1070 else
1071 /* Create a new binding. */
1072 push_binding (id, decl, b);
1073
1074 if (TREE_CODE (decl) == OVERLOAD || (flags & PUSH_USING))
1075 /* We must put the OVERLOAD into a TREE_LIST since the
1076 TREE_CHAIN of an OVERLOAD is already used. Similarly for
1077 decls that got here through a using-declaration. */
1078 decl = build_tree_list (NULL_TREE, decl);
1079
1080 /* And put DECL on the list of things declared by the current
1081 binding level. */
1082 add_decl_to_level (decl, b);
1083 }
No doubt, before insertion, it needs check if the name is new in the scope. Obviously, lookup_name_current_level returns NULL for “Host”. And at last, add_decl_to_level at line 1082 records the name of declaration into the binding scope. Next returns back pushdecl, at line 890, set_identifier_type_value the type of this identifier as the TYPE_DECL.
In the end, after installing the template parameter Host within the special sk_template_parm scope, we get the rough layout as following figure.
Figure 49: brief layout after pushing “Host”
Notice that current_template_parms records the nested level of template parameters. For a template declaration, its template parameter list contains parameter in form of template < template-parameter-list > class identifier [opt], current_template_parms can help to tell at which level should the parameter be bound.
2254 tree
2255 end_template_parm_list (tree parms) in pt.c
2256 {
2257 int nparms;
2258 tree parm, next;
2259 tree saved_parmlist = make_tree_vec (list_length (parms));
2260
2261 current_template_parms
2262 = tree_cons (size_int (processing_template_decl),
2263 saved_parmlist, current_template_parms);
2264
2265 for (parm = parms, nparms = 0; parm; parm = next, nparms++)
2266 {
2267 next = TREE_CHAIN (parm);
2268 TREE_VEC_ELT (saved_parmlist, nparms) = parm;
2269 TREE_CHAIN (parm) = NULL_TREE;
2270 }
2271
2272 --processing_template_parmlist;
2273
2274 return saved_parmlist;
2275 }
748 #define current_template_parms scope_chain->template_parms in cp-tree.h
Before moving ahead, considering following example:
template <typename A> class BoxA {
public:
template<typename B, typename C> class BoxB {};
};
When processing class BoxB, notice that it is contained within a template class BoxA. Obvious, BoxB not only depends on type parameter B, but also on that type parameter A of BoxA; it is important that records type parameter A as part of template parameter during handling BoxB.
Figure 50: layout of nested template parameters
In current version, when handling declaration of BoxB, processing_template_decl will be 2 (assuming BoxA is within global scope), then before invoking end_template_parm_list to finish the processing of parameter of BoxB, current_template_parms holds the node with purpose of 1 which is the parameter of BoxA. After executing the function, we can have the layout of paramters for BoxB as above figure. See that the list holds parameters of different level, while value slot of each node holds parameters of the same level. At this point, the intermediate tree looks like:
Figure 51: Rough intermediate tree after handling template parameter