diff options
author | Jason Merrill <jason@redhat.com> | 2012-08-30 22:50:08 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2012-08-30 22:50:08 -0400 |
commit | 091bffba90e0c70f76ee138f92024a6f3b7aa2bc (patch) | |
tree | 424314c23f47f26c9a20d19dc68f81690672bb2e /gcc/cp | |
parent | 5cb25c9c7b6581f62151741e3ceb2c5e57def30e (diff) | |
download | gcc-091bffba90e0c70f76ee138f92024a6f3b7aa2bc.zip gcc-091bffba90e0c70f76ee138f92024a6f3b7aa2bc.tar.gz gcc-091bffba90e0c70f76ee138f92024a6f3b7aa2bc.tar.bz2 |
friend.c (make_friend_class): Handle template template parameters.
* friend.c (make_friend_class): Handle template template parameters.
* parser.c (cp_parser_template_declaration_after_export): Likewise.
* pt.c (tsubst_friend_class): Likewise.
(instantiate_class_template_1): Likewise
* decl.c (check_elaborated_type_specifier): Likewise.
(lookup_and_check_tag): Likewise.
From-SVN: r190828
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/decl.c | 12 | ||||
-rw-r--r-- | gcc/cp/friend.c | 5 | ||||
-rw-r--r-- | gcc/cp/parser.c | 4 | ||||
-rw-r--r-- | gcc/cp/pt.c | 9 |
5 files changed, 31 insertions, 6 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f334778..fc49329 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,12 @@ 2012-08-30 Jason Merrill <jason@redhat.com> + * friend.c (make_friend_class): Handle template template parameters. + * parser.c (cp_parser_template_declaration_after_export): Likewise. + * pt.c (tsubst_friend_class): Likewise. + (instantiate_class_template_1): Likewise + * decl.c (check_elaborated_type_specifier): Likewise. + (lookup_and_check_tag): Likewise. + * pt.c (get_class_bindings): Call coerce_template_parms. Add main_tmpl parameter. (more_specialized_class): Add main_tmpl parameter. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 19485fc..c909dea 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -11484,9 +11484,10 @@ check_elaborated_type_specifier (enum tag_types tag_code, type, tag_name (tag_code)); return error_mark_node; } - /* Accept bound template template parameters. */ + /* Accept template template parameters. */ else if (allow_template_p - && TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM) + && (TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM + || TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM)) ; /* [dcl.type.elab] @@ -11574,7 +11575,9 @@ lookup_and_check_tag (enum tag_types tag_code, tree name, else decl = lookup_type_scope (name, scope); - if (decl && DECL_CLASS_TEMPLATE_P (decl)) + if (decl + && (DECL_CLASS_TEMPLATE_P (decl) + || DECL_TEMPLATE_TEMPLATE_PARM_P (decl))) decl = DECL_TEMPLATE_RESULT (decl); if (decl && TREE_CODE (decl) == TYPE_DECL) @@ -11679,6 +11682,9 @@ xref_tag_1 (enum tag_types tag_code, tree name, && template_class_depth (current_class_type) && template_header_p) { + if (TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM) + return t; + /* Since SCOPE is not TS_CURRENT, we are not looking at a definition of this tag. Since, in addition, we are currently processing a (member) template declaration of a template diff --git a/gcc/cp/friend.c b/gcc/cp/friend.c index d0cbaed..d4548ff 100644 --- a/gcc/cp/friend.c +++ b/gcc/cp/friend.c @@ -224,7 +224,8 @@ make_friend_class (tree type, tree friend_type, bool complain) int class_template_depth = template_class_depth (type); int friend_depth = processing_template_decl - class_template_depth; - if (! MAYBE_CLASS_TYPE_P (friend_type)) + if (! MAYBE_CLASS_TYPE_P (friend_type) + && TREE_CODE (friend_type) != TEMPLATE_TEMPLATE_PARM) { /* N1791: If the type specifier in a friend declaration designates a (possibly cv-qualified) class type, that class is declared as a @@ -349,6 +350,8 @@ make_friend_class (tree type, tree friend_type, bool complain) error ("template parameter type %qT declared %<friend%>", friend_type); return; } + else if (TREE_CODE (friend_type) == TEMPLATE_TEMPLATE_PARM) + friend_type = TYPE_NAME (friend_type); else if (!CLASSTYPE_TEMPLATE_INFO (friend_type)) { /* template <class T> friend class A; where A is not a template */ diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 0f897c9..091a967 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -21240,7 +21240,9 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p) decl = finish_member_template_decl (decl); } - else if (friend_p && decl && TREE_CODE (decl) == TYPE_DECL) + else if (friend_p && decl + && (TREE_CODE (decl) == TYPE_DECL + || DECL_TYPE_TEMPLATE_P (decl))) make_friend_class (current_class_type, TREE_TYPE (decl), /*complain=*/true); } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 792e9d1..6506a67 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -8152,6 +8152,12 @@ tsubst_friend_class (tree friend_tmpl, tree args) tree tmpl; tree context; + if (DECL_TEMPLATE_TEMPLATE_PARM_P (friend_tmpl)) + { + tree t = tsubst (TREE_TYPE (friend_tmpl), args, tf_none, NULL_TREE); + return TREE_TYPE (t); + } + context = CP_DECL_CONTEXT (friend_tmpl); if (context != global_namespace) @@ -8736,7 +8742,8 @@ instantiate_class_template_1 (tree type) } else { - if (TYPE_P (t) || DECL_CLASS_TEMPLATE_P (t)) + if (TYPE_P (t) || DECL_CLASS_TEMPLATE_P (t) + || DECL_TEMPLATE_TEMPLATE_PARM_P (t)) { /* Build new CLASSTYPE_FRIEND_CLASSES. */ |