cp-tree.def (BOUND_TEMPLATE_TEMPLATE_PARM): New tree code.

* cp-tree.def (BOUND_TEMPLATE_TEMPLATE_PARM): New tree code.
        (TEMPLATE_TEMPLATE_PARM): Adjust comment.
        * cp-tree.h (TYPE_BINFO): Adjust comment.
        (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO): Likewise.
        (TEMPLATE_TYPE_PARM_INDEX): Likewise.
        (IS_AGGR_TYPE): Use BOUND_TEMPLATE_TEMPLATE_PARM instead.
        (TYPE_TEMPLATE_INFO): Likewise.
        (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL): Likewise.
        * class.c (push_nested_class): Likewise.
        * decl.c (lookup_name_real): Likewise.
        (grokdeclarator): Likewise.
        (grok_op_properties): Likewise.
        (xref_tag): Likewise.
        (xref_basetypes): Likewise.
        * decl2.c (constructor_name_full): Likewise.
        (arg_assoc_template_arg): Add TEMPLATE_TEMPLATE_PARM case.
        (arg_assoc_type): Use BOUND_TEMPLATE_TEMPLATE_PARM instead.
        * error.c (dump_type): Split TEMPLATE_TEMPLATE_PARM case.
        (dump_type_prefix): Add BOUND_TEMPLATE_TEMPLATE_PARM.
        (dump_type_suffix): Likewise.
        * init.c (is_aggr_type): Use BOUND_TEMPLATE_TEMPLATE_PARM
        instead.
        (get_aggr_from_typedef): Likewise.
        * mangle.c (write_type): Split TEMPLATE_TEMPLATE_PARM case.
        (write_expression): Add BOUND_TEMPLATE_TEMPLATE_PARM.
        (write_template_parm): Likewise.
        (write_template_template_parm): Check tree code instead of
        using TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
        * method.c (build_overload_nested_name): Add
        BOUND_TEMPLATE_TEMPLATE_PARM.
        (process_overload_item): Split TEMPLATE_TEMPLATE_PARM case.
        * parse.y (bad_parm): Add BOUND_TEMPLATE_TEMPLATE_PARM.
        * pt.c (convert_template_argument): Check tree code instead of
        using TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
        (for_each_template_parm_r): Split TEMPLATE_TEMPLATE_PARM case.
        (for_each_template_parm): Adjust comment.
        (tsubst): Add BOUND_TEMPLATE_TEMPLATE_PARM.  Reorganize.
        (tsubst_copy): Add BOUND_TEMPLATE_TEMPLATE_PARM.
        (unify): Add BOUND_TEMPLATE_TEMPLATE_PARM.  Reorganize.  Use
        template_args_equal to compare template template parameter cases.
        * ptree.c (print_lang_type): Add BOUND_TEMPLATE_TEMPLATE_PARM.
        * search.c (lookup_field_1): Use BOUND_TEMPLATE_TEMPLATE_PARM
        instead.
        * tree.c (copy_template_template_parm): Decide whether to create
        a TEMPLATE_TEMPLATE_PARM or BOUND_TEMPLATE_TEMPLATE_PARM node.
        (walk_tree): Add BOUND_TEMPLATE_TEMPLATE_PARM.
        (copy_tree_r): Likewise.
        * typeck.c (comptypes): Likewise.  Check tree code instead of
        using TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.

From-SVN: r36149
This commit is contained in:
Kriang Lerdsuwanakij 2000-09-05 01:01:39 +00:00 committed by Jason Merrill
parent 31e0ab1f76
commit a1281f4503
17 changed files with 252 additions and 154 deletions

View File

