[PATCH] D53457: clang-cl: Add "/clang:" pass-through arg support.

2019-07-03 Thread Nico Weber via Phabricator via cfe-commits
thakis added a comment.
Herald added a project: clang.

I noticed that this causes memory errors in certain situations. 
https://bugs.llvm.org/show_bug.cgi?id=42501 has details. Can you take a look?


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53457/new/

https://reviews.llvm.org/D53457



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53457: clang-cl: Add "/clang:" pass-through arg support.

2018-11-08 Thread Hans Wennborg via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC346393: clang-cl: Add /clang: pass-through arg 
support. (authored by hans, committed by ).

Repository:
  rC Clang

https://reviews.llvm.org/D53457

Files:
  docs/UsersManual.rst
  include/clang/Driver/CLCompatOptions.td
  include/clang/Driver/Driver.h
  lib/Driver/Driver.cpp
  test/Driver/cl-options.c

Index: include/clang/Driver/CLCompatOptions.td
===
--- include/clang/Driver/CLCompatOptions.td
+++ include/clang/Driver/CLCompatOptions.td
@@ -321,6 +321,8 @@
 def _SLASH_volatile_ms  : Option<["/", "-"], "volatile:ms", KIND_FLAG>,
   Group<_SLASH_volatile_Group>, Flags<[CLOption, DriverOption]>,
   HelpText<"Volatile loads and stores have acquire and release semantics">;
+def _SLASH_clang : CLJoined<"clang:">,
+  HelpText<"Pass  to the clang driver">, MetaVarName<"">;
 def _SLASH_Zl : CLFlag<"Zl">,
   HelpText<"Don't mention any default libraries in the object file">;
 
Index: include/clang/Driver/Driver.h
===
--- include/clang/Driver/Driver.h
+++ include/clang/Driver/Driver.h
@@ -362,6 +362,7 @@
   /// ParseArgStrings - Parse the given list of strings into an
   /// ArgList.
   llvm::opt::InputArgList ParseArgStrings(ArrayRef Args,
+  bool IsClCompatMode,
   bool );
 
   /// BuildInputs - Construct the list of inputs and their types from
@@ -552,7 +553,7 @@
 
   /// Get bitmasks for which option flags to include and exclude based on
   /// the driver mode.
-  std::pair getIncludeExcludeOptionFlagMasks() const;
+  std::pair getIncludeExcludeOptionFlagMasks(bool IsClCompatMode) const;
 
   /// Helper used in BuildJobsForAction.  Doesn't use the cache when building
   /// jobs specifically for the given action, but will use the cache when
Index: test/Driver/cl-options.c
===
--- test/Driver/cl-options.c
+++ test/Driver/cl-options.c
@@ -619,5 +619,19 @@
 // RUN: --version \
 // RUN: -Werror /Zs -- %s 2>&1
 
+// Accept clang options under the /clang: flag.
+// The first test case ensures that the SLP vectorizer is on by default and that
+// it's being turned off by the /clang:-fno-slp-vectorize flag.
+
+// RUN: %clang_cl -O2 -### -- %s 2>&1 | FileCheck -check-prefix=NOCLANG %s
+// NOCLANG: "--dependent-lib=libcmt"
+// NOCLANG-SAME: "-vectorize-slp"
+// NOCLANG-NOT: "--dependent-lib=msvcrt"
+
+// RUN: %clang_cl -O2 -MD /clang:-fno-slp-vectorize /clang:-MD /clang:-MF /clang:my_dependency_file.dep -### -- %s 2>&1 | FileCheck -check-prefix=CLANG %s
+// CLANG: "--dependent-lib=msvcrt"
+// CLANG-SAME: "-dependency-file" "my_dependency_file.dep"
+// CLANG-NOT: "--dependent-lib=libcmt"
+// CLANG-NOT: "-vectorize-slp"
 
 void f() { }
Index: lib/Driver/Driver.cpp
===
--- lib/Driver/Driver.cpp
+++ lib/Driver/Driver.cpp
@@ -166,14 +166,15 @@
 }
 
 InputArgList Driver::ParseArgStrings(ArrayRef ArgStrings,
+ bool IsClCompatMode,
  bool ) {
   llvm::PrettyStackTraceString CrashInfo("Command line argument parsing");
   ContainsError = false;
 
   unsigned IncludedFlagsBitmask;
   unsigned ExcludedFlagsBitmask;
   std::tie(IncludedFlagsBitmask, ExcludedFlagsBitmask) =
-  getIncludeExcludeOptionFlagMasks();
+  getIncludeExcludeOptionFlagMasks(IsClCompatMode);
 
   unsigned MissingArgIndex, MissingArgCount;
   InputArgList Args =
@@ -730,7 +731,7 @@
   ConfigFile = CfgFileName.str();
   bool ContainErrors;
   CfgOptions = llvm::make_unique(
-  ParseArgStrings(NewCfgArgs, ContainErrors));
+  ParseArgStrings(NewCfgArgs, IsCLMode(), ContainErrors));
   if (ContainErrors) {
 CfgOptions.reset();
 return true;
@@ -924,7 +925,7 @@
   // Arguments specified in command line.
   bool ContainsError;
   CLOptions = llvm::make_unique(
-  ParseArgStrings(ArgList.slice(1), ContainsError));
+  ParseArgStrings(ArgList.slice(1), IsCLMode(), ContainsError));
 
   // Try parsing configuration file.
   if (!ContainsError)
@@ -934,21 +935,47 @@
   // All arguments, from both config file and command line.
   InputArgList Args = std::move(HasConfigFile ? std::move(*CfgOptions)
   : std::move(*CLOptions));
