diff options
author | Fabien Chêne <fabien@gcc.gnu.org> | 2011-12-13 19:46:58 +0100 |
---|---|---|
committer | Fabien Chêne <fabien@gcc.gnu.org> | 2011-12-13 19:46:58 +0100 |
commit | 0f8fa9b67833f5f15226564b3f6bb782f5493517 (patch) | |
tree | 42d417ed9dfb4115cfed8440e8d3927916c549a9 /gcc | |
parent | 863ea6cf55e6f8d7469e257d22eb2c69a0cb181c (diff) | |
download | gcc-0f8fa9b67833f5f15226564b3f6bb782f5493517.zip gcc-0f8fa9b67833f5f15226564b3f6bb782f5493517.tar.gz gcc-0f8fa9b67833f5f15226564b3f6bb782f5493517.tar.bz2 |
re PR c++/14258 (typename in a using declaration not supported)
gcc/testsuite/ChangeLog
2011-12-11 Fabien Chene <fabien@gcc.gnu.org>
PR c++/14258
* g++.dg/template/using16.C: New.
* g++.dg/template/using17.C: New.
gcc/cp/ChangeLog
2011-12-11 Fabien Chene <fabien@gcc.gnu.org>
PR c++/14258
* cp-tree.h (USING_DECL_TYPENAME_P): New macro.
* parser.c (cp_parser_nonclass_name): Handle using declarations
that refer to a dependent type.
(cp_parser_using_declaration): Set USING_DECL_TYPENAME_P to 1 if
the using declaration refers to a dependent type.
From-SVN: r182292
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 4 | ||||
-rw-r--r-- | gcc/cp/parser.c | 32 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/using16.C | 42 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/using17.C | 44 |
6 files changed, 133 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3f04054..3e7abcc 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2011-12-13 Fabien Chêne <fabien@gcc.gnu.org> + + PR c++/14258 + * cp-tree.h (USING_DECL_TYPENAME_P): New macro. + * parser.c (cp_parser_nonclass_name): Handle using declarations + that refer to a dependent type. + (cp_parser_using_declaration): Set USING_DECL_TYPENAME_P to 1 if + the using declaration refers to a dependent type. + 2011-12-12 Jakub Jelinek <jakub@redhat.com> PR c++/51496 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index f443816..a96adbb 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -130,6 +130,7 @@ c-common.h, not after. DECL_TEMPLATE_INSTANTIATED (in a VAR_DECL or a FUNCTION_DECL) DECL_MEMBER_TEMPLATE_P (in TEMPLATE_DECL) FUNCTION_PARAMETER_PACK_P (in PARM_DECL) + USING_DECL_TYPENAME_P (in USING_DECL) 2: DECL_THIS_EXTERN (in VAR_DECL or FUNCTION_DECL). DECL_IMPLICIT_TYPEDEF_P (in a TYPE_DECL) 3: DECL_IN_AGGR_P. @@ -2521,6 +2522,9 @@ extern void decl_shadowed_for_var_insert (tree, tree); /* The decls named by a using decl. */ #define USING_DECL_DECLS(NODE) DECL_INITIAL (USING_DECL_CHECK (NODE)) +/* Non zero if the using decl refers to a dependent type. */ +#define USING_DECL_TYPENAME_P(NODE) DECL_LANG_FLAG_1 (USING_DECL_CHECK (NODE)) + /* In a VAR_DECL, true if we have a shadowed local variable in the shadowed var table for this VAR_DECL. */ #define DECL_HAS_SHADOWED_FOR_VAR_P(NODE) \ diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 2bd91ec..91280b7 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -13807,9 +13807,26 @@ cp_parser_nonclass_name (cp_parser* parser) /* Look up the type-name. */ type_decl = cp_parser_lookup_name_simple (parser, identifier, token->location); - /* If it is a using decl, use its underlying decl. */ - type_decl = strip_using_decl (type_decl); - + if (TREE_CODE (type_decl) == USING_DECL) + { + if (!DECL_DEPENDENT_P (type_decl)) + type_decl = strip_using_decl (type_decl); + else if (USING_DECL_TYPENAME_P (type_decl)) + { + /* We have found a type introduced by a using + declaration at class scope that refers to a dependent + type. + + using typename :: [opt] nested-name-specifier unqualified-id ; + */ + type_decl = make_typename_type (TREE_TYPE (type_decl), + DECL_NAME (type_decl), + typename_type, tf_error); + if (type_decl != error_mark_node) + type_decl = TYPE_NAME (type_decl); + } + } + if (TREE_CODE (type_decl) != TYPE_DECL && (objc_is_id (identifier) || objc_is_class_name (identifier))) { @@ -14947,6 +14964,9 @@ cp_parser_using_declaration (cp_parser* parser, /* Create the USING_DECL. */ decl = do_class_using_decl (parser->scope, identifier); + if (typename_p) + USING_DECL_TYPENAME_P (decl) = 1; + if (check_for_bare_parameter_packs (decl)) return false; else @@ -18900,7 +18920,11 @@ cp_parser_member_declaration (cp_parser* parser) parser->colon_corrects_to_scope_p = false; if (cp_parser_using_declaration (parser, /*access_declaration=*/true)) - goto out; + { + warning (OPT_Wdeprecated, "access declarations are deprecated; " + "employ using declarations instead"); + goto out; + } /* Parse the decl-specifier-seq. */ decl_spec_token_start = cp_lexer_peek_token (parser->lexer); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e5fa8ba..50595b2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2011-12-11 Fabien Chêne <fabien@gcc.gnu.org> + + PR c++/14258 + * g++.dg/template/using16.C: New. + * g++.dg/template/using17.C: New. + 2011-12-13 Martin Jambor <mjambor@suse.cz> PR tree-optimization/51362 diff --git a/gcc/testsuite/g++.dg/template/using16.C b/gcc/testsuite/g++.dg/template/using16.C new file mode 100644 index 0000000..589f7f1 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/using16.C @@ -0,0 +1,42 @@ +// { dg-do compile } + +template <class T> +struct A +{ + typedef T type; +}; + +template <class T> +struct B +{ + class type + { + type(); // { dg-error "private" } + }; +}; + +template <class T> +struct C : A<T>, B<T> +{ + using typename B<T>::type; + + void f() + { + type j; // { dg-error "context" } + } +}; + +template class C<int>; // { dg-message "required" } + +template <class T> +struct D +{ + typedef T type; +}; + +template <class T> +class E : D<T> +{ + using typename D<T>::type; // { dg-message "previous" } + using typename D<T>::type; // { dg-error "redeclaration" } +}; diff --git a/gcc/testsuite/g++.dg/template/using17.C b/gcc/testsuite/g++.dg/template/using17.C new file mode 100644 index 0000000..1af1dc7 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/using17.C @@ -0,0 +1,44 @@ +// PR c++/14258 +// { dg-do run } + +template<typename T> +struct A +{ + typedef T type; + typedef A type2; +}; + +template<typename T> +struct B : A<T> +{ + using typename A<T>::type; + type t; + + using typename A<T>::type2; + + type f() + { + type i = 1; + return i; + } +}; + +int main() +{ + B<int>::type t = 4; + if (t != 4) + __builtin_abort(); + + B<double> b; + b.t = 3; + if (b.t != 3) + __builtin_abort(); + + B<long> b2; + if (b2.f() != 1) + __builtin_abort(); + + B<double>::type2::type tt = 12; + if (tt != 12) + __builtin_abort(); +} |