Author: rsmith Date: Thu May 18 20:54:59 2017 New Revision: 303398 URL: http://llvm.org/viewvc/llvm-project?rev=303398&view=rev Log: When a type-id is unexpectedly given a name, assume that the name is unrelated syntax unless we have a reason to think otherwise.
This improves error recovery in a couple of cases. Modified: cfe/trunk/include/clang/Sema/DeclSpec.h cfe/trunk/lib/Parse/ParseDecl.cpp cfe/trunk/test/Parser/cxx-template-argument.cpp cfe/trunk/test/Parser/cxx0x-decl.cpp cfe/trunk/test/Sema/block-args.c Modified: cfe/trunk/include/clang/Sema/DeclSpec.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DeclSpec.h?rev=303398&r1=303397&r2=303398&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/DeclSpec.h (original) +++ cfe/trunk/include/clang/Sema/DeclSpec.h Thu May 18 20:54:59 2017 @@ -1999,41 +1999,6 @@ public: llvm_unreachable("unknown context kind!"); } - /// diagnoseIdentifier - Return true if the identifier is prohibited and - /// should be diagnosed (because it cannot be anything else). - bool diagnoseIdentifier() const { - switch (Context) { - case FileContext: - case KNRTypeListContext: - case MemberContext: - case BlockContext: - case ForContext: - case InitStmtContext: - case ConditionContext: - case PrototypeContext: - case LambdaExprParameterContext: - case TemplateParamContext: - case CXXCatchContext: - case ObjCCatchContext: - case TypeNameContext: - case FunctionalCastContext: - case ConversionIdContext: - case ObjCParameterContext: - case ObjCResultContext: - case BlockLiteralContext: - case CXXNewContext: - case LambdaExprContext: - return false; - - case AliasDeclContext: - case AliasTemplateContext: - case TemplateTypeArgContext: - case TrailingReturnContext: - return true; - } - llvm_unreachable("unknown context kind!"); - } - /// Return true if the context permits a C++17 decomposition declarator. bool mayHaveDecompositionDeclarator() const { switch (Context) { Modified: cfe/trunk/lib/Parse/ParseDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=303398&r1=303397&r2=303398&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParseDecl.cpp (original) +++ cfe/trunk/lib/Parse/ParseDecl.cpp Thu May 18 20:54:59 2017 @@ -5542,11 +5542,28 @@ void Parser::ParseDirectDeclarator(Decla D.SetRangeEnd(Tok.getLocation()); ConsumeToken(); goto PastIdentifier; - } else if (Tok.is(tok::identifier) && D.diagnoseIdentifier()) { - // A virt-specifier isn't treated as an identifier if it appears after a - // trailing-return-type. - if (D.getContext() != Declarator::TrailingReturnContext || - !isCXX11VirtSpecifier(Tok)) { + } else if (Tok.is(tok::identifier) && !D.mayHaveIdentifier()) { + // We're not allowed an identifier here, but we got one. Try to figure out + // if the user was trying to attach a name to the type, or whether the name + // is some unrelated trailing syntax. + bool DiagnoseIdentifier = false; + if (D.hasGroupingParens()) + // An identifier within parens is unlikely to be intended to be anything + // other than a name being "declared". + DiagnoseIdentifier = true; + else if (D.getContext() == Declarator::TemplateTypeArgContext) + // T<int N> is an accidental identifier; T<int N indicates a missing '>'. + DiagnoseIdentifier = + NextToken().isOneOf(tok::comma, tok::greater, tok::greatergreater); + else if (D.getContext() == Declarator::AliasDeclContext || + D.getContext() == Declarator::AliasTemplateContext) + // The most likely error is that the ';' was forgotten. + DiagnoseIdentifier = NextToken().isOneOf(tok::comma, tok::semi); + else if (D.getContext() == Declarator::TrailingReturnContext && + !isCXX11VirtSpecifier(Tok)) + DiagnoseIdentifier = NextToken().isOneOf( + tok::comma, tok::semi, tok::equal, tok::l_brace, tok::kw_try); + if (DiagnoseIdentifier) { Diag(Tok.getLocation(), diag::err_unexpected_unqualified_id) << FixItHint::CreateRemoval(Tok.getLocation()); D.SetIdentifier(nullptr, Tok.getLocation()); Modified: cfe/trunk/test/Parser/cxx-template-argument.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-template-argument.cpp?rev=303398&r1=303397&r2=303398&view=diff ============================================================================== --- cfe/trunk/test/Parser/cxx-template-argument.cpp (original) +++ cfe/trunk/test/Parser/cxx-template-argument.cpp Thu May 18 20:54:59 2017 @@ -10,7 +10,7 @@ template<typename T> struct A {}; // Check for template argument lists followed by junk // FIXME: The diagnostics here aren't great... A<int+> int x; // expected-error {{expected '>'}} expected-error {{expected unqualified-id}} -A<int x; // expected-error {{type-id cannot have a name}} expected-error {{expected '>'}} +A<int x; // expected-error {{expected '>'}} // PR8912 template <bool> struct S {}; Modified: cfe/trunk/test/Parser/cxx0x-decl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-decl.cpp?rev=303398&r1=303397&r2=303398&view=diff ============================================================================== --- cfe/trunk/test/Parser/cxx0x-decl.cpp (original) +++ cfe/trunk/test/Parser/cxx0x-decl.cpp Thu May 18 20:54:59 2017 @@ -137,6 +137,9 @@ namespace AliasDeclEndLocation { >\ > // expected-error {{expected ';' after alias declaration}} ; + using D = AliasDeclEndLocation::A<int + > // expected-error {{expected ';' after alias declaration}} + B something_else; } struct Base { virtual void f() = 0; virtual void g() = 0; virtual void h() = 0; }; Modified: cfe/trunk/test/Sema/block-args.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/block-args.c?rev=303398&r1=303397&r2=303398&view=diff ============================================================================== --- cfe/trunk/test/Sema/block-args.c (original) +++ cfe/trunk/test/Sema/block-args.c Thu May 18 20:54:59 2017 @@ -37,7 +37,7 @@ void f0() { // rdar://problem/8962770 void test4() { - int (^f)() = ^((x)) { }; // expected-error {{expected ')'}} expected-warning {{type specifier missing}} expected-note {{to match this}} + int (^f)() = ^((x)) { }; // expected-warning {{type specifier missing}} expected-error {{type-id cannot have a name}} } // rdar://problem/9170609 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits