Commit 6c30752f by Mark Mitchell Committed by Mark Mitchell

cp-tree.h (TI_PENDING_SPECIALIZATION_FLAG): Remove.

	* cp-tree.h (TI_PENDING_SPECIALIZATION_FLAG): Remove.
	* class.c (finish_struct): Remove hackery to deal with explicit
	specializations in class scope.
	* decl.c (grokfndecl): Improve error-recovery.
	* decl2.c (grokfield): Likewise.
	* pt.c (check_specialization_scope): New function.
	(begin_specialization): Call it.
	(process_partial_specialization): New function, split out from
	push_template_decl.  Check partial specializations more
	stringently.
	(push_template_decl): Call it.
	(check_explicit_specialization): Don't attempt to handle explicit
	specializations in class scope.
	(template_parm_data): Document.  Add current_arg and
	arg_uses_template_parms.
	(mark_template_parm): Set it.
	(tsubst_arg_types): Remove unused variable.
	* semantics.c (begin_class_definition): Tweak.

From-SVN: r22271
parent 00dd3ccd
1998-09-05 Mark Mitchell <mark@markmitchell.com>
* cp-tree.h (TI_PENDING_SPECIALIZATION_FLAG): Remove.
* class.c (finish_struct): Remove hackery to deal with explicit
specializations in class scope.
* decl.c (grokfndecl): Improve error-recovery.
* decl2.c (grokfield): Likewise.
* pt.c (check_specialization_scope): New function.
(begin_specialization): Call it.
(process_partial_specialization): New function, split out from
push_template_decl. Check partial specializations more
stringently.
(push_template_decl): Call it.
(check_explicit_specialization): Don't attempt to handle explicit
specializations in class scope.
(template_parm_data): Document. Add current_arg and
arg_uses_template_parms.
(mark_template_parm): Set it.
(tsubst_arg_types): Remove unused variable.
* semantics.c (begin_class_definition): Tweak.
1998-09-04 Mark Mitchell <mark@markmitchell.com>
* inc/typeinfo (type_info::type_info(const char*)): Make
......
......@@ -4148,8 +4148,6 @@ finish_struct (t, list_of_fieldlists, attributes, warn_anon)
{
tree fields = NULL_TREE;
tree *tail = &TYPE_METHODS (t);
tree specializations = NULL_TREE;
tree *specialization_tail = &specializations;
tree name = TYPE_NAME (t);
tree x, last_x = NULL_TREE;
tree access;
......@@ -4259,19 +4257,6 @@ finish_struct (t, list_of_fieldlists, attributes, warn_anon)
if (last_x)
TREE_CHAIN (last_x) = next_x;
if (DECL_TEMPLATE_SPECIALIZATION (x))
/* We don't enter the specialization into the class
method vector since specializations don't affect
overloading. Instead we keep track of the
specializations, and process them after the method
vector is complete. */
{
*specialization_tail = x;
specialization_tail = &TREE_CHAIN (x);
TREE_CHAIN (x) = NULL_TREE;
continue;
}
/* Link x onto end of TYPE_METHODS. */
*tail = x;
tail = &TREE_CHAIN (x);
......@@ -4359,27 +4344,6 @@ finish_struct (t, list_of_fieldlists, attributes, warn_anon)
t = finish_struct_1 (t, warn_anon);
TYPE_BEING_DEFINED (t) = 0;
/* Now, figure out which member templates we're specializing. */
for (x = specializations; x != NULL_TREE; x = TREE_CHAIN (x))
{
int pending_specialization;
pending_specialization
= TI_PENDING_SPECIALIZATION_FLAG (DECL_TEMPLATE_INFO (x));
check_explicit_specialization
(lookup_template_function (DECL_NAME (x), DECL_TI_ARGS (x)),
x, 0, 1 | (8 * pending_specialization));
TI_PENDING_SPECIALIZATION_FLAG (DECL_TEMPLATE_INFO (x)) = 0;
/* Now, the assembler name will be correct for fn, so we
make its RTL. */
DECL_RTL (x) = 0;
make_decl_rtl (x, NULL_PTR, 1);
DECL_RTL (DECL_TI_TEMPLATE (x)) = 0;
make_decl_rtl (DECL_TI_TEMPLATE (x), NULL_PTR, 1);
}
if (current_class_type)
popclass (0);
else
......
......@@ -35,7 +35,6 @@ Boston, MA 02111-1307, USA. */
(TREE_MANGLED) (in IDENTIFIER_NODE) (commented-out).
1: IDENTIFIER_VIRTUAL_P.
TI_PENDING_TEMPLATE_FLAG.
TI_PENDING_SPECIALIZATION_FLAG.
TEMPLATE_PARMS_FOR_INLINE.
DELETE_EXPR_USE_VEC (in DELETE_EXPR).
(TREE_CALLS_NEW) (in _EXPR or _REF) (commented-out).
......@@ -1267,11 +1266,6 @@ struct lang_decl
#define TI_SPEC_INFO(NODE) (TREE_CHAIN (NODE))
#define TI_PENDING_TEMPLATE_FLAG(NODE) TREE_LANG_FLAG_1 (NODE)
/* TI_PENDING_SPECIALIZATION_FLAG on a template-info node indicates
that the template is a specialization of a member template, but
that we don't yet know which one. */
#define TI_PENDING_SPECIALIZATION_FLAG(NODE) TREE_LANG_FLAG_1 (NODE)
/* The TEMPLATE_DECL instantiated or specialized by NODE. This
TEMPLATE_DECL will be the immediate parent, not the most general
template. For example, in:
......
......@@ -8016,6 +8016,8 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
template_count,
2 * (funcdef_flag != 0) +
4 * (friendp != 0));
if (decl == error_mark_node)
return error_mark_node;
if ((! TYPE_FOR_JAVA (ctype) || check_java_method (ctype, decl))
&& check)
......@@ -8063,6 +8065,9 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
template_count,
2 * (funcdef_flag != 0) +
4 * (friendp != 0));
if (decl == error_mark_node)
return error_mark_node;
if (ctype != NULL_TREE
&& (! TYPE_FOR_JAVA (ctype) || check_java_method (ctype, decl))
&& check)
......@@ -10392,10 +10397,15 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
if (decl && DECL_NAME (decl))
{
if (template_class_depth (current_class_type) == 0)
decl
= check_explicit_specialization
(declarator, decl,
template_count, 2 * (funcdef_flag != 0) + 4);
{
decl
= check_explicit_specialization
(declarator, decl,
template_count, 2 * (funcdef_flag != 0) + 4);
if (decl == error_mark_node)
return error_mark_node;
}
t = do_friend (ctype, declarator, decl,
last_function_parms, flags, quals,
funcdef_flag);
......
......@@ -1606,8 +1606,8 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
init = NULL_TREE;
value = grokdeclarator (declarator, declspecs, FIELD, init != 0, NULL_TREE);
if (! value)
return value; /* friend or constructor went bad. */
if (! value || value == error_mark_node)
return NULL_TREE; /* friend or constructor went bad. */
/* Pass friendly classes back. */
if (TREE_CODE (value) == VOID_TYPE)
......
......@@ -1234,9 +1234,9 @@ begin_class_definition (t)
&& TREE_CODE (TYPE_CONTEXT (t)) != NAMESPACE_DECL
&& ! current_class_type)
push_template_decl (TYPE_STUB_DECL (t));
maybe_process_partial_specialization (t);
pushclass (t, 0);
TYPE_BEING_DEFINED (t) = 1;
maybe_process_partial_specialization (t);
/* Reset the interface data, at the earliest possible
moment, as it might have been set via a class foo;
before. */
......
......@@ -5,11 +5,13 @@ struct S
{
template <class T>
void foo(T t);
template <>
void foo<int>(int) {}
};
template <>
template <>
void S<char*>::foo<int>(int) {}
int main()
{
S<char*> s;
......
......@@ -7,13 +7,14 @@ struct S
template <class T>
void foo(T t);
template <>
void foo(int) { }
template <class T>
void bar(T t) { this->template foo<U>(3.74); }
};
template <>
template <>
void S<int>::foo(int) { }
int main()
{
S<int> s;
......
......@@ -4,11 +4,11 @@ struct S
{
template <class T>
void foo(T t);
template <>
void foo<int>(int i) { }
};
template <>
void S::foo<int>(int i) { }
int main()
{
S s;
......
......@@ -4,12 +4,13 @@ struct S
struct Y {
template <class T>
void foo(T t);
template <>
void foo<int>(int i) { }
};
};
template <>
template <>
void S::Y<char>::foo<int>(int i) { }
int main()
{
S::Y<char> s;
......
......@@ -4,9 +4,6 @@ struct S
{
template <class T>
void foo(T t);
template <>
void foo(int i);
};
......
......@@ -4,9 +4,6 @@ struct S
{
template <class T>
void foo(T t);
template <>
void foo(int i);
};
......
......@@ -7,9 +7,9 @@ struct S3
static char* h(U);
};
template <class T>
template <>
char* S3<T>::h(int) { return __PRETTY_FUNCTION__; }
template <>
char* S3<double>::h(int) { return __PRETTY_FUNCTION__; }
template <>
template <>
......
......@@ -5,14 +5,15 @@ struct S
{
template <int i>
int f(int j) { abort(); return 0; }
template <>
int f<7>(int j) { return j + 7; }
template <>
int f<8>(int j) { return j + 8; }
};
template <>
template <>
int S<double>::f<7>(int j) { return j + 7; }
template <>
template <>
int S<double>::f<8>(int j) { return j + 8; }
int main()
{
......
......@@ -7,9 +7,9 @@ struct S
int f(U u);
};
template <class T>
template <>
int S<T>::f(int i) { return 1; }
template <>
int S<char>::f(int i) { return 1; }
int main()
{
......
......@@ -8,9 +8,9 @@ struct S
};
template <class T>
template <>
int S<T>::f<int>(int i) { return 1; }
template <>
int S<char>::f<int>(int i) { return 1; }
int main()
{
......
......@@ -14,11 +14,11 @@ struct S1
template <class T>
void f(T* t);
template <>
void f(int* ip) {}
};
template <>
void S1::f(int* ip) {}
template <class U>
struct S2
{
......@@ -27,11 +27,12 @@ struct S2
template <class T>
void f(T* t);
template <>
void f(int* ip) {}
};
template <>
template <>
void S2<double>::f(int* ip) {}
int main()
{
int* ip;
......
......@@ -28,9 +28,9 @@ struct S3
static int h(U);
};
template <class T>
template <>
int S3<T>::h(int) { return 0; }
template <>
int S3<double>::h(int) { return 0; }
template <>
template <>
......
// Build don't link:
template <class T>
struct S {
template <class U> void f(U);
template <> void f<int>(int); // ERROR - specialization
template <class V> struct I {};
template <class V> struct I<V*> {};
template <> struct I<int>; // ERROR - specialization
};
// Build don't link:
template <class T> struct S {};
template <class T = int> struct S<T*> {}; // ERROR - default argument
template <int I, int J> struct A {};
template <int I> struct A<I+5, I*2> {}; // ERROR - argument involves parameter
template <class T, T t> struct C {};
template <class T> struct C<T, 1>; // ERROR - type depends on parameter
int i;
template <class T> struct C<T*, &i>; // ERROR - type depends on parameter
template< int X, int (*array_ptr)[X] > class B {};
int array[5];
template< int X > class B<X,&array> { }; // ERROR - type depends on parameter
// Build don't link:
template <class T>
struct S
{
template <class U>
void f();
};
template <class T>
template <> // ERROR - enclosing classes not specialized
void S<T>::f<int> ()
{
}
......@@ -4,21 +4,23 @@ struct S1
{
template <class T>
void f(T t1, T t2);
template <>
void f(int i1, int i2);
};
template <>
void S1::f(int i1, int i2);
template <class U>
struct S2
{
template <class T>
void f(T t1, T t2);
template <>
void f(int i1, int i2);
};
template <>
template <>
void S2<char>::f(int i1, int i2);
void h()
{
S1 s1;
......
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