summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse/ParseDecl.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2017-05-19 01:54:59 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2017-05-19 01:54:59 +0000
commit74639b1900ec07276ab40f1eea3e632f204000fe (patch)
treeeb5f2c53f4abdaa9448c533a9959925f48c104fe /clang/lib/Parse/ParseDecl.cpp
parent8f1d87a79abb91cb44292e5cfde350e85a119385 (diff)
downloadbcm5719-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.cpp27
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());
OpenPOWER on IntegriCloud