majnemer updated this revision to Diff 29836.
majnemer added a comment.

- Address review comments


http://reviews.llvm.org/D11233

Files:
  include/clang/Basic/IdentifierTable.h
  include/clang/Basic/TokenKinds.def
  include/clang/Parse/Parser.h
  lib/Parse/ParseDeclCXX.cpp
  lib/Parse/Parser.cpp
  test/SemaCXX/MicrosoftCompatibility.cpp

Index: test/SemaCXX/MicrosoftCompatibility.cpp
===================================================================
--- test/SemaCXX/MicrosoftCompatibility.cpp
+++ test/SemaCXX/MicrosoftCompatibility.cpp
@@ -9,11 +9,16 @@
 typedef unsigned int char32_t;
 #endif
 
-#if _MSC_VER >= 1900
 _Atomic(int) z;
-#else
-struct _Atomic {};
-#endif
+struct _Atomic {
+  _Atomic() {}
+  ~_Atomic() {}
+};
+struct atomic : _Atomic {
+  typedef _Atomic TheBase;
+  TheBase field;
+};
+_Atomic(int) alpha;
 
 typename decltype(3) a; // expected-warning {{expected a qualified name after 'typename'}}
 
Index: lib/Parse/Parser.cpp
===================================================================
--- lib/Parse/Parser.cpp
+++ lib/Parse/Parser.cpp
@@ -517,6 +517,8 @@
     PP.SetPoisonReason(Ident_AbnormalTermination,diag::err_seh___finally_block);
   }
 
+  Ident__Atomic = nullptr;
+
   Actions.Initialize();
 
   // Prime the lexer look-ahead.
Index: lib/Parse/ParseDeclCXX.cpp
===================================================================
--- lib/Parse/ParseDeclCXX.cpp
+++ lib/Parse/ParseDeclCXX.cpp
@@ -1307,6 +1307,41 @@
     // allow libstdc++ 4.2 and libc++ to work properly.
     TryKeywordIdentFallback(true);
 
+  struct PreserveIdentifierInfoRAII {
+    void set(IdentifierInfo *AtomicII) {
+      II = AtomicII;
+      TK = II->getTokenID();
+    }
+    ~PreserveIdentifierInfoRAII() {
+      if (II) {
+        if (TK == tok::identifier && II->getTokenID() != tok::identifier)
+          II->RevertTokenIDToIdentifier();
+        else if (TK != tok::identifier && II->getTokenID() == tok::identifier)
+          II->RevertIdentifierToTokenID(TK);
+      }
+    }
+    IdentifierInfo *II = nullptr;
+    tok::TokenKind TK;
+  };
+
+  PreserveIdentifierInfoRAII AtomicTokenGuard;
+  if (getLangOpts().MSVCCompat) {
+    if (!Ident__Atomic)
+      Ident__Atomic = &PP.getIdentifierTable().get("_Atomic");
+    AtomicTokenGuard.set(Ident__Atomic);
+  }
+
+  // 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.
+  if (getLangOpts().MSVCCompat && Tok.is(tok::kw__Atomic) &&
+      TagType == DeclSpec::TST_struct) {
+    Ident__Atomic->RevertTokenIDToIdentifier();
+    Tok.setKind(tok::identifier);
+  }
+
   // Parse the (optional) nested-name-specifier.
   CXXScopeSpec &SS = DS.getTypeSpecScope();
   if (getLangOpts().CPlusPlus) {
@@ -1858,6 +1893,12 @@
   CheckMisplacedCXX11Attribute(Attributes, StartLoc);
 
   // Parse the class-name.
+  if (getLangOpts().MSVCCompat && Tok.isNot(tok::identifier) &&
+      !Tok.isAnnotation() && Tok.getIdentifierInfo() &&
+      Tok.is(tok::kw__Atomic)) {
+    Ident__Atomic->RevertTokenIDToIdentifier();
+    Tok.setKind(tok::identifier);
+  }
   SourceLocation EndLocation;
   SourceLocation BaseLoc;
   TypeResult BaseType = ParseBaseTypeSpecifier(BaseLoc, EndLocation);
Index: include/clang/Parse/Parser.h
===================================================================
--- include/clang/Parse/Parser.h
+++ include/clang/Parse/Parser.h
@@ -137,6 +137,9 @@
   mutable IdentifierInfo *Ident_final;
   mutable IdentifierInfo *Ident_override;
 
+  /// \brief Identifier for "_Atomic".
+  IdentifierInfo *Ident__Atomic;
+
   // C++ type trait keywords that can be reverted to identifiers and still be
   // used as type traits.
   llvm::SmallDenseMap<IdentifierInfo *, tok::TokenKind> RevertibleTypeTraits;
Index: include/clang/Basic/TokenKinds.def
===================================================================
--- include/clang/Basic/TokenKinds.def
+++ include/clang/Basic/TokenKinds.def
@@ -280,7 +280,7 @@
 KEYWORD(while                       , KEYALL)
 KEYWORD(_Alignas                    , KEYALL)
 KEYWORD(_Alignof                    , KEYALL)
-KEYWORD(_Atomic                     , KEYALL|KEYNOMS18|KEYNOOPENCL)
+KEYWORD(_Atomic                     , KEYALL|KEYNOOPENCL)
 KEYWORD(_Bool                       , KEYNOCXX)
 KEYWORD(_Complex                    , KEYALL)
 KEYWORD(_Generic                    , KEYALL)
Index: include/clang/Basic/IdentifierTable.h
===================================================================
--- include/clang/Basic/IdentifierTable.h
+++ include/clang/Basic/IdentifierTable.h
@@ -166,6 +166,11 @@
     TokenID = tok::identifier;
     RevertedTokenID = true;
   }
+  void RevertIdentifierToTokenID(tok::TokenKind TK) {
+    assert(TokenID == tok::identifier && "Should be at tok::identifier");
+    TokenID = TK;
+    RevertedTokenID = false;
+  }
 
   /// \brief Return the preprocessor keyword ID for this identifier.
   ///
_______________________________________________
cfe-commits mailing list
cfe-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to