From cfe507bee830d9c451bbbdc1f1a5cc36dfc89616 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Tue, 17 Aug 1999 22:35:19 +0000 Subject: [PATCH] decl.c (add_decl_to_level): New function. * decl.c (add_decl_to_level): New function. (push_local_binding): Use it. (find_binding): Fix typo in comment. (pushdecl): Use add_decl_to_level. Put templates on the corresponding namespace-scope binding levels. * dump.c (dequeue_and_dump): Print the specializations of a template. * pt.c (push_template_decl_real): Don't push a template multiple times. From-SVN: r28738 --- gcc/cp/ChangeLog | 12 ++++++++++++ gcc/cp/decl.c | 49 ++++++++++++++++++++++++++++++++---------------- gcc/cp/dump.c | 7 ++++++- gcc/cp/pt.c | 6 ++++-- 4 files changed, 55 insertions(+), 19 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index da75c334d44..ee595ab50c0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,15 @@ +1999-08-17 Mark Mitchell + + * decl.c (add_decl_to_level): New function. + (push_local_binding): Use it. + (find_binding): Fix typo in comment. + (pushdecl): Use add_decl_to_level. Put templates on the + corresponding namespace-scope binding levels. + * dump.c (dequeue_and_dump): Print the specializations of a + template. + * pt.c (push_template_decl_real): Don't push a template multiple + times. + 1999-08-17 Mark Mitchell * cp-tree.h (CALL_DECLARATOR_PARMS): New macro. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index d5fcbeae89d..baf1a32cbf5 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -189,6 +189,7 @@ static tree poplevel_class PROTO((void)); static void warn_about_implicit_typename_lookup PROTO((tree, tree)); static int walk_namespaces_r PROTO((tree, walk_namespaces_fn, void *)); static int walk_globals_r PROTO((tree, void *)); +static void add_decl_to_level PROTO((tree, struct binding_level *)); #if defined (DEBUG_CP_BINDING_LEVELS) static void indent PROTO((void)); @@ -1099,9 +1100,29 @@ add_binding (id, decl) return ok; } -/* Bind DECL to ID in the current_binding_level. - If PUSH_USING is set in FLAGS, we know that DECL doesn't really belong - to this binding level, that it got here through a using-declaration. */ +/* Add DECL to the list of things declared in B. */ + +static void +add_decl_to_level (decl, b) + tree decl; + struct binding_level *b; +{ + /* Only things that will live forever should go in the global + binding level. */ + my_friendly_assert (!(b == global_binding_level + && !TREE_PERMANENT (decl)), + 19990817); + + /* We build up the list in reverse order, and reverse it later if + necessary. */ + TREE_CHAIN (decl) = b->names; + b->names = decl; +} + +/* Bind DECL to ID in the current_binding_level, assumed to be a local + binding level. If PUSH_USING is set in FLAGS, we know that DECL + doesn't really belong to this binding level, that it got here + through a using-declaration. */ void push_local_binding (id, decl, flags) @@ -1138,8 +1159,7 @@ push_local_binding (id, decl, flags) /* And put DECL on the list of things declared by the current binding level. */ - TREE_CHAIN (decl) = b->names; - b->names = decl; + add_decl_to_level (decl, b); } /* Bind DECL to ID in the class_binding_level. Returns nonzero if the @@ -2148,7 +2168,7 @@ find_binding (name, scope) my_friendly_assert (TREE_CODE (iter) == CPLUS_BINDING, 374); if (BINDING_SCOPE (iter) == scope) { - /* Move binding found to the fron of the list, so + /* Move binding found to the front of the list, so subsequent lookups will find it faster. */ if (prev) { @@ -3955,7 +3975,12 @@ pushdecl (x) need_new_binding = 0; } else if (DECL_FUNCTION_TEMPLATE_P (x) && DECL_NAMESPACE_SCOPE_P (x)) - return push_overloaded_decl (x, PUSH_GLOBAL); + { + t = push_overloaded_decl (x, PUSH_GLOBAL); + if (t == x) + add_decl_to_level (x, NAMESPACE_LEVEL (CP_DECL_CONTEXT (t))); + return t; + } /* If declaring a type as a typedef, copy the type (unless we're at line 0), and install this TYPE_DECL as the new type's typedef @@ -4189,15 +4214,7 @@ pushdecl (x) } if (need_new_binding) - { - /* Put decls on list in reverse order. - We will reverse them later if necessary. */ - TREE_CHAIN (x) = current_binding_level->names; - current_binding_level->names = x; - if (current_binding_level == global_binding_level - && !TREE_PERMANENT (x)) - my_friendly_abort (124); - } + add_decl_to_level (x, current_binding_level); return x; } diff --git a/gcc/cp/dump.c b/gcc/cp/dump.c index e04655264a8..d67ab68867d 100644 --- a/gcc/cp/dump.c +++ b/gcc/cp/dump.c @@ -606,7 +606,7 @@ dequeue_and_dump (di) if (DECL_CONV_FN_P (t)) dump_string (di, "conversion"); if (dump_children_p) - dump_child ("body", DECL_INITIAL (t)); + dump_child ("body", DECL_SAVED_TREE (t)); break; case NAMESPACE_DECL: @@ -618,6 +618,11 @@ dequeue_and_dump (di) dump_child ("dcls", cp_namespace_decls (t)); break; + case TEMPLATE_DECL: + if (dump_children_p) + dump_child ("spcs", DECL_TEMPLATE_SPECIALIZATIONS (t)); + break; + case OVERLOAD: if (dump_children_p) { diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index cf2050ab20d..924f03fad59 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -2385,6 +2385,7 @@ push_template_decl_real (decl, is_friend) tree ctx; int primary; int is_partial; + int new_template_p = 0; /* See if this is a partial specialization. */ is_partial = (DECL_IMPLICIT_TYPEDEF_P (decl) @@ -2449,7 +2450,8 @@ push_template_decl_real (decl, is_friend) else { tmpl = build_template_decl (decl, current_template_parms); - + new_template_p = 1; + if (DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_SPECIALIZATION (decl)) { @@ -2560,7 +2562,7 @@ push_template_decl_real (decl, is_friend) that we do not try to push a global template friend declared in a template class; such a thing may well depend on the template parameters of the class. */ - if (! ctx + if (new_template_p && !ctx && !(is_friend && template_class_depth (current_class_type) > 0)) tmpl = pushdecl_namespace_level (tmpl);