From e03e9e15f2a66fe1b947322850e37b8133521759 Mon Sep 17 00:00:00 2001 From: Alp Toker Date: Sat, 31 May 2014 16:32:22 +0000 Subject: [PATCH] Preprocessor: make C++ operator names as macro identifiers a compatible extension With recent changes, this is now a compatible language extension and can be safely enabled with -ms-extensions instead of requiring the full -ms-compatibility MSVC drop-in mode. As such we can now also emit an extension warning under -Wmicrosoft to help users port their code. llvm-svn: 209978 --- clang/include/clang/Basic/DiagnosticLexKinds.td | 2 ++ clang/lib/Lex/PPDirectives.cpp | 11 ++++++----- clang/test/Parser/MicrosoftExtensions.cpp | 3 +++ .../test/Preprocessor/cxx_oper_keyword_ms_compat.cpp | 3 ++- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td index 01f56089d949..a32b9025c1dd 100644 --- a/clang/include/clang/Basic/DiagnosticLexKinds.td +++ b/clang/include/clang/Basic/DiagnosticLexKinds.td @@ -501,6 +501,8 @@ def ext_pp_bad_paste_ms : ExtWarn< InGroup>; def err_pp_operator_used_as_macro_name : Error< "C++ operator %0 (aka %1) used as a macro name">; +def ext_pp_operator_used_as_macro_name : Extension< + "C++ operator %0 (aka %1) used as a macro name">, InGroup; def err_pp_illegal_floating_literal : Error< "floating point literal in preprocessor expression">; def err_pp_line_requires_integer : Error< diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp index 46e8f07c510a..a8dde086baf2 100644 --- a/clang/lib/Lex/PPDirectives.cpp +++ b/clang/lib/Lex/PPDirectives.cpp @@ -145,11 +145,12 @@ bool Preprocessor::CheckMacroName(Token &MacroNameTok, char isDefineUndef) { if (!II->isCPlusPlusOperatorKeyword()) return Diag(MacroNameTok, diag::err_pp_macro_not_identifier); - if (!getLangOpts().MSVCCompat) - // C++ 2.5p2: Alternative tokens behave the same as its primary token - // except for their spellings. - Diag(MacroNameTok, diag::err_pp_operator_used_as_macro_name) - << II << MacroNameTok.getKind(); + // C++ 2.5p2: Alternative tokens behave the same as its primary token + // except for their spellings. + Diag(MacroNameTok, getLangOpts().MicrosoftExt + ? diag::ext_pp_operator_used_as_macro_name + : diag::err_pp_operator_used_as_macro_name) + << II << MacroNameTok.getKind(); // Allow #defining |and| and friends for Microsoft compatibility or // recovery when legacy C headers are included in C++. diff --git a/clang/test/Parser/MicrosoftExtensions.cpp b/clang/test/Parser/MicrosoftExtensions.cpp index 5f3c2a26fc03..72d6c2ed58c4 100644 --- a/clang/test/Parser/MicrosoftExtensions.cpp +++ b/clang/test/Parser/MicrosoftExtensions.cpp @@ -426,3 +426,6 @@ void TestProperty() { sp.V11++; ++sp.V11; } + +//expected-warning@+1 {{C++ operator 'and' (aka '&&') used as a macro name}} +#define and foo diff --git a/clang/test/Preprocessor/cxx_oper_keyword_ms_compat.cpp b/clang/test/Preprocessor/cxx_oper_keyword_ms_compat.cpp index dcf6908c329e..8e1351e34728 100644 --- a/clang/test/Preprocessor/cxx_oper_keyword_ms_compat.cpp +++ b/clang/test/Preprocessor/cxx_oper_keyword_ms_compat.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 %s -E -fms-compatibility +// RUN: %clang_cc1 %s -E -verify -fms-extensions +// expected-no-diagnostics bool f() { // Check that operators still work before redefining them.