]> granicus.if.org Git - clang/commitdiff
Allow operator keywords to be #defined in ms-ext mode.
authorNico Weber <nicolasweber@gmx.de>
Wed, 29 Feb 2012 22:54:43 +0000 (22:54 +0000)
committerNico Weber <nicolasweber@gmx.de>
Wed, 29 Feb 2012 22:54:43 +0000 (22:54 +0000)
Fixes PR10606.

I'm not sure if this is the best way to go about it, but
I locally enabled this code path without the msext conditional,
and all tests pass, except for test/Preprocessor/cxx_oper_keyword.cpp
which explicitly checks that operator keywords can't be redefined.

I also parsed chromium/win with a clang with and without this patch.
It introduced no new errors, but removes 43 existing errors.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151768 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Lex/Preprocessor.h
lib/Lex/PPDirectives.cpp
test/Preprocessor/cxx_oper_keyword_ms_ext.cpp [new file with mode: 0644]

index 8c3b7421370977bb57e5a4171f7a89687a7a0648..feed6a8bfa912ce0246b3f9d0aba27496ad95f30 100644 (file)
@@ -815,8 +815,8 @@ public:
   /// SmallVector. Note that the returned StringRef may not point to the
   /// supplied buffer if a copy can be avoided.
   StringRef getSpelling(const Token &Tok,
-                              SmallVectorImpl<char> &Buffer,
-                              bool *Invalid = 0) const;
+                        SmallVectorImpl<char> &Buffer,
+                        bool *Invalid = 0) const;
 
   /// getSpellingOfSingleCharacterNumericConstant - Tok is a numeric constant
   /// with length 1, return the character.
index 748bc38054ddc8cbaaa8a61a64a628609d22571e..8988e48af559e69245895c80b97d7b44459ff88d 100644 (file)
@@ -120,8 +120,15 @@ void Preprocessor::ReadMacroName(Token &MacroNameTok, char isDefineUndef) {
     std::string Spelling = getSpelling(MacroNameTok, &Invalid);
     if (Invalid)
       return;
-    
+
     const IdentifierInfo &Info = Identifiers.get(Spelling);
+
+    // Allow #defining |and| and friends in microsoft mode.
+    if (Info.isCPlusPlusOperatorKeyword() && getLangOptions().MicrosoftExt) {
+      MacroNameTok.setIdentifierInfo(getIdentifierInfo(Spelling));
+      return;
+    }
+
     if (Info.isCPlusPlusOperatorKeyword())
       // C++ 2.5p2: Alternative tokens behave the same as its primary token
       // except for their spellings.
diff --git a/test/Preprocessor/cxx_oper_keyword_ms_ext.cpp b/test/Preprocessor/cxx_oper_keyword_ms_ext.cpp
new file mode 100644 (file)
index 0000000..99caa2c
--- /dev/null
@@ -0,0 +1,179 @@
+// RUN: %clang_cc1 %s -E -fms-extensions
+
+bool f() {
+  // Check that operators still work before redefining them.
+#if compl 0 bitand 1
+  return true and false;
+#endif
+}
+
+// All c++ keywords should be #define-able in ms mode.
+// (operators like "and" aren't normally, the rest always is.)
+#define and
+#define and_eq
+#define alignas
+#define alignof
+#define asm
+#define auto
+#define bitand
+#define bitor
+#define bool
+#define break
+#define case
+#define catch
+#define char
+#define char16_t
+#define char32_t
+#define class
+#define compl
+#define const
+#define constexpr
+#define const_cast
+#define continue
+#define decltype
+#define default
+#define delete
+#define double
+#define dynamic_cast
+#define else
+#define enum
+#define explicit
+#define export
+#define extern
+#define false
+#define float
+#define for
+#define friend
+#define goto
+#define if
+#define inline
+#define int
+#define long
+#define mutable
+#define namespace
+#define new
+#define noexcept
+#define not
+#define not_eq
+#define nullptr
+#define operator
+#define or
+#define or_eq
+#define private
+#define protected
+#define public
+#define register
+#define reinterpret_cast
+#define return
+#define short
+#define signed
+#define sizeof
+#define static
+#define static_assert
+#define static_cast
+#define struct
+#define switch
+#define template
+#define this
+#define thread_local
+#define throw
+#define true
+#define try
+#define typedef
+#define typeid
+#define typename
+#define union
+#define unsigned
+#define using
+#define virtual
+#define void
+#define volatile
+#define wchar_t
+#define while
+#define xor
+#define xor_eq
+
+// Check this is all properly defined away.
+and
+and_eq
+alignas
+alignof
+asm
+auto
+bitand
+bitor
+bool
+break
+case
+catch
+char
+char16_t
+char32_t
+class
+compl
+const
+constexpr
+const_cast
+continue
+decltype
+default
+delete
+double
+dynamic_cast
+else
+enum
+explicit
+export
+extern
+false
+float
+for
+friend
+goto
+if
+inline
+int
+long
+mutable
+namespace
+new
+noexcept
+not
+not_eq
+nullptr
+operator
+or
+or_eq
+private
+protected
+public
+register
+reinterpret_cast
+return
+short
+signed
+sizeof
+static
+static_assert
+static_cast
+struct
+switch
+template
+this
+thread_local
+throw
+true
+try
+typedef
+typeid
+typename
+union
+unsigned
+using
+virtual
+void
+volatile
+wchar_t
+while
+xor
+xor_eq