From: Nico Weber Date: Wed, 29 Feb 2012 22:54:43 +0000 (+0000) Subject: Allow operator keywords to be #defined in ms-ext mode. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f4fb07ed4dfd144a39d904fc77b3b0bab580eb2e;p=clang Allow operator keywords to be #defined in ms-ext mode. 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 --- diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index 8c3b742137..feed6a8bfa 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -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 &Buffer, - bool *Invalid = 0) const; + SmallVectorImpl &Buffer, + bool *Invalid = 0) const; /// getSpellingOfSingleCharacterNumericConstant - Tok is a numeric constant /// with length 1, return the character. diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp index 748bc38054..8988e48af5 100644 --- a/lib/Lex/PPDirectives.cpp +++ b/lib/Lex/PPDirectives.cpp @@ -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 index 0000000000..99caa2c4a3 --- /dev/null +++ b/test/Preprocessor/cxx_oper_keyword_ms_ext.cpp @@ -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