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:
parent
31e0ab1f76
commit
a1281f4503
17 changed files with 252 additions and 154 deletions
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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, $$);
|
||||
}
|
||||
|
|
171
gcc/cp/pt.c
171
gcc/cp/pt.c
|
@ -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]'),
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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:
|
||||
|
|
27
gcc/testsuite/g++.old-deja/g++.pt/ttp62.C
Normal file
27
gcc/testsuite/g++.old-deja/g++.pt/ttp62.C
Normal 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;
|
||||
}
|
Loading…
Add table
Reference in a new issue