diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 52 | ||||
-rw-r--r-- | gcc/cp/class.c | 2 | ||||
-rw-r--r-- | gcc/cp/cp-tree.def | 10 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 17 | ||||
-rw-r--r-- | gcc/cp/decl.c | 10 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 8 | ||||
-rw-r--r-- | gcc/cp/error.c | 30 | ||||
-rw-r--r-- | gcc/cp/init.c | 4 | ||||
-rw-r--r-- | gcc/cp/mangle.c | 18 | ||||
-rw-r--r-- | gcc/cp/method.c | 36 | ||||
-rw-r--r-- | gcc/cp/parse.y | 2 | ||||
-rw-r--r-- | gcc/cp/pt.c | 175 | ||||
-rw-r--r-- | gcc/cp/ptree.c | 1 | ||||
-rw-r--r-- | gcc/cp/search.c | 2 | ||||
-rw-r--r-- | gcc/cp/tree.c | 10 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.pt/ttp62.C | 27 |
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; +} |