diff options
author | Haojian Wu <hokein.wu@gmail.com> | 2020-04-08 15:08:48 +0200 |
---|---|---|
committer | Haojian Wu <hokein.wu@gmail.com> | 2020-04-08 15:15:33 +0200 |
commit | 625acd8f6847a156b236b8f11b4b02b11cac3766 (patch) | |
tree | dbcd205209b8d11a94b4d9659b7e1cf3f5cad337 /clang/lib/Parse/ParseDecl.cpp | |
parent | 6c4b40def77622a5cf62a219ef4af63dc876e144 (diff) | |
download | llvm-625acd8f6847a156b236b8f11b4b02b11cac3766.zip llvm-625acd8f6847a156b236b8f11b4b02b11cac3766.tar.gz llvm-625acd8f6847a156b236b8f11b4b02b11cac3766.tar.bz2 |
[Parser] Improve diagnostic and error recovery when C++ keywords are used as identifiers.
Summary:
Previously, clang emitted a less-usefull diagnostic and didnt recover
well when the keywords is used as identifier in function paramter.
```
void foo(int case, int x); // previously we drop all parameters after
`int case`.
```
Reviewers: sammccall
Reviewed By: sammccall
Subscribers: cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D77633
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index e60d1f6..8bd7571 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -6815,6 +6815,31 @@ void Parser::ParseParameterDeclarationClause( Actions.containsUnexpandedParameterPacks(ParmDeclarator)) DiagnoseMisplacedEllipsisInDeclarator(ConsumeToken(), ParmDeclarator); + // Now we are at the point where declarator parsing is finished. + // + // Try to catch keywords in place of the identifier in a declarator, and + // in particular the common case where: + // 1 identifier comes at the end of the declarator + // 2 if the identifier is dropped, the declarator is valid but anonymous + // (no identifier) + // 3 declarator parsing succeeds, and then we have a trailing keyword, + // which is never valid in a param list (e.g. missing a ',') + // And we can't handle this in ParseDeclarator because in general keywords + // may be allowed to follow the declarator. (And in some cases there'd be + // better recovery like inserting punctuation). ParseDeclarator is just + // treating this as an anonymous parameter, and fortunately at this point + // we've already almost done that. + // + // We care about case 1) where the declarator type should be known, and + // the identifier should be null. + if (!ParmDeclarator.isInvalidType() && !ParmDeclarator.hasName()) { + if (Tok.getIdentifierInfo() && + Tok.getIdentifierInfo()->isKeyword(getLangOpts())) { + Diag(Tok, diag::err_keyword_as_parameter) << PP.getSpelling(Tok); + // Consume the keyword. + ConsumeToken(); + } + } // Inform the actions module about the parameter declarator, so it gets // added to the current scope. Decl *Param = Actions.ActOnParamDeclarator(getCurScope(), ParmDeclarator); |