diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-05-19 01:54:59 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-05-19 01:54:59 +0000 |
commit | 74639b1900ec07276ab40f1eea3e632f204000fe (patch) | |
tree | eb5f2c53f4abdaa9448c533a9959925f48c104fe /clang/lib/Parse/ParseDecl.cpp | |
parent | 8f1d87a79abb91cb44292e5cfde350e85a119385 (diff) | |
download | bcm5719-llvm-74639b1900ec07276ab40f1eea3e632f204000fe.tar.gz bcm5719-llvm-74639b1900ec07276ab40f1eea3e632f204000fe.zip |
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.
llvm-svn: 303398
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 69e1af0ed0b..b785f5f7d2e 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -5542,11 +5542,28 @@ void Parser::ParseDirectDeclarator(Declarator &D) { 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()); |