This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH to push template decls onto binding lists
- To: gcc-patches at gcc dot gnu dot org
- Subject: PATCH to push template decls onto binding lists
- From: Mark Mitchell <mark at codesourcery dot com>
- Date: Tue, 17 Aug 1999 15:39:12 -0700
- Organization: CodeSourcery, LLC
We weren't putting TEMPLATE_DECLs on to the list of things declared in
a namespace. That doesn't matter to the compiler per se, but it does
matter to tools that will make use of the C++ front-end in the future.
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
1999-08-17 Mark Mitchell <mark@codesourcery.com>
* 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.
Index: decl.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/decl.c,v
retrieving revision 1.409
diff -c -p -r1.409 decl.c
*** decl.c 1999/08/16 22:08:40 1.409
--- decl.c 1999/08/17 22:03:33
*************** static tree poplevel_class PROTO((void))
*** 189,194 ****
--- 189,195 ----
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));
*************** add_binding (id, decl)
*** 1099,1108 ****
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. */
void
push_local_binding (id, decl, flags)
tree id;
--- 1100,1129 ----
return ok;
}
! /* 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)
tree id;
*************** push_local_binding (id, decl, flags)
*** 1138,1145 ****
/* And put DECL on the list of things declared by the current
binding level. */
! TREE_CHAIN (decl) = b->names;
! b->names = decl;
}
/* Bind DECL to ID in the class_binding_level. Returns nonzero if the
--- 1159,1165 ----
/* And put DECL on the list of things declared by the current
binding level. */
! add_decl_to_level (decl, b);
}
/* Bind DECL to ID in the class_binding_level. Returns nonzero if the
*************** find_binding (name, scope)
*** 2148,2154 ****
my_friendly_assert (TREE_CODE (iter) == CPLUS_BINDING, 374);
if (BINDING_SCOPE (iter) == scope)
{
! /* Move binding found to the fron of the list, so
subsequent lookups will find it faster. */
if (prev)
{
--- 2168,2174 ----
my_friendly_assert (TREE_CODE (iter) == CPLUS_BINDING, 374);
if (BINDING_SCOPE (iter) == scope)
{
! /* Move binding found to the front of the list, so
subsequent lookups will find it faster. */
if (prev)
{
*************** pushdecl (x)
*** 3955,3961 ****
need_new_binding = 0;
}
else if (DECL_FUNCTION_TEMPLATE_P (x) && DECL_NAMESPACE_SCOPE_P (x))
! return push_overloaded_decl (x, PUSH_GLOBAL);
/* 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
--- 3975,3986 ----
need_new_binding = 0;
}
else if (DECL_FUNCTION_TEMPLATE_P (x) && DECL_NAMESPACE_SCOPE_P (x))
! {
! 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
*************** pushdecl (x)
*** 4189,4203 ****
}
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);
! }
return x;
}
--- 4214,4220 ----
}
if (need_new_binding)
! add_decl_to_level (x, current_binding_level);
return x;
}
Index: dump.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/dump.c,v
retrieving revision 1.4
diff -c -p -r1.4 dump.c
*** dump.c 1999/08/14 09:23:27 1.4
--- dump.c 1999/08/17 22:03:33
*************** dequeue_and_dump (di)
*** 606,612 ****
if (DECL_CONV_FN_P (t))
dump_string (di, "conversion");
if (dump_children_p)
! dump_child ("body", DECL_INITIAL (t));
break;
case NAMESPACE_DECL:
--- 606,612 ----
if (DECL_CONV_FN_P (t))
dump_string (di, "conversion");
if (dump_children_p)
! dump_child ("body", DECL_SAVED_TREE (t));
break;
case NAMESPACE_DECL:
*************** dequeue_and_dump (di)
*** 616,621 ****
--- 616,626 ----
break;
if (dump_children_p)
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:
Index: pt.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/pt.c,v
retrieving revision 1.331
diff -c -p -r1.331 pt.c
*** pt.c 1999/08/16 19:01:31 1.331
--- pt.c 1999/08/17 22:03:38
*************** push_template_decl_real (decl, is_friend
*** 2385,2390 ****
--- 2385,2391 ----
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)
*************** push_template_decl_real (decl, is_friend
*** 2449,2455 ****
else
{
tmpl = build_template_decl (decl, current_template_parms);
!
if (DECL_LANG_SPECIFIC (decl)
&& DECL_TEMPLATE_SPECIALIZATION (decl))
{
--- 2450,2457 ----
else
{
tmpl = build_template_decl (decl, current_template_parms);
! new_template_p = 1;
!
if (DECL_LANG_SPECIFIC (decl)
&& DECL_TEMPLATE_SPECIALIZATION (decl))
{
*************** push_template_decl_real (decl, is_friend
*** 2560,2566 ****
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
&& !(is_friend && template_class_depth (current_class_type) > 0))
tmpl = pushdecl_namespace_level (tmpl);
--- 2562,2568 ----
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 (new_template_p && !ctx
&& !(is_friend && template_class_depth (current_class_type) > 0))
tmpl = pushdecl_namespace_level (tmpl);