mstorsjo created this revision.
mstorsjo added reviewers: rnk, smeenai, compnerd, phosek, rupprecht.

libtool inspects the output of `$CC -v` to detect what object files and 
libraries are linked in by default. When clang is built as a native windows 
executable, all paths are formatted with backslashes, and the backslashes cause 
each argument to be enclosed in quotes. The backslashes and quotes break 
further processing within libtool (which is implemented in shell script, 
running in e.g. msys) pretty badly.

Between unix style pathes (that only work in tools that are linked to the msys 
runtime, essentially the same as cygwin) and proper windows style paths (with 
backslashes, that don't work within shell scripts and msys environments), the 
best compromise is to use windows style paths (starting with e.g. `c:`) but 
with forward slashes, which both msys based tools, shell scripts and native 
windows executables can cope with. This incidentally turns out to be the form 
of paths that GCC prints out when run with `-v` on windows as well.

This patch applies a rewrite from backslashes to forwad slashes on all command 
line arguments printed when compiling with `-v`, if the target triple is 
mingw/cygwin.

The patch isn't super pretty but hopefully should be acceptable unless there 
are better suggestions on how to handle it. Any suggestions on how would one go 
about to add a test for this?


Repository:
  rC Clang

https://reviews.llvm.org/D53066

Files:
  include/clang/Driver/Job.h
  lib/Driver/Compilation.cpp
  lib/Driver/Job.cpp

Index: lib/Driver/Job.cpp
===================================================================
--- lib/Driver/Job.cpp
+++ lib/Driver/Job.cpp
@@ -98,7 +98,13 @@
   return false;
 }
 
-void Command::printArg(raw_ostream &OS, StringRef Arg, bool Quote) {
+void Command::printArg(raw_ostream &OS, StringRef Arg, bool Quote,
+                       llvm::sys::path::Style PathStyle) {
+  std::string Buf;
+  if (PathStyle == llvm::sys::path::Style::posix) {
+    Buf = llvm::sys::path::convert_to_slash(Arg);
+    Arg = Buf;
+  }
   const bool Escape = Arg.find_first_of("\"\\$") != StringRef::npos;
 
   if (!Quote && !Escape) {
@@ -212,10 +218,11 @@
 }
 
 void Command::Print(raw_ostream &OS, const char *Terminator, bool Quote,
-                    CrashReportInfo *CrashInfo) const {
+                    CrashReportInfo *CrashInfo,
+                    llvm::sys::path::Style PathStyle) const {
   // Always quote the exe.
   OS << ' ';
-  printArg(OS, Executable, /*Quote=*/true);
+  printArg(OS, Executable, /*Quote=*/true, PathStyle);
 
   ArrayRef<const char *> Args = Arguments;
   SmallVector<const char *, 128> ArgsRespFile;
@@ -263,14 +270,14 @@
     }
 
     OS << ' ';
-    printArg(OS, Arg, Quote);
+    printArg(OS, Arg, Quote, PathStyle);
   }
 
   if (CrashInfo && HaveCrashVFS) {
     OS << ' ';
-    printArg(OS, "-ivfsoverlay", Quote);
+    printArg(OS, "-ivfsoverlay", Quote, PathStyle);
     OS << ' ';
-    printArg(OS, CrashInfo->VFSPath.str(), Quote);
+    printArg(OS, CrashInfo->VFSPath.str(), Quote, PathStyle);
 
     // The leftover modules from the crash are stored in
     //  <name>.cache/vfs/modules
@@ -285,7 +292,7 @@
     ModCachePath.append(RelModCacheDir.c_str());
 
     OS << ' ';
-    printArg(OS, ModCachePath, Quote);
+    printArg(OS, ModCachePath, Quote, PathStyle);
   }
 
   if (ResponseFile != nullptr) {
@@ -372,11 +379,12 @@
     : Command(Source_, Creator_, Executable_, Arguments_, Inputs),
       Fallback(std::move(Fallback_)) {}
 
-void FallbackCommand::Print(raw_ostream &OS, const char *Terminator,
-                            bool Quote, CrashReportInfo *CrashInfo) const {
-  Command::Print(OS, "", Quote, CrashInfo);
+void FallbackCommand::Print(raw_ostream &OS, const char *Terminator, bool Quote,
+                            CrashReportInfo *CrashInfo,
+                            llvm::sys::path::Style PathStyle) const {
+  Command::Print(OS, "", Quote, CrashInfo, PathStyle);
   OS << " ||";
-  Fallback->Print(OS, Terminator, Quote, CrashInfo);
+  Fallback->Print(OS, Terminator, Quote, CrashInfo, PathStyle);
 }
 
 static bool ShouldFallback(int ExitCode) {
@@ -413,7 +421,8 @@
     : Command(Source_, Creator_, Executable_, Arguments_, Inputs) {}
 
 void ForceSuccessCommand::Print(raw_ostream &OS, const char *Terminator,
-                            bool Quote, CrashReportInfo *CrashInfo) const {
+                                bool Quote, CrashReportInfo *CrashInfo,
+                                llvm::sys::path::Style PathStyle) const {
   Command::Print(OS, "", Quote, CrashInfo);
   OS << " || (exit 0)" << Terminator;
 }
Index: lib/Driver/Compilation.cpp
===================================================================
--- lib/Driver/Compilation.cpp
+++ lib/Driver/Compilation.cpp
@@ -174,7 +174,12 @@
     if (getDriver().CCPrintOptions)
       *OS << "[Logging clang options]";
 
-    C.Print(*OS, "\n", /*Quote=*/getDriver().CCPrintOptions);
+    llvm::Triple TT(llvm::Triple::normalize(getDriver().getTargetTriple()));
+    llvm::sys::path::Style PathStyle = TT.isOSCygMing()
+                                           ? llvm::sys::path::Style::posix
+                                           : llvm::sys::path::Style::native;
+    C.Print(*OS, "\n", /*Quote=*/getDriver().CCPrintOptions, nullptr,
+            PathStyle);
 
     if (OS != &llvm::errs())
       delete OS;
Index: include/clang/Driver/Job.h
===================================================================
--- include/clang/Driver/Job.h
+++ include/clang/Driver/Job.h
@@ -17,6 +17,7 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/iterator.h"
 #include "llvm/Option/Option.h"
+#include "llvm/Support/Path.h"
 #include <memory>
 #include <string>
 #include <utility>
@@ -95,8 +96,10 @@
   Command(const Command &) = default;
   virtual ~Command() = default;
 
-  virtual void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
-                     CrashReportInfo *CrashInfo = nullptr) const;
+  virtual void Print(
+      llvm::raw_ostream &OS, const char *Terminator, bool Quote,
+      CrashReportInfo *CrashInfo = nullptr,
+      llvm::sys::path::Style PathStyle = llvm::sys::path::Style::native) const;
 
   virtual int Execute(ArrayRef<Optional<StringRef>> Redirects,
                       std::string *ErrMsg, bool *ExecutionFailed) const;
@@ -127,7 +130,9 @@
   const llvm::opt::ArgStringList &getArguments() const { return Arguments; }
 
   /// Print a command argument, and optionally quote it.
-  static void printArg(llvm::raw_ostream &OS, StringRef Arg, bool Quote);
+  static void
+  printArg(llvm::raw_ostream &OS, StringRef Arg, bool Quote,
+           llvm::sys::path::Style PathStyle = llvm::sys::path::Style::native);
 };
 
 /// Like Command, but with a fallback which is executed in case
@@ -140,7 +145,9 @@
                   std::unique_ptr<Command> Fallback_);
 
   void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
-             CrashReportInfo *CrashInfo = nullptr) const override;
+             CrashReportInfo *CrashInfo = nullptr,
+             llvm::sys::path::Style PathStyle =
+                 llvm::sys::path::Style::native) const override;
 
   int Execute(ArrayRef<Optional<StringRef>> Redirects, std::string *ErrMsg,
               bool *ExecutionFailed) const override;
@@ -157,7 +164,9 @@
                       ArrayRef<InputInfo> Inputs);
 
   void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
-             CrashReportInfo *CrashInfo = nullptr) const override;
+             CrashReportInfo *CrashInfo = nullptr,
+             llvm::sys::path::Style PathStyle =
+                 llvm::sys::path::Style::native) const override;
 
   int Execute(ArrayRef<Optional<StringRef>> Redirects, std::string *ErrMsg,
               bool *ExecutionFailed) const override;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to