mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-01-16 07:24:47 +08:00
pt.c (redeclare_class_template): New function.
* pt.c (redeclare_class_template): New function. * cp_tree.h (redeclare_class_template): Declare it. * decl.c (xref_tag): Use it. From-SVN: r18855
This commit is contained in:
parent
7daa142bd6
commit
7fe6899fb7
@ -1,3 +1,9 @@
|
||||
Fri Mar 27 13:22:18 1998 Mark Mitchell <mmitchell@usa.net>
|
||||
|
||||
* pt.c (redeclare_class_template): New function.
|
||||
* cp_tree.h (redeclare_class_template): Declare it.
|
||||
* decl.c (xref_tag): Use it.
|
||||
|
||||
Thu Mar 26 11:16:30 1998 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* call.c (build_over_call): Check IS_AGGR_TYPE, not
|
||||
|
@ -2457,6 +2457,7 @@ extern tree end_template_parm_list PROTO((tree));
|
||||
extern void end_template_decl PROTO((void));
|
||||
extern tree current_template_args PROTO((void));
|
||||
extern tree push_template_decl PROTO((tree));
|
||||
extern void redeclare_class_template PROTO((tree));
|
||||
extern tree lookup_template_class PROTO((tree, tree, tree, tree));
|
||||
extern tree lookup_template_function PROTO((tree, tree));
|
||||
extern int uses_template_parms PROTO((tree));
|
||||
|
@ -10889,6 +10889,9 @@ xref_tag (code_type_node, name, binfo, globalize)
|
||||
if (BINDING_VALUE (binding) == NULL_TREE)
|
||||
BINDING_VALUE (binding) = TYPE_NAME (ref);
|
||||
}
|
||||
|
||||
if (!globalize && processing_template_decl && IS_AGGR_TYPE (ref))
|
||||
redeclare_class_template (ref);
|
||||
}
|
||||
|
||||
if (binfo)
|
||||
|
60
gcc/cp/pt.c
60
gcc/cp/pt.c
@ -1792,6 +1792,66 @@ push_template_decl (decl)
|
||||
return DECL_TEMPLATE_RESULT (tmpl);
|
||||
}
|
||||
|
||||
/* Called when a class template TYPE is redeclared, e.g.:
|
||||
|
||||
template <class T> struct S;
|
||||
template <class T> struct S {}; */
|
||||
|
||||
void
|
||||
redeclare_class_template (type)
|
||||
tree type;
|
||||
{
|
||||
tree tmpl = CLASSTYPE_TI_TEMPLATE (type);
|
||||
tree tmpl_parms = DECL_INNERMOST_TEMPLATE_PARMS (tmpl);
|
||||
tree parms = INNERMOST_TEMPLATE_PARMS (current_template_parms);
|
||||
int i;
|
||||
|
||||
if (!PRIMARY_TEMPLATE_P (tmpl))
|
||||
/* The type is nested in some template class. Nothing to worry
|
||||
about here; there are no new template parameters for the nested
|
||||
type. */
|
||||
return;
|
||||
|
||||
if (TREE_VEC_LENGTH (parms) != TREE_VEC_LENGTH (tmpl_parms))
|
||||
{
|
||||
cp_error_at ("previous declaration `%D'", tmpl);
|
||||
cp_error ("used %d template parameter%s instead of %d",
|
||||
TREE_VEC_LENGTH (tmpl_parms),
|
||||
TREE_VEC_LENGTH (tmpl_parms) == 1 ? "" : "s",
|
||||
TREE_VEC_LENGTH (parms));
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < TREE_VEC_LENGTH (tmpl_parms); ++i)
|
||||
{
|
||||
tree tmpl_parm = TREE_VALUE (TREE_VEC_ELT (tmpl_parms, i));
|
||||
tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
|
||||
tree tmpl_default = TREE_PURPOSE (TREE_VEC_ELT (tmpl_parms, i));
|
||||
tree parm_default = TREE_PURPOSE (TREE_VEC_ELT (parms, i));
|
||||
|
||||
if (TREE_CODE (tmpl_parm) != TREE_CODE (parm))
|
||||
{
|
||||
cp_error_at ("template parameter `%#D'", tmpl_parm);
|
||||
cp_error ("redeclared here as `%#D'", parm);
|
||||
return;
|
||||
}
|
||||
|
||||
if (tmpl_default != NULL_TREE && parm_default != NULL_TREE)
|
||||
{
|
||||
/* We have in [temp.param]:
|
||||
|
||||
A template-parameter may not be given default arguments
|
||||
by two different declarations in the same scope. */
|
||||
cp_error ("redefinition of default argument for `%#D'", parm);
|
||||
return;
|
||||
}
|
||||
|
||||
if (parm_default != NULL_TREE)
|
||||
/* Update the previous template parameters (which are the ones
|
||||
that will really count) with the new default value. */
|
||||
TREE_PURPOSE (TREE_VEC_ELT (tmpl_parms, i)) = parm_default;
|
||||
}
|
||||
}
|
||||
|
||||
/* Attempt to convert the non-type template parameter EXPR to the
|
||||
indicated TYPE. If the conversion is successful, return the
|
||||
|
16
gcc/testsuite/g++.old-deja/g++.pt/defarg3.C
Normal file
16
gcc/testsuite/g++.old-deja/g++.pt/defarg3.C
Normal file
@ -0,0 +1,16 @@
|
||||
// Build don't link:
|
||||
|
||||
template <class T>
|
||||
struct S;
|
||||
|
||||
template <class T = int>
|
||||
struct S {};
|
||||
|
||||
template <class T>
|
||||
struct S;
|
||||
|
||||
void f()
|
||||
{
|
||||
S<> s;
|
||||
}
|
||||
|
22
gcc/testsuite/g++.old-deja/g++.pt/redecl1.C
Normal file
22
gcc/testsuite/g++.old-deja/g++.pt/redecl1.C
Normal file
@ -0,0 +1,22 @@
|
||||
// Build don't link:
|
||||
|
||||
template <class T>
|
||||
struct S1; // ERROR - previous declaration
|
||||
|
||||
template <class T, class U>
|
||||
struct S1 {}; // ERROR - used 1 template parameter
|
||||
|
||||
template <class T = int>
|
||||
struct S2;
|
||||
|
||||
template <class T = int>
|
||||
struct S2; // ERROR - redefinition of default
|
||||
|
||||
template <class T> // ERROR - template parameter
|
||||
struct S3;
|
||||
|
||||
template <int I>
|
||||
struct S3; // ERROR - redeclared here
|
||||
|
||||
template <template <class T> class C>
|
||||
struct S3; // ERROR - redeclared here
|
Loading…
Reference in New Issue
Block a user