summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Parse/ParseDecl.cpp12
-rw-r--r--clang/lib/Parse/ParseDeclCXX.cpp38
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);
OpenPOWER on IntegriCloud