-  if (HasConfigFile)
-for (auto *Opt : *CLOptions) {
-  if (Opt->getOption().matches(options::OPT_config))
-continue;
+
+  auto appendOneArg = [](const Arg *Opt, const Arg *BaseArg) {
   unsigned Index = Args.MakeIndex(Opt->getSpelling());
-  const Arg *BaseArg = >getBaseArg();
-  if (BaseArg == Opt)
-BaseArg = nullptr;
   Arg *Copy = new llvm::opt::Arg(Opt->getOption(), Opt->getSpelling(),
  Index, 

[PATCH] D53457: clang-cl: Add "/clang:" pass-through arg support.

2018-11-08 Thread Hans Wennborg via Phabricator via cfe-commits
hans added a comment.

In https://reviews.llvm.org/D53457#1291020, @neerajksingh wrote:

> Reid, Hans, or someone else with commit access. If the revision looks good, 
> could you please submit to SVN?
>
> Any particular testing I should run beforehand? I ran the clang tests locally 
> on Windows.


I'll run the tests on Linux and commit.


https://reviews.llvm.org/D53457



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53457: clang-cl: Add "/clang:" pass-through arg support.

2018-11-07 Thread Neeraj K. Singh via Phabricator via cfe-commits
neerajksingh added a comment.

Reid, Hans, or someone else with commit access. If the revision looks good, 
could you please submit to SVN?

Any particular testing I should run beforehand? I ran the clang tests locally 
on Windows.


https://reviews.llvm.org/D53457



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53457: clang-cl: Add "/clang:" pass-through arg support.

2018-11-07 Thread Neeraj K. Singh via Phabricator via cfe-commits
neerajksingh updated this revision to Diff 173072.
neerajksingh marked an inline comment as done.

https://reviews.llvm.org/D53457

Files:
  docs/UsersManual.rst
  include/clang/Driver/CLCompatOptions.td
  include/clang/Driver/Driver.h
  lib/Driver/Driver.cpp
  test/Driver/cl-options.c

Index: test/Driver/cl-options.c
===
--- test/Driver/cl-options.c
+++ test/Driver/cl-options.c
@@ -614,5 +614,19 @@
 // RUN: --version \
 // RUN: -Werror /Zs -- %s 2>&1
 
+// Accept clang options under the /clang: flag.
+// The first test case ensures that the SLP vectorizer is on by default and that
+// it's being turned off by the /clang:-fno-slp-vectorize flag.
+
+// RUN: %clang_cl -O2 -### -- %s 2>&1 | FileCheck -check-prefix=NOCLANG %s
+// NOCLANG: "--dependent-lib=libcmt"
+// NOCLANG-SAME: "-vectorize-slp"
+// NOCLANG-NOT: "--dependent-lib=msvcrt"
+
+// RUN: %clang_cl -O2 -MD /clang:-fno-slp-vectorize /clang:-MD /clang:-MF /clang:my_dependency_file.dep -### -- %s 2>&1 | FileCheck -check-prefix=CLANG %s
+// CLANG: "--dependent-lib=msvcrt"
+// CLANG-SAME: "-dependency-file" "my_dependency_file.dep"
+// CLANG-NOT: "--dependent-lib=libcmt"
+// CLANG-NOT: "-vectorize-slp"
 
 void f() { }
Index: lib/Driver/Driver.cpp
===
--- lib/Driver/Driver.cpp
+++ lib/Driver/Driver.cpp
@@ -166,14 +166,15 @@
 }
 
 InputArgList Driver::ParseArgStrings(ArrayRef ArgStrings,
+ bool IsClCompatMode,
  bool ) {
   llvm::PrettyStackTraceString CrashInfo("Command line argument parsing");
   ContainsError = false;
 
   unsigned IncludedFlagsBitmask;
   unsigned ExcludedFlagsBitmask;
   std::tie(IncludedFlagsBitmask, ExcludedFlagsBitmask) =
-  getIncludeExcludeOptionFlagMasks();
+  getIncludeExcludeOptionFlagMasks(IsClCompatMode);
 
   unsigned MissingArgIndex, MissingArgCount;
   InputArgList Args =
@@ -730,7 +731,7 @@
   ConfigFile = CfgFileName.str();
   bool ContainErrors;
   CfgOptions = llvm::make_unique(
-  ParseArgStrings(NewCfgArgs, ContainErrors));
+  ParseArgStrings(NewCfgArgs, IsCLMode(), ContainErrors));
   if (ContainErrors) {
 CfgOptions.reset();
 return true;
@@ -924,7 +925,7 @@
   // Arguments specified in command line.
   bool ContainsError;
   CLOptions = llvm::make_unique(
-  ParseArgStrings(ArgList.slice(1), ContainsError));
+  ParseArgStrings(ArgList.slice(1), IsCLMode(), ContainsError));
 
   // Try parsing configuration file.
   if (!ContainsError)
@@ -934,21 +935,47 @@
   // All arguments, from both config file and command line.
   InputArgList Args = std::move(HasConfigFile ? std::move(*CfgOptions)
   : std::move(*CLOptions));
-  if (HasConfigFile)
-for (auto *Opt : *CLOptions) {
-  if (Opt->getOption().matches(options::OPT_config))
-continue;
+
+  auto appendOneArg = [](const Arg *Opt, const Arg *BaseArg) {
   unsigned Index = Args.MakeIndex(Opt->getSpelling());
-  const Arg *BaseArg = >getBaseArg();
-  if (BaseArg == Opt)
-BaseArg = nullptr;
   Arg *Copy = new llvm::opt::Arg(Opt->getOption(), Opt->getSpelling(),
  Index, BaseArg);
   Copy->getValues() = Opt->getValues();
   if (Opt->isClaimed())
 Copy->claim();
   Args.append(Copy);
+  };
+
+  if (HasConfigFile)
+for (auto *Opt : *CLOptions) {
+  if (Opt->getOption().matches(options::OPT_config))
+continue;
+  const Arg *BaseArg = >getBaseArg();
+  if (BaseArg == Opt)
+BaseArg = nullptr;
+  appendOneArg(Opt, BaseArg);
+}
+
+  // In CL mode, look for any pass-through arguments
+  if (IsCLMode() && !ContainsError) {
+SmallVector CLModePassThroughArgList;
+for (const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
+  A->claim();
+  CLModePassThroughArgList.push_back(A->getValue());
+}
+
+if (!CLModePassThroughArgList.empty()) {
+  // Parse any pass through args using default clang processing rather
+  // than clang-cl processing.
+  auto CLModePassThroughOptions = llvm::make_unique(
+  ParseArgStrings(CLModePassThroughArgList, false, ContainsError));
+
+  if (!ContainsError)
+for (auto *Opt : *CLModePassThroughOptions) {
+  appendOneArg(Opt, nullptr);
+}
 }
+  }
 
   // FIXME: This stuff needs to go into the Compilation, not the driver.
   bool CCCPrintPhases;
@@ -1452,7 +1479,7 @@
   unsigned IncludedFlagsBitmask;
   unsigned ExcludedFlagsBitmask;
   std::tie(IncludedFlagsBitmask, ExcludedFlagsBitmask) =
-  getIncludeExcludeOptionFlagMasks();
+  getIncludeExcludeOptionFlagMasks(IsCLMode());
 
   ExcludedFlagsBitmask |= options::NoDriverOption;
   if (!ShowHidden)
@@ -4661,11 +4688,11 @@
   return false;
 }
 
-std::pair Driver::getIncludeExcludeOptionFlagMasks() const {

[PATCH] D53457: clang-cl: Add "/clang:" pass-through arg support.

2018-11-07 Thread Neeraj K. Singh via Phabricator via cfe-commits
neerajksingh marked 2 inline comments as done.
neerajksingh added a comment.

Will update revision...




Comment at: test/Driver/cl-options.c:619
+
+// RUN: %clang_cl -O2 -### -- %s 2>&1 | FileCheck -check-prefix=NOCLANG %s
+// NOCLANG: "--dependent-lib=libcmt"

hans wrote:
> I'm not sure this test adds much value..
This test ensures that the next test is actually testing something (i.e. that 
the settings change between the two runs).


https://reviews.llvm.org/D53457



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53457: clang-cl: Add "/clang:" pass-through arg support.

2018-11-06 Thread Hans Wennborg via Phabricator via cfe-commits
hans accepted this revision.
hans added a comment.
This revision is now accepted and ready to land.

Okay, looks good to me (with a small nit).




Comment at: docs/UsersManual.rst:2852
   /Brepro Emit an object file which can be reproduced over 
time
+  /clang:Pass  to the clang driver
   /C  Don't discard comments when preprocessing

ultra nit: no space between the colon and 



Comment at: test/Driver/cl-options.c:619
+
+// RUN: %clang_cl -O2 -### -- %s 2>&1 | FileCheck -check-prefix=NOCLANG %s
+// NOCLANG: "--dependent-lib=libcmt"

I'm not sure this test adds much value..


https://reviews.llvm.org/D53457



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53457: clang-cl: Add "/clang:" pass-through arg support.

2018-11-05 Thread Neeraj K. Singh via Phabricator via cfe-commits
neerajksingh updated this revision to Diff 172615.
neerajksingh added a comment.

Make it clear in the documentation that the /clang flags are added to the end.


https://reviews.llvm.org/D53457

Files:
  docs/UsersManual.rst
  include/clang/Driver/CLCompatOptions.td
  include/clang/Driver/Driver.h
  lib/Driver/Driver.cpp
  test/Driver/cl-options.c

Index: test/Driver/cl-options.c
===
--- test/Driver/cl-options.c
+++ test/Driver/cl-options.c
@@ -614,5 +614,17 @@
 // RUN: --version \
 // RUN: -Werror /Zs -- %s 2>&1
 
+// Accept clang options under the /clang: flag.
+
+// RUN: %clang_cl -O2 -### -- %s 2>&1 | FileCheck -check-prefix=NOCLANG %s
+// NOCLANG: "--dependent-lib=libcmt"
+// NOCLANG-SAME: "-vectorize-slp"
+// NOCLANG-NOT: "--dependent-lib=msvcrt"
+
+// RUN: %clang_cl -O2 -MD /clang:-fno-slp-vectorize /clang:-MD /clang:-MF /clang:my_dependency_file.dep -### -- %s 2>&1 | FileCheck -check-prefix=CLANG %s
+// CLANG: "--dependent-lib=msvcrt"
+// CLANG-SAME: "-dependency-file" "my_dependency_file.dep"
+// CLANG-NOT: "--dependent-lib=libcmt"
+// CLANG-NOT: "-vectorize-slp"
 
 void f() { }
Index: lib/Driver/Driver.cpp
===
--- lib/Driver/Driver.cpp
+++ lib/Driver/Driver.cpp
@@ -166,14 +166,15 @@
 }
 
 InputArgList Driver::ParseArgStrings(ArrayRef ArgStrings,
+ bool IsClCompatMode,
  bool ) {
   llvm::PrettyStackTraceString CrashInfo("Command line argument parsing");
   ContainsError = false;
 
   unsigned IncludedFlagsBitmask;
   unsigned ExcludedFlagsBitmask;
   std::tie(IncludedFlagsBitmask, ExcludedFlagsBitmask) =
-  getIncludeExcludeOptionFlagMasks();
+  getIncludeExcludeOptionFlagMasks(IsClCompatMode);
 
   unsigned MissingArgIndex, MissingArgCount;
   InputArgList Args =
@@ -730,7 +731,7 @@
   ConfigFile = CfgFileName.str();
   bool ContainErrors;
   CfgOptions = llvm::make_unique(
-  ParseArgStrings(NewCfgArgs, ContainErrors));
+  ParseArgStrings(NewCfgArgs, IsCLMode(), ContainErrors));
   if (ContainErrors) {
 CfgOptions.reset();
 return true;
@@ -924,7 +925,7 @@
   // Arguments specified in command line.
   bool ContainsError;
   CLOptions = llvm::make_unique(
-  ParseArgStrings(ArgList.slice(1), ContainsError));
+  ParseArgStrings(ArgList.slice(1), IsCLMode(), ContainsError));
 
   // Try parsing configuration file.
   if (!ContainsError)
@@ -934,21 +935,47 @@
   // All arguments, from both config file and command line.
   InputArgList Args = std::move(HasConfigFile ? std::move(*CfgOptions)
   : std::move(*CLOptions));
-  if (HasConfigFile)
-for (auto *Opt : *CLOptions) {
-  if (Opt->getOption().matches(options::OPT_config))
-continue;
+
+  auto appendOneArg = [](const Arg *Opt, const Arg *BaseArg) {
   unsigned Index = Args.MakeIndex(Opt->getSpelling());
-  const Arg *BaseArg = >getBaseArg();
-  if (BaseArg == Opt)
-BaseArg = nullptr;
   Arg *Copy = new llvm::opt::Arg(Opt->getOption(), Opt->getSpelling(),
  Index, BaseArg);
   Copy->getValues() = Opt->getValues();
   if (Opt->isClaimed())
 Copy->claim();
   Args.append(Copy);
+  };
+
+  if (HasConfigFile)
+for (auto *Opt : *CLOptions) {
+  if (Opt->getOption().matches(options::OPT_config))
+continue;
+  const Arg *BaseArg = >getBaseArg();
+  if (BaseArg == Opt)
+BaseArg = nullptr;
+  appendOneArg(Opt, BaseArg);
+}
+
+  // In CL mode, look for any pass-through arguments
+  if (IsCLMode() && !ContainsError) {
+SmallVector CLModePassThroughArgList;
+for (const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
+  A->claim();
+  CLModePassThroughArgList.push_back(A->getValue());
+}
+
+if (!CLModePassThroughArgList.empty()) {
+  // Parse any pass through args using default clang processing rather
+  // than clang-cl processing.
+  auto CLModePassThroughOptions = llvm::make_unique(
+  ParseArgStrings(CLModePassThroughArgList, false, ContainsError));
+
+  if (!ContainsError)
+for (auto *Opt : *CLModePassThroughOptions) {
+  appendOneArg(Opt, nullptr);
+}
 }
+  }
 
   // FIXME: This stuff needs to go into the Compilation, not the driver.
   bool CCCPrintPhases;
@@ -1452,7 +1479,7 @@
   unsigned IncludedFlagsBitmask;
   unsigned ExcludedFlagsBitmask;
   std::tie(IncludedFlagsBitmask, ExcludedFlagsBitmask) =
-  getIncludeExcludeOptionFlagMasks();
+  getIncludeExcludeOptionFlagMasks(IsCLMode());
 
   ExcludedFlagsBitmask |= options::NoDriverOption;
   if (!ShowHidden)
@@ -4661,11 +4688,11 @@
   return false;
 }
 
-std::pair Driver::getIncludeExcludeOptionFlagMasks() const {
+std::pair Driver::getIncludeExcludeOptionFlagMasks(bool IsClCompatMode) const {
   

[PATCH] D53457: clang-cl: Add "/clang:" pass-through arg support.

2018-10-31 Thread Hans Wennborg via Phabricator via cfe-commits
hans added a comment.

In https://reviews.llvm.org/D53457#1279191, @neerajksingh wrote:

> In https://reviews.llvm.org/D53457#1278579, @hans wrote:
>
> > The `-Xclang` option has the same issue, and I think `/clang:` should work 
> > similarly, i.e. `/clang:-MF /clang:`. It's not pretty, but at 
> > least it's consistent. Yes, that means processing consecutive `/Xclang:` 
> > options together, but hopefully that's doable.
>
>
> It looks like the handling for -Xclang is a lot simpler (in 
> `Clang::ConstructJob`).  There the Xclang options are all gathered and 
> forwarded at a particular spot in the command line for cc1.  They aren't 
> interleaved with other options, and it wouldn't really make sense to do so 
> anyway since it doesn't really look like cc1 arguments are constructed from 
> driver arguments in any particular order.
>
> The llvm/lib/Option/OptTable.cpp code is not really setup to easily 
> interleave arguments like would be required for your request.  Can you see a 
> way to accomplish what you want without a deep refactoring of 
> OptTable::ParseArgs and the InputArgList class?


Okay, if it's hard to do, I suppose collecting the /clang: options and 
processing them separately after the others is the second-best option. We'll 
need to make sure the behaviour is well-documented.


https://reviews.llvm.org/D53457



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53457: clang-cl: Add "/clang:" pass-through arg support.

2018-10-29 Thread Neeraj K. Singh via Phabricator via cfe-commits
neerajksingh added a comment.

In https://reviews.llvm.org/D53457#1278579, @hans wrote:

> The `-Xclang` option has the same issue, and I think `/clang:` should work 
> similarly, i.e. `/clang:-MF /clang:`. It's not pretty, but at least 
> it's consistent. Yes, that means processing consecutive `/Xclang:` options 
> together, but hopefully that's doable.


It looks like the handling for -Xclang is a lot simpler (in 
`Clang::ConstructJob`).  There the Xclang options are all gathered and 
forwarded at a particular spot in the command line for cc1.  They aren't 
interleaved with other options, and it wouldn't really make sense to do so 
anyway since it doesn't really look like cc1 arguments are constructed from 
driver arguments in any particular order.

The llvm/lib/Option/OptTable.cpp code is not really setup to easily interleave 
arguments like would be required for your request.  Can you see a way to 
accomplish what you want without a deep refactoring of OptTable::ParseArgs and 
the InputArgList class?


https://reviews.llvm.org/D53457



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53457: clang-cl: Add "/clang:" pass-through arg support.

2018-10-29 Thread Hans Wennborg via Phabricator via cfe-commits
hans added a comment.

In https://reviews.llvm.org/D53457#1277950, @neerajksingh wrote:

> In https://reviews.llvm.org/D53457#1277315, @hans wrote:
>
> >   One note about flag ordering: the /clang: flags are concatenated to the 
> > end of
> >   the argument list, so in cases where the last flag wins, the /clang: flags
> >   will be chosen regardless of their order relative to other flags on the 
> > driver
> >   command line.
> >
> >
> > This seems a little unfortunate. I wonder if it would be possible to not 
> > have this restriction, i.e. to process these in-line with the rest of the 
> > flags?
> >
> > One way to achieve this would be to change Driver::ParseArgStrings() to 
> > handle the "/clang:" arguments. After doing the regular option parsing, it 
> > would look for "/clang:" options and substitute them for the underlying 
> > option. This has the downside of adding some option-specific logic to 
> > ParseArgStrings, but on the other hand it's less intrusive than passing 
> > around the IsCLMode bool. Do you think something like this could work?
>
>
> One difficulty occurs with options that have separated values, like the 
> `/clang:-MF /clang:` case.  In this case, we need to take two 
> /clang: arguments and process them next to each other in order to form a 
> single coherent argument/value pair. Another option is to allow the user to 
> specify the option like `/clang:"-MF "` and then require that the 
> user specify any flags that need a value in a single /clang: argument.  This 
> would require some code to split the value string on spaces before passing it 
> on to clang argument parsing.
>
> Do you have any preference or better suggestion for the option-with-value 
> case?


The `-Xclang` option has the same issue, and I think `/clang:` should work 
similarly, i.e. `/clang:-MF /clang:`. It's not pretty, but at least 
it's consistent. Yes, that means processing consecutive `/Xclang:` options 
together, but hopefully that's doable.


https://reviews.llvm.org/D53457



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53457: clang-cl: Add "/clang:" pass-through arg support.

2018-10-26 Thread Neeraj K. Singh via Phabricator via cfe-commits
neerajksingh updated this revision to Diff 171382.
neerajksingh added a comment.

Fix hans' comments.


https://reviews.llvm.org/D53457

Files:
  docs/UsersManual.rst
  include/clang/Driver/CLCompatOptions.td
  include/clang/Driver/Driver.h
  lib/Driver/Driver.cpp
  test/Driver/cl-options.c

Index: test/Driver/cl-options.c
===
--- test/Driver/cl-options.c
+++ test/Driver/cl-options.c
@@ -614,5 +614,17 @@
 // RUN: --version \
 // RUN: -Werror /Zs -- %s 2>&1
 
+// Accept clang options under the /clang: flag.
+
+// RUN: %clang_cl -O2 -### -- %s 2>&1 | FileCheck -check-prefix=NOCLANG %s
+// NOCLANG: "--dependent-lib=libcmt"
+// NOCLANG-SAME: "-vectorize-slp"
+// NOCLANG-NOT: "--dependent-lib=msvcrt"
+
+// RUN: %clang_cl -O2 -MD /clang:-fno-slp-vectorize /clang:-MD /clang:-MF /clang:my_dependency_file.dep -### -- %s 2>&1 | FileCheck -check-prefix=CLANG %s
+// CLANG: "--dependent-lib=msvcrt"
+// CLANG-SAME: "-dependency-file" "my_dependency_file.dep"
+// CLANG-NOT: "--dependent-lib=libcmt"
+// CLANG-NOT: "-vectorize-slp"
 
 void f() { }
Index: lib/Driver/Driver.cpp
===
--- lib/Driver/Driver.cpp
+++ lib/Driver/Driver.cpp
@@ -166,14 +166,15 @@
 }
 
 InputArgList Driver::ParseArgStrings(ArrayRef ArgStrings,
+ bool IsClCompatMode,
  bool ) {
   llvm::PrettyStackTraceString CrashInfo("Command line argument parsing");
   ContainsError = false;
 
   unsigned IncludedFlagsBitmask;
   unsigned ExcludedFlagsBitmask;
   std::tie(IncludedFlagsBitmask, ExcludedFlagsBitmask) =
-  getIncludeExcludeOptionFlagMasks();
+  getIncludeExcludeOptionFlagMasks(IsClCompatMode);
 
   unsigned MissingArgIndex, MissingArgCount;
   InputArgList Args =
@@ -730,7 +731,7 @@
   ConfigFile = CfgFileName.str();
   bool ContainErrors;
   CfgOptions = llvm::make_unique(
-  ParseArgStrings(NewCfgArgs, ContainErrors));
+  ParseArgStrings(NewCfgArgs, IsCLMode(), ContainErrors));
   if (ContainErrors) {
 CfgOptions.reset();
 return true;
@@ -924,7 +925,7 @@
   // Arguments specified in command line.
   bool ContainsError;
   CLOptions = llvm::make_unique(
-  ParseArgStrings(ArgList.slice(1), ContainsError));
+  ParseArgStrings(ArgList.slice(1), IsCLMode(), ContainsError));
 
   // Try parsing configuration file.
   if (!ContainsError)
@@ -934,21 +935,47 @@
   // All arguments, from both config file and command line.
   InputArgList Args = std::move(HasConfigFile ? std::move(*CfgOptions)
   : std::move(*CLOptions));
-  if (HasConfigFile)
-for (auto *Opt : *CLOptions) {
-  if (Opt->getOption().matches(options::OPT_config))
-continue;
+
+  auto appendOneArg = [](const Arg *Opt, const Arg *BaseArg) {
   unsigned Index = Args.MakeIndex(Opt->getSpelling());
-  const Arg *BaseArg = >getBaseArg();
-  if (BaseArg == Opt)
-BaseArg = nullptr;
   Arg *Copy = new llvm::opt::Arg(Opt->getOption(), Opt->getSpelling(),
  Index, BaseArg);
   Copy->getValues() = Opt->getValues();
   if (Opt->isClaimed())
 Copy->claim();
   Args.append(Copy);
+  };
+
+  if (HasConfigFile)
+for (auto *Opt : *CLOptions) {
+  if (Opt->getOption().matches(options::OPT_config))
+continue;
+  const Arg *BaseArg = >getBaseArg();
+  if (BaseArg == Opt)
+BaseArg = nullptr;
+  appendOneArg(Opt, BaseArg);
+}
+
+  // In CL mode, look for any pass-through arguments
+  if (IsCLMode() && !ContainsError) {
+SmallVector CLModePassThroughArgList;
+for (const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
+  A->claim();
+  CLModePassThroughArgList.push_back(A->getValue());
+}
+
+if (!CLModePassThroughArgList.empty()) {
+  // Parse any pass through args using default clang processing rather
+  // than clang-cl processing.
+  auto CLModePassThroughOptions = llvm::make_unique(
+  ParseArgStrings(CLModePassThroughArgList, false, ContainsError));
+
+  if (!ContainsError)
+for (auto *Opt : *CLModePassThroughOptions) {
+  appendOneArg(Opt, nullptr);
+}
 }
+  }
 
   // FIXME: This stuff needs to go into the Compilation, not the driver.
   bool CCCPrintPhases;
@@ -1452,7 +1479,7 @@
   unsigned IncludedFlagsBitmask;
   unsigned ExcludedFlagsBitmask;
   std::tie(IncludedFlagsBitmask, ExcludedFlagsBitmask) =
-  getIncludeExcludeOptionFlagMasks();
+  getIncludeExcludeOptionFlagMasks(IsCLMode());
 
   ExcludedFlagsBitmask |= options::NoDriverOption;
   if (!ShowHidden)
@@ -4661,11 +4688,11 @@
   return false;
 }
 
-std::pair Driver::getIncludeExcludeOptionFlagMasks() const {
+std::pair Driver::getIncludeExcludeOptionFlagMasks(bool IsClCompatMode) const {
   unsigned IncludedFlagsBitmask = 0;
   unsigned 

[PATCH] D53457: clang-cl: Add "/clang:" pass-through arg support.

2018-10-26 Thread Neeraj K. Singh via Phabricator via cfe-commits
neerajksingh added a comment.

In https://reviews.llvm.org/D53457#1277315, @hans wrote:

>   One note about flag ordering: the /clang: flags are concatenated to the end 
> of
>   the argument list, so in cases where the last flag wins, the /clang: flags
>   will be chosen regardless of their order relative to other flags on the 
> driver
>   command line.
>
>
> This seems a little unfortunate. I wonder if it would be possible to not have 
> this restriction, i.e. to process these in-line with the rest of the flags?
>
> One way to achieve this would be to change Driver::ParseArgStrings() to 
> handle the "/clang:" arguments. After doing the regular option parsing, it 
> would look for "/clang:" options and substitute them for the underlying 
> option. This has the downside of adding some option-specific logic to 
> ParseArgStrings, but on the other hand it's less intrusive than passing 
> around the IsCLMode bool. Do you think something like this could work?


One difficulty occurs with options that have separated values, like the 
`/clang:-MF /clang:` case.  In this case, we need to take two /clang: 
arguments and process them next to each other in order to form a single 
coherent argument/value pair. Another option is to allow the user to specify 
the option like `/clang:"-MF "` and then require that the user 
specify any flags that need a value in a single /clang: argument.  This would 
require some code to split the value string on spaces before passing it on to 
clang argument parsing.

Do you have any preference or better suggestion for the option-with-value case?


https://reviews.llvm.org/D53457



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53457: clang-cl: Add "/clang:" pass-through arg support.

2018-10-26 Thread Hans Wennborg via Phabricator via cfe-commits
hans added a comment.

  One note about flag ordering: the /clang: flags are concatenated to the end of
  the argument list, so in cases where the last flag wins, the /clang: flags
  will be chosen regardless of their order relative to other flags on the driver
  command line.

This seems a little unfortunate. I wonder if it would be possible to not have 
this restriction, i.e. to process these in-line with the rest of the flags?

One way to achieve this would be to change Driver::ParseArgStrings() to handle 
the "/clang:" arguments. After doing the regular option parsing, it would look 
for "/clang:" options and substitute them for the underlying option. This has 
the downside of adding some option-specific logic to ParseArgStrings, but on 
the other hand it's less intrusive than passing around the IsCLMode bool. Do 
you think something like this could work?




Comment at: docs/UsersManual.rst:3100
+
+The /clang: Option
+

Thanks for thinking about the docs!

I think we should put this above the /fallback section, since this new flag is 
more important and /fallback shouldn't be used much these days.



Comment at: include/clang/Driver/CLCompatOptions.td:324
   HelpText<"Volatile loads and stores have acquire and release semantics">;
+def _SLASH_clang : CLJoinedOrSeparate<"clang:">,
+  HelpText<"Pass  to the clang driver">, MetaVarName<"">;

Do we really want the "OrSeparate" part of this? Is there any downside of 
limiting it to "/clang:-foo" rather than also allowing "/clang: -foo"?


https://reviews.llvm.org/D53457



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53457: clang-cl: Add "/clang:" pass-through arg support.

2018-10-25 Thread Neeraj K. Singh via Phabricator via cfe-commits
neerajksingh updated this revision to Diff 171233.

https://reviews.llvm.org/D53457

Files:
  docs/UsersManual.rst
  include/clang/Driver/CLCompatOptions.td
  include/clang/Driver/Driver.h
  lib/Driver/Driver.cpp
  test/Driver/cl-options.c

Index: test/Driver/cl-options.c
===
--- test/Driver/cl-options.c
+++ test/Driver/cl-options.c
@@ -614,5 +614,17 @@
 // RUN: --version \
 // RUN: -Werror /Zs -- %s 2>&1
 
+// Accept clang options under the /clang: flag.
+
+// RUN: %clang_cl -O2 -### -- %s 2>&1 | FileCheck -check-prefix=NOCLANG %s
+// NOCLANG: "--dependent-lib=libcmt"
+// NOCLANG-SAME: "-vectorize-slp"
+// NOCLANG-NOT: "--dependent-lib=msvcrt"
+
+// RUN: %clang_cl -O2 -MD /clang:-fno-slp-vectorize /clang:-MD /clang:-MF /clang:my_dependency_file.dep -### -- %s 2>&1 | FileCheck -check-prefix=CLANG %s
+// CLANG: "--dependent-lib=msvcrt"
+// CLANG-SAME: "-dependency-file" "my_dependency_file.dep"
+// CLANG-NOT: "--dependent-lib=libcmt"
+// CLANG-NOT: "-vectorize-slp"
 
 void f() { }
Index: lib/Driver/Driver.cpp
===
--- lib/Driver/Driver.cpp
+++ lib/Driver/Driver.cpp
@@ -166,14 +166,15 @@
 }
 
 InputArgList Driver::ParseArgStrings(ArrayRef ArgStrings,
+ bool IsClCompatMode,
  bool ) {
   llvm::PrettyStackTraceString CrashInfo("Command line argument parsing");
   ContainsError = false;
 
   unsigned IncludedFlagsBitmask;
   unsigned ExcludedFlagsBitmask;
   std::tie(IncludedFlagsBitmask, ExcludedFlagsBitmask) =
-  getIncludeExcludeOptionFlagMasks();
+  getIncludeExcludeOptionFlagMasks(IsClCompatMode);
 
   unsigned MissingArgIndex, MissingArgCount;
   InputArgList Args =
@@ -730,7 +731,7 @@
   ConfigFile = CfgFileName.str();
   bool ContainErrors;
   CfgOptions = llvm::make_unique(
-  ParseArgStrings(NewCfgArgs, ContainErrors));
+  ParseArgStrings(NewCfgArgs, IsCLMode(), ContainErrors));
   if (ContainErrors) {
 CfgOptions.reset();
 return true;
@@ -924,7 +925,7 @@
   // Arguments specified in command line.
   bool ContainsError;
   CLOptions = llvm::make_unique(
-  ParseArgStrings(ArgList.slice(1), ContainsError));
+  ParseArgStrings(ArgList.slice(1), IsCLMode(), ContainsError));
 
   // Try parsing configuration file.
   if (!ContainsError)
@@ -934,21 +935,47 @@
   // All arguments, from both config file and command line.
   InputArgList Args = std::move(HasConfigFile ? std::move(*CfgOptions)
   : std::move(*CLOptions));
-  if (HasConfigFile)
-for (auto *Opt : *CLOptions) {
-  if (Opt->getOption().matches(options::OPT_config))
-continue;
+
+  auto appendOneArg = [](const Arg *Opt, const Arg *BaseArg) {
   unsigned Index = Args.MakeIndex(Opt->getSpelling());
-  const Arg *BaseArg = >getBaseArg();
-  if (BaseArg == Opt)
-BaseArg = nullptr;
   Arg *Copy = new llvm::opt::Arg(Opt->getOption(), Opt->getSpelling(),
  Index, BaseArg);
   Copy->getValues() = Opt->getValues();
   if (Opt->isClaimed())
 Copy->claim();
   Args.append(Copy);
+  };
+
+  if (HasConfigFile)
+for (auto *Opt : *CLOptions) {
+  if (Opt->getOption().matches(options::OPT_config))
+continue;
+  const Arg *BaseArg = >getBaseArg();
+  if (BaseArg == Opt)
+BaseArg = nullptr;
+  appendOneArg(Opt, BaseArg);
+}
+
+  // In CL mode, look for any pass-through arguments
+  if (IsCLMode() && !ContainsError) {
+SmallVector CLModePassThroughArgList;
+for (const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
+  A->claim();
+  CLModePassThroughArgList.push_back(A->getValue());
+}
+
+if (!CLModePassThroughArgList.empty()) {
+  // Parse any pass through args using default clang processing rather
+  // than clang-cl processing.
+  auto CLModePassThroughOptions = llvm::make_unique(
+  ParseArgStrings(CLModePassThroughArgList, false, ContainsError));
+
+  if (!ContainsError)
+for (auto *Opt : *CLModePassThroughOptions) {
+  appendOneArg(Opt, nullptr);
+}
 }
+  }
 
   // FIXME: This stuff needs to go into the Compilation, not the driver.
   bool CCCPrintPhases;
@@ -1452,7 +1479,7 @@
   unsigned IncludedFlagsBitmask;
   unsigned ExcludedFlagsBitmask;
   std::tie(IncludedFlagsBitmask, ExcludedFlagsBitmask) =
-  getIncludeExcludeOptionFlagMasks();
+  getIncludeExcludeOptionFlagMasks(IsCLMode());
 
   ExcludedFlagsBitmask |= options::NoDriverOption;
   if (!ShowHidden)
@@ -4661,11 +4688,11 @@
   return false;
 }
 
-std::pair Driver::getIncludeExcludeOptionFlagMasks() const {
+std::pair Driver::getIncludeExcludeOptionFlagMasks(bool IsClCompatMode) const {
   unsigned IncludedFlagsBitmask = 0;
   unsigned ExcludedFlagsBitmask = options::NoDriverOption;
 
-  if (Mode == 

[PATCH] D53457: clang-cl: Add "/clang:" pass-through arg support.

2018-10-25 Thread Neeraj K. Singh via Phabricator via cfe-commits
neerajksingh updated this revision to Diff 171203.
neerajksingh retitled this revision from "clang-cl: Add "/Xdriver:" 
pass-through arg support." to "clang-cl: Add "/clang:" pass-through arg 
support.".
neerajksingh edited the summary of this revision.
neerajksingh added a comment.

Change the spelling of from "/Xdriver:" to "/clang:".

Refactor getIncludeExcludeOptionFlagMasks to take whether we're in CL mode as 
an argument, making the function pure.


https://reviews.llvm.org/D53457

Files:
  include/clang/Driver/CLCompatOptions.td
  include/clang/Driver/Driver.h
  lib/Driver/Driver.cpp
  test/Driver/cl-options.c

Index: test/Driver/cl-options.c
===
--- test/Driver/cl-options.c
+++ test/Driver/cl-options.c
@@ -614,5 +614,17 @@
 // RUN: --version \
 // RUN: -Werror /Zs -- %s 2>&1
 
+// Accept clang options under the /clang: flag.
+
+// RUN: %clang_cl -O2 -### -- %s 2>&1 | FileCheck -check-prefix=NOCLANG %s
+// NOCLANG: "--dependent-lib=libcmt"
+// NOCLANG-SAME: "-vectorize-slp"
+// NOCLANG-NOT: "--dependent-lib=msvcrt"
+
+// RUN: %clang_cl -O2 -MD /clang:-fno-slp-vectorize /clang:-MD /clang:-MF /clang:my_dependency_file.dep -### -- %s 2>&1 | FileCheck -check-prefix=CLANG %s
+// CLANG: "--dependent-lib=msvcrt"
+// CLANG-SAME: "-dependency-file" "my_dependency_file.dep"
+// CLANG-NOT: "--dependent-lib=libcmt"
+// CLANG-NOT: "-vectorize-slp"
 
 void f() { }
Index: lib/Driver/Driver.cpp
===
--- lib/Driver/Driver.cpp
+++ lib/Driver/Driver.cpp
@@ -166,14 +166,15 @@
 }
 
 InputArgList Driver::ParseArgStrings(ArrayRef ArgStrings,
+ bool IsClCompatMode,
  bool ) {
   llvm::PrettyStackTraceString CrashInfo("Command line argument parsing");
   ContainsError = false;
 
   unsigned IncludedFlagsBitmask;
   unsigned ExcludedFlagsBitmask;
   std::tie(IncludedFlagsBitmask, ExcludedFlagsBitmask) =
-  getIncludeExcludeOptionFlagMasks();
+  getIncludeExcludeOptionFlagMasks(IsClCompatMode);
 
   unsigned MissingArgIndex, MissingArgCount;
   InputArgList Args =
@@ -730,7 +731,7 @@
   ConfigFile = CfgFileName.str();
   bool ContainErrors;
   CfgOptions = llvm::make_unique(
-  ParseArgStrings(NewCfgArgs, ContainErrors));
+  ParseArgStrings(NewCfgArgs, IsCLMode(), ContainErrors));
   if (ContainErrors) {
 CfgOptions.reset();
 return true;
@@ -924,7 +925,7 @@
   // Arguments specified in command line.
   bool ContainsError;
   CLOptions = llvm::make_unique(
-  ParseArgStrings(ArgList.slice(1), ContainsError));
+  ParseArgStrings(ArgList.slice(1), IsCLMode(), ContainsError));
 
   // Try parsing configuration file.
   if (!ContainsError)
@@ -934,21 +935,47 @@
   // All arguments, from both config file and command line.
   InputArgList Args = std::move(HasConfigFile ? std::move(*CfgOptions)
   : std::move(*CLOptions));
-  if (HasConfigFile)
-for (auto *Opt : *CLOptions) {
-  if (Opt->getOption().matches(options::OPT_config))
-continue;
+
+  auto appendOneArg = [](const Arg *Opt, const Arg *BaseArg) {
   unsigned Index = Args.MakeIndex(Opt->getSpelling());
-  const Arg *BaseArg = >getBaseArg();
-  if (BaseArg == Opt)
-BaseArg = nullptr;
   Arg *Copy = new llvm::opt::Arg(Opt->getOption(), Opt->getSpelling(),
  Index, BaseArg);
   Copy->getValues() = Opt->getValues();
   if (Opt->isClaimed())
 Copy->claim();
   Args.append(Copy);
+  };
+
+  if (HasConfigFile)
+for (auto *Opt : *CLOptions) {
+  if (Opt->getOption().matches(options::OPT_config))
+continue;
+  const Arg *BaseArg = >getBaseArg();
+  if (BaseArg == Opt)
+BaseArg = nullptr;
+  appendOneArg(Opt, BaseArg);
+}
+
+  // In CL mode, look for any pass-through arguments
+  if (IsCLMode() && !ContainsError) {
+SmallVector CLModePassThroughArgList;
+for (const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
+  A->claim();
+  CLModePassThroughArgList.push_back(A->getValue());
+}
+
+if (!CLModePassThroughArgList.empty()) {
+  // Parse any pass through args using default clang processing rather
+  // than clang-cl processing.
+  auto CLModePassThroughOptions = llvm::make_unique(
+  ParseArgStrings(CLModePassThroughArgList, false, ContainsError));
+
+  if (!ContainsError)
+for (auto *Opt : *CLModePassThroughOptions) {
+  appendOneArg(Opt, nullptr);
+}
 }
+  }
 
   // FIXME: This stuff needs to go into the Compilation, not the driver.
   bool CCCPrintPhases;
@@ -1452,7 +1479,7 @@
   unsigned IncludedFlagsBitmask;
   unsigned ExcludedFlagsBitmask;
   std::tie(IncludedFlagsBitmask, ExcludedFlagsBitmask) =
-  getIncludeExcludeOptionFlagMasks();
+