Updated patch for g++-980308: bug in template template parameter implementation again
Kriang Lerdsuwanakij
lerdsuwa@scf-fs.usc.edu
Fri Mar 20 10:51:00 GMT 1998
Hi
Here is my updated version of the patch at
http://www.cygnus.com/ml/egcs-bugs/1998-Mar/0317.html
Some unnecessary function calls and memory allocation in tsubst changes
are removed in this version.
--Kriang
* pt.c (complete_template_args): New function.
(get_bindings): Deal with specializations of function templates
with return type containing parameters from outer class
templates.
(tsubst, TEMPLATE_TEMPLATE_PARM): When reducing parameter level,
alos substitute arguments.
*** pt.c 1998/03/17 05:39:06 1.7
--- pt.c 1998/03/20 17:53:28
*************** static tree get_class_bindings PROTO((tr
*** 81,86 ****
--- 81,87 ----
static tree coerce_template_parms PROTO((tree, tree, tree, int, int, int));
static tree tsubst_enum PROTO((tree, tree, tree *));
static tree add_to_template_args PROTO((tree, tree));
+ static tree complete_template_args PROTO((tree, tree));
static int type_unification_real PROTO((tree, tree *, tree, tree,
int, int, int));
static void note_template_header PROTO((int));
*************** is_member_template (t)
*** 339,344 ****
--- 340,413 ----
return 0;
}
+ /* Return a new template argument vector which contains all of ARGS
+ for all outer templates TYPE is contained in, but has as its
+ innermost set of arguments the EXTRA_ARGS. */
+
+ static tree
+ complete_template_args (decl, extra_args)
+ tree decl;
+ tree extra_args;
+ {
+ int depth;
+ tree type;
+
+ my_friendly_assert (TREE_CODE (decl) == TEMPLATE_DECL, 0);
+ my_friendly_assert (TREE_CODE (extra_args) == TREE_VEC, 0);
+
+ decl = DECL_TEMPLATE_RESULT (decl);
+ type = DECL_REAL_CONTEXT (decl);
+
+ /* For constructor and destructor, it can be template simply
+ because the class it belongs to is. If this is the case,
+ it and its context share the same template arguments and
+ we don't want its context in template_class_depth
+ computation. */
+
+ if (DECL_LANG_SPECIFIC (decl) && DECL_CONSTRUCTOR_P (decl))
+ {
+ /* Check whether its context is a template class. */
+ if (CLASSTYPE_TEMPLATE_INFO (type)
+ && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type))
+ && uses_template_parms (CLASSTYPE_TI_ARGS (type)))
+ {
+ if (comp_template_args (CLASSTYPE_TI_ARGS (type),
+ DECL_TI_ARGS (decl)))
+ type = TYPE_CONTEXT (type);
+
+ }
+ }
+ else if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl)))
+ {
+ /* There is no template destructors. */
+ type = TYPE_CONTEXT (type);
+ }
+
+ depth = template_class_depth (type);
+ if (depth)
+ {
+ tree new_args = make_tree_vec (depth + 1);
+
+ for (; type && TREE_CODE (type) != FUNCTION_DECL;
+ type = TYPE_CONTEXT (type))
+ {
+ if (CLASSTYPE_TEMPLATE_INFO (type)
+ && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type))
+ && uses_template_parms (CLASSTYPE_TI_ARGS (type)))
+ {
+ --depth;
+ TREE_VEC_ELT (new_args, depth) = CLASSTYPE_TI_ARGS (type);
+ }
+ }
+
+ TREE_VEC_ELT (new_args,
+ TREE_VEC_LENGTH (new_args) - 1) = extra_args;
+ extra_args = new_args;
+ }
+
+ return extra_args;
+ }
+
/* Return a new template argument vector which contains all of ARGS,
but has as its innermost set of arguments the EXTRA_ARGS. */
*************** tsubst (t, args, in_decl)
*** 3575,3580 ****
--- 3644,3657 ----
TYPE_MAIN_VARIANT (r) = r;
TYPE_POINTER_TO (r) = NULL_TREE;
TYPE_REFERENCE_TO (r) = NULL_TREE;
+
+ if (TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM
+ && CLASSTYPE_TEMPLATE_INFO (t))
+ {
+ tree argvec = tsubst (CLASSTYPE_TI_ARGS (t), args, in_decl);
+ CLASSTYPE_TEMPLATE_INFO (r)
+ = perm_tree_cons (TYPE_NAME (t), argvec, NULL_TREE);
+ }
break;
case TEMPLATE_PARM_INDEX:
*************** get_bindings (fn, decl, explicit_args)
*** 5745,5751 ****
if (i == 0)
{
/* Check to see that the resulting return type is also OK. */
! tree t = tsubst (TREE_TYPE (TREE_TYPE (fn)), targs, NULL_TREE);
if (!comptypes (t, TREE_TYPE (TREE_TYPE (decl)), 1))
return NULL_TREE;
--- 5822,5830 ----
if (i == 0)
{
/* Check to see that the resulting return type is also OK. */
! tree t = tsubst (TREE_TYPE (TREE_TYPE (fn)),
! complete_template_args (fn, targs),
! NULL_TREE);
if (!comptypes (t, TREE_TYPE (TREE_TYPE (decl)), 1))
return NULL_TREE;
More information about the Gcc-bugs
mailing list