@ -1,3 +1,55 @@
2000-09-04 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
* cp-tree.def (BOUND_TEMPLATE_TEMPLATE_PARM): New tree code.
(TEMPLATE_TEMPLATE_PARM): Adjust comment.
* cp-tree.h (TYPE_BINFO): Adjust comment.
(TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO): Likewise.
(TEMPLATE_TYPE_PARM_INDEX): Likewise.
(IS_AGGR_TYPE): Use BOUND_TEMPLATE_TEMPLATE_PARM instead.
(TYPE_TEMPLATE_INFO): Likewise.
(TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL): Likewise.
* class.c (push_nested_class): Likewise.
* decl.c (lookup_name_real): Likewise.
(grokdeclarator): Likewise.
(grok_op_properties): Likewise.
(xref_tag): Likewise.
(xref_basetypes): Likewise.
* decl2.c (constructor_name_full): Likewise.
(arg_assoc_template_arg): Add TEMPLATE_TEMPLATE_PARM case.
(arg_assoc_type): Use BOUND_TEMPLATE_TEMPLATE_PARM instead.
* error.c (dump_type): Split TEMPLATE_TEMPLATE_PARM case.
(dump_type_prefix): Add BOUND_TEMPLATE_TEMPLATE_PARM.
(dump_type_suffix): Likewise.
* init.c (is_aggr_type): Use BOUND_TEMPLATE_TEMPLATE_PARM
instead.
(get_aggr_from_typedef): Likewise.
* mangle.c (write_type): Split TEMPLATE_TEMPLATE_PARM case.
(write_expression): Add BOUND_TEMPLATE_TEMPLATE_PARM.
(write_template_parm): Likewise.
(write_template_template_parm): Check tree code instead of
using TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
* method.c (build_overload_nested_name): Add
BOUND_TEMPLATE_TEMPLATE_PARM.
(process_overload_item): Split TEMPLATE_TEMPLATE_PARM case.
* parse.y (bad_parm): Add BOUND_TEMPLATE_TEMPLATE_PARM.
* pt.c (convert_template_argument): Check tree code instead of
using TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
(for_each_template_parm_r): Split TEMPLATE_TEMPLATE_PARM case.
(for_each_template_parm): Adjust comment.
(tsubst): Add BOUND_TEMPLATE_TEMPLATE_PARM. Reorganize.
(tsubst_copy): Add BOUND_TEMPLATE_TEMPLATE_PARM.
(unify): Add BOUND_TEMPLATE_TEMPLATE_PARM. Reorganize. Use
template_args_equal to compare template template parameter cases.
* ptree.c (print_lang_type): Add BOUND_TEMPLATE_TEMPLATE_PARM.
* search.c (lookup_field_1): Use BOUND_TEMPLATE_TEMPLATE_PARM
instead.
* tree.c (copy_template_template_parm): Decide whether to create
a TEMPLATE_TEMPLATE_PARM or BOUND_TEMPLATE_TEMPLATE_PARM node.
(walk_tree): Add BOUND_TEMPLATE_TEMPLATE_PARM.
(copy_tree_r): Likewise.
* typeck.c (comptypes): Likewise. Check tree code instead of
using TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
2000-09-04 Mark Elbrecht <snowball3@bigfoot.com>
* decl.c (finish_function): Move the code for handling functions

View File

@ -5644,7 +5644,7 @@ push_nested_class (type, modify)
|| TREE_CODE (type) == NAMESPACE_DECL
|| ! IS_AGGR_TYPE (type)
|| TREE_CODE (type) == TEMPLATE_TYPE_PARM
|| TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM)
|| TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM)
return;
context = DECL_CONTEXT (TYPE_MAIN_DECL (type));

View File

@ -144,14 +144,16 @@ DEFTREECODE (TEMPLATE_TYPE_PARM, "template_type_parm", 't', 0)
This parameter must be a type. The TYPE_FIELDS value will be a
TEMPLATE_PARM_INDEX.
If it is used without template arguments like TT in C<TT>,
It is used without template arguments like TT in C<TT>,
TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO is NULL_TREE
and TYPE_NAME is a TEMPLATE_DECL.
and TYPE_NAME is a TEMPLATE_DECL. */
DEFTREECODE (TEMPLATE_TEMPLATE_PARM, "template_template_parm", 't', 0)
Otherwise it is used with bound template arguments like TT<int>.
/* Like TEMPLATE_TEMPLATE_PARM it is used with bound template arguments
like TT<int>.
In this case, TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO contains the
template name and its bound arguments. TYPE_NAME is a TYPE_DECL. */
DEFTREECODE (TEMPLATE_TEMPLATE_PARM, "template_template_parm", 't', 0)
DEFTREECODE (BOUND_TEMPLATE_TEMPLATE_PARM, "bound_template_template_parm", 't', 0)
/* A type designated by `typename T::t'. TYPE_CONTEXT is `T',
TYPE_NAME is an IDENTIFIER_NODE for `t'. If the type was named via

View File

@ -112,8 +112,8 @@ Boston, MA 02111-1307, USA. */
TYPE_BINFO
For an ENUMERAL_TYPE, this is ENUM_TEMPLATE_INFO.
For a TYPENAME_TYPE, this is TYPENAME_TYPE_FULLNAME.
For a TEMPLATE_TEMPLATE_PARM, this is
TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
For a TEMPLATE_TEMPLATE_PARM or BOUND_TEMPLATE_TEMPLATE_PARM,
this is TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
BINFO_VIRTUALS
For a binfo, this is a TREE_LIST. The BV_DELTA of each node
@ -1241,8 +1241,7 @@ enum languages { lang_c, lang_cplusplus, lang_java };
(TREE_CODE (t) == TEMPLATE_TYPE_PARM \
|| TREE_CODE (t) == TYPENAME_TYPE \
|| TREE_CODE (t) == TYPEOF_TYPE \
|| (TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM \
&& TYPE_TEMPLATE_INFO (t)) \
|| TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM \
|| TYPE_LANG_FLAG_5 (t))
/* Set IS_AGGR_TYPE for T to VAL. T must be a class, struct, or
@ -2298,14 +2297,14 @@ struct lang_decl
non-type template parameters. */
#define ENUM_TEMPLATE_INFO(NODE) (TYPE_BINFO (ENUMERAL_TYPE_CHECK (NODE)))
/* Template information for a template template parameter. */
/* Template information for a bound template template parameter. */
#define TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO(NODE) (TYPE_BINFO (NODE))
/* Template information for an ENUMERAL_, RECORD_, or UNION_TYPE. */
#define TYPE_TEMPLATE_INFO(NODE) \
(TREE_CODE (NODE) == ENUMERAL_TYPE \
? ENUM_TEMPLATE_INFO (NODE) : \
(TREE_CODE (NODE) == TEMPLATE_TEMPLATE_PARM \
(TREE_CODE (NODE) == BOUND_TEMPLATE_TEMPLATE_PARM \
? TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (NODE) : \
(TYPE_LANG_SPECIFIC (NODE) \
? CLASSTYPE_TEMPLATE_INFO (NODE) \
@ -3716,8 +3715,8 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG };
#define TEMPLATE_PARM_ORIG_LEVEL(NODE) (TEMPLATE_PARM_INDEX_CAST (NODE)->orig_level)
#define TEMPLATE_PARM_DECL(NODE) (TEMPLATE_PARM_INDEX_CAST (NODE)->decl)
/* These macros are for accessing the fields of TEMPLATE_TYPE_PARM
and TEMPLATE_TEMPLATE_PARM nodes. */
/* These macros are for accessing the fields of TEMPLATE_TYPE_PARM,
TEMPLATE_TEMPLATE_PARM and BOUND_TEMPLATE_TEMPLATE_PARM nodes. */
#define TEMPLATE_TYPE_PARM_INDEX(NODE) (TYPE_FIELDS (NODE))
#define TEMPLATE_TYPE_IDX(NODE) \
(TEMPLATE_PARM_IDX (TEMPLATE_TYPE_PARM_INDEX (NODE)))
@ -3755,7 +3754,7 @@ enum tree_string_flags
/* Returns the TEMPLATE_DECL associated to a TEMPLATE_TEMPLATE_PARM
node. */
#define TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL(NODE) \
(TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (NODE) \
((TREE_CODE (NODE) == BOUND_TEMPLATE_TEMPLATE_PARM) \
? TYPE_TI_TEMPLATE (NODE) \
: TYPE_NAME (NODE))

View File

@ -5925,7 +5925,7 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
}
else if (! IS_AGGR_TYPE (type)
|| TREE_CODE (type) == TEMPLATE_TYPE_PARM
|| TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM
|| TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM
|| TREE_CODE (type) == TYPENAME_TYPE)
/* Someone else will give an error about this if needed. */
val = NULL_TREE;
@ -9873,7 +9873,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
&& TREE_CODE (TREE_OPERAND (decl, 1)) == INDIRECT_REF)
ctype = cname;
else if (TREE_CODE (cname) == TEMPLATE_TYPE_PARM
|| TREE_CODE (cname) == TEMPLATE_TEMPLATE_PARM)
|| TREE_CODE (cname) == BOUND_TEMPLATE_TEMPLATE_PARM)
{
cp_error ("`%T::%D' is not a valid declarator", cname,
TREE_OPERAND (decl, 1));
@ -12461,7 +12461,7 @@ grok_op_properties (decl, virtualp, friendp)
if (IS_AGGR_TYPE (arg)
|| TREE_CODE (arg) == ENUMERAL_TYPE
|| TREE_CODE (arg) == TEMPLATE_TYPE_PARM
|| TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
|| TREE_CODE (arg) == BOUND_TEMPLATE_TEMPLATE_PARM)
goto foundaggr;
}
cp_error
@ -12768,7 +12768,7 @@ xref_tag (code_type_node, name, globalize)
t = IDENTIFIER_TYPE_VALUE (name);
if (t && TREE_CODE (t) != code && TREE_CODE (t) != TEMPLATE_TYPE_PARM
&& TREE_CODE (t) != TEMPLATE_TEMPLATE_PARM)
&& TREE_CODE (t) != BOUND_TEMPLATE_TEMPLATE_PARM)
t = NULL_TREE;
if (! globalize)
@ -13014,7 +13014,7 @@ xref_basetypes (code_type_node, name, ref, binfo)
|| (TREE_CODE (basetype) != RECORD_TYPE
&& TREE_CODE (basetype) != TYPENAME_TYPE
&& TREE_CODE (basetype) != TEMPLATE_TYPE_PARM
&& TREE_CODE (basetype) != TEMPLATE_TEMPLATE_PARM))
&& TREE_CODE (basetype) != BOUND_TEMPLATE_TEMPLATE_PARM))
{
cp_error ("base type `%T' fails to be a struct or class type",
TREE_VALUE (binfo));

View File

@ -2043,7 +2043,7 @@ constructor_name_full (thing)
tree thing;
{
if (TREE_CODE (thing) == TEMPLATE_TYPE_PARM
|| TREE_CODE (thing) == TEMPLATE_TEMPLATE_PARM
|| TREE_CODE (thing) == BOUND_TEMPLATE_TEMPLATE_PARM
|| TREE_CODE (thing) == TYPENAME_TYPE)
thing = TYPE_NAME (thing);
else if (IS_AGGR_TYPE_CODE (TREE_CODE (thing)))
@ -4860,7 +4860,9 @@ arg_assoc_template_arg (k, arg)
contribute to the set of associated namespaces. ] */
/* Consider first template template arguments. */
if (TREE_CODE (arg) == TEMPLATE_DECL)
if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
return 0;
else if (TREE_CODE (arg) == TEMPLATE_DECL)
{
tree ctx = CP_DECL_CONTEXT (arg);
@ -4976,7 +4978,7 @@ arg_assoc_type (k, type)
/* Associate the return type. */
return arg_assoc_type (k, TREE_TYPE (type));
case TEMPLATE_TYPE_PARM:
case TEMPLATE_TEMPLATE_PARM:
case BOUND_TEMPLATE_TEMPLATE_PARM:
return 0;
case TYPENAME_TYPE:
return 0;

View File

@ -462,22 +462,21 @@ dump_type (t, flags)
break;
case TEMPLATE_TEMPLATE_PARM:
if (!TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t))
{
/* For parameters inside template signature. */
if (TYPE_IDENTIFIER (t))
OB_PUTID (TYPE_IDENTIFIER (t));
else
OB_PUTS ("{anonymous template template parameter}");
}
/* For parameters inside template signature. */
if (TYPE_IDENTIFIER (t))
OB_PUTID (TYPE_IDENTIFIER (t));
else
{
tree args = TYPE_TI_ARGS (t);
OB_PUTID (TYPE_IDENTIFIER (t));
OB_PUTC ('<');
dump_template_argument_list (args, flags);
OB_END_TEMPLATE_ID ();
}
OB_PUTS ("{anonymous template template parameter}");
break;
case BOUND_TEMPLATE_TEMPLATE_PARM:
{
tree args = TYPE_TI_ARGS (t);
OB_PUTID (TYPE_IDENTIFIER (t));
OB_PUTC ('<');
dump_template_argument_list (args, flags);
OB_END_TEMPLATE_ID ();
}
break;
case TEMPLATE_TYPE_PARM:
@ -704,6 +703,7 @@ dump_type_prefix (t, flags)
case RECORD_TYPE:
case TEMPLATE_TYPE_PARM:
case TEMPLATE_TEMPLATE_PARM:
case BOUND_TEMPLATE_TEMPLATE_PARM:
case TREE_LIST:
case TYPE_DECL:
case TREE_VEC:

View File

@ -1390,7 +1390,7 @@ is_aggr_type (type, or_else)
if (! IS_AGGR_TYPE (type)
&& TREE_CODE (type) != TEMPLATE_TYPE_PARM
&& TREE_CODE (type) != TEMPLATE_TEMPLATE_PARM)
&& TREE_CODE (type) != BOUND_TEMPLATE_TEMPLATE_PARM)
{
if (or_else)
cp_error ("`%T' is not an aggregate type", type);
@ -1422,7 +1422,7 @@ get_aggr_from_typedef (name, or_else)
if (! IS_AGGR_TYPE (type)
&& TREE_CODE (type) != TEMPLATE_TYPE_PARM
&& TREE_CODE (type) != TEMPLATE_TEMPLATE_PARM)
&& TREE_CODE (type) != BOUND_TEMPLATE_TEMPLATE_PARM)
{
if (or_else)
cp_error ("type `%T' is of non-aggregate type", type);

View File

@ -1319,9 +1319,12 @@ write_type (type)
case TEMPLATE_TEMPLATE_PARM:
write_template_template_param (type);
if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (type))
write_template_args
(TI_ARGS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (type)));
break;
case BOUND_TEMPLATE_TEMPLATE_PARM:
write_template_template_param (type);
write_template_args
(TI_ARGS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (type)));
break;
case OFFSET_TYPE:
@ -1624,7 +1627,8 @@ write_expression (expr)
/* Handle template parameters. */
if (code == TEMPLATE_TYPE_PARM
|| code == TEMPLATE_TEMPLATE_PARM
|| code == TEMPLATE_PARM_INDEX)
|| code == BOUND_TEMPLATE_TEMPLATE_PARM
|| code == TEMPLATE_PARM_INDEX)
write_template_param (expr);
/* Handle literals. */
else if (TREE_CODE_CLASS (code) == 'c')
@ -1863,7 +1867,8 @@ write_pointer_to_member_type (type)
}
/* Non-terminal <template-param>. PARM is a TEMPLATE_TYPE_PARM,
TEMPLATE_TEMPLATE_PARM, or a TEMPLATE_PARM_INDEX.
TEMPLATE_TEMPLATE_PARM, BOUND_TEMPLATE_TEMPLATE_PARM or a
TEMPLATE_PARM_INDEX.
<template-param> ::= T </parameter/ number> _ */
@ -1879,6 +1884,7 @@ write_template_param (parm)
{
case TEMPLATE_TYPE_PARM:
case TEMPLATE_TEMPLATE_PARM:
case BOUND_TEMPLATE_TEMPLATE_PARM:
parm_index = TEMPLATE_TYPE_IDX (parm);
break;
@ -1911,7 +1917,7 @@ write_template_template_param (parm)
/* PARM, a TEMPLATE_TEMPLATE_PARM, is an instantiation of the
template template parameter. The substitution candidate here is
only the template. */
if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (parm))
if (TREE_CODE (parm) == BOUND_TEMPLATE_TEMPLATE_PARM)
{
template
= TI_TEMPLATE (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (parm));

View File

@ -446,7 +446,8 @@ build_overload_nested_name (decl)
/* For a template type parameter, we want to output an 'Xn'
rather than 'T' or some such. */
if (TREE_CODE (context) == TEMPLATE_TYPE_PARM
|| TREE_CODE (context) == TEMPLATE_TEMPLATE_PARM)
|| TREE_CODE (context) == TEMPLATE_TEMPLATE_PARM
|| TREE_CODE (context) == BOUND_TEMPLATE_TEMPLATE_PARM)
build_mangled_name_for_type (context);
else
{
@ -1512,26 +1513,23 @@ process_overload_item (parmtype, extra_Gcode)
OB_PUTC ('?');
break;
case TEMPLATE_TEMPLATE_PARM:
case BOUND_TEMPLATE_TEMPLATE_PARM:
/* Find and output the original template parameter
declaration. */
if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (parmtype))
{
build_mangled_template_parm_index ("tzX",
TEMPLATE_TYPE_PARM_INDEX
(parmtype));
build_template_parm_names
(DECL_INNERMOST_TEMPLATE_PARMS (TYPE_TI_TEMPLATE (parmtype)),
TYPE_TI_ARGS (parmtype));
}
else
{
build_mangled_template_parm_index ("ZzX",
TEMPLATE_TYPE_PARM_INDEX
(parmtype));
build_template_template_parm_names
(DECL_INNERMOST_TEMPLATE_PARMS (TYPE_STUB_DECL (parmtype)));
}
build_mangled_template_parm_index ("tzX",
TEMPLATE_TYPE_PARM_INDEX
(parmtype));
build_template_parm_names
(DECL_INNERMOST_TEMPLATE_PARMS (TYPE_TI_TEMPLATE (parmtype)),
TYPE_TI_ARGS (parmtype));
break;
case TEMPLATE_TEMPLATE_PARM:
build_mangled_template_parm_index ("ZzX",
TEMPLATE_TYPE_PARM_INDEX
(parmtype));
build_template_template_parm_names
(DECL_INNERMOST_TEMPLATE_PARMS (TYPE_STUB_DECL (parmtype)));
break;
case TEMPLATE_TYPE_PARM:

View File

@ -3713,7 +3713,7 @@ bad_parm:
error ("type specifier omitted for parameter");
if (TREE_CODE ($$) == SCOPE_REF
&& (TREE_CODE (TREE_OPERAND ($$, 0)) == TEMPLATE_TYPE_PARM
|| TREE_CODE (TREE_OPERAND ($$, 0)) == TEMPLATE_TEMPLATE_PARM))
|| TREE_CODE (TREE_OPERAND ($$, 0)) == BOUND_TEMPLATE_TEMPLATE_PARM))
cp_error (" perhaps you want `typename %E' to make it a type", $$);
$$ = build_tree_list (integer_type_node, $$);
}

View File

@ -3206,8 +3206,7 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
is_tmpl_type
= ((TREE_CODE (arg) == TEMPLATE_DECL
&& TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL)
|| (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
&& !TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (arg))
|| TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
|| (TREE_CODE (arg) == RECORD_TYPE
&& CLASSTYPE_TEMPLATE_INFO (arg)
&& TREE_CODE (TYPE_NAME (arg)) == TYPE_DECL
@ -4187,13 +4186,13 @@ for_each_template_parm_r (tp, walk_subtrees, d)
return error_mark_node;
break;
case TEMPLATE_TEMPLATE_PARM:
case BOUND_TEMPLATE_TEMPLATE_PARM:
/* Record template parameters such as `T' inside `TT<T>'. */
if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t)
&& for_each_template_parm (TYPE_TI_ARGS (t), fn, data))
if (for_each_template_parm (TYPE_TI_ARGS (t), fn, data))
return error_mark_node;
/* Fall through. */
case TEMPLATE_TEMPLATE_PARM:
case TEMPLATE_TYPE_PARM:
case TEMPLATE_PARM_INDEX:
if (fn && (*fn)(t, data))
@ -4255,8 +4254,9 @@ for_each_template_parm_r (tp, walk_subtrees, d)
return NULL_TREE;
}
/* For each TEMPLATE_TYPE_PARM, TEMPLATE_TEMPLATE_PARM, or
TEMPLATE_PARM_INDEX in T, call FN with the parameter and the DATA.
/* For each TEMPLATE_TYPE_PARM, TEMPLATE_TEMPLATE_PARM,
BOUND_TEMPLATE_TEMPLATE_PARM or TEMPLATE_PARM_INDEX in T,
call FN with the parameter and the DATA.
If FN returns non-zero, the iteration is terminated, and
for_each_template_parm returns 1. Otherwise, the iteration
continues. If FN never returns a non-zero value, the value
@ -6222,6 +6222,7 @@ tsubst (t, args, complain, in_decl)
case TEMPLATE_TYPE_PARM:
case TEMPLATE_TEMPLATE_PARM:
case BOUND_TEMPLATE_TEMPLATE_PARM:
case TEMPLATE_PARM_INDEX:
{
int idx;
@ -6231,7 +6232,8 @@ tsubst (t, args, complain, in_decl)
r = NULL_TREE;
if (TREE_CODE (t) == TEMPLATE_TYPE_PARM
|| TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM)
|| TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM
|| TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM)
{
idx = TEMPLATE_TYPE_IDX (t);
level = TEMPLATE_TYPE_LEVEL (t);
@ -6261,38 +6263,33 @@ tsubst (t, args, complain, in_decl)
(arg, CP_TYPE_QUALS (arg) | CP_TYPE_QUALS (t),
complain);
}
else if (TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM)
else if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM)
{
if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t))
{
/* We are processing a type constructed from
a template template parameter */
tree argvec = tsubst (TYPE_TI_ARGS (t),
args, complain, in_decl);
if (argvec == error_mark_node)
return error_mark_node;
/* We are processing a type constructed from
a template template parameter */
tree argvec = tsubst (TYPE_TI_ARGS (t),
args, complain, in_decl);
if (argvec == error_mark_node)
return error_mark_node;
/* We can get a TEMPLATE_TEMPLATE_PARM here when
we are resolving nested-types in the signature of
a member function templates.
Otherwise ARG is a TEMPLATE_DECL and is the real
template to be instantiated. */
if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
arg = TYPE_NAME (arg);
/* We can get a TEMPLATE_TEMPLATE_PARM here when
we are resolving nested-types in the signature of
a member function templates.
Otherwise ARG is a TEMPLATE_DECL and is the real
template to be instantiated. */
if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
arg = TYPE_NAME (arg);
r = lookup_template_class (arg,
argvec, in_decl,
DECL_CONTEXT (arg),
/*entering_scope=*/0);
return cp_build_qualified_type_real (r,
TYPE_QUALS (t),
complain);
}
else
/* We are processing a template argument list. */
return arg;
r = lookup_template_class (arg,
argvec, in_decl,
DECL_CONTEXT (arg),
/*entering_scope=*/0);
return cp_build_qualified_type_real (r,
TYPE_QUALS (t),
complain);
}
else
/* TEMPLATE_TEMPLATE_PARM or TEMPLATE_PARM_INDEX. */
return arg;
}
}
@ -6312,6 +6309,7 @@ tsubst (t, args, complain, in_decl)
{
case TEMPLATE_TYPE_PARM:
case TEMPLATE_TEMPLATE_PARM:
case BOUND_TEMPLATE_TEMPLATE_PARM:
if (CP_TYPE_QUALS (t))
{
r = tsubst (TYPE_MAIN_VARIANT (t), args, complain, in_decl);
@ -6329,8 +6327,7 @@ tsubst (t, args, complain, in_decl)
TYPE_POINTER_TO (r) = NULL_TREE;
TYPE_REFERENCE_TO (r) = NULL_TREE;
if (TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM
&& TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t))
if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM)
{
tree argvec = tsubst (TYPE_TI_ARGS (t), args,
complain, in_decl);
@ -7032,6 +7029,7 @@ tsubst_copy (t, args, complain, in_decl)
case INTEGER_TYPE:
case TEMPLATE_TYPE_PARM:
case TEMPLATE_TEMPLATE_PARM:
case BOUND_TEMPLATE_TEMPLATE_PARM:
case TEMPLATE_PARM_INDEX:
case POINTER_TYPE:
case REFERENCE_TYPE:
@ -8302,6 +8300,7 @@ unify (tparms, targs, parm, arg, strict)
case TEMPLATE_TYPE_PARM:
case TEMPLATE_TEMPLATE_PARM:
case BOUND_TEMPLATE_TEMPLATE_PARM:
tparm = TREE_VALUE (TREE_VEC_ELT (tparms, 0));
if (TEMPLATE_TYPE_LEVEL (parm)
@ -8321,53 +8320,61 @@ unify (tparms, targs, parm, arg, strict)
&& TREE_CODE (tparm) != TEMPLATE_DECL))
return 1;
if (TREE_CODE (parm) == TEMPLATE_TEMPLATE_PARM)
if (TREE_CODE (parm) == BOUND_TEMPLATE_TEMPLATE_PARM)
{
if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (parm))
{
/* We arrive here when PARM does not involve template
specialization. */
/* ARG must be constructed from a template class. */
if (TREE_CODE (arg) != RECORD_TYPE || !CLASSTYPE_TEMPLATE_INFO (arg))
return 1;
/* ARG must be constructed from a template class. */
if (TREE_CODE (arg) != RECORD_TYPE || !CLASSTYPE_TEMPLATE_INFO (arg))
return 1;
{
tree parmtmpl = TYPE_TI_TEMPLATE (parm);
tree parmvec = TYPE_TI_ARGS (parm);
tree argvec = CLASSTYPE_TI_ARGS (arg);
tree argtmplvec
= DECL_INNERMOST_TEMPLATE_PARMS (CLASSTYPE_TI_TEMPLATE (arg));
int i;
{
tree parmtmpl = TYPE_TI_TEMPLATE (parm);
tree parmvec = TYPE_TI_ARGS (parm);
tree argvec = CLASSTYPE_TI_ARGS (arg);
tree argtmplvec
= DECL_INNERMOST_TEMPLATE_PARMS (CLASSTYPE_TI_TEMPLATE (arg));
int i;
/* The parameter and argument roles have to be switched here
in order to handle default arguments properly. For example,
template<template <class> class TT> void f(TT<int>)
should be able to accept vector<int> which comes from
template <class T, class Allocator = allocator>
class vector. */
/* The parameter and argument roles have to be switched here
in order to handle default arguments properly. For example,
template<template <class> class TT> void f(TT<int>)
should be able to accept vector<int> which comes from
template <class T, class Allocator = allocator>
class vector. */
if (coerce_template_parms (argtmplvec, parmvec, parmtmpl, 0, 1)
== error_mark_node)
return 1;
if (coerce_template_parms (argtmplvec, parmvec, parmtmpl, 0, 1)
== error_mark_node)
return 1;
/* Deduce arguments T, i from TT<T> or TT<i>.
We check each element of PARMVEC and ARGVEC individually
rather than the whole TREE_VEC since they can have
different number of elements. */
/* Deduce arguments T, i from TT<T> or TT<i>.
We check each element of PARMVEC and ARGVEC individually
rather than the whole TREE_VEC since they can have
different number of elements. */
for (i = 0; i < TREE_VEC_LENGTH (parmvec); ++i)
{
tree t = TREE_VEC_ELT (parmvec, i);
for (i = 0; i < TREE_VEC_LENGTH (parmvec); ++i)
{
tree t = TREE_VEC_ELT (parmvec, i);
if (unify (tparms, targs, t,
TREE_VEC_ELT (argvec, i),
UNIFY_ALLOW_NONE))
return 1;
}
if (unify (tparms, targs, t,
TREE_VEC_ELT (argvec, i),
UNIFY_ALLOW_NONE))
return 1;
}
arg = CLASSTYPE_TI_TEMPLATE (arg);
}
}
arg = CLASSTYPE_TI_TEMPLATE (arg);
/* Fall through to deduce template name. */
}
if (TREE_CODE (parm) == TEMPLATE_TEMPLATE_PARM
|| TREE_CODE (parm) == BOUND_TEMPLATE_TEMPLATE_PARM)
{
/* Deduce template name TT from TT, TT<>, TT<T> and TT<i>. */
/* Simple cases: Value already set, does match or doesn't. */
if (targ != NULL_TREE && template_args_equal (targ, arg))
return 0;
else if (targ)
return 1;
}
else
{
@ -8388,13 +8395,13 @@ unify (tparms, targs, parm, arg, strict)
/*complain=*/0);
if (arg == error_mark_node)
return 1;
}
/* Simple cases: Value already set, does match or doesn't. */
if (targ != NULL_TREE && same_type_p (targ, arg))
return 0;
else if (targ)
return 1;
/* Simple cases: Value already set, does match or doesn't. */
if (targ != NULL_TREE && same_type_p (targ, arg))
return 0;
else if (targ)
return 1;
}
/* Make sure that ARG is not a variable-sized array. (Note that
were talking about variable-sized arrays (like `int[n]'),

View File

@ -75,6 +75,7 @@ print_lang_type (file, node, indent)
{
case TEMPLATE_TYPE_PARM:
case TEMPLATE_TEMPLATE_PARM:
case BOUND_TEMPLATE_TEMPLATE_PARM:
indent_to (file, indent + 3);
fputs ("index ", file);
fprintf (file, HOST_WIDE_INT_PRINT_DEC, TEMPLATE_TYPE_IDX (node));

View File

@ -587,7 +587,7 @@ lookup_field_1 (type, name)
register tree field;
if (TREE_CODE (type) == TEMPLATE_TYPE_PARM
|| TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM)
|| TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM)
/* The TYPE_FIELDS of a TEMPLATE_TYPE_PARM are not fields at all;
instead TYPE_FIELDS is the TEMPLATE_PARM_INDEX. (Miraculously,
the code often worked even when we treated the index as a list

View File

@ -1176,7 +1176,8 @@ build_exception_variant (type, raises)
return v;
}
/* Given a TEMPLATE_TEMPLATE_PARM node T, create a new one together with its
/* Given a TEMPLATE_TEMPLATE_PARM or BOUND_TEMPLATE_TEMPLATE_PARM
node T, create a new one together with its
lang_specific field and its corresponding *_DECL node.
If NEWARGS is not NULL_TREE, this parameter is bound with new set of
arguments. */
@ -1189,9 +1190,9 @@ copy_template_template_parm (t, newargs)
tree decl = TYPE_NAME (t);
tree t2;
t2 = make_aggr_type (TEMPLATE_TEMPLATE_PARM);
if (newargs == NULL_TREE)
{
t2 = make_aggr_type (TREE_CODE (t));
decl = copy_decl (decl);
/* No need to copy these. */
@ -1201,6 +1202,7 @@ copy_template_template_parm (t, newargs)
}
else
{
t2 = make_aggr_type (BOUND_TEMPLATE_TEMPLATE_PARM);
decl = build_decl (TYPE_DECL, DECL_NAME (decl), NULL_TREE);
/* These nodes have to be created to reflect new TYPE_DECL and template
@ -1329,6 +1331,7 @@ walk_tree (tp, func, data)
case STRING_CST:
case DEFAULT_ARG:
case TEMPLATE_TEMPLATE_PARM:
case BOUND_TEMPLATE_TEMPLATE_PARM:
case TEMPLATE_PARM_INDEX:
case TEMPLATE_TYPE_PARM:
case REAL_TYPE:
@ -1581,7 +1584,8 @@ copy_tree_r (tp, walk_subtrees, data)
if (TREE_CODE (*tp) == SCOPE_STMT)
SCOPE_STMT_BLOCK (*tp) = NULL_TREE;
}
else if (code == TEMPLATE_TEMPLATE_PARM)
else if (code == TEMPLATE_TEMPLATE_PARM
|| code == BOUND_TEMPLATE_TEMPLATE_PARM)
/* These must be copied specially. */
*tp = copy_template_template_parm (*tp, NULL_TREE);
else if (TREE_CODE_CLASS (code) == 't')

View File

@ -1012,6 +1012,7 @@ comptypes (t1, t2, strict)
switch (TREE_CODE (t1))
{
case TEMPLATE_TEMPLATE_PARM:
case BOUND_TEMPLATE_TEMPLATE_PARM:
if (TEMPLATE_TYPE_IDX (t1) != TEMPLATE_TYPE_IDX (t2)
|| TEMPLATE_TYPE_LEVEL (t1) != TEMPLATE_TYPE_LEVEL (t2))
return 0;
@ -1019,8 +1020,7 @@ comptypes (t1, t2, strict)
(DECL_TEMPLATE_PARMS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t1)),
DECL_TEMPLATE_PARMS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t2))))
return 0;
if (!TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t1)
&& ! TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t2))
if (TREE_CODE (t1) == TEMPLATE_TEMPLATE_PARM)
return 1;
/* Don't check inheritance. */
strict = COMPARE_STRICT;
@ -1030,7 +1030,7 @@ comptypes (t1, t2, strict)
case UNION_TYPE:
if (TYPE_TEMPLATE_INFO (t1) && TYPE_TEMPLATE_INFO (t2)
&& (TYPE_TI_TEMPLATE (t1) == TYPE_TI_TEMPLATE (t2)
|| TREE_CODE (t1) == TEMPLATE_TEMPLATE_PARM))
|| TREE_CODE (t1) == BOUND_TEMPLATE_TEMPLATE_PARM))
val = comp_template_args (TYPE_TI_ARGS (t1),
TYPE_TI_ARGS (t2));
look_hard:

View File

@ -0,0 +1,27 @@
// Origin: Ewgenij Gawrilow <gawrilow@math.TU-Berlin.DE>
#include <iostream>
template <template <class X> class B, class A>
struct is_instance_of {
enum { answer=false };
};
template <template <class X> class B, class T>
struct is_instance_of<B, B<T> > {
enum { answer=true };
};
template <class X> struct C { };
template <class X> struct D { };
template <class T>
bool is_C (const T&) {
return is_instance_of<C,T>::answer;
};
int main() {
cout << "should be true: " << is_C(C<int>()) << endl;
cout << "should be false: " << is_C(D<int>()) << endl;
return 0;
}