diff options
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 12 | ||||
| -rw-r--r-- | clang/lib/Parse/ParseDeclCXX.cpp | 38 |
2 files changed, 50 insertions, 0 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index acfe0ca0e82..40687d8f27b 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -2647,6 +2647,18 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, const char *PrevSpec = nullptr; unsigned DiagID = 0; + // HACK: MSVC doesn't consider _Atomic to be a keyword and its STL + // implementation for VS2013 uses _Atomic as an identifier for one of the + // classes in <atomic>. + // + // A typedef declaration containing _Atomic<...> is among the places where + // the class is used. If we are currently parsing such a declaration, treat + // the token as an identifier. + if (getLangOpts().MSVCCompat && Tok.is(tok::kw__Atomic) && + DS.getStorageClassSpec() == clang::DeclSpec::SCS_typedef && + !DS.hasTypeSpecifier() && GetLookAheadToken(1).is(tok::less)) + Tok.setKind(tok::identifier); + SourceLocation Loc = Tok.getLocation(); switch (Tok.getKind()) { diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 79138900b83..88ffb25a388 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -1308,6 +1308,35 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // allow libstdc++ 4.2 and libc++ to work properly. TryKeywordIdentFallback(true); + struct PreserveAtomicIdentifierInfoRAII { + PreserveAtomicIdentifierInfoRAII(Token &Tok, bool Enabled) + : AtomicII(nullptr) { + if (!Enabled) + return; + assert(Tok.is(tok::kw__Atomic)); + AtomicII = Tok.getIdentifierInfo(); + AtomicII->revertTokenIDToIdentifier(); + Tok.setKind(tok::identifier); + } + ~PreserveAtomicIdentifierInfoRAII() { + if (!AtomicII) + return; + AtomicII->revertIdentifierToTokenID(tok::kw__Atomic); + } + IdentifierInfo *AtomicII; + }; + + // HACK: MSVC doesn't consider _Atomic to be a keyword and its STL + // implementation for VS2013 uses _Atomic as an identifier for one of the + // classes in <atomic>. When we are parsing 'struct _Atomic', don't consider + // '_Atomic' to be a keyword. We are careful to undo this so that clang can + // use '_Atomic' in its own header files. + bool ShouldChangeAtomicToIdentifier = getLangOpts().MSVCCompat && + Tok.is(tok::kw__Atomic) && + TagType == DeclSpec::TST_struct; + PreserveAtomicIdentifierInfoRAII AtomicTokenGuard( + Tok, ShouldChangeAtomicToIdentifier); + // Parse the (optional) nested-name-specifier. CXXScopeSpec &SS = DS.getTypeSpecScope(); if (getLangOpts().CPlusPlus) { @@ -1859,6 +1888,15 @@ BaseResult Parser::ParseBaseSpecifier(Decl *ClassDecl) { CheckMisplacedCXX11Attribute(Attributes, StartLoc); // Parse the class-name. + + // HACK: MSVC doesn't consider _Atomic to be a keyword and its STL + // implementation for VS2013 uses _Atomic as an identifier for one of the + // classes in <atomic>. Treat '_Atomic' to be an identifier when we are + // parsing the class-name for a base specifier. + if (getLangOpts().MSVCCompat && Tok.is(tok::kw__Atomic) && + NextToken().is(tok::less)) + Tok.setKind(tok::identifier); + SourceLocation EndLocation; SourceLocation BaseLoc; TypeResult BaseType = ParseBaseTypeSpecifier(BaseLoc, EndLocation); |

