cp_declarator *declarator,
location_t declarator_location)
{
- unsigned num_templates;
-
- /* We haven't seen any classes that involve template parameters yet. */
- num_templates = 0;
-
switch (declarator->kind)
{
case cdk_id:
- if (declarator->u.id.qualifying_scope)
- {
- tree scope;
-
- scope = declarator->u.id.qualifying_scope;
-
- while (scope && CLASS_TYPE_P (scope))
- {
- /* You're supposed to have one `template <...>'
- for every template class, but you don't need one
- for a full specialization. For example:
-
- template <class T> struct S{};
- template <> struct S<int> { void f(); };
- void S<int>::f () {}
-
- is correct; there shouldn't be a `template <>' for
- the definition of `S<int>::f'. */
- if (!CLASSTYPE_TEMPLATE_INFO (scope))
- /* If SCOPE does not have template information of any
- kind, then it is not a template, nor is it nested
- within a template. */
- break;
- if (explicit_class_specialization_p (scope))
- break;
- if (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (scope)))
- ++num_templates;
-
- scope = TYPE_CONTEXT (scope);
- }
- }
- else if (TREE_CODE (declarator->u.id.unqualified_name)
- == TEMPLATE_ID_EXPR)
- /* If the DECLARATOR has the form `X<y>' then it uses one
- additional level of template parameters. */
- ++num_templates;
+ {
+ unsigned num_templates = 0;
+ tree scope = declarator->u.id.qualifying_scope;
- return cp_parser_check_template_parameters
- (parser, num_templates, declarator_location, declarator);
+ if (scope)
+ num_templates = num_template_headers_for_class (scope);
+ else if (TREE_CODE (declarator->u.id.unqualified_name)
+ == TEMPLATE_ID_EXPR)
+ /* If the DECLARATOR has the form `X<y>' then it uses one
+ additional level of template parameters. */
+ ++num_templates;
+ return cp_parser_check_template_parameters
+ (parser, num_templates, declarator_location, declarator);
+ }
case cdk_function:
case cdk_array:
int
num_template_headers_for_class (tree ctype)
{
- int template_count = 0;
- tree t = ctype;
- while (t != NULL_TREE && CLASS_TYPE_P (t))
+ int num_templates = 0;
+
+ while (ctype && CLASS_TYPE_P (ctype))
{
/* You're supposed to have one `template <...>' for every
template class, but you don't need one for a full
is correct; there shouldn't be a `template <>' for the
definition of `S<int>::f'. */
- if (CLASSTYPE_TEMPLATE_SPECIALIZATION (t)
- && !any_dependent_template_arguments_p (CLASSTYPE_TI_ARGS (t)))
- /* T is an explicit (not partial) specialization. All
- containing classes must therefore also be explicitly
- specialized. */
+ if (!CLASSTYPE_TEMPLATE_INFO (ctype))
+ /* If CTYPE does not have template information of any
+ kind, then it is not a template, nor is it nested
+ within a template. */
+ break;
+ if (explicit_class_specialization_p (ctype))
break;
- if ((CLASSTYPE_USE_TEMPLATE (t) || CLASSTYPE_IS_TEMPLATE (t))
- && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t)))
- template_count += 1;
+ if (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (ctype)))
+ ++num_templates;
- t = TYPE_MAIN_DECL (t);
- t = DECL_CONTEXT (t);
+ ctype = TYPE_CONTEXT (ctype);
}
- return template_count;
+ return num_templates;
}
/* Do a simple sanity check on the template headers that precede the