Commit cae40af6 by Jason Merrill

cp-tree.h (TEMPLATE_PARMS_FOR_INLINE): New macro.

	* cp-tree.h (TEMPLATE_PARMS_FOR_INLINE): New macro.
	* pt.c (inline_needs_template_parms): New fn.
	(original_template): New fn.
	(push_inline_template_parms_recursive): New fn.
	(maybe_begin_member_template_processing): Use them.
	(maybe_end_member_template_processing): Likewise.
	(is_member_or_friend_template): Rename to is_member_template.
	Member functions of local classes are never member templates.
	* lex.c (do_identifier): Handle TEMPLATE_DECL that was
	added in the class scope to catch redefinition error.
	* pt.c (reduce_template_parm_level): Also copy
	the DECL_TEMPLATE_PARMS field.

From-SVN: r18595
parent debf0b88
Sun Mar 15 02:07:26 1998 Jason Merrill <jason@yorick.cygnus.com>
* cp-tree.h (TEMPLATE_PARMS_FOR_INLINE): New macro.
* pt.c (inline_needs_template_parms): New fn.
(original_template): New fn.
(push_inline_template_parms_recursive): New fn.
(maybe_begin_member_template_processing): Use them.
(maybe_end_member_template_processing): Likewise.
(is_member_or_friend_template): Rename to is_member_template.
Member functions of local classes are never member templates.
Sun Mar 15 01:14:22 1998 Kriang Lerdsuwanakij <lerdsuwa@scf.usc.edu>
* lex.c (do_identifier): Handle TEMPLATE_DECL that was
added in the class scope to catch redefinition error.
* pt.c (reduce_template_parm_level): Also copy
the DECL_TEMPLATE_PARMS field.
Sun Mar 15 10:54:08 1998 Mark Mitchell <mmitchell@usa.net> Sun Mar 15 10:54:08 1998 Mark Mitchell <mmitchell@usa.net>
* pt.c (tsubst): Clear TYPE_REFERENCE_TO when creating a * pt.c (tsubst): Clear TYPE_REFERENCE_TO when creating a
...@@ -15,7 +34,8 @@ Sun Mar 15 12:26:02 1998 Manfred Hollstein <manfred@s-direktnet.de> ...@@ -15,7 +34,8 @@ Sun Mar 15 12:26:02 1998 Manfred Hollstein <manfred@s-direktnet.de>
Thu Mar 12 09:39:40 1998 Manfred Hollstein <manfred@s-direktnet.de> Thu Mar 12 09:39:40 1998 Manfred Hollstein <manfred@s-direktnet.de>
* lang-specs.h: Properly put brackets around array elements in initializer. * lang-specs.h: Properly put brackets around array elements in
initializer.
* typeck.c (build_binary_op_nodefault): Correctly place parens around * typeck.c (build_binary_op_nodefault): Correctly place parens around
&& and || in expression. && and || in expression.
...@@ -32,7 +52,8 @@ Thu Mar 12 09:26:04 1998 Manfred Hollstein <manfred@s-direktnet.de> ...@@ -32,7 +52,8 @@ Thu Mar 12 09:26:04 1998 Manfred Hollstein <manfred@s-direktnet.de>
* except.c (do_unwind): #if 0 definition of unused variables fcall * except.c (do_unwind): #if 0 definition of unused variables fcall
and next_pc. and next_pc.
* expr.c (extract_scalar_init): #if 0 prototype and function definition. * expr.c (extract_scalar_init): #if 0 prototype and function
definition.
* init.c (expand_aggr_init_1): Remove unused variable init_type. * init.c (expand_aggr_init_1): Remove unused variable init_type.
(build_new_1): Remove unused variable t. (build_new_1): Remove unused variable t.
......
...@@ -1157,6 +1157,8 @@ struct lang_decl ...@@ -1157,6 +1157,8 @@ struct lang_decl
#define CLASSTYPE_TI_SPEC_INFO(NODE) TI_SPEC_INFO (CLASSTYPE_TEMPLATE_INFO (NODE)) #define CLASSTYPE_TI_SPEC_INFO(NODE) TI_SPEC_INFO (CLASSTYPE_TEMPLATE_INFO (NODE))
#define INNERMOST_TEMPLATE_PARMS(NODE) TREE_VALUE(NODE) #define INNERMOST_TEMPLATE_PARMS(NODE) TREE_VALUE(NODE)
#define TEMPLATE_PARMS_FOR_INLINE(NODE) TREE_LANG_FLAG_1 (NODE)
#define DECL_SAVED_TREE(NODE) DECL_MEMFUNC_POINTER_TO (NODE) #define DECL_SAVED_TREE(NODE) DECL_MEMFUNC_POINTER_TO (NODE)
#define COMPOUND_STMT_NO_SCOPE(NODE) TREE_LANG_FLAG_0 (NODE) #define COMPOUND_STMT_NO_SCOPE(NODE) TREE_LANG_FLAG_0 (NODE)
#define NEW_EXPR_USE_GLOBAL(NODE) TREE_LANG_FLAG_0 (NODE) #define NEW_EXPR_USE_GLOBAL(NODE) TREE_LANG_FLAG_0 (NODE)
......
...@@ -2811,7 +2811,8 @@ do_identifier (token, parsing) ...@@ -2811,7 +2811,8 @@ do_identifier (token, parsing)
But we still want to return this value. */ But we still want to return this value. */
id = lookup_field (current_class_type, token, 0, 0); id = lookup_field (current_class_type, token, 0, 0);
else if (TREE_CODE (field) == VAR_DECL else if (TREE_CODE (field) == VAR_DECL
|| TREE_CODE (field) == CONST_DECL) || TREE_CODE (field) == CONST_DECL
|| TREE_CODE (field) == TEMPLATE_DECL)
id = field; id = field;
else if (TREE_CODE (field) != FIELD_DECL) else if (TREE_CODE (field) != FIELD_DECL)
my_friendly_abort (61); my_friendly_abort (61);
......
...@@ -86,7 +86,6 @@ static int type_unification_real PROTO((tree, tree *, tree, tree, ...@@ -86,7 +86,6 @@ static int type_unification_real PROTO((tree, tree *, tree, tree,
static void note_template_header PROTO((int)); static void note_template_header PROTO((int));
static tree maybe_fold_nontype_arg PROTO((tree)); static tree maybe_fold_nontype_arg PROTO((tree));
static tree convert_nontype_argument PROTO((tree, tree)); static tree convert_nontype_argument PROTO((tree, tree));
static int is_member_or_friend_template PROTO((tree, int));
/* Do any processing required when DECL (a member template declaration /* Do any processing required when DECL (a member template declaration
using TEMPLATE_PARAMETERS as its innermost parameter list) is using TEMPLATE_PARAMETERS as its innermost parameter list) is
...@@ -164,31 +163,60 @@ template_class_depth (type) ...@@ -164,31 +163,60 @@ template_class_depth (type)
return depth; return depth;
} }
/* Restore the template parameter context for a member template or /* Return the original template for this decl, disregarding any
a friend template defined in a class definition. */ specializations. */
void static tree
maybe_begin_member_template_processing (decl) original_template (decl)
tree decl; tree decl;
{ {
tree parms; while (DECL_TEMPLATE_INFO (decl))
int i; decl = DECL_TI_TEMPLATE (decl);
return decl;
}
if (!is_member_or_friend_template (decl, 1)) /* Returns 1 if processing DECL as part of do_pending_inlines
return; needs us to push template parms. */
static int
inline_needs_template_parms (decl)
tree decl;
{
if (! DECL_TEMPLATE_INFO (decl))
return 0;
return (list_length (DECL_TEMPLATE_PARMS (original_template (decl)))
> (processing_template_decl + DECL_TEMPLATE_SPECIALIZATION (decl)));
}
parms = DECL_INNERMOST_TEMPLATE_PARMS (DECL_TI_TEMPLATE (decl)); /* Subroutine of maybe_begin_member_template_processing.
Push the template parms in PARMS, starting from LEVELS steps into the
chain, and ending at the beginning, since template parms are listed
innermost first. */
static void
push_inline_template_parms_recursive (parmlist, levels)
tree parmlist;
int levels;
{
tree parms = TREE_VALUE (parmlist);
int i;
if (levels > 1)
push_inline_template_parms_recursive (TREE_CHAIN (parmlist), levels - 1);
++processing_template_decl; ++processing_template_decl;
current_template_parms current_template_parms
= tree_cons (build_int_2 (0, processing_template_decl), = tree_cons (build_int_2 (0, processing_template_decl),
parms, current_template_parms); parms, current_template_parms);
TEMPLATE_PARMS_FOR_INLINE (current_template_parms) = 1;
pushlevel (0); pushlevel (0);
for (i = 0; i < TREE_VEC_LENGTH (parms); ++i) for (i = 0; i < TREE_VEC_LENGTH (parms); ++i)
{ {
tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i)); tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (parm)) == 'd', 0); my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (parm)) == 'd', 0);
switch (TREE_CODE (parm)) switch (TREE_CODE (parm))
{ {
case TYPE_DECL: case TYPE_DECL:
...@@ -204,7 +232,7 @@ maybe_begin_member_template_processing (decl) ...@@ -204,7 +232,7 @@ maybe_begin_member_template_processing (decl)
DECL_INITIAL (decl) = DECL_INITIAL (parm); DECL_INITIAL (decl) = DECL_INITIAL (parm);
pushdecl (decl); pushdecl (decl);
} }
break; break;
default: default:
my_friendly_abort (0); my_friendly_abort (0);
...@@ -212,25 +240,51 @@ maybe_begin_member_template_processing (decl) ...@@ -212,25 +240,51 @@ maybe_begin_member_template_processing (decl)
} }
} }
/* Restore the template parameter context for a member template or
a friend template defined in a class definition. */
void
maybe_begin_member_template_processing (decl)
tree decl;
{
tree parms;
int levels;
if (! inline_needs_template_parms (decl))
return;
parms = DECL_TEMPLATE_PARMS (original_template (decl));
levels = list_length (parms) - processing_template_decl;
if (DECL_TEMPLATE_SPECIALIZATION (decl))
{
--levels;
parms = TREE_CHAIN (parms);
}
push_inline_template_parms_recursive (parms, levels);
}
/* Undo the effects of begin_member_template_processing. */ /* Undo the effects of begin_member_template_processing. */
void void
maybe_end_member_template_processing (decl) maybe_end_member_template_processing (decl)
tree decl; tree decl;
{ {
if (!is_member_or_friend_template (decl, 1))
return;
if (! processing_template_decl) if (! processing_template_decl)
return; return;
--processing_template_decl; while (current_template_parms
current_template_parms = TREE_CHAIN (current_template_parms); && TEMPLATE_PARMS_FOR_INLINE (current_template_parms))
poplevel (0, 0, 0); {
--processing_template_decl;
current_template_parms = TREE_CHAIN (current_template_parms);
poplevel (0, 0, 0);
}
} }
/* Returns non-zero iff T is a member template function, or, if /* Returns non-zero iff T is a member template function. We must be
ALLOW_FRIEND is non-zero, a friend template function. We must be
careful as in careful as in
template <class T> class C { void f(); } template <class T> class C { void f(); }
...@@ -244,10 +298,9 @@ maybe_end_member_template_processing (decl) ...@@ -244,10 +298,9 @@ maybe_end_member_template_processing (decl)
then neither C<int>::f<char> nor C<T>::f<double> is considered then neither C<int>::f<char> nor C<T>::f<double> is considered
to be a member template. */ to be a member template. */
static int int
is_member_or_friend_template (t, allow_friend) is_member_template (t)
tree t; tree t;
int allow_friend;
{ {
if (TREE_CODE (t) != FUNCTION_DECL if (TREE_CODE (t) != FUNCTION_DECL
&& !DECL_FUNCTION_TEMPLATE_P (t)) && !DECL_FUNCTION_TEMPLATE_P (t))
...@@ -255,15 +308,14 @@ is_member_or_friend_template (t, allow_friend) ...@@ -255,15 +308,14 @@ is_member_or_friend_template (t, allow_friend)
certainly not a member template. */ certainly not a member template. */
return 0; return 0;
if (((DECL_FUNCTION_MEMBER_P (t) /* A local class can't have member templates. */
|| (allow_friend && DECL_FRIEND_P (t))) if (hack_decl_function_context (t))
return 0;
if ((DECL_FUNCTION_MEMBER_P (t)
&& !DECL_TEMPLATE_SPECIALIZATION (t)) && !DECL_TEMPLATE_SPECIALIZATION (t))
|| (TREE_CODE (t) == TEMPLATE_DECL || (TREE_CODE (t) == TEMPLATE_DECL
&& (DECL_FUNCTION_MEMBER_P (DECL_TEMPLATE_RESULT (t)) && DECL_FUNCTION_MEMBER_P (DECL_TEMPLATE_RESULT (t))))
|| (allow_friend
&& DECL_FUNCTION_TEMPLATE_P (t)
&& DECL_FRIEND_P (DECL_TEMPLATE_RESULT (t))
&& DECL_CLASS_CONTEXT (t)))))
{ {
tree tmpl; tree tmpl;
...@@ -275,27 +327,18 @@ is_member_or_friend_template (t, allow_friend) ...@@ -275,27 +327,18 @@ is_member_or_friend_template (t, allow_friend)
else else
tmpl = NULL_TREE; tmpl = NULL_TREE;
if (tmpl && if (tmpl
/* If there are more levels of template parameters than /* If there are more levels of template parameters than
there are template classes surrounding the declaration, there are template classes surrounding the declaration,
then we have a member template. */ then we have a member template. */
list_length (DECL_TEMPLATE_PARMS (tmpl)) > && (list_length (DECL_TEMPLATE_PARMS (tmpl)) >
template_class_depth (DECL_CLASS_CONTEXT (t))) template_class_depth (DECL_CLASS_CONTEXT (t))))
return 1; return 1;
} }
return 0; return 0;
} }
/* Returns non-zero iff T is a member template. */
int
is_member_template (t)
tree t;
{
return is_member_or_friend_template (t, 0);
}
/* Return a new template argument vector which contains all of ARGS, /* Return a new template argument vector which contains all of ARGS,
but has as its innermost set of arguments the EXTRA_ARGS. */ but has as its innermost set of arguments the EXTRA_ARGS. */
...@@ -1092,6 +1135,10 @@ reduce_template_parm_level (index, type, levels) ...@@ -1092,6 +1135,10 @@ reduce_template_parm_level (index, type, levels)
TEMPLATE_PARM_ORIG_LEVEL (index), TEMPLATE_PARM_ORIG_LEVEL (index),
decl, type); decl, type);
TEMPLATE_PARM_DESCENDANTS (index) = t; TEMPLATE_PARM_DESCENDANTS (index) = t;
/* Template template parameters need this. */
DECL_TEMPLATE_PARMS (decl)
= DECL_TEMPLATE_PARMS (TEMPLATE_PARM_DECL (index));
} }
return TEMPLATE_PARM_DESCENDANTS (index); return TEMPLATE_PARM_DESCENDANTS (index);
......
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