Fix review issues.  Also check the target triple to determine which toolchain 
to use (x86, x64, or arm).

http://reviews.llvm.org/D5892

Files:
  lib/Driver/ToolChains.h
  lib/Driver/Tools.cpp
  lib/Driver/WindowsToolChain.cpp
Index: lib/Driver/ToolChains.h
===================================================================
--- lib/Driver/ToolChains.h
+++ lib/Driver/ToolChains.h
@@ -746,7 +746,9 @@
                                llvm::opt::ArgStringList &CC1Args) const override;
 
   bool getWindowsSDKDir(std::string &path, int &major, int &minor) const;
-  bool getVisualStudioDir(std::string &path) const;
+  bool getVisualStudioInstallDir(std::string &path) const;
+  bool getVisualStudioBinariesFolder(const char *clangProgramPath,
+                                     std::string &path) const;
 
 protected:
   void AddSystemIncludeWithSubfolder(const llvm::opt::ArgList &DriverArgs,
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -7816,37 +7816,12 @@
 static std::string FindVisualStudioExecutable(const ToolChain &TC,
                                               const char *Exe,
                                               const char *ClangProgramPath) {
-  // Since a particular Visual Studio executable is tied to a set of system
-  // includes and libraries, first try to use the same location that we use for
-  // the include paths to ensure that a consistent build environment is located.
   const toolchains::Windows &WTC = static_cast<const toolchains::Windows &>(TC);
-  std::string visualStudioDir;
-  if (WTC.getVisualStudioDir(visualStudioDir)) {
-    SmallString<128> VSDir(visualStudioDir);
-    llvm::sys::path::append(VSDir, "VC\\bin");
-    llvm::sys::path::append(VSDir, Exe);
-    if (llvm::sys::fs::can_execute(VSDir.c_str()))
-      return VSDir.str();
-  }
-
-  // If it could not be found, we're already probably broken, but try to
-  // fallback to PATH anyway.
-  llvm::Optional<std::string> OptPath = llvm::sys::Process::GetEnv("PATH");
-  if (!OptPath.hasValue())
-    return Exe;
-
-  const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
-  SmallVector<StringRef, 8> PathSegments;
-  llvm::SplitString(OptPath.getValue(), PathSegments, EnvPathSeparatorStr);
-
-  for (StringRef PathSegment : PathSegments) {
-    if (PathSegment.empty())
-      continue;
-
-    SmallString<128> FilePath(PathSegment);
+  std::string visualStudioBinDir;
+  if (WTC.getVisualStudioBinariesFolder(ClangProgramPath, visualStudioBinDir)) {
+    SmallString<128> FilePath(visualStudioBinDir);
     llvm::sys::path::append(FilePath, Exe);
-    if (llvm::sys::fs::can_execute(FilePath.c_str()) &&
-        !llvm::sys::fs::equivalent(FilePath.c_str(), ClangProgramPath))
+    if (llvm::sys::fs::can_execute(FilePath.c_str()))
       return FilePath.str();
   }
 
Index: lib/Driver/WindowsToolChain.cpp
===================================================================
--- lib/Driver/WindowsToolChain.cpp
+++ lib/Driver/WindowsToolChain.cpp
@@ -14,10 +14,13 @@
 #include "clang/Driver/Driver.h"
 #include "clang/Driver/DriverDiagnostic.h"
 #include "clang/Driver/Options.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/Config/llvm-config.h"
 #include "llvm/Option/Arg.h"
 #include "llvm/Option/ArgList.h"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Process.h"
 
 // Include the necessary headers to interface with the Windows registry and
 // environment.
@@ -211,8 +214,87 @@
   return hasSDKDir && !path.empty();
 }
 
+// Get the location to use for Visual Studio binaries.  The location priority
+// is: %VCINSTALLDIR% > %PATH% > newest copy of Visual Studio installed on
+// system (as reported by the registry).
+bool Windows::getVisualStudioBinariesFolder(const char *clangProgramPath,
+                                            std::string &path) const {
+  path.clear();
+
+  SmallString<128> BinDir;
+
+  // First check the environment variables that vsvars32.bat sets.
+  const char *vcinstalldir = getenv("VCINSTALLDIR");
+  if (vcinstalldir) {
+    BinDir = vcinstalldir;
+    llvm::sys::path::append(BinDir, "VC");
+  } else {
+    // Next walk the PATH, trying to find a cl.exe in the path.  If we find one,
+    // use that.  However, make sure it's not clang's cl.exe.
+    llvm::Optional<std::string> OptPath = llvm::sys::Process::GetEnv("PATH");
+    if (OptPath.hasValue()) {
+      const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
+      SmallVector<StringRef, 8> PathSegments;
+      llvm::SplitString(OptPath.getValue(), PathSegments, EnvPathSeparatorStr);
+
+      for (StringRef PathSegment : PathSegments) {
+        if (PathSegment.empty())
+          continue;
+
+        SmallString<128> FilePath(PathSegment);
+        llvm::sys::path::append(FilePath, "cl.exe");
+        if (llvm::sys::fs::can_execute(FilePath.c_str()) &&
+            !llvm::sys::fs::equivalent(FilePath.c_str(), clangProgramPath)) {
+          // If we found it on the PATH, use it exactly as is with no
+          // modifications.
+          path = PathSegment;
+          return true;
+        }
+      }
+    }
+
+    std::string installDir;
+    // With no VCINSTALLDIR and nothing on the PATH, if we can't find it in the
+    // registry then we have no choice but to fail.
+    if (!getVisualStudioInstallDir(installDir))
+      return false;
+
+    // Regardless of what binary we're ultimately trying to find, we make sure
+    // that this is a Visual Studio directory by checking for cl.exe.  We use
+    // cl.exe instead of other binaries like link.exe because programs such as
+    // GnuWin32 also have a utility called link.exe, so cl.exe is the least
+    // ambiguous.
+    BinDir = installDir;
+    llvm::sys::path::append(BinDir, "VC\\bin");
+    SmallString<128> ClPath(BinDir);
+    llvm::sys::path::append(ClPath, "cl.exe");
+
+    if (!llvm::sys::fs::can_execute(ClPath.c_str()))
+      return false;
+  }
+
+  if (BinDir.empty())
+    return false;
+
+  switch (getArch()) {
+  case llvm::Triple::x86:
+    break;
+  case llvm::Triple::x86_64:
+    llvm::sys::path::append(BinDir, "amd64");
+    break;
+  case llvm::Triple::arm:
+    llvm::sys::path::append(BinDir, "arm");
+    break;
+  default:
+    // Whatever this is, Visual Studio doesn't have a toolchain for it.
+    return false;
+  }
+  path = BinDir.str();
+  return true;
+}
+
 // Get Visual Studio installation directory.
-bool Windows::getVisualStudioDir(std::string &path) const {
+bool Windows::getVisualStudioInstallDir(std::string &path) const {
   // First check the environment variables that vsvars32.bat sets.
   const char *vcinstalldir = getenv("VCINSTALLDIR");
   if (vcinstalldir) {
@@ -305,7 +387,7 @@
 
   // When built with access to the proper Windows APIs, try to actually find
   // the correct include paths first.
-  if (getVisualStudioDir(VSDir)) {
+  if (getVisualStudioInstallDir(VSDir)) {
     AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, VSDir, "VC\\include");
 
     std::string WindowsSDKDir;
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to