zero9178 created this revision.
zero9178 added reviewers: rnk, thakis, hans, mstorsjo.
Herald added a subscriber: dang.
zero9178 requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This patch adds the command line options /permissive and /permissive- to 
clang-cl. These flags are used in MSVC to enable various /Zc language 
conformance options at once. In particular, /permissive is used to enable the 
various non standard behaviour of MSVC, while /permissive- is the opposite.

When either of two command lines are specified they are simply expanded to the 
various underlying /Zc options. In particular when /permissive is passed it 
currently expands to:

- /Zc:twoPhase- (disable two phase lookup)
- -fno-operator-names (disable C++ operator keywords)

/permissive- expands to the opposites of these flags + /Zc:strictStrings 
(/Zc:strictStrings- does not currently exist). In the future, if any more MSVC 
workarounds are ever added they can easily be added to the expansion. One is 
also able to override settings done by permissive. Specifying /permissive- 
/Zc:twoPhase- will apply the settings from permissive minus, but disables two 
phase lookup.

Motivation for this patch was mainly parity with MSVC as well as compatibility 
with Windows SDK headers. The /permissive page from MSVC documents various 
workarounds that have to be done for the Windows SDK headers [1], when MSVC is 
used with /permissive-. In these, Microsoft often recommends simply compiling 
with /permissive for the specified source files. Since some of these also apply 
to clang-cl (which acts like /permissive- by default mostly), and some are 
currently implemented as "hacks" within clang that I'd like to remove, adding 
/permissive and /permissive- to be in full parity with MSVC and Microsofts 
documentation made sense to me.

[1] 
https://docs.microsoft.com/en-us/cpp/build/reference/permissive-standards-conformance?view=msvc-160#windows-header-issues

Depends on https://reviews.llvm.org/D103749 for the -foperator-names CLI option


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D103773

Files:
  clang/include/clang/Driver/Options.td
  clang/lib/Driver/ToolChains/MSVC.cpp
  clang/test/Driver/cl-permissive.c


Index: clang/test/Driver/cl-permissive.c
===================================================================
--- /dev/null
+++ clang/test/Driver/cl-permissive.c
@@ -0,0 +1,17 @@
+// Note: %s must be preceded by --, otherwise it may be interpreted as a
+// command-line option, e.g. on Mac where %s is commonly under /Users.
+
+// RUN: %clang_cl /permissive -### -- %s 2>&1 | FileCheck 
-check-prefix=PERMISSIVE %s
+// PERMISSIVE: "-fno-operator-names"
+// PERMISSIVE: "-fdelayed-template-parsing"
+// RUN: %clang_cl /permissive- -### -- %s 2>&1 | FileCheck 
-check-prefix=PERMISSIVE-MINUS %s
+// PERMISSIVE-MINUS-NOT: "-fno-operator-names"
+// PERMISSIVE-MINUS-NOT: "-fdelayed-template-parsing"
+
+// The switches set by permissive may then still be manually enabled or 
disabled
+// RUN: %clang_cl /permissive /Zc:twoPhase -### -- %s 2>&1 | FileCheck 
-check-prefix=PERMISSIVE-OVERWRITE %s
+// PERMISSIVE-OVERWRITE: "-fno-operator-names"
+// PERMISSIVE-OVERWRITE-NOT: "-fdelayed-template-parsing"
+// RUN: %clang_cl /permissive- /Zc:twoPhase- -### -- %s 2>&1 | FileCheck 
-check-prefix=PERMISSIVE-MINUS-OVERWRITE %s
+// PERMISSIVE-MINUS-OVERWRITE-NOT: "-fno-operator-names"
+// PERMISSIVE-MINUS-OVERWRITE: "-fdelayed-template-parsing"
Index: clang/lib/Driver/ToolChains/MSVC.cpp
===================================================================
--- clang/lib/Driver/ToolChains/MSVC.cpp
+++ clang/lib/Driver/ToolChains/MSVC.cpp
@@ -1489,6 +1489,20 @@
   DAL.AddJoinedArg(A, Opts.getOption(options::OPT_D), NewVal);
 }
 
