diff options
Diffstat (limited to 'clang/lib/Parse/Parser.cpp')
-rw-r--r-- | clang/lib/Parse/Parser.cpp | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 310105a4ac6..f7c0f3f550e 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -1517,16 +1517,34 @@ Parser::TryAnnotateName(bool IsAddressOfOperand, } bool Parser::TryKeywordIdentFallback(bool DisableKeyword) { - assert(Tok.isNot(tok::identifier)); + assert(!Tok.is(tok::identifier) && !Tok.isAnnotation()); Diag(Tok, diag::ext_keyword_as_ident) << PP.getSpelling(Tok) << DisableKeyword; - if (DisableKeyword) - Tok.getIdentifierInfo()->RevertTokenIDToIdentifier(); + if (DisableKeyword) { + IdentifierInfo *II = Tok.getIdentifierInfo(); + ContextualKeywords[II] = Tok.getKind(); + II->RevertTokenIDToIdentifier(); + } Tok.setKind(tok::identifier); return true; } +bool Parser::TryIdentKeywordUpgrade() { + assert(Tok.is(tok::identifier)); + const IdentifierInfo *II = Tok.getIdentifierInfo(); + assert(II->hasRevertedTokenIDToIdentifier()); + // If we find that this is in fact the name of a type trait, + // update the token kind in place and parse again to treat it as + // the appropriate kind of type trait. + llvm::SmallDenseMap<const IdentifierInfo *, tok::TokenKind>::iterator Known = + ContextualKeywords.find(II); + if (Known == ContextualKeywords.end()) + return false; + Tok.setKind(Known->second); + return true; +} + /// TryAnnotateTypeOrScopeToken - If the current token position is on a /// typename (possibly qualified in C++) or a C++ scope specifier not followed /// by a typename, TryAnnotateTypeOrScopeToken will replace one or more tokens |