From cae40af6efc85015875dbf8e5e2210b72d86817a Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Sun, 15 Mar 1998 14:53:08 -0500 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 25 ++++++++++- gcc/cp/cp-tree.h | 2 + gcc/cp/lex.c | 3 +- gcc/cp/pt.c | 133 +++++++++++++++++++++++++++++++++++++------------------ 4 files changed, 117 insertions(+), 46 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 84ea33f..9b47256 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,22 @@ +Sun Mar 15 02:07:26 1998 Jason Merrill + + * 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 + + * 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 * pt.c (tsubst): Clear TYPE_REFERENCE_TO when creating a @@ -15,7 +34,8 @@ Sun Mar 15 12:26:02 1998 Manfred Hollstein Thu Mar 12 09:39:40 1998 Manfred Hollstein - * 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 && and || in expression. @@ -32,7 +52,8 @@ Thu Mar 12 09:26:04 1998 Manfred Hollstein * except.c (do_unwind): #if 0 definition of unused variables fcall 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. (build_new_1): Remove unused variable t. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 1cee86b..0e9f9d8 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1157,6 +1157,8 @@ struct lang_decl #define CLASSTYPE_TI_SPEC_INFO(NODE) TI_SPEC_INFO (CLASSTYPE_TEMPLATE_INFO (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 COMPOUND_STMT_NO_SCOPE(NODE) TREE_LANG_FLAG_0 (NODE) #define NEW_EXPR_USE_GLOBAL(NODE) TREE_LANG_FLAG_0 (NODE) diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index b953f95..26c9221 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -2811,7 +2811,8 @@ do_identifier (token, parsing) But we still want to return this value. */ id = lookup_field (current_class_type, token, 0, 0); else if (TREE_CODE (field) == VAR_DECL - || TREE_CODE (field) == CONST_DECL) + || TREE_CODE (field) == CONST_DECL + || TREE_CODE (field) == TEMPLATE_DECL) id = field; else if (TREE_CODE (field) != FIELD_DECL) my_friendly_abort (61); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 9b67811..52a4254 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -86,7 +86,6 @@ static int type_unification_real PROTO((tree, tree *, tree, tree, static void note_template_header PROTO((int)); static tree maybe_fold_nontype_arg PROTO((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 using TEMPLATE_PARAMETERS as its innermost parameter list) is @@ -164,31 +163,60 @@ template_class_depth (type) return depth; } -/* Restore the template parameter context for a member template or - a friend template defined in a class definition. */ +/* Return the original template for this decl, disregarding any + specializations. */ -void -maybe_begin_member_template_processing (decl) +static tree +original_template (decl) tree decl; { - tree parms; - int i; + while (DECL_TEMPLATE_INFO (decl)) + decl = DECL_TI_TEMPLATE (decl); + return decl; +} - if (!is_member_or_friend_template (decl, 1)) - return; +/* Returns 1 if processing DECL as part of do_pending_inlines + 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; - current_template_parms + current_template_parms = tree_cons (build_int_2 (0, processing_template_decl), parms, current_template_parms); + TEMPLATE_PARMS_FOR_INLINE (current_template_parms) = 1; + pushlevel (0); for (i = 0; i < TREE_VEC_LENGTH (parms); ++i) { tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i)); my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (parm)) == 'd', 0); - + switch (TREE_CODE (parm)) { case TYPE_DECL: @@ -204,7 +232,7 @@ maybe_begin_member_template_processing (decl) DECL_INITIAL (decl) = DECL_INITIAL (parm); pushdecl (decl); } - break; + break; default: my_friendly_abort (0); @@ -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. */ void maybe_end_member_template_processing (decl) tree decl; { - if (!is_member_or_friend_template (decl, 1)) - return; - if (! processing_template_decl) return; - --processing_template_decl; - current_template_parms = TREE_CHAIN (current_template_parms); - poplevel (0, 0, 0); + while (current_template_parms + && TEMPLATE_PARMS_FOR_INLINE (current_template_parms)) + { + --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 - ALLOW_FRIEND is non-zero, a friend template function. We must be +/* Returns non-zero iff T is a member template function. We must be careful as in template class C { void f(); } @@ -244,10 +298,9 @@ maybe_end_member_template_processing (decl) then neither C::f nor C::f is considered to be a member template. */ -static int -is_member_or_friend_template (t, allow_friend) +int +is_member_template (t) tree t; - int allow_friend; { if (TREE_CODE (t) != FUNCTION_DECL && !DECL_FUNCTION_TEMPLATE_P (t)) @@ -255,15 +308,14 @@ is_member_or_friend_template (t, allow_friend) certainly not a member template. */ return 0; - if (((DECL_FUNCTION_MEMBER_P (t) - || (allow_friend && DECL_FRIEND_P (t))) + /* A local class can't have member templates. */ + if (hack_decl_function_context (t)) + return 0; + + if ((DECL_FUNCTION_MEMBER_P (t) && !DECL_TEMPLATE_SPECIALIZATION (t)) || (TREE_CODE (t) == TEMPLATE_DECL - && (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))))) + && DECL_FUNCTION_MEMBER_P (DECL_TEMPLATE_RESULT (t)))) { tree tmpl; @@ -275,27 +327,18 @@ is_member_or_friend_template (t, allow_friend) else tmpl = NULL_TREE; - if (tmpl && + if (tmpl /* If there are more levels of template parameters than there are template classes surrounding the declaration, then we have a member template. */ - list_length (DECL_TEMPLATE_PARMS (tmpl)) > - template_class_depth (DECL_CLASS_CONTEXT (t))) + && (list_length (DECL_TEMPLATE_PARMS (tmpl)) > + template_class_depth (DECL_CLASS_CONTEXT (t)))) return 1; } 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, but has as its innermost set of arguments the EXTRA_ARGS. */ @@ -1092,6 +1135,10 @@ reduce_template_parm_level (index, type, levels) TEMPLATE_PARM_ORIG_LEVEL (index), decl, type); 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); -- 2.7.4