r249556 - [VFS] Port driver tool chains to VFS.

Jan Vesely via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 7 13:09:50 PDT 2015


This change breaks cmake build:
undefined reference to `clang::DiagnosticIDs::DiagnosticIDs()'
/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)'
/home/jvesely/llvm/tools/clang/unittests/Driver/ToolChainTest.cpp:35:
undefined reference to
`clang::vfs::InMemoryFileSystem::InMemoryFileSystem()'
/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> >)'
/home/jvesely/llvm/tools/clang/unittests/Driver/ToolChainTest.cpp:33:
undefined reference to `clang::DiagnosticsEngine::~DiagnosticsEngine()'
CMakeFiles/ClangDriverTests.dir/ToolChainTest.cpp.o: In function
`~TestDiagnosticConsumer':
/home/jvesely/llvm/tools/clang/unittests/Driver/ToolChainTest.cpp:32:
undefined reference to `clang::DiagnosticConsumer::~DiagnosticConsumer()'
CMakeFiles/ClangDriverTests.dir/ToolChainTest.cpp.o: In function
`clang::DiagnosticConsumer::DiagnosticConsumer()':
/home/jvesely/llvm/tools/clang/include/clang/Basic/Diagnostic.h:1313:
undefined reference to `vtable for clang::DiagnosticConsumer'
CMakeFiles/ClangDriverTests.dir/ToolChainTest.cpp.o: In function
`llvm::RefCountedBase<clang::DiagnosticIDs>::Release() const':
/home/jvesely/llvm/include/llvm/ADT/IntrusiveRefCntPtr.h:54: undefined
reference to `clang::DiagnosticIDs::~DiagnosticIDs()'
CMakeFiles/ClangDriverTests.dir/ToolChainTest.cpp.o:(.data.rel.ro+0x80):
undefined reference to
`clang::DiagnosticConsumer::IncludeInDiagnosticCounts() const'
CMakeFiles/ClangDriverTests.dir/ToolChainTest.cpp.o:(.data.rel.ro+0x88):
undefined reference to
`clang::DiagnosticConsumer::HandleDiagnostic(clang::DiagnosticsEngine::Level,
clang::Diagnostic const&)'
collect2: error: ld returned 1 exit status

using Diagnostics requires linking to libclangBasic. Please consider the
attached patch.

BR,
Jan



On Wed, Oct 7, 2015 at 10:48 AM, Benjamin Kramer via cfe-commits <
cfe-commits at lists.llvm.org> wrote:

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


More information about the cfe-commits mailing list