diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9c4cd015178..97e5b3b0171 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2009-07-13 Andrew Pinski + + PR C++/22154 + * parser.c (cp_parser_elaborated_type_specifier): Accept typename in + front of qualified names. + 2009-07-12 Jason Merrill PR c++/36628 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index d6d4d5bbd27..94fba02aa34 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -11591,6 +11591,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, tree identifier; tree type = NULL_TREE; tree attributes = NULL_TREE; + tree globalscope; cp_token *token = NULL; /* See if we're looking at the `enum' keyword. */ @@ -11622,9 +11623,6 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, cp_lexer_consume_token (parser->lexer); /* Remember that it's a `typename' type. */ tag_type = typename_type; - /* The `typename' keyword is only allowed in templates. */ - if (!processing_template_decl) - permerror (input_location, "using % outside of template"); } /* Otherwise it must be a class-key. */ else @@ -11637,10 +11635,10 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, } /* Look for the `::' operator. */ - cp_parser_global_scope_opt (parser, - /*current_scope_valid_p=*/false); + globalscope = cp_parser_global_scope_opt (parser, + /*current_scope_valid_p=*/false); /* Look for the nested-name-specifier. */ - if (tag_type == typename_type) + if (tag_type == typename_type && !globalscope) { if (!cp_parser_nested_name_specifier (parser, /*typename_keyword_p=*/true, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c97a8d74409..15c06b49e08 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2009-07-13 Andrew Pinski + + PR C++/22154 + * g++.old-deja/g++.pt/typename10.C: Update for DR 382, typename in + front of qualified names are allowed. + * g++.dg/parse/crash10.C: Likewise. + * g++.dg/parse/error15.C: Likewise. + * g++.dg/parse/typename9.C: Likewise. + * g++.dg/parse/error8.C: Likewise. + 2009-07-13 Janus Weil PR fortran/40646 diff --git a/gcc/testsuite/g++.dg/parse/crash10.C b/gcc/testsuite/g++.dg/parse/crash10.C index 8212fcb5b29..712e8767487 100644 --- a/gcc/testsuite/g++.dg/parse/crash10.C +++ b/gcc/testsuite/g++.dg/parse/crash10.C @@ -9,5 +9,5 @@ class { - typename:: // { dg-error "" "" } + typename:: ; // { dg-error "" "" } diff --git a/gcc/testsuite/g++.dg/parse/error15.C b/gcc/testsuite/g++.dg/parse/error15.C index c5d3d3d7d67..2352193bcd6 100644 --- a/gcc/testsuite/g++.dg/parse/error15.C +++ b/gcc/testsuite/g++.dg/parse/error15.C @@ -14,7 +14,7 @@ N::A f2; // { dg-error "1:invalid use of template-name 'N::A' witho N::INVALID f3; // { dg-error "1:'INVALID' in namespace 'N' does not name a type" } N::C::INVALID f4; // { dg-error "1:'INVALID' in class 'N::C' does not name a type" } N::K f6; // { dg-error "1:'K' in namespace 'N' does not name a type" } -typename N::A f7; // { dg-error "1:using 'typename' outside of template" "1" } +typename N::A f7; // { dg-error "13:invalid use of template-name 'N::A' without an argument list" "13" { target *-*-* } 17 } // { dg-error "17:invalid type in declaration before ';' token" "17" { target *-*-* } 17 } @@ -24,7 +24,7 @@ struct B N::INVALID f3; // { dg-error "3:'INVALID' in namespace 'N' does not name a type" } N::C::INVALID f4; // { dg-error "3:'INVALID' in class 'N::C' does not name a type" } N::K f6; // { dg-error "3:'K' in namespace 'N' does not name a type" } - typename N::A f7; // { dg-error "3:using 'typename' outside of template" } + typename N::A f7; // { dg-error "15:invalid use of template-name 'N::A' without an argument list" "15" { target *-*-* } 27 } }; diff --git a/gcc/testsuite/g++.dg/parse/error8.C b/gcc/testsuite/g++.dg/parse/error8.C index ba572b0db7d..6d3bf5a856a 100644 --- a/gcc/testsuite/g++.dg/parse/error8.C +++ b/gcc/testsuite/g++.dg/parse/error8.C @@ -4,7 +4,6 @@ struct A { friend typename struct B; }; -// { dg-error "19:using 'typename' outside of template" "" { target *-*-* } 4 } // { dg-error "28:expected nested-name-specifier before 'struct'" "" { target *-*-* } 4 } // { dg-error "35:multiple types in one declaration" "" { target *-*-* } 4 } // { dg-error "12:friend declaration does not name a class or function" "" { target *-*-* } 4 } diff --git a/gcc/testsuite/g++.dg/parse/typename9.C b/gcc/testsuite/g++.dg/parse/typename9.C index aa72cd6c584..8d77072197b 100644 --- a/gcc/testsuite/g++.dg/parse/typename9.C +++ b/gcc/testsuite/g++.dg/parse/typename9.C @@ -1,3 +1,6 @@ +// check that using a qualified name with a typename does +// not report an error. + struct A { typedef int X; }; -int i = typename A::X(); // { dg-error "typename" } +int i = typename A::X(); diff --git a/gcc/testsuite/g++.old-deja/g++.pt/typename10.C b/gcc/testsuite/g++.old-deja/g++.pt/typename10.C index f778c42f098..cdd9850ac0d 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/typename10.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/typename10.C @@ -4,4 +4,4 @@ struct S { typedef int I; }; -void f(typename S::I); // { dg-error "" } using typename outside of template +void f(typename S::I);