<div dir="ltr">This change breaks cmake build:<div><div>undefined reference to `clang::DiagnosticIDs::DiagnosticIDs()'</div><div>/home/jvesely/llvm/tools/clang/unittests/Driver/ToolChainTest.cpp:33: undefined reference to `clang::DiagnosticsEngine::DiagnosticsEngine(llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> const&, clang::DiagnosticOptions*, clang::DiagnosticConsumer*, bool)'</div><div>/home/jvesely/llvm/tools/clang/unittests/Driver/ToolChainTest.cpp:35: undefined reference to `clang::vfs::InMemoryFileSystem::InMemoryFileSystem()'</div><div>/home/jvesely/llvm/tools/clang/unittests/Driver/ToolChainTest.cpp:59: undefined reference to `clang::vfs::InMemoryFileSystem::addFile(llvm::Twine const&, long, std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer> >)'</div><div>/home/jvesely/llvm/tools/clang/unittests/Driver/ToolChainTest.cpp:33: undefined reference to `clang::DiagnosticsEngine::~DiagnosticsEngine()'</div><div>CMakeFiles/ClangDriverTests.dir/ToolChainTest.cpp.o: In function `~TestDiagnosticConsumer':</div><div>/home/jvesely/llvm/tools/clang/unittests/Driver/ToolChainTest.cpp:32: undefined reference to `clang::DiagnosticConsumer::~DiagnosticConsumer()'</div><div>CMakeFiles/ClangDriverTests.dir/ToolChainTest.cpp.o: In function `clang::DiagnosticConsumer::DiagnosticConsumer()':</div><div>/home/jvesely/llvm/tools/clang/include/clang/Basic/Diagnostic.h:1313: undefined reference to `vtable for clang::DiagnosticConsumer'</div><div>CMakeFiles/ClangDriverTests.dir/ToolChainTest.cpp.o: In function `llvm::RefCountedBase<clang::DiagnosticIDs>::Release() const':</div><div>/home/jvesely/llvm/include/llvm/ADT/IntrusiveRefCntPtr.h:54: undefined reference to `clang::DiagnosticIDs::~DiagnosticIDs()'</div><div>CMakeFiles/ClangDriverTests.dir/ToolChainTest.cpp.o:(.<a href="http://data.rel.ro">data.rel.ro</a>+0x80): undefined reference to `clang::DiagnosticConsumer::IncludeInDiagnosticCounts() const'</div><div>CMakeFiles/ClangDriverTests.dir/ToolChainTest.cpp.o:(.<a href="http://data.rel.ro">data.rel.ro</a>+0x88): undefined reference to `clang::DiagnosticConsumer::HandleDiagnostic(clang::DiagnosticsEngine::Level, clang::Diagnostic const&)'</div><div>collect2: error: ld returned 1 exit status</div></div><div><br></div><div>using Diagnostics requires linking to libclangBasic. Please consider the attached patch.</div><div><br></div><div>BR,</div><div>Jan</div><div><br></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Oct 7, 2015 at 10:48 AM, Benjamin Kramer via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: d0k<br>
Date: Wed Oct  7 10:48:01 2015<br>
New Revision: 249556<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=249556&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=249556&view=rev</a><br>
Log:<br>
[VFS] Port driver tool chains to VFS.<br>
<br>
There are still some loose ends here but it's sufficient so we can detect<br>
GCC headers that are inside of a VFS.<br>
<br>
Added:<br>
    cfe/trunk/unittests/Driver/ToolChainTest.cpp<br>
Modified:<br>
    cfe/trunk/include/clang/Basic/VirtualFileSystem.h<br>
    cfe/trunk/include/clang/Driver/Driver.h<br>
    cfe/trunk/include/clang/Driver/ToolChain.h<br>
    cfe/trunk/lib/Basic/VirtualFileSystem.cpp<br>
    cfe/trunk/lib/Driver/Driver.cpp<br>
    cfe/trunk/lib/Driver/ToolChain.cpp<br>
    cfe/trunk/lib/Driver/ToolChains.cpp<br>
    cfe/trunk/lib/Driver/ToolChains.h<br>
    cfe/trunk/lib/Driver/Tools.cpp<br>
    cfe/trunk/unittests/Driver/CMakeLists.txt<br>
<br>
Modified: cfe/trunk/include/clang/Basic/VirtualFileSystem.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/VirtualFileSystem.h?rev=249556&r1=249555&r2=249556&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/VirtualFileSystem.h?rev=249556&r1=249555&r2=249556&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Basic/VirtualFileSystem.h (original)<br>
+++ cfe/trunk/include/clang/Basic/VirtualFileSystem.h Wed Oct  7 10:48:01 2015<br>
@@ -206,6 +206,9 @@ public:<br>
   /// Get the working directory of this file system.<br>
   virtual llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const = 0;<br>
<br>
+  /// Check whether a file exists. Provided for convenience.<br>
+  bool exists(const Twine &Path);<br>
+<br>
   /// Make \a Path an absolute path.<br>
   ///<br>
   /// Makes \a Path absolute using the current directory if it is not already.<br>
<br>
Modified: cfe/trunk/include/clang/Driver/Driver.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Driver.h?rev=249556&r1=249555&r2=249556&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Driver.h?rev=249556&r1=249555&r2=249556&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Driver/Driver.h (original)<br>
+++ cfe/trunk/include/clang/Driver/Driver.h Wed Oct  7 10:48:01 2015<br>
@@ -36,6 +36,11 @@ namespace opt {<br>
 }<br>
<br>
 namespace clang {<br>
+<br>
+namespace vfs {<br>
+class FileSystem;<br>
+}<br>
+<br>
 namespace driver {<br>
<br>
   class Action;<br>
@@ -54,6 +59,8 @@ class Driver {<br>
<br>
   DiagnosticsEngine &Diags;<br>
<br>
+  IntrusiveRefCntPtr<vfs::FileSystem> VFS;<br>
+<br>
   enum DriverMode {<br>
     GCCMode,<br>
     GXXMode,<br>
@@ -201,9 +208,9 @@ private:<br>
                                  SmallVectorImpl<std::string> &Names) const;<br>
<br>
 public:<br>
-  Driver(StringRef _ClangExecutable,<br>
-         StringRef _DefaultTargetTriple,<br>
-         DiagnosticsEngine &_Diags);<br>
+  Driver(StringRef ClangExecutable, StringRef DefaultTargetTriple,<br>
+         DiagnosticsEngine &Diags,<br>
+         IntrusiveRefCntPtr<vfs::FileSystem> VFS = nullptr);<br>
   ~Driver();<br>
<br>
   /// @name Accessors<br>
@@ -216,6 +223,8 @@ public:<br>
<br>
   const DiagnosticsEngine &getDiags() const { return Diags; }<br>
<br>
+  vfs::FileSystem &getVFS() const { return *VFS; }<br>
+<br>
   bool getCheckInputsExist() const { return CheckInputsExist; }<br>
<br>
   void setCheckInputsExist(bool Value) { CheckInputsExist = Value; }<br>
<br>
Modified: cfe/trunk/include/clang/Driver/ToolChain.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/ToolChain.h?rev=249556&r1=249555&r2=249556&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/ToolChain.h?rev=249556&r1=249555&r2=249556&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Driver/ToolChain.h (original)<br>
+++ cfe/trunk/include/clang/Driver/ToolChain.h Wed Oct  7 10:48:01 2015<br>
@@ -30,7 +30,10 @@ namespace opt {<br>
 }<br>
<br>
 namespace clang {<br>
-  class ObjCRuntime;<br>
+class ObjCRuntime;<br>
+namespace vfs {<br>
+class FileSystem;<br>
+}<br>
<br>
 namespace driver {<br>
   class Compilation;<br>
@@ -119,7 +122,8 @@ public:<br>
<br>
   // Accessors<br>
<br>
-  const Driver &getDriver() const;<br>
+  const Driver &getDriver() const { return D; }<br>
+  vfs::FileSystem &getVFS() const;<br>
   const llvm::Triple &getTriple() const { return Triple; }<br>
<br>
   llvm::Triple::ArchType getArch() const { return Triple.getArch(); }<br>
<br>
Modified: cfe/trunk/lib/Basic/VirtualFileSystem.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/VirtualFileSystem.cpp?rev=249556&r1=249555&r2=249556&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/VirtualFileSystem.cpp?rev=249556&r1=249555&r2=249556&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Basic/VirtualFileSystem.cpp (original)<br>
+++ cfe/trunk/lib/Basic/VirtualFileSystem.cpp Wed Oct  7 10:48:01 2015<br>
@@ -105,6 +105,11 @@ std::error_code FileSystem::makeAbsolute<br>
   return llvm::sys::fs::make_absolute(WorkingDir.get(), Path);<br>
 }<br>
<br>
+bool FileSystem::exists(const Twine &Path) {<br>
+  auto Status = status(Path);<br>
+  return Status && Status->exists();<br>
+}<br>
+<br>
 //===-----------------------------------------------------------------------===/<br>
 // RealFileSystem implementation<br>
 //===-----------------------------------------------------------------------===/<br>
<br>
Modified: cfe/trunk/lib/Driver/Driver.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Driver.cpp?rev=249556&r1=249555&r2=249556&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Driver.cpp?rev=249556&r1=249555&r2=249556&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Driver/Driver.cpp (original)<br>
+++ cfe/trunk/lib/Driver/Driver.cpp Wed Oct  7 10:48:01 2015<br>
@@ -11,6 +11,7 @@<br>
 #include "InputInfo.h"<br>
 #include "ToolChains.h"<br>
 #include "clang/Basic/Version.h"<br>
+#include "clang/Basic/VirtualFileSystem.h"<br>
 #include "clang/Config/config.h"<br>
 #include "clang/Driver/Action.h"<br>
 #include "clang/Driver/Compilation.h"<br>
@@ -46,8 +47,9 @@ using namespace clang;<br>
 using namespace llvm::opt;<br>
<br>
 Driver::Driver(StringRef ClangExecutable, StringRef DefaultTargetTriple,<br>
-               DiagnosticsEngine &Diags)<br>
-    : Opts(createDriverOptTable()), Diags(Diags), Mode(GCCMode),<br>
+               DiagnosticsEngine &Diags,<br>
+               IntrusiveRefCntPtr<vfs::FileSystem> VFS)<br>
+    : Opts(createDriverOptTable()), Diags(Diags), VFS(VFS), Mode(GCCMode),<br>
       SaveTemps(SaveTempsNone), ClangExecutable(ClangExecutable),<br>
       SysRoot(DEFAULT_SYSROOT), UseStdLib(true),<br>
       DefaultTargetTriple(DefaultTargetTriple),<br>
@@ -57,6 +59,10 @@ Driver::Driver(StringRef ClangExecutable<br>
       CCGenDiagnostics(false), CCCGenericGCCName(""), CheckInputsExist(true),<br>
       CCCUsePCH(true), SuppressMissingInputWarning(false) {<br>
<br>
+  // Provide a sane fallback if no VFS is specified.<br>
+  if (!this->VFS)<br>
+    this->VFS = vfs::getRealFileSystem();<br>
+<br>
   Name = llvm::sys::path::filename(ClangExecutable);<br>
   Dir = llvm::sys::path::parent_path(ClangExecutable);<br>
<br>
<br>
Modified: cfe/trunk/lib/Driver/ToolChain.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChain.cpp?rev=249556&r1=249555&r2=249556&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChain.cpp?rev=249556&r1=249555&r2=249556&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Driver/ToolChain.cpp (original)<br>
+++ cfe/trunk/lib/Driver/ToolChain.cpp Wed Oct  7 10:48:01 2015<br>
@@ -75,9 +75,7 @@ ToolChain::ToolChain(const Driver &D, co<br>
 ToolChain::~ToolChain() {<br>
 }<br>
<br>
-const Driver &ToolChain::getDriver() const {<br>
- return D;<br>
-}<br>
+vfs::FileSystem &ToolChain::getVFS() const { return getDriver().getVFS(); }<br>
<br>
 bool ToolChain::useIntegratedAs() const {<br>
   return Args.hasFlag(options::OPT_fintegrated_as,<br>
<br>
Modified: cfe/trunk/lib/Driver/ToolChains.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains.cpp?rev=249556&r1=249555&r2=249556&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains.cpp?rev=249556&r1=249555&r2=249556&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Driver/ToolChains.cpp (original)<br>
+++ cfe/trunk/lib/Driver/ToolChains.cpp Wed Oct  7 10:48:01 2015<br>
@@ -10,6 +10,7 @@<br>
 #include "ToolChains.h"<br>
 #include "clang/Basic/ObjCRuntime.h"<br>
 #include "clang/Basic/Version.h"<br>
+#include "clang/Basic/VirtualFileSystem.h"<br>
 #include "clang/Config/config.h" // for GCC_INSTALL_PREFIX<br>
 #include "clang/Driver/Compilation.h"<br>
 #include "clang/Driver/Driver.h"<br>
@@ -275,7 +276,7 @@ void MachO::AddLinkRuntimeLib(const ArgL<br>
   // For now, allow missing resource libraries to support developers who may<br>
   // not have compiler-rt checked out or integrated into their build (unless<br>
   // we explicitly force linking with this library).<br>
-  if (AlwaysLink || llvm::sys::fs::exists(P))<br>
+  if (AlwaysLink || getVFS().exists(P))<br>
     CmdArgs.push_back(Args.MakeArgString(P));<br>
<br>
   // Adding the rpaths might negatively interact when other rpaths are involved,<br>
@@ -424,13 +425,13 @@ void Darwin::AddDeploymentTarget(Derived<br>
   // isysroot.<br>
   if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {<br>
     // Warn if the path does not exist.<br>
-    if (!llvm::sys::fs::exists(A->getValue()))<br>
+    if (!getVFS().exists(A->getValue()))<br>
       getDriver().Diag(clang::diag::warn_missing_sysroot) << A->getValue();<br>
   } else {<br>
     if (char *env = ::getenv("SDKROOT")) {<br>
       // We only use this value as the default if it is an absolute path,<br>
       // exists, and it is not the root path.<br>
-      if (llvm::sys::path::is_absolute(env) && llvm::sys::fs::exists(env) &&<br>
+      if (llvm::sys::path::is_absolute(env) && getVFS().exists(env) &&<br>
           StringRef(env) != "/") {<br>
         Args.append(Args.MakeSeparateArg(<br>
             nullptr, Opts.getOption(options::OPT_isysroot), env));<br>
@@ -582,10 +583,10 @@ void DarwinClang::AddCXXStdlibLibArgs(co<br>
       SmallString<128> P(A->getValue());<br>
       llvm::sys::path::append(P, "usr", "lib", "libstdc++.dylib");<br>
<br>
-      if (!llvm::sys::fs::exists(P)) {<br>
+      if (!getVFS().exists(P)) {<br>
         llvm::sys::path::remove_filename(P);<br>
         llvm::sys::path::append(P, "libstdc++.6.dylib");<br>
-        if (llvm::sys::fs::exists(P)) {<br>
+        if (getVFS().exists(P)) {<br>
           CmdArgs.push_back(Args.MakeArgString(P));<br>
           return;<br>
         }<br>
@@ -595,8 +596,8 @@ void DarwinClang::AddCXXStdlibLibArgs(co<br>
     // Otherwise, look in the root.<br>
     // FIXME: This should be removed someday when we don't have to care about<br>
     // 10.6 and earlier, where /usr/lib/libstdc++.dylib does not exist.<br>
-    if (!llvm::sys::fs::exists("/usr/lib/libstdc++.dylib") &&<br>
-        llvm::sys::fs::exists("/usr/lib/libstdc++.6.dylib")) {<br>
+    if (!getVFS().exists("/usr/lib/libstdc++.dylib") &&<br>
+        getVFS().exists("/usr/lib/libstdc++.6.dylib")) {<br>
       CmdArgs.push_back("/usr/lib/libstdc++.6.dylib");<br>
       return;<br>
     }<br>
@@ -626,7 +627,7 @@ void DarwinClang::AddCCKextLibArgs(const<br>
<br>
   // For now, allow missing resource libraries to support developers who may<br>
   // not have compiler-rt checked out or integrated into their build.<br>
-  if (llvm::sys::fs::exists(P))<br>
+  if (getVFS().exists(P))<br>
     CmdArgs.push_back(Args.MakeArgString(P));<br>
 }<br>
<br>
@@ -1166,7 +1167,7 @@ static llvm::StringRef getGCCToolchainDi<br>
 /// necessary because the driver doesn't store the final version of the target<br>
 /// triple.<br>
 void Generic_GCC::GCCInstallationDetector::init(<br>
-    const Driver &D, const llvm::Triple &TargetTriple, const ArgList &Args,<br>
+    const llvm::Triple &TargetTriple, const ArgList &Args,<br>
     ArrayRef<std::string> ExtraTripleAliases) {<br>
   llvm::Triple BiarchVariantTriple = TargetTriple.isArch32Bit()<br>
                                          ? TargetTriple.get64BitArchVariant()<br>
@@ -1209,11 +1210,11 @@ void Generic_GCC::GCCInstallationDetecto<br>
   // installation available. GCC installs are ranked by version number.<br>
   Version = GCCVersion::Parse("0.0.0");<br>
   for (const std::string &Prefix : Prefixes) {<br>
-    if (!llvm::sys::fs::exists(Prefix))<br>
+    if (!D.getVFS().exists(Prefix))<br>
       continue;<br>
     for (StringRef Suffix : CandidateLibDirs) {<br>
       const std::string LibDir = Prefix + Suffix.str();<br>
-      if (!llvm::sys::fs::exists(LibDir))<br>
+      if (!D.getVFS().exists(LibDir))<br>
         continue;<br>
       for (StringRef Candidate : ExtraTripleAliases) // Try these first.<br>
         ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate);<br>
@@ -1222,7 +1223,7 @@ void Generic_GCC::GCCInstallationDetecto<br>
     }<br>
     for (StringRef Suffix : CandidateBiarchLibDirs) {<br>
       const std::string LibDir = Prefix + Suffix.str();<br>
-      if (!llvm::sys::fs::exists(LibDir))<br>
+      if (!D.getVFS().exists(LibDir))<br>
         continue;<br>
       for (StringRef Candidate : CandidateBiarchTripleAliases)<br>
         ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate,<br>
@@ -1480,10 +1481,8 @@ bool Generic_GCC::GCCInstallationDetecto<br>
 // \brief -- try common CUDA installation paths looking for files we need for<br>
 // CUDA compilation.<br>
<br>
-void<br>
-Generic_GCC::CudaInstallationDetector::init(const Driver &D,<br>
-                                            const llvm::Triple &TargetTriple,<br>
-                                            const llvm::opt::ArgList &Args) {<br>
+void Generic_GCC::CudaInstallationDetector::init(<br>
+    const llvm::Triple &TargetTriple, const llvm::opt::ArgList &Args) {<br>
   SmallVector<std::string, 4> CudaPathCandidates;<br>
<br>
   if (Args.hasArg(options::OPT_cuda_path_EQ))<br>
@@ -1495,7 +1494,7 @@ Generic_GCC::CudaInstallationDetector::i<br>
   }<br>
<br>
   for (const auto &CudaPath : CudaPathCandidates) {<br>
-    if (CudaPath.empty() || !llvm::sys::fs::exists(CudaPath))<br>
+    if (CudaPath.empty() || !D.getVFS().exists(CudaPath))<br>
       continue;<br>
<br>
     CudaInstallPath = CudaPath;<br>
@@ -1504,9 +1503,9 @@ Generic_GCC::CudaInstallationDetector::i<br>
     CudaLibPath =<br>
         CudaInstallPath + (TargetTriple.isArch64Bit() ? "/lib64" : "/lib");<br>
<br>
-    if (!(llvm::sys::fs::exists(CudaIncludePath) &&<br>
-          llvm::sys::fs::exists(CudaLibPath) &&<br>
-          llvm::sys::fs::exists(CudaLibDevicePath)))<br>
+    if (!(D.getVFS().exists(CudaIncludePath) &&<br>
+          D.getVFS().exists(CudaLibPath) &&<br>
+          D.getVFS().exists(CudaLibDevicePath)))<br>
       continue;<br>
<br>
     IsValid = true;<br>
@@ -1967,13 +1966,13 @@ void Generic_GCC::GCCInstallationDetecto<br>
   // /usr/gcc/<major>.<minor>/lib/gcc/<triple>/<major>.<minor>.<patch>/, so we<br>
   // need to iterate twice.<br>
   std::error_code EC;<br>
-  for (llvm::sys::fs::directory_iterator LI(LibDir, EC), LE; !EC && LI != LE;<br>
-       LI = LI.increment(EC)) {<br>
-    StringRef VersionText = llvm::sys::path::filename(LI->path());<br>
+  for (vfs::directory_iterator LI = D.getVFS().dir_begin(LibDir, EC), LE;<br>
+       !EC && LI != LE; LI = LI.increment(EC)) {<br>
+    StringRef VersionText = llvm::sys::path::filename(LI->getName());<br>
     GCCVersion CandidateVersion = GCCVersion::Parse(VersionText);<br>
<br>
     if (CandidateVersion.Major != -1) // Filter obviously bad entries.<br>
-      if (!CandidateGCCInstallPaths.insert(LI->path()).second)<br>
+      if (!CandidateGCCInstallPaths.insert(LI->getName()).second)<br>
         continue; // Saw this path before; no need to look at it again.<br>
     if (CandidateVersion.isOlderThan(4, 1, 1))<br>
       continue;<br>
@@ -1982,16 +1981,18 @@ void Generic_GCC::GCCInstallationDetecto<br>
<br>
     GCCInstallPath =<br>
         LibDir + "/" + VersionText.str() + "/lib/gcc/" + CandidateTriple.str();<br>
-    if (!llvm::sys::fs::exists(GCCInstallPath))<br>
+    if (!D.getVFS().exists(GCCInstallPath))<br>
       continue;<br>
<br>
     // If we make it here there has to be at least one GCC version, let's just<br>
     // use the latest one.<br>
     std::error_code EEC;<br>
-    for (llvm::sys::fs::directory_iterator LLI(GCCInstallPath, EEC), LLE;<br>
+    for (vfs::directory_iterator<br>
+             LLI = D.getVFS().dir_begin(GCCInstallPath, EEC),<br>
+             LLE;<br>
          !EEC && LLI != LLE; LLI = LLI.increment(EEC)) {<br>
<br>
-      StringRef SubVersionText = llvm::sys::path::filename(LLI->path());<br>
+      StringRef SubVersionText = llvm::sys::path::filename(LLI->getName());<br>
       GCCVersion CandidateSubVersion = GCCVersion::Parse(SubVersionText);<br>
<br>
       if (CandidateSubVersion > Version)<br>
@@ -2048,12 +2049,14 @@ void Generic_GCC::GCCInstallationDetecto<br>
   for (unsigned i = 0; i < NumLibSuffixes; ++i) {<br>
     StringRef LibSuffix = LibAndInstallSuffixes[i][0];<br>
     std::error_code EC;<br>
-    for (llvm::sys::fs::directory_iterator LI(LibDir + LibSuffix, EC), LE;<br>
+    for (vfs::directory_iterator<br>
+             LI = D.getVFS().dir_begin(LibDir + LibSuffix, EC),<br>
+             LE;<br>
          !EC && LI != LE; LI = LI.increment(EC)) {<br>
-      StringRef VersionText = llvm::sys::path::filename(LI->path());<br>
+      StringRef VersionText = llvm::sys::path::filename(LI->getName());<br>
       GCCVersion CandidateVersion = GCCVersion::Parse(VersionText);<br>
       if (CandidateVersion.Major != -1) // Filter obviously bad entries.<br>
-        if (!CandidateGCCInstallPaths.insert(LI->path()).second)<br>
+        if (!CandidateGCCInstallPaths.insert(LI->getName()).second)<br>
           continue; // Saw this path before; no need to look at it again.<br>
       if (CandidateVersion.isOlderThan(4, 1, 1))<br>
         continue;<br>
@@ -2065,9 +2068,9 @@ void Generic_GCC::GCCInstallationDetecto<br>
       // Debian mips multilibs behave more like the rest of the biarch ones,<br>
       // so handle them there<br>
       if (isMipsArch(TargetArch)) {<br>
-        if (!findMIPSMultilibs(TargetTriple, LI->path(), Args, Detected))<br>
+        if (!findMIPSMultilibs(TargetTriple, LI->getName(), Args, Detected))<br>
           continue;<br>
-      } else if (!findBiarchMultilibs(TargetTriple, LI->path(), Args,<br>
+      } else if (!findBiarchMultilibs(TargetTriple, LI->getName(), Args,<br>
                                       NeedsBiarchSuffix, Detected)) {<br>
         continue;<br>
       }<br>
@@ -2090,7 +2093,7 @@ void Generic_GCC::GCCInstallationDetecto<br>
<br>
 Generic_GCC::Generic_GCC(const Driver &D, const llvm::Triple &Triple,<br>
                          const ArgList &Args)<br>
-    : ToolChain(D, Triple, Args), GCCInstallation(), CudaInstallation() {<br>
+    : ToolChain(D, Triple, Args), GCCInstallation(D), CudaInstallation(D) {<br>
   getProgramPaths().push_back(getDriver().getInstalledDir());<br>
   if (getDriver().getInstalledDir() != getDriver().Dir)<br>
     getProgramPaths().push_back(getDriver().Dir);<br>
@@ -2183,7 +2186,7 @@ void Generic_ELF::addClangTargetOptions(<br>
 /// Hexagon Toolchain<br>
<br>
 std::string HexagonToolChain::GetGnuDir(const std::string &InstalledDir,<br>
-                                        const ArgList &Args) {<br>
+                                        const ArgList &Args) const {<br>
   // Locate the rest of the toolchain ...<br>
   std::string GccToolchain = getGCCToolchainDir(Args);<br>
<br>
@@ -2191,11 +2194,11 @@ std::string HexagonToolChain::GetGnuDir(<br>
     return GccToolchain;<br>
<br>
   std::string InstallRelDir = InstalledDir + "/../../gnu";<br>
-  if (llvm::sys::fs::exists(InstallRelDir))<br>
+  if (getVFS().exists(InstallRelDir))<br>
     return InstallRelDir;<br>
<br>
   std::string PrefixRelDir = std::string(LLVM_PREFIX) + "/../gnu";<br>
-  if (llvm::sys::fs::exists(PrefixRelDir))<br>
+  if (getVFS().exists(PrefixRelDir))<br>
     return PrefixRelDir;<br>
<br>
   return InstallRelDir;<br>
@@ -2221,7 +2224,8 @@ bool HexagonToolChain::UsesG0(const char<br>
   return smallDataThreshold && smallDataThreshold[0] == '0';<br>
 }<br>
<br>
-static void GetHexagonLibraryPaths(const ArgList &Args, const std::string &Ver,<br>
+static void GetHexagonLibraryPaths(const HexagonToolChain &TC,<br>
+                                   const ArgList &Args, const std::string &Ver,<br>
                                    const std::string &MarchString,<br>
                                    const std::string &InstalledDir,<br>
                                    ToolChain::path_list *LibPaths) {<br>
@@ -2240,8 +2244,7 @@ static void GetHexagonLibraryPaths(const<br>
   const std::string MarchSuffix = "/" + MarchString;<br>
   const std::string G0Suffix = "/G0";<br>
   const std::string MarchG0Suffix = MarchSuffix + G0Suffix;<br>
-  const std::string RootDir =<br>
-      HexagonToolChain::GetGnuDir(InstalledDir, Args) + "/";<br>
+  const std::string RootDir = TC.GetGnuDir(InstalledDir, Args) + "/";<br>
<br>
   // lib/gcc/hexagon/...<br>
   std::string LibGCCHexagonDir = RootDir + "lib/gcc/hexagon/";<br>
@@ -2269,21 +2272,21 @@ HexagonToolChain::HexagonToolChain(const<br>
                                    const ArgList &Args)<br>
     : Linux(D, Triple, Args) {<br>
   const std::string InstalledDir(getDriver().getInstalledDir());<br>
-  const std::string GnuDir = HexagonToolChain::GetGnuDir(InstalledDir, Args);<br>
+  const std::string GnuDir = GetGnuDir(InstalledDir, Args);<br>
<br>
   // Note: Generic_GCC::Generic_GCC adds InstalledDir and getDriver().Dir to<br>
   // program paths<br>
   const std::string BinDir(GnuDir + "/bin");<br>
-  if (llvm::sys::fs::exists(BinDir))<br>
+  if (D.getVFS().exists(BinDir))<br>
     getProgramPaths().push_back(BinDir);<br>
<br>
   // Determine version of GCC libraries and headers to use.<br>
   const std::string HexagonDir(GnuDir + "/lib/gcc/hexagon");<br>
   std::error_code ec;<br>
   GCCVersion MaxVersion = GCCVersion::Parse("0.0.0");<br>
-  for (llvm::sys::fs::directory_iterator di(HexagonDir, ec), de;<br>
+  for (vfs::directory_iterator di = D.getVFS().dir_begin(HexagonDir, ec), de;<br>
        !ec && di != de; di = di.increment(ec)) {<br>
-    GCCVersion cv = GCCVersion::Parse(llvm::sys::path::filename(di->path()));<br>
+    GCCVersion cv = GCCVersion::Parse(llvm::sys::path::filename(di->getName()));<br>
     if (MaxVersion < cv)<br>
       MaxVersion = cv;<br>
   }<br>
@@ -2296,8 +2299,8 @@ HexagonToolChain::HexagonToolChain(const<br>
   // support 'linux' we'll need to fix this up<br>
   LibPaths->clear();<br>
<br>
-  GetHexagonLibraryPaths(Args, GetGCCLibAndIncVersion(), GetTargetCPU(Args),<br>
-                         InstalledDir, LibPaths);<br>
+  GetHexagonLibraryPaths(*this, Args, GetGCCLibAndIncVersion(),<br>
+                         GetTargetCPU(Args), InstalledDir, LibPaths);<br>
 }<br>
<br>
 HexagonToolChain::~HexagonToolChain() {}<br>
@@ -2319,7 +2322,7 @@ void HexagonToolChain::AddClangSystemInc<br>
     return;<br>
<br>
   std::string Ver(GetGCCLibAndIncVersion());<br>
-  std::string GnuDir = HexagonToolChain::GetGnuDir(D.InstalledDir, DriverArgs);<br>
+  std::string GnuDir = GetGnuDir(D.InstalledDir, DriverArgs);<br>
   std::string HexagonDir(GnuDir + "/lib/gcc/hexagon/" + Ver);<br>
   addExternCSystemInclude(DriverArgs, CC1Args, HexagonDir + "/include");<br>
   addExternCSystemInclude(DriverArgs, CC1Args, HexagonDir + "/include-fixed");<br>
@@ -2334,8 +2337,7 @@ void HexagonToolChain::AddClangCXXStdlib<br>
<br>
   const Driver &D = getDriver();<br>
   std::string Ver(GetGCCLibAndIncVersion());<br>
-  SmallString<128> IncludeDir(<br>
-      HexagonToolChain::GetGnuDir(D.InstalledDir, DriverArgs));<br>
+  SmallString<128> IncludeDir(GetGnuDir(D.InstalledDir, DriverArgs));<br>
<br>
   llvm::sys::path::append(IncludeDir, "hexagon/include/c++/");<br>
   llvm::sys::path::append(IncludeDir, Ver);<br>
@@ -2742,7 +2744,7 @@ FreeBSD::FreeBSD(const Driver &D, const<br>
   // back to '/usr/lib' if it doesn't exist.<br>
   if ((Triple.getArch() == llvm::Triple::x86 ||<br>
        Triple.getArch() == llvm::Triple::ppc) &&<br>
-      llvm::sys::fs::exists(getDriver().SysRoot + "/usr/lib32/crt1.o"))<br>
+      D.getVFS().exists(getDriver().SysRoot + "/usr/lib32/crt1.o"))<br>
     getFilePaths().push_back(getDriver().SysRoot + "/usr/lib32");<br>
   else<br>
     getFilePaths().push_back(getDriver().SysRoot + "/usr/lib");<br>
@@ -2952,8 +2954,9 @@ Tool *Minix::buildAssembler() const {<br>
<br>
 Tool *Minix::buildLinker() const { return new tools::minix::Linker(*this); }<br>
<br>
-static void addPathIfExists(Twine Path, ToolChain::path_list &Paths) {<br>
-  if (llvm::sys::fs::exists(Path))<br>
+static void addPathIfExists(const Driver &D, const Twine &Path,<br>
+                            ToolChain::path_list &Paths) {<br>
+  if (D.getVFS().exists(Path))<br>
     Paths.push_back(Path.str());<br>
 }<br>
<br>
@@ -2963,17 +2966,17 @@ Solaris::Solaris(const Driver &D, const<br>
                  const ArgList &Args)<br>
     : Generic_GCC(D, Triple, Args) {<br>
<br>
-  GCCInstallation.init(D, Triple, Args);<br>
+  GCCInstallation.init(Triple, Args);<br>
<br>
   path_list &Paths = getFilePaths();<br>
   if (GCCInstallation.isValid())<br>
-    addPathIfExists(GCCInstallation.getInstallPath(), Paths);<br>
+    addPathIfExists(D, GCCInstallation.getInstallPath(), Paths);<br>
<br>
-  addPathIfExists(getDriver().getInstalledDir(), Paths);<br>
+  addPathIfExists(D, getDriver().getInstalledDir(), Paths);<br>
   if (getDriver().getInstalledDir() != getDriver().Dir)<br>
-    addPathIfExists(getDriver().Dir, Paths);<br>
+    addPathIfExists(D, getDriver().Dir, Paths);<br>
<br>
-  addPathIfExists(getDriver().SysRoot + getDriver().Dir + "/../lib", Paths);<br>
+  addPathIfExists(D, getDriver().SysRoot + getDriver().Dir + "/../lib", Paths);<br>
<br>
   std::string LibPath = "/usr/lib/";<br>
   switch (Triple.getArch()) {<br>
@@ -2990,7 +2993,7 @@ Solaris::Solaris(const Driver &D, const<br>
     llvm_unreachable("Unsupported architecture");<br>
   }<br>
<br>
-  addPathIfExists(getDriver().SysRoot + LibPath, Paths);<br>
+  addPathIfExists(D, getDriver().SysRoot + LibPath, Paths);<br>
 }<br>
<br>
 Tool *Solaris::buildAssembler() const {<br>
@@ -3076,7 +3079,7 @@ static bool IsUbuntu(enum Distro Distro)<br>
   return Distro >= UbuntuHardy && Distro <= UbuntuWily;<br>
 }<br>
<br>
-static Distro DetectDistro(llvm::Triple::ArchType Arch) {<br>
+static Distro DetectDistro(const Driver &D, llvm::Triple::ArchType Arch) {<br>
   llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> File =<br>
       llvm::MemoryBuffer::getFile("/etc/lsb-release");<br>
   if (File) {<br>
@@ -3142,13 +3145,13 @@ static Distro DetectDistro(llvm::Triple:<br>
     return UnknownDistro;<br>
   }<br>
<br>
-  if (llvm::sys::fs::exists("/etc/SuSE-release"))<br>
+  if (D.getVFS().exists("/etc/SuSE-release"))<br>
     return OpenSUSE;<br>
<br>
-  if (llvm::sys::fs::exists("/etc/exherbo-release"))<br>
+  if (D.getVFS().exists("/etc/exherbo-release"))<br>
     return Exherbo;<br>
<br>
-  if (llvm::sys::fs::exists("/etc/arch-release"))<br>
+  if (D.getVFS().exists("/etc/arch-release"))<br>
     return ArchLinux;<br>
<br>
   return UnknownDistro;<br>
@@ -3160,7 +3163,8 @@ static Distro DetectDistro(llvm::Triple:<br>
 /// a target-triple directory in the library and header search paths.<br>
 /// Unfortunately, this triple does not align with the vanilla target triple,<br>
 /// so we provide a rough mapping here.<br>
-static std::string getMultiarchTriple(const llvm::Triple &TargetTriple,<br>
+static std::string getMultiarchTriple(const Driver &D,<br>
+                                      const llvm::Triple &TargetTriple,<br>
                                       StringRef SysRoot) {<br>
   llvm::Triple::EnvironmentType TargetEnvironment = TargetTriple.getEnvironment();<br>
<br>
@@ -3177,85 +3181,85 @@ static std::string getMultiarchTriple(co<br>
   case llvm::Triple::arm:<br>
   case llvm::Triple::thumb:<br>
     if (TargetEnvironment == llvm::Triple::GNUEABIHF) {<br>
-      if (llvm::sys::fs::exists(SysRoot + "/lib/arm-linux-gnueabihf"))<br>
+      if (D.getVFS().exists(SysRoot + "/lib/arm-linux-gnueabihf"))<br>
         return "arm-linux-gnueabihf";<br>
     } else {<br>
-      if (llvm::sys::fs::exists(SysRoot + "/lib/arm-linux-gnueabi"))<br>
+      if (D.getVFS().exists(SysRoot + "/lib/arm-linux-gnueabi"))<br>
         return "arm-linux-gnueabi";<br>
     }<br>
     break;<br>
   case llvm::Triple::armeb:<br>
   case llvm::Triple::thumbeb:<br>
     if (TargetEnvironment == llvm::Triple::GNUEABIHF) {<br>
-      if (llvm::sys::fs::exists(SysRoot + "/lib/armeb-linux-gnueabihf"))<br>
+      if (D.getVFS().exists(SysRoot + "/lib/armeb-linux-gnueabihf"))<br>
         return "armeb-linux-gnueabihf";<br>
     } else {<br>
-      if (llvm::sys::fs::exists(SysRoot + "/lib/armeb-linux-gnueabi"))<br>
+      if (D.getVFS().exists(SysRoot + "/lib/armeb-linux-gnueabi"))<br>
         return "armeb-linux-gnueabi";<br>
     }<br>
     break;<br>
   case llvm::Triple::x86:<br>
-    if (llvm::sys::fs::exists(SysRoot + "/lib/i386-linux-gnu"))<br>
+    if (D.getVFS().exists(SysRoot + "/lib/i386-linux-gnu"))<br>
       return "i386-linux-gnu";<br>
     break;<br>
   case llvm::Triple::x86_64:<br>
     // We don't want this for x32, otherwise it will match x86_64 libs<br>
     if (TargetEnvironment != llvm::Triple::GNUX32 &&<br>
-        llvm::sys::fs::exists(SysRoot + "/lib/x86_64-linux-gnu"))<br>
+        D.getVFS().exists(SysRoot + "/lib/x86_64-linux-gnu"))<br>
       return "x86_64-linux-gnu";<br>
     break;<br>
   case llvm::Triple::aarch64:<br>
-    if (llvm::sys::fs::exists(SysRoot + "/lib/aarch64-linux-gnu"))<br>
+    if (D.getVFS().exists(SysRoot + "/lib/aarch64-linux-gnu"))<br>
       return "aarch64-linux-gnu";<br>
     break;<br>
   case llvm::Triple::aarch64_be:<br>
-    if (llvm::sys::fs::exists(SysRoot + "/lib/aarch64_be-linux-gnu"))<br>
+    if (D.getVFS().exists(SysRoot + "/lib/aarch64_be-linux-gnu"))<br>
       return "aarch64_be-linux-gnu";<br>
     break;<br>
   case llvm::Triple::mips:<br>
-    if (llvm::sys::fs::exists(SysRoot + "/lib/mips-linux-gnu"))<br>
+    if (D.getVFS().exists(SysRoot + "/lib/mips-linux-gnu"))<br>
       return "mips-linux-gnu";<br>
     break;<br>
   case llvm::Triple::mipsel:<br>
-    if (llvm::sys::fs::exists(SysRoot + "/lib/mipsel-linux-gnu"))<br>
+    if (D.getVFS().exists(SysRoot + "/lib/mipsel-linux-gnu"))<br>
       return "mipsel-linux-gnu";<br>
     break;<br>
   case llvm::Triple::mips64:<br>
-    if (llvm::sys::fs::exists(SysRoot + "/lib/mips64-linux-gnu"))<br>
+    if (D.getVFS().exists(SysRoot + "/lib/mips64-linux-gnu"))<br>
       return "mips64-linux-gnu";<br>
-    if (llvm::sys::fs::exists(SysRoot + "/lib/mips64-linux-gnuabi64"))<br>
+    if (D.getVFS().exists(SysRoot + "/lib/mips64-linux-gnuabi64"))<br>
       return "mips64-linux-gnuabi64";<br>
     break;<br>
   case llvm::Triple::mips64el:<br>
-    if (llvm::sys::fs::exists(SysRoot + "/lib/mips64el-linux-gnu"))<br>
+    if (D.getVFS().exists(SysRoot + "/lib/mips64el-linux-gnu"))<br>
       return "mips64el-linux-gnu";<br>
-    if (llvm::sys::fs::exists(SysRoot + "/lib/mips64el-linux-gnuabi64"))<br>
+    if (D.getVFS().exists(SysRoot + "/lib/mips64el-linux-gnuabi64"))<br>
       return "mips64el-linux-gnuabi64";<br>
     break;<br>
   case llvm::Triple::ppc:<br>
-    if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc-linux-gnuspe"))<br>
+    if (D.getVFS().exists(SysRoot + "/lib/powerpc-linux-gnuspe"))<br>
       return "powerpc-linux-gnuspe";<br>
-    if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc-linux-gnu"))<br>
+    if (D.getVFS().exists(SysRoot + "/lib/powerpc-linux-gnu"))<br>
       return "powerpc-linux-gnu";<br>
     break;<br>
   case llvm::Triple::ppc64:<br>
-    if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc64-linux-gnu"))<br>
+    if (D.getVFS().exists(SysRoot + "/lib/powerpc64-linux-gnu"))<br>
       return "powerpc64-linux-gnu";<br>
     break;<br>
   case llvm::Triple::ppc64le:<br>
-    if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc64le-linux-gnu"))<br>
+    if (D.getVFS().exists(SysRoot + "/lib/powerpc64le-linux-gnu"))<br>
       return "powerpc64le-linux-gnu";<br>
     break;<br>
   case llvm::Triple::sparc:<br>
-    if (llvm::sys::fs::exists(SysRoot + "/lib/sparc-linux-gnu"))<br>
+    if (D.getVFS().exists(SysRoot + "/lib/sparc-linux-gnu"))<br>
       return "sparc-linux-gnu";<br>
     break;<br>
   case llvm::Triple::sparcv9:<br>
-    if (llvm::sys::fs::exists(SysRoot + "/lib/sparc64-linux-gnu"))<br>
+    if (D.getVFS().exists(SysRoot + "/lib/sparc64-linux-gnu"))<br>
       return "sparc64-linux-gnu";<br>
     break;<br>
   case llvm::Triple::systemz:<br>
-    if (llvm::sys::fs::exists(SysRoot + "/lib/s390x-linux-gnu"))<br>
+    if (D.getVFS().exists(SysRoot + "/lib/s390x-linux-gnu"))<br>
       return "s390x-linux-gnu";<br>
     break;<br>
   }<br>
@@ -3294,8 +3298,8 @@ static StringRef getOSLibDir(const llvm:<br>
<br>
 Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)<br>
     : Generic_ELF(D, Triple, Args) {<br>
-  GCCInstallation.init(D, Triple, Args);<br>
-  CudaInstallation.init(D, Triple, Args);<br>
+  GCCInstallation.init(Triple, Args);<br>
+  CudaInstallation.init(Triple, Args);<br>
   Multilibs = GCCInstallation.getMultilibs();<br>
   llvm::Triple::ArchType Arch = Triple.getArch();<br>
   std::string SysRoot = computeSysRoot();<br>
@@ -3315,7 +3319,7 @@ Linux::Linux(const Driver &D, const llvm<br>
<br>
   Linker = GetLinkerPath();<br>
<br>
-  Distro Distro = DetectDistro(Arch);<br>
+  Distro Distro = DetectDistro(D, Arch);<br>
<br>
   if (IsOpenSUSE(Distro) || IsUbuntu(Distro)) {<br>
     ExtraOpts.push_back("-z");<br>
@@ -3365,7 +3369,7 @@ Linux::Linux(const Driver &D, const llvm<br>
   path_list &Paths = getFilePaths();<br>
<br>
   const std::string OSLibDir = getOSLibDir(Triple, Args);<br>
-  const std::string MultiarchTriple = getMultiarchTriple(Triple, SysRoot);<br>
+  const std::string MultiarchTriple = getMultiarchTriple(D, Triple, SysRoot);<br>
<br>
   // Add the multilib suffixed paths where they are available.<br>
   if (GCCInstallation.isValid()) {<br>
@@ -3375,7 +3379,7 @@ Linux::Linux(const Driver &D, const llvm<br>
<br>
     // Sourcery CodeBench MIPS toolchain holds some libraries under<br>
     // a biarch-like suffix of the GCC installation.<br>
-    addPathIfExists((GCCInstallation.getInstallPath() + Multilib.gccSuffix()),<br>
+    addPathIfExists(D, GCCInstallation.getInstallPath() + Multilib.gccSuffix(),<br>
                     Paths);<br>
<br>
     // GCC cross compiling toolchains will install target libraries which ship<br>
@@ -3396,8 +3400,8 @@ Linux::Linux(const Driver &D, const llvm<br>
     //<br>
     // Note that this matches the GCC behavior. See the below comment for where<br>
     // Clang diverges from GCC's behavior.<br>
-    addPathIfExists(LibPath + "/../" + GCCTriple.str() + "/lib/../" + OSLibDir +<br>
-                        Multilib.osSuffix(),<br>
+    addPathIfExists(D, LibPath + "/../" + GCCTriple.str() + "/lib/../" +<br>
+                           OSLibDir + Multilib.osSuffix(),<br>
                     Paths);<br>
<br>
     // If the GCC installation we found is inside of the sysroot, we want to<br>
@@ -3410,8 +3414,8 @@ Linux::Linux(const Driver &D, const llvm<br>
     // configurations but this seems somewhere between questionable and simply<br>
     // a bug.<br>
     if (StringRef(LibPath).startswith(SysRoot)) {<br>
-      addPathIfExists(LibPath + "/" + MultiarchTriple, Paths);<br>
-      addPathIfExists(LibPath + "/../" + OSLibDir, Paths);<br>
+      addPathIfExists(D, LibPath + "/" + MultiarchTriple, Paths);<br>
+      addPathIfExists(D, LibPath + "/../" + OSLibDir, Paths);<br>
     }<br>
   }<br>
<br>
@@ -3421,27 +3425,29 @@ Linux::Linux(const Driver &D, const llvm<br>
   // FIXME: It's not clear whether we should use the driver's installed<br>
   // directory ('Dir' below) or the ResourceDir.<br>
   if (StringRef(D.Dir).startswith(SysRoot)) {<br>
-    addPathIfExists(D.Dir + "/../lib/" + MultiarchTriple, Paths);<br>
-    addPathIfExists(D.Dir + "/../" + OSLibDir, Paths);<br>
+    addPathIfExists(D, D.Dir + "/../lib/" + MultiarchTriple, Paths);<br>
+    addPathIfExists(D, D.Dir + "/../" + OSLibDir, Paths);<br>
   }<br>
<br>
-  addPathIfExists(SysRoot + "/lib/" + MultiarchTriple, Paths);<br>
-  addPathIfExists(SysRoot + "/lib/../" + OSLibDir, Paths);<br>
-  addPathIfExists(SysRoot + "/usr/lib/" + MultiarchTriple, Paths);<br>
-  addPathIfExists(SysRoot + "/usr/lib/../" + OSLibDir, Paths);<br>
+  addPathIfExists(D, SysRoot + "/lib/" + MultiarchTriple, Paths);<br>
+  addPathIfExists(D, SysRoot + "/lib/../" + OSLibDir, Paths);<br>
+  addPathIfExists(D, SysRoot + "/usr/lib/" + MultiarchTriple, Paths);<br>
+  addPathIfExists(D, SysRoot + "/usr/lib/../" + OSLibDir, Paths);<br>
<br>
   // Try walking via the GCC triple path in case of biarch or multiarch GCC<br>
   // installations with strange symlinks.<br>
   if (GCCInstallation.isValid()) {<br>
-    addPathIfExists(SysRoot + "/usr/lib/" + GCCInstallation.getTriple().str() +<br>
+    addPathIfExists(D,<br>
+                    SysRoot + "/usr/lib/" + GCCInstallation.getTriple().str() +<br>
                         "/../../" + OSLibDir,<br>
                     Paths);<br>
<br>
     // Add the 'other' biarch variant path<br>
     Multilib BiarchSibling;<br>
     if (GCCInstallation.getBiarchSibling(BiarchSibling)) {<br>
-      addPathIfExists(<br>
-          GCCInstallation.getInstallPath() + BiarchSibling.gccSuffix(), Paths);<br>
+      addPathIfExists(D, GCCInstallation.getInstallPath() +<br>
+                             BiarchSibling.gccSuffix(),<br>
+                      Paths);<br>
     }<br>
<br>
     // See comments above on the multilib variant for details of why this is<br>
@@ -3449,14 +3455,14 @@ Linux::Linux(const Driver &D, const llvm<br>
     const std::string &LibPath = GCCInstallation.getParentLibPath();<br>
     const llvm::Triple &GCCTriple = GCCInstallation.getTriple();<br>
     const Multilib &Multilib = GCCInstallation.getMultilib();<br>
-    addPathIfExists(LibPath + "/../" + GCCTriple.str() + "/lib" +<br>
-                        Multilib.osSuffix(),<br>
+    addPathIfExists(D, LibPath + "/../" + GCCTriple.str() + "/lib" +<br>
+                           Multilib.osSuffix(),<br>
                     Paths);<br>
<br>
     // See comments above on the multilib variant for details of why this is<br>
     // only included from within the sysroot.<br>
     if (StringRef(LibPath).startswith(SysRoot))<br>
-      addPathIfExists(LibPath, Paths);<br>
+      addPathIfExists(D, LibPath, Paths);<br>
   }<br>
<br>
   // Similar to the logic for GCC above, if we are currently running Clang<br>
@@ -3465,10 +3471,10 @@ Linux::Linux(const Driver &D, const llvm<br>
   // FIXME: It's not clear whether we should use the driver's installed<br>
   // directory ('Dir' below) or the ResourceDir.<br>
   if (StringRef(D.Dir).startswith(SysRoot))<br>
-    addPathIfExists(D.Dir + "/../lib", Paths);<br>
+    addPathIfExists(D, D.Dir + "/../lib", Paths);<br>
<br>
-  addPathIfExists(SysRoot + "/lib", Paths);<br>
-  addPathIfExists(SysRoot + "/usr/lib", Paths);<br>
+  addPathIfExists(D, SysRoot + "/lib", Paths);<br>
+  addPathIfExists(D, SysRoot + "/usr/lib", Paths);<br>
 }<br>
<br>
 bool Linux::HasNativeLLVMSupport() const { return true; }<br>
@@ -3498,12 +3504,12 @@ std::string Linux::computeSysRoot() cons<br>
       (InstallDir + "/../../../../" + TripleStr + "/libc" + Multilib.osSuffix())<br>
           .str();<br>
<br>
-  if (llvm::sys::fs::exists(Path))<br>
+  if (getVFS().exists(Path))<br>
     return Path;<br>
<br>
   Path = (InstallDir + "/../../../../sysroot" + Multilib.osSuffix()).str();<br>
<br>
-  if (llvm::sys::fs::exists(Path))<br>
+  if (getVFS().exists(Path))<br>
     return Path;<br>
<br>
   return std::string();<br>
@@ -3651,7 +3657,7 @@ void Linux::AddClangSystemIncludeArgs(co<br>
     break;<br>
   }<br>
   for (StringRef Dir : MultiarchIncludeDirs) {<br>
-    if (llvm::sys::fs::exists(SysRoot + Dir)) {<br>
+    if (D.getVFS().exists(SysRoot + Dir)) {<br>
       addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + Dir);<br>
       break;<br>
     }<br>
@@ -3669,11 +3675,11 @@ void Linux::AddClangSystemIncludeArgs(co<br>
 }<br>
<br>
 /// \brief Helper to add the variant paths of a libstdc++ installation.<br>
-/*static*/ bool Linux::addLibStdCXXIncludePaths(<br>
+bool Linux::addLibStdCXXIncludePaths(<br>
     Twine Base, Twine Suffix, StringRef GCCTriple, StringRef GCCMultiarchTriple,<br>
     StringRef TargetMultiarchTriple, Twine IncludeSuffix,<br>
-    const ArgList &DriverArgs, ArgStringList &CC1Args) {<br>
-  if (!llvm::sys::fs::exists(Base + Suffix))<br>
+    const ArgList &DriverArgs, ArgStringList &CC1Args) const {<br>
+  if (!getVFS().exists(Base + Suffix))<br>
     return false;<br>
<br>
   addSystemInclude(DriverArgs, CC1Args, Base + Suffix);<br>
@@ -3682,7 +3688,7 @@ void Linux::AddClangSystemIncludeArgs(co<br>
   // that path exists or we have neither a GCC nor target multiarch triple, use<br>
   // this vanilla search path.<br>
   if ((GCCMultiarchTriple.empty() && TargetMultiarchTriple.empty()) ||<br>
-      llvm::sys::fs::exists(Base + Suffix + "/" + GCCTriple + IncludeSuffix)) {<br>
+      getVFS().exists(Base + Suffix + "/" + GCCTriple + IncludeSuffix)) {<br>
     addSystemInclude(DriverArgs, CC1Args,<br>
                      Base + Suffix + "/" + GCCTriple + IncludeSuffix);<br>
   } else {<br>
@@ -3720,7 +3726,7 @@ void Linux::AddClangCXXStdlibIncludeArgs<br>
         // FIXME: We should really remove this. It doesn't make any sense.<br>
         getDriver().SysRoot + "/usr/include/c++/v1"};<br>
     for (const auto &IncludePath : LibCXXIncludePathCandidates) {<br>
-      if (!llvm::sys::fs::exists(IncludePath))<br>
+      if (!getVFS().exists(IncludePath))<br>
         continue;<br>
       // Add the first candidate that exists.<br>
       addSystemInclude(DriverArgs, CC1Args, IncludePath);<br>
@@ -3741,10 +3747,10 @@ void Linux::AddClangCXXStdlibIncludeArgs<br>
   StringRef InstallDir = GCCInstallation.getInstallPath();<br>
   StringRef TripleStr = GCCInstallation.getTriple().str();<br>
   const Multilib &Multilib = GCCInstallation.getMultilib();<br>
-  const std::string GCCMultiarchTriple =<br>
-      getMultiarchTriple(GCCInstallation.getTriple(), getDriver().SysRoot);<br>
+  const std::string GCCMultiarchTriple = getMultiarchTriple(<br>
+      getDriver(), GCCInstallation.getTriple(), getDriver().SysRoot);<br>
   const std::string TargetMultiarchTriple =<br>
-      getMultiarchTriple(getTriple(), getDriver().SysRoot);<br>
+      getMultiarchTriple(getDriver(), getTriple(), getDriver().SysRoot);<br>
   const GCCVersion &Version = GCCInstallation.getVersion();<br>
<br>
   // The primary search for libstdc++ supports multiarch variants.<br>
@@ -3821,7 +3827,7 @@ DragonFly::DragonFly(const Driver &D, co<br>
<br>
   getFilePaths().push_back(getDriver().Dir + "/../lib");<br>
   getFilePaths().push_back("/usr/lib");<br>
-  if (llvm::sys::fs::exists("/usr/lib/gcc47"))<br>
+  if (D.getVFS().exists("/usr/lib/gcc47"))<br>
     getFilePaths().push_back("/usr/lib/gcc47");<br>
   else<br>
     getFilePaths().push_back("/usr/lib/gcc44");<br>
@@ -3973,7 +3979,7 @@ MyriadToolChain::MyriadToolChain(const D<br>
   case llvm::Triple::sparc:<br>
   case llvm::Triple::sparcel:<br>
   case llvm::Triple::shave:<br>
-    GCCInstallation.init(D, Triple, Args, {"sparc-myriad-elf"});<br>
+    GCCInstallation.init(Triple, Args, {"sparc-myriad-elf"});<br>
   }<br>
 }<br>
<br>
<br>
Modified: cfe/trunk/lib/Driver/ToolChains.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains.h?rev=249556&r1=249555&r2=249556&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains.h?rev=249556&r1=249555&r2=249556&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Driver/ToolChains.h (original)<br>
+++ cfe/trunk/lib/Driver/ToolChains.h Wed Oct  7 10:48:01 2015<br>
@@ -78,6 +78,7 @@ public:<br>
   class GCCInstallationDetector {<br>
     bool IsValid;<br>
     llvm::Triple GCCTriple;<br>
+    const Driver &D;<br>
<br>
     // FIXME: These might be better as path objects.<br>
     std::string GCCInstallPath;<br>
@@ -99,9 +100,8 @@ public:<br>
     MultilibSet Multilibs;<br>
<br>
   public:<br>
-    GCCInstallationDetector() : IsValid(false) {}<br>
-    void init(const Driver &D, const llvm::Triple &TargetTriple,<br>
-              const llvm::opt::ArgList &Args,<br>
+    explicit GCCInstallationDetector(const Driver &D) : IsValid(false), D(D) {}<br>
+    void init(const llvm::Triple &TargetTriple, const llvm::opt::ArgList &Args,<br>
               ArrayRef<std::string> ExtraTripleAliases = None);<br>
<br>
     /// \brief Check whether we detected a valid GCC install.<br>
@@ -161,15 +161,15 @@ protected:<br>
<br>
   class CudaInstallationDetector {<br>
     bool IsValid;<br>
+    const Driver &D;<br>
     std::string CudaInstallPath;<br>
     std::string CudaLibPath;<br>
     std::string CudaLibDevicePath;<br>
     std::string CudaIncludePath;<br>
<br>
   public:<br>
-    CudaInstallationDetector() : IsValid(false) {}<br>
-    void init(const Driver &D, const llvm::Triple &TargetTriple,<br>
-              const llvm::opt::ArgList &Args);<br>
+    CudaInstallationDetector(const Driver &D) : IsValid(false), D(D) {}<br>
+    void init(const llvm::Triple &TargetTriple, const llvm::opt::ArgList &Args);<br>
<br>
     /// \brief Check whether we detected a valid Cuda install.<br>
     bool isValid() const { return IsValid; }<br>
@@ -733,13 +733,12 @@ protected:<br>
   Tool *buildLinker() const override;<br>
<br>
 private:<br>
-  static bool addLibStdCXXIncludePaths(Twine Base, Twine Suffix,<br>
-                                       StringRef GCCTriple,<br>
-                                       StringRef GCCMultiarchTriple,<br>
-                                       StringRef TargetMultiarchTriple,<br>
-                                       Twine IncludeSuffix,<br>
-                                       const llvm::opt::ArgList &DriverArgs,<br>
-                                       llvm::opt::ArgStringList &CC1Args);<br>
+  bool addLibStdCXXIncludePaths(Twine Base, Twine Suffix, StringRef GCCTriple,<br>
+                                StringRef GCCMultiarchTriple,<br>
+                                StringRef TargetMultiarchTriple,<br>
+                                Twine IncludeSuffix,<br>
+                                const llvm::opt::ArgList &DriverArgs,<br>
+                                llvm::opt::ArgStringList &CC1Args) const;<br>
<br>
   std::string computeSysRoot() const;<br>
 };<br>
@@ -777,8 +776,8 @@ public:<br>
<br>
   StringRef GetGCCLibAndIncVersion() const { return GCCLibAndIncVersion.Text; }<br>
<br>
-  static std::string GetGnuDir(const std::string &InstalledDir,<br>
-                               const llvm::opt::ArgList &Args);<br>
+  std::string GetGnuDir(const std::string &InstalledDir,<br>
+                        const llvm::opt::ArgList &Args) const;<br>
<br>
   static StringRef GetTargetCPU(const llvm::opt::ArgList &Args);<br>
<br>
<br>
Modified: cfe/trunk/lib/Driver/Tools.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=249556&r1=249555&r2=249556&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=249556&r1=249555&r2=249556&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Driver/Tools.cpp (original)<br>
+++ cfe/trunk/lib/Driver/Tools.cpp Wed Oct  7 10:48:01 2015<br>
@@ -5955,8 +5955,7 @@ constructHexagonLinkArgs(Compilation &C,<br>
   const std::string MarchSuffix = "/" + MarchString;<br>
   const std::string G0Suffix = "/G0";<br>
   const std::string MarchG0Suffix = MarchSuffix + G0Suffix;<br>
-  const std::string RootDir =<br>
-      toolchains::HexagonToolChain::GetGnuDir(D.InstalledDir, Args) + "/";<br>
+  const std::string RootDir = ToolChain.GetGnuDir(D.InstalledDir, Args) + "/";<br>
   const std::string StartFilesDir =<br>
       RootDir + "hexagon/lib" + (useG0 ? MarchG0Suffix : MarchSuffix);<br>
<br>
<br>
Modified: cfe/trunk/unittests/Driver/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Driver/CMakeLists.txt?rev=249556&r1=249555&r2=249556&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Driver/CMakeLists.txt?rev=249556&r1=249555&r2=249556&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/unittests/Driver/CMakeLists.txt (original)<br>
+++ cfe/trunk/unittests/Driver/CMakeLists.txt Wed Oct  7 10:48:01 2015<br>
@@ -3,6 +3,7 @@ set(LLVM_LINK_COMPONENTS<br>
   )<br>
<br>
 add_clang_unittest(ClangDriverTests<br>
+  ToolChainTest.cpp<br>
   MultilibTest.cpp<br>
   )<br>
<br>
<br>
Added: cfe/trunk/unittests/Driver/ToolChainTest.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Driver/ToolChainTest.cpp?rev=249556&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Driver/ToolChainTest.cpp?rev=249556&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/unittests/Driver/ToolChainTest.cpp (added)<br>
+++ cfe/trunk/unittests/Driver/ToolChainTest.cpp Wed Oct  7 10:48:01 2015<br>
@@ -0,0 +1,74 @@<br>
+//===- unittests/Driver/ToolChainTest.cpp --- ToolChain tests -------------===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// Unit tests for ToolChains.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#include "clang/Driver/ToolChain.h"<br>
+#include "clang/Basic/DiagnosticIDs.h"<br>
+#include "clang/Basic/DiagnosticOptions.h"<br>
+#include "clang/Basic/LLVM.h"<br>
+#include "clang/Basic/VirtualFileSystem.h"<br>
+#include "clang/Driver/Compilation.h"<br>
+#include "clang/Driver/Driver.h"<br>
+#include "llvm/Support/raw_ostream.h"<br>
+#include "gtest/gtest.h"<br>
+using namespace clang;<br>
+using namespace clang::driver;<br>
+<br>
+namespace {<br>
+<br>
+TEST(ToolChainTest, VFSGCCInstallation) {<br>
+  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();<br>
+<br>
+  IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());<br>
+  struct TestDiagnosticConsumer : public DiagnosticConsumer {};<br>
+  DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);<br>
+  IntrusiveRefCntPtr<vfs::InMemoryFileSystem> InMemoryFileSystem(<br>
+      new vfs::InMemoryFileSystem);<br>
+  Driver TheDriver("/usr/bin/clang", "arm-linux-gnueabihf", Diags,<br>
+                   InMemoryFileSystem);<br>
+<br>
+  const char *EmptyFiles[] = {<br>
+      "foo.cpp",<br>
+      "/usr/bin/clang",<br>
+      "/usr/lib/gcc/arm-linux-gnueabi/4.6.1/crtbegin.o",<br>
+      "/usr/lib/gcc/arm-linux-gnueabi/4.6.1/crtend.o",<br>
+      "/usr/lib/gcc/arm-linux-gnueabihf/4.6.3/crtbegin.o",<br>
+      "/usr/lib/gcc/arm-linux-gnueabihf/4.6.3/crtend.o",<br>
+      "/usr/lib/arm-linux-gnueabi/crt1.o",<br>
+      "/usr/lib/arm-linux-gnueabi/crti.o",<br>
+      "/usr/lib/arm-linux-gnueabi/crtn.o",<br>
+      "/usr/lib/arm-linux-gnueabihf/crt1.o",<br>
+      "/usr/lib/arm-linux-gnueabihf/crti.o",<br>
+      "/usr/lib/arm-linux-gnueabihf/crtn.o",<br>
+      "/usr/include/arm-linux-gnueabi/.keep",<br>
+      "/usr/include/arm-linux-gnueabihf/.keep",<br>
+      "/lib/arm-linux-gnueabi/.keep",<br>
+      "/lib/arm-linux-gnueabihf/.keep"};<br>
+<br>
+  for (const char *Path : EmptyFiles)<br>
+    InMemoryFileSystem->addFile(Path, 0,<br>
+                                llvm::MemoryBuffer::getMemBuffer("\n"));<br>
+<br>
+  std::unique_ptr<Compilation> C(<br>
+      TheDriver.BuildCompilation({"-fsyntax-only", "foo.cpp"}));<br>
+<br>
+  std::string S;<br>
+  {<br>
+    llvm::raw_string_ostream OS(S);<br>
+    C->getDefaultToolChain().printVerboseInfo(OS);<br>
+  }<br>
+  EXPECT_EQ("Found candidate GCC installation: "<br>
+            "/usr/lib/gcc/arm-linux-gnueabihf/4.6.3\n",<br>
+            S);<br>
+}<br>
+<br>
+} // end anonymous namespace<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>