Commit 75b0bbce by Richard Kenner

(instantiate_class_template): Add the new instantiation to template_classes.

(do_pending_expansions): Call instantiate_member_templates on all of
the classes in template_classes.
(coerce_template_parms): Since template parameters are shared among all
instantiations, we have to substitute in the real types in TREE_TYPE (parm).
(push_template_decls): Ditto.
(grok_template_type): Deleted as template parameters are shared	among all
instantiations.

From-SVN: r10041
parent acc9fe20
/* Handle parameterized types (templates) for GNU C++. /* Handle parameterized types (templates) for GNU C++.
Copyright (C) 1992, 1993 Free Software Foundation, Inc. Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing. Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing.
This file is part of GNU CC. This file is part of GNU CC.
...@@ -52,6 +52,11 @@ struct pending_inline *pending_template_expansions; ...@@ -52,6 +52,11 @@ struct pending_inline *pending_template_expansions;
int processing_template_decl; int processing_template_decl;
int processing_template_defn; int processing_template_defn;
/* This is a kludge to handle instantiation of template methods that are
used before their definition. It should not be necessary after the
template rewrite. */
static tree template_classes;
#define obstack_chunk_alloc xmalloc #define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free #define obstack_chunk_free free
...@@ -324,48 +329,7 @@ end_template_decl (d1, d2, is_class, defn) ...@@ -324,48 +329,7 @@ end_template_decl (d1, d2, is_class, defn)
(void) get_pending_sizes (); (void) get_pending_sizes ();
} }
/* If TYPE contains a template parm type, then substitute that type tree tsubst PROTO ((tree, tree*, int, tree));
with its actual type that is found in TVEC. */
static void
grok_template_type (tvec, type)
tree tvec;
tree* type;
{
switch (TREE_CODE (*type))
{
case TEMPLATE_TYPE_PARM:
if (*type != TYPE_MAIN_VARIANT (*type))
{
/* we are here for cases like const T* etc. */
grok_template_type (tvec, &TYPE_MAIN_VARIANT (*type));
*type = cp_build_type_variant (TYPE_MAIN_VARIANT (*type),
TYPE_READONLY (*type),
TYPE_VOLATILE (*type));
}
else
*type = TREE_VEC_ELT (tvec, TEMPLATE_TYPE_IDX (*type));
return;
case POINTER_TYPE:
case REFERENCE_TYPE:
grok_template_type (tvec, &TREE_TYPE (*type));
return;
case FUNCTION_TYPE:
{
tree p;
/* take care of function's return type first */
grok_template_type (tvec, &TREE_TYPE (*type));
/* take care of function's arguments */
for (p = TYPE_ARG_TYPES (*type); p; p = TREE_CHAIN (p))
grok_template_type (tvec, &TREE_VALUE (p));
return;
}
default:
break;
}
return;
}
/* Convert all template arguments to their appropriate types, and return /* Convert all template arguments to their appropriate types, and return
a vector containing the resulting values. If any error occurs, return a vector containing the resulting values. If any error occurs, return
...@@ -451,8 +415,9 @@ coerce_template_parms (parms, arglist, in_decl) ...@@ -451,8 +415,9 @@ coerce_template_parms (parms, arglist, in_decl)
} }
else else
{ {
grok_template_type (vec, &TREE_TYPE (parm)); tree t = tsubst (TREE_TYPE (parm), &TREE_VEC_ELT (vec, 0),
val = digest_init (TREE_TYPE (parm), arg, (tree *) 0); TREE_VEC_LENGTH (vec), in_decl);
val = digest_init (t, arg, (tree *) 0);
if (val == error_mark_node) if (val == error_mark_node)
; ;
...@@ -680,16 +645,19 @@ push_template_decls (parmlist, arglist, class_level) ...@@ -680,16 +645,19 @@ push_template_decls (parmlist, arglist, class_level)
{ {
/* add const decl to namespace */ /* add const decl to namespace */
tree val; tree val;
tree parmtype;
if (requires_type) if (requires_type)
{ {
error ("template use error: value provided where type needed"); error ("template use error: value provided where type needed");
continue; continue;
} }
val = digest_init (TREE_TYPE (parm), arg, (tree *) 0); parmtype = tsubst (TREE_TYPE (parm), &TREE_VEC_ELT (arglist, 0),
TREE_VEC_LENGTH (arglist), NULL_TREE);
val = digest_init (parmtype, arg, (tree *) 0);
if (val != error_mark_node) if (val != error_mark_node)
{ {
decl = build_decl (CONST_DECL, DECL_NAME (parm), decl = build_decl (CONST_DECL, DECL_NAME (parm),
TREE_TYPE (parm)); parmtype);
DECL_INITIAL (decl) = val; DECL_INITIAL (decl) = val;
TREE_READONLY (decl) = 1; TREE_READONLY (decl) = 1;
} }
...@@ -779,7 +747,7 @@ uses_template_parms (t) ...@@ -779,7 +747,7 @@ uses_template_parms (t)
return 1; return 1;
return uses_template_parms (TREE_TYPE (t)); return uses_template_parms (TREE_TYPE (t));
case METHOD_TYPE: case METHOD_TYPE:
if (uses_template_parms (TYPE_OFFSET_BASETYPE (t))) if (uses_template_parms (TYPE_METHOD_BASETYPE (t)))
return 1; return 1;
if (uses_template_parms (TYPE_ARG_TYPES (t))) if (uses_template_parms (TYPE_ARG_TYPES (t)))
return 1; return 1;
...@@ -1074,6 +1042,8 @@ instantiate_class_template (classname, setup_parse) ...@@ -1074,6 +1042,8 @@ instantiate_class_template (classname, setup_parse)
processing_template_defn++; processing_template_defn++;
if (!flag_external_templates) if (!flag_external_templates)
interface_unknown++; interface_unknown++;
template_classes
= perm_tree_cons (classname, NULL_TREE, template_classes);
} }
else else
{ {
...@@ -1151,7 +1121,7 @@ search_nested_type_in_tmpl (tmpl, type) ...@@ -1151,7 +1121,7 @@ search_nested_type_in_tmpl (tmpl, type)
return t; return t;
} }
static tree tree
tsubst (t, args, nargs, in_decl) tsubst (t, args, nargs, in_decl)
tree t, *args; tree t, *args;
int nargs; int nargs;
...@@ -1570,7 +1540,7 @@ tsubst (t, args, nargs, in_decl) ...@@ -1570,7 +1540,7 @@ tsubst (t, args, nargs, in_decl)
case FUNCTION_TYPE: case FUNCTION_TYPE:
case METHOD_TYPE: case METHOD_TYPE:
{ {
tree values = TYPE_VALUES (t); /* same as TYPE_ARG_TYPES */ tree values = TYPE_ARG_TYPES (t);
tree context = TYPE_CONTEXT (t); tree context = TYPE_CONTEXT (t);
tree new_value; tree new_value;
...@@ -2367,6 +2337,12 @@ do_pending_expansions () ...@@ -2367,6 +2337,12 @@ do_pending_expansions ()
{ {
struct pending_inline *i, *new_list = 0; struct pending_inline *i, *new_list = 0;
{
tree t;
for (t = template_classes; t; t = TREE_CHAIN (t))
instantiate_member_templates (TREE_PURPOSE (t));
}
if (!pending_template_expansions) if (!pending_template_expansions)
return 0; return 0;
......
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