+static void TranslatePermissive(Arg *A, llvm::opt::DerivedArgList &DAL,
+                                const OptTable &Opts) {
+  DAL.AddFlagArg(A, Opts.getOption(options::OPT__SLASH_Zc_twoPhase_));
+  DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_operator_names));
+  // There is currently no /Zc:strictStrings- in clang-cl
+}
+
+static void TranslatePermissiveMinus(Arg *A, llvm::opt::DerivedArgList &DAL,
+                                     const OptTable &Opts) {
+  DAL.AddFlagArg(A, Opts.getOption(options::OPT__SLASH_Zc_twoPhase));
+  DAL.AddFlagArg(A, Opts.getOption(options::OPT_foperator_names));
+  DAL.AddFlagArg(A, Opts.getOption(options::OPT__SLASH_Zc_strictStrings));
+}
+
 llvm::opt::DerivedArgList *
 MSVCToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
                              StringRef BoundArch,
@@ -1531,6 +1545,12 @@
     } else if (A->getOption().matches(options::OPT_D)) {
       // Translate -Dfoo#bar into -Dfoo=bar.
       TranslateDArg(A, *DAL, Opts);
+    } else if (A->getOption().matches(options::OPT__SLASH_permissive)) {
+      // Expand /permissive
+      TranslatePermissive(A, *DAL, Opts);
+    } else if (A->getOption().matches(options::OPT__SLASH_permissive_)) {
+      // Expand /permissive-
+      TranslatePermissiveMinus(A, *DAL, Opts);
     } else if (OFK != Action::OFK_HIP) {
       // HIP Toolchain translates input args by itself.
       DAL->append(A);
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -6094,6 +6094,10 @@
   HelpText<"Deprecated (set output file name); use /Fe or /Fe">,
   MetaVarName<"<file or dir/>">;
 def _SLASH_P : CLFlag<"P">, HelpText<"Preprocess to file">;
+def _SLASH_permissive : CLFlag<"permissive">,
+  HelpText<"Enable some non conforming code to compile">;
+def _SLASH_permissive_ : CLFlag<"permissive-">,
+  HelpText<"Disable non conforming code from compiling (default)">;
 def _SLASH_Tc : CLCompileJoinedOrSeparate<"Tc">,
   HelpText<"Treat <file> as C source file">, MetaVarName<"<file>">;
 def _SLASH_TC : CLCompileFlag<"TC">, HelpText<"Treat all source files as C">;
@@ -6175,7 +6179,6 @@
 def _SLASH_JMC : CLIgnoredFlag<"JMC">;
 def _SLASH_kernel_ : CLIgnoredFlag<"kernel-">;
 def _SLASH_nologo : CLIgnoredFlag<"nologo">;
-def _SLASH_permissive_ : CLIgnoredFlag<"permissive-">;
 def _SLASH_RTC : CLIgnoredJoined<"RTC">;
 def _SLASH_sdl : CLIgnoredFlag<"sdl">;
 def _SLASH_sdl_ : CLIgnoredFlag<"sdl-">;


Index: clang/test/Driver/cl-permissive.c
===================================================================
--- /dev/null
+++ clang/test/Driver/cl-permissive.c
@@ -0,0 +1,17 @@
+// Note: %s must be preceded by --, otherwise it may be interpreted as a
+// command-line option, e.g. on Mac where %s is commonly under /Users.
+
+// RUN: %clang_cl /permissive -### -- %s 2>&1 | FileCheck -check-prefix=PERMISSIVE %s
+// PERMISSIVE: "-fno-operator-names"
+// PERMISSIVE: "-fdelayed-template-parsing"
+// RUN: %clang_cl /permissive- -### -- %s 2>&1 | FileCheck -check-prefix=PERMISSIVE-MINUS %s
+// PERMISSIVE-MINUS-NOT: "-fno-operator-names"
+// PERMISSIVE-MINUS-NOT: "-fdelayed-template-parsing"
+
+// The switches set by permissive may then still be manually enabled or disabled
+// RUN: %clang_cl /permissive /Zc:twoPhase -### -- %s 2>&1 | FileCheck -check-prefix=PERMISSIVE-OVERWRITE %s
+// PERMISSIVE-OVERWRITE: "-fno-operator-names"
+// PERMISSIVE-OVERWRITE-NOT: "-fdelayed-template-parsing"
+// RUN: %clang_cl /permissive- /Zc:twoPhase- -### -- %s 2>&1 | FileCheck -check-prefix=PERMISSIVE-MINUS-OVERWRITE %s
+// PERMISSIVE-MINUS-OVERWRITE-NOT: "-fno-operator-names"
+// PERMISSIVE-MINUS-OVERWRITE: "-fdelayed-template-parsing"
Index: clang/lib/Driver/ToolChains/MSVC.cpp
===================================================================
--- clang/lib/Driver/ToolChains/MSVC.cpp
+++ clang/lib/Driver/ToolChains/MSVC.cpp
@@ -1489,6 +1489,20 @@
   DAL.AddJoinedArg(A, Opts.getOption(options::OPT_D), NewVal);
 }
 
+static void TranslatePermissive(Arg *A, llvm::opt::DerivedArgList &DAL,
+                                const OptTable &Opts) {
+  DAL.AddFlagArg(A, Opts.getOption(options::OPT__SLASH_Zc_twoPhase_));
+  DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_operator_names));
+  // There is currently no /Zc:strictStrings- in clang-cl
+}
+
+static void TranslatePermissiveMinus(Arg *A, llvm::opt::DerivedArgList &DAL,
+                                     const OptTable &Opts) {
+  DAL.AddFlagArg(A, Opts.getOption(options::OPT__SLASH_Zc_twoPhase));
+  DAL.AddFlagArg(A, Opts.getOption(options::OPT_foperator_names));
+  DAL.AddFlagArg(A, Opts.getOption(options::OPT__SLASH_Zc_strictStrings));
+}
+
 llvm::opt::DerivedArgList *
 MSVCToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
                              StringRef BoundArch,
@@ -1531,6 +1545,12 @@
     } else if (A->getOption().matches(options::OPT_D)) {
       // Translate -Dfoo#bar into -Dfoo=bar.
       TranslateDArg(A, *DAL, Opts);
+    } else if (A->getOption().matches(options::OPT__SLASH_permissive)) {
+      // Expand /permissive
+      TranslatePermissive(A, *DAL, Opts);
+    } else if (A->getOption().matches(options::OPT__SLASH_permissive_)) {
+      // Expand /permissive-
+      TranslatePermissiveMinus(A, *DAL, Opts);
     } else if (OFK != Action::OFK_HIP) {
       // HIP Toolchain translates input args by itself.
       DAL->append(A);
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -6094,6 +6094,10 @@
   HelpText<"Deprecated (set output file name); use /Fe or /Fe">,
   MetaVarName<"<file or dir/>">;
 def _SLASH_P : CLFlag<"P">, HelpText<"Preprocess to file">;
+def _SLASH_permissive : CLFlag<"permissive">,
+  HelpText<"Enable some non conforming code to compile">;
+def _SLASH_permissive_ : CLFlag<"permissive-">,
+  HelpText<"Disable non conforming code from compiling (default)">;
 def _SLASH_Tc : CLCompileJoinedOrSeparate<"Tc">,
   HelpText<"Treat <file> as C source file">, MetaVarName<"<file>">;
 def _SLASH_TC : CLCompileFlag<"TC">, HelpText<"Treat all source files as C">;
@@ -6175,7 +6179,6 @@
 def _SLASH_JMC : CLIgnoredFlag<"JMC">;
 def _SLASH_kernel_ : CLIgnoredFlag<"kernel-">;
 def _SLASH_nologo : CLIgnoredFlag<"nologo">;
-def _SLASH_permissive_ : CLIgnoredFlag<"permissive-">;
 def _SLASH_RTC : CLIgnoredJoined<"RTC">;
 def _SLASH_sdl : CLIgnoredFlag<"sdl">;
 def _SLASH_sdl_ : CLIgnoredFlag<"sdl-">;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to