For Microsoft compatibility, set fno_operator_names
authorErich Keane <erich.keane@intel.com>
Wed, 24 May 2017 19:31:19 +0000 (19:31 +0000)
committerErich Keane <erich.keane@intel.com>
Wed, 24 May 2017 19:31:19 +0000 (19:31 +0000)
There's a Microsoft header in the Windows SDK which won't
compile with clang because it uses an operator name (and)
as a field name. This patch allows that file to compile by
setting the option which disables operator names.
The header which doesn't compile <Query.h> C:/Program Files (x86)/
Windows Kits/10/include/10.0.14393.0/um\Query.h:259:40:
error: expected member name or ';' after declaration specifiers

  /* [case()] */ NODERESTRICTION or;
                   ~~~~~~~~~~~~~~~ ^

                   1 error generated.

Contributed for Melanie Blower

Differential Revision:https://reviews.llvm.org/D33505

llvm-svn: 303798

clang/lib/Frontend/CompilerInvocation.cpp
clang/test/Parser/MicrosoftExtensions.cpp
clang/test/Preprocessor/cxx_oper_keyword.cpp

index 859e8ba..0716879 100644 (file)
@@ -1882,7 +1882,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
   Opts.GNUKeywords = Args.hasFlag(OPT_fgnu_keywords, OPT_fno_gnu_keywords,
                                   Opts.GNUKeywords);
 
-  if (Args.hasArg(OPT_fno_operator_names))
+  if (Args.hasArg(OPT_fno_operator_names) || Args.hasArg(OPT_fms_compatibility))
     Opts.CXXOperatorNames = 0;
 
   if (Args.hasArg(OPT_fcuda_is_device))
index 74f4bb3..aabf3bf 100644 (file)
@@ -261,9 +261,8 @@ int __identifier(else} = __identifier(for); // expected-error {{missing ')' afte
 #define identifier_weird(x) __identifier(x
 int k = identifier_weird(if)); // expected-error {{use of undeclared identifier 'if'}}
 
-// This is a bit weird, but the alternative tokens aren't keywords, and this
-// behavior matches MSVC. FIXME: Consider supporting this anyway.
-extern int __identifier(and) r; // expected-error {{cannot convert '&&' token to an identifier}}
+// 'and' is not an operator name with Microsoft compatibility.
+extern int __identifier(and) r; // expected-error {{expected ';' after top level declarator}}
 
 void f() {
   __identifier(() // expected-error {{cannot convert '(' token to an identifier}}
@@ -355,7 +354,6 @@ void TestProperty() {
   ++sp.V11;
 }
 
-//expected-warning@+1 {{C++ operator 'and' (aka '&&') used as a macro name}}
 #define and foo
 
 struct __declspec(uuid("00000000-0000-0000-C000-000000000046")) __declspec(novtable) IUnknown {};
index 89a094d..dce0fa0 100644 (file)
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 %s -E -verify -DOPERATOR_NAMES
 // RUN: %clang_cc1 %s -E -verify -fno-operator-names
+// RUN: %clang_cc1 %s    -verify -DTESTWIN -fms-compatibility
 
 #ifndef OPERATOR_NAMES
 //expected-error@+3 {{token is not a valid binary operator in a preprocessor subexpression}}
 #ifdef and
 #warning and is defined
 #endif
+
+#ifdef TESTWIN
+// For cl compatibility, fno-operator-names is enabled by default.
+int and;
+int bitand;
+int bitor;
+int compl;
+int not;
+int or;
+int xor;
+#endif