Commit fd4de5ff by Mark Mitchell Committed by Mark Mitchell

pt.c (check_specialization_scope): Fix spelling error.

	* pt.c (check_specialization_scope): Fix spelling error.
	(check_explicit_specialization): Remove code to handle explicit
	specializations in class scope; they are now correctly diagnosed
	as errors.

From-SVN: r22414
parent 028d0b2a
1998-09-14 Mark Mitchell <mark@markmitchell.com>
* pt.c (check_specialization_scope): Fix spelling error.
(check_explicit_specialization): Remove code to handle explicit
specializations in class scope; they are now correctly diagnosed
as errors.
1998-09-10 Mark Mitchell <mark@markmitchell.com> 1998-09-10 Mark Mitchell <mark@markmitchell.com>
* decl.c (pushdecl): Don't copy types if the * decl.c (pushdecl): Don't copy types if the
......
...@@ -605,7 +605,7 @@ check_specialization_scope () ...@@ -605,7 +605,7 @@ check_specialization_scope ()
explicitly specialize a class member template if its enclosing explicitly specialize a class member template if its enclosing
class templates are not explicitly specialized as well. */ class templates are not explicitly specialized as well. */
if (current_template_parms) if (current_template_parms)
cp_error ("enclosing class templates are not explicit specialized"); cp_error ("enclosing class templates are not explicitly specialized");
} }
/* We've just seen template <>. */ /* We've just seen template <>. */
...@@ -1031,15 +1031,8 @@ determine_specialization (template_id, decl, targs_out, ...@@ -1031,15 +1031,8 @@ determine_specialization (template_id, decl, targs_out,
FLAGS is a bitmask consisting of the following flags: FLAGS is a bitmask consisting of the following flags:
1: We are being called by finish_struct. (We are unable to
determine what template is specialized by an in-class
declaration until the class definition is complete, so
finish_struct_methods calls this function again later to finish
the job.)
2: The function has a definition. 2: The function has a definition.
4: The function is a friend. 4: The function is a friend.
8: The function is known to be a specialization of a member
template.
The TEMPLATE_COUNT is the number of references to qualifying The TEMPLATE_COUNT is the number of references to qualifying
template classes that appeared in the name of the function. For template classes that appeared in the name of the function. For
...@@ -1070,126 +1063,122 @@ check_explicit_specialization (declarator, decl, template_count, flags) ...@@ -1070,126 +1063,122 @@ check_explicit_specialization (declarator, decl, template_count, flags)
int template_count; int template_count;
int flags; int flags;
{ {
int finish_member = flags & 1;
int have_def = flags & 2; int have_def = flags & 2;
int is_friend = flags & 4; int is_friend = flags & 4;
int specialization = 0; int specialization = 0;
int explicit_instantiation = 0; int explicit_instantiation = 0;
int member_specialization = flags & 8; int member_specialization = 0;
tree ctype = DECL_CLASS_CONTEXT (decl); tree ctype = DECL_CLASS_CONTEXT (decl);
tree dname = DECL_NAME (decl); tree dname = DECL_NAME (decl);
if (!finish_member) if (processing_specialization)
{ {
if (processing_specialization) /* The last template header was of the form template <>. */
{
/* The last template header was of the form template <>. */
if (template_header_count > template_count) if (template_header_count > template_count)
{ {
/* There were more template headers than qualifying template /* There were more template headers than qualifying template
classes. */ classes. */
if (template_header_count - template_count > 1) if (template_header_count - template_count > 1)
/* There shouldn't be that many template parameter /* There shouldn't be that many template parameter
lists. There can be at most one parameter list for lists. There can be at most one parameter list for
every qualifying class, plus one for the function every qualifying class, plus one for the function
itself. */ itself. */
cp_error ("too many template parameter lists in declaration of `%D'", decl); cp_error ("too many template parameter lists in declaration of `%D'", decl);
SET_DECL_TEMPLATE_SPECIALIZATION (decl); SET_DECL_TEMPLATE_SPECIALIZATION (decl);
if (ctype) if (ctype)
member_specialization = 1; member_specialization = 1;
else else
specialization = 1; specialization = 1;
} }
else if (template_header_count == template_count) else if (template_header_count == template_count)
{ {
/* The counts are equal. So, this might be a /* The counts are equal. So, this might be a
specialization, but it is not a specialization of a specialization, but it is not a specialization of a
member template. It might be something like member template. It might be something like
template <class T> struct S { template <class T> struct S {
void f(int i); void f(int i);
}; };
template <> template <>
void S<int>::f(int i) {} */ void S<int>::f(int i) {} */
specialization = 1; specialization = 1;
SET_DECL_TEMPLATE_SPECIALIZATION (decl); SET_DECL_TEMPLATE_SPECIALIZATION (decl);
}
else
{
/* This cannot be an explicit specialization. There are not
enough headers for all of the qualifying classes. For
example, we might have:
template <>
void S<int>::T<char>::f();
But, we're missing another template <>. */
cp_error("too few template parameter lists in declaration of `%D'", decl);
return decl;
}
} }
else if (processing_explicit_instantiation) else
{ {
if (template_header_count) /* This cannot be an explicit specialization. There are not
cp_error ("template parameter list used in explicit instantiation"); enough headers for all of the qualifying classes. For
example, we might have:
template <>
void S<int>::T<char>::f();
But, we're missing another template <>. */
cp_error("too few template parameter lists in declaration of `%D'", decl);
return decl;
}
}
else if (processing_explicit_instantiation)
{
if (template_header_count)
cp_error ("template parameter list used in explicit instantiation");
if (have_def) if (have_def)
cp_error ("definition provided for explicit instantiation"); cp_error ("definition provided for explicit instantiation");
explicit_instantiation = 1; explicit_instantiation = 1;
} }
else if (ctype != NULL_TREE else if (ctype != NULL_TREE
&& !TYPE_BEING_DEFINED (ctype) && !TYPE_BEING_DEFINED (ctype)
&& CLASSTYPE_TEMPLATE_INSTANTIATION (ctype) && CLASSTYPE_TEMPLATE_INSTANTIATION (ctype)
&& !is_friend) && !is_friend)
{ {
/* This case catches outdated code that looks like this: /* This case catches outdated code that looks like this:
template <class T> struct S { void f(); }; template <class T> struct S { void f(); };
void S<int>::f() {} // Missing template <> void S<int>::f() {} // Missing template <>
We disable this check when the type is being defined to We disable this check when the type is being defined to
avoid complaining about default compiler-generated avoid complaining about default compiler-generated
constructors, destructors, and assignment operators. constructors, destructors, and assignment operators.
Since the type is an instantiation, not a specialization, Since the type is an instantiation, not a specialization,
these are the only functions that can be defined before these are the only functions that can be defined before
the class is complete. */ the class is complete. */
/* If they said /* If they said
template <class T> void S<int>::f() {} template <class T> void S<int>::f() {}
that's bogus. */ that's bogus. */
if (template_header_count) if (template_header_count)
{
cp_error ("template parameters specified in specialization");
return decl;
}
if (pedantic)
cp_pedwarn
("explicit specialization not preceded by `template <>'");
specialization = 1;
SET_DECL_TEMPLATE_SPECIALIZATION (decl);
}
else if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR)
{ {
if (is_friend) cp_error ("template parameters specified in specialization");
/* This could be something like: return decl;
}
template <class T> void f(T); if (pedantic)
class S { friend void f<>(int); } */ cp_pedwarn
specialization = 1; ("explicit specialization not preceded by `template <>'");
else specialization = 1;
{ SET_DECL_TEMPLATE_SPECIALIZATION (decl);
/* This case handles bogus declarations like template <> }
template <class T> void f<int>(); */ else if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR)
{
if (is_friend)
/* This could be something like:
cp_error ("template-id `%D' in declaration of primary template", template <class T> void f(T);
declarator); class S { friend void f<>(int); } */
return decl; specialization = 1;
} else
{
/* This case handles bogus declarations like template <>
template <class T> void f<int>(); */
cp_error ("template-id `%D' in declaration of primary template",
declarator);
return decl;
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment