aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog52
-rw-r--r--gcc/cp/class.c2
-rw-r--r--gcc/cp/cp-tree.def10
-rw-r--r--gcc/cp/cp-tree.h17
-rw-r--r--gcc/cp/decl.c10
-rw-r--r--gcc/cp/decl2.c8
-rw-r--r--gcc/cp/error.c30
-rw-r--r--gcc/cp/init.c4
-rw-r--r--gcc/cp/mangle.c18
-rw-r--r--gcc/cp/method.c36
-rw-r--r--gcc/cp/parse.y2
-rw-r--r--gcc/cp/pt.c175
-rw-r--r--gcc/cp/ptree.c1
-rw-r--r--gcc/cp/search.c2
-rw-r--r--gcc/cp/tree.c10
-rw-r--r--gcc/cp/typeck.c6
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/ttp62.C27
17 files changed, 254 insertions, 156 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 564de16..d4388fc 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index c10f09d..d4c2ad2 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -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));
diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def
index 71edb20..07ec1ea 100644
--- a/gcc/cp/cp-tree.def
+++ b/gcc/cp/cp-tree.def
@@ -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
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 4fee6ff..2da46de 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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))
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 0f4d1c1..664d125 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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));
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 417348c..7fbd80c 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -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;
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 8a48360..873f787 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -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:
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 91449c1..7d1e3b4 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -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);
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index fb4d166..da04480 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -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));
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 4c024d1..1e5c4e3 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -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:
diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y
index 8f23d91..eb6a01a 100644
--- a/gcc/cp/parse.y
+++ b/gcc/cp/parse.y
@@ -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, $$);
}
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index abf4f9b..cddf0f9 100644
--- a/gcc/cp/pt.c
+++ b/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);
-
- 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;
+ /* 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
+ /* 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. */
-
- if (coerce_template_parms (argtmplvec, parmvec, parmtmpl, 0, 1)
- == error_mark_node)
- return 1;
+ /* 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;
- /* 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]'),
diff --git a/gcc/cp/ptree.c b/gcc/cp/ptree.c
index d3cd45e..5c4ac84 100644
--- a/gcc/cp/ptree.c
+++ b/gcc/cp/ptree.c
@@ -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));
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index bf19ce8..befcb99 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -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
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 371f00f..be2459a 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -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')
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 015df0e..823aaec 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -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:
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/ttp62.C b/gcc/testsuite/g++.old-deja/g++.pt/ttp62.C
new file mode 100644
index 0000000..77013c4
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.pt/ttp62.C
@@ -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;
+}