diff options
-rw-r--r-- | clang/include/clang/Basic/DiagnosticParseKinds.td | 2 | ||||
-rw-r--r-- | clang/lib/Parse/ParseDeclCXX.cpp | 17 | ||||
-rw-r--r-- | clang/test/CXX/class.derived/p1.cpp | 4 |
3 files changed, 13 insertions, 10 deletions
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 3ec893ec514..f8b54400e01 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -249,6 +249,8 @@ def err_missing_comma_before_ellipsis : Error< "C requires a comma prior to the ellipsis in a variadic function type">; def err_unexpected_typedef_ident : Error< "unexpected type name %0: expected identifier">; +def err_unexpected_scope_on_base_decltype : Error< + "unexpected namespace scope prior to decltype">; def err_expected_class_name : Error<"expected class name">; def err_unspecified_vla_size_with_static : Error< "'static' may not be used with an unspecified variable length array size">; diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index bdd41a27dfe..8530ff2740a 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -713,13 +713,20 @@ void Parser::ParseUnderlyingTypeSpecifier(DeclSpec &DS) { /// Parser::TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &BaseLoc, SourceLocation &EndLocation) { + // Parse optional nested-name-specifier + CXXScopeSpec SS; + ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false); + + BaseLoc = Tok.getLocation(); + // Parse decltype-specifier if (Tok.is(tok::kw_decltype)) { + if (SS.isNotEmpty()) + Diag(SS.getBeginLoc(), diag::err_unexpected_scope_on_base_decltype) + << FixItHint::CreateRemoval(SS.getRange()); // Fake up a Declarator to use with ActOnTypeName. DeclSpec DS(AttrFactory); - BaseLoc = Tok.getLocation(); - ParseDecltypeSpecifier(DS); EndLocation = DS.getSourceRange().getEnd(); @@ -727,12 +734,6 @@ Parser::TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &BaseLoc, return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); } - // Parse optional nested-name-specifier - CXXScopeSpec SS; - ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false); - - BaseLoc = Tok.getLocation(); - // Check whether we have a template-id that names a type. if (Tok.is(tok::annot_template_id)) { TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); diff --git a/clang/test/CXX/class.derived/p1.cpp b/clang/test/CXX/class.derived/p1.cpp index dcbe63fd09a..d819ea23894 100644 --- a/clang/test/CXX/class.derived/p1.cpp +++ b/clang/test/CXX/class.derived/p1.cpp @@ -31,7 +31,7 @@ namespace PR11216 { struct Foo { Base foo(); }; Derived3<Foo> d; - struct Derived4 : :: decltype(Base()) { }; // expected-error {{expected class name}} + struct Derived4 : :: decltype(Base()) { }; // expected-error {{unexpected namespace scope prior to decltype}} - struct Derived5 : PR11216:: decltype(Base()) { }; // expected-error {{expected class name}} + struct Derived5 : PR11216:: decltype(Base()) { }; // expected-error {{unexpected namespace scope prior to decltype}} } |