diff --git a/lib/Basic/VirtualFileSystem.cpp b/lib/Basic/VirtualFileSystem.cpp
new file mode 100644
index 0000000..9a88cfd
--- /dev/null
+++ b/lib/Basic/VirtualFileSystem.cpp
@@ -0,0 +1,841 @@
+//===- VirtualFileSystem.cpp - Virtual File System Layer --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// This file implements the VirtualFileSystem interface.
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/VirtualFileSystem.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/YAMLParser.h"
+#include <atomic>
+#include <memory>
+
+using namespace clang;
+using namespace clang::vfs;
+using namespace llvm;
+using llvm::sys::fs::file_status;
+using llvm::sys::fs::file_type;
+using llvm::sys::fs::perms;
+using llvm::sys::fs::UniqueID;
+
+Status::Status(const file_status &Status)
+    : UID(Status.getUniqueID()), MTime(Status.getLastModificationTime()),
+      User(Status.getUser()), Group(Status.getGroup()), Size(Status.getSize()),
+      Type(Status.type()), Perms(Status.permissions()) {}
+
+Status::Status(StringRef Name, StringRef ExternalName, UniqueID UID,
+               sys::TimeValue MTime, uint32_t User, uint32_t Group,
+               uint64_t Size, file_type Type, perms Perms)
+    : Name(Name), UID(UID), MTime(MTime), User(User), Group(Group), Size(Size),
+      Type(Type), Perms(Perms) {}
+
+bool Status::equivalent(const Status &Other) const {
+  return getUniqueID() == Other.getUniqueID();
+}
+bool Status::isDirectory() const {
+  return Type == file_type::directory_file;
+}
+bool Status::isRegularFile() const {
+  return Type == file_type::regular_file;
+}
+bool Status::isOther() const {
+  return exists() && !isRegularFile() && !isDirectory() && !isSymlink();
+}
+bool Status::isSymlink() const {
+  return Type == file_type::symlink_file;
+}
+bool Status::isStatusKnown() const {
+  return Type != file_type::status_error;
+}
+bool Status::exists() const {
+  return isStatusKnown() && Type != file_type::file_not_found;
+}
+
+File::~File() {}
+
+FileSystem::~FileSystem() {}
+
+error_code FileSystem::getBufferForFile(const llvm::Twine &Name,
+                                        std::unique_ptr<MemoryBuffer> &Result,
+                                        int64_t FileSize,
+                                        bool RequiresNullTerminator) {
+  std::unique_ptr<File> F;
+  if (error_code EC = openFileForRead(Name, F))
+    return EC;
+
+  error_code EC = F->getBuffer(Name, Result, FileSize, RequiresNullTerminator);
+  return EC;
+}
+
+//===-----------------------------------------------------------------------===/
+// RealFileSystem implementation
+//===-----------------------------------------------------------------------===/
+
+namespace {
+/// \brief Wrapper around a raw file descriptor.
+class RealFile : public File {
+  int FD;
+  Status S;
+  friend class RealFileSystem;
+  RealFile(int FD) : FD(FD) {
+    assert(FD >= 0 && "Invalid or inactive file descriptor");
+  }
+
+public:
+  ~RealFile();
+  ErrorOr<Status> status() override;
+  error_code getBuffer(const Twine &Name, std::unique_ptr<MemoryBuffer> &Result,
+                       int64_t FileSize = -1,
+                       bool RequiresNullTerminator = true) override;
+  error_code close() override;
+  void setName(StringRef Name) override;
+};
+} // end anonymous namespace
+RealFile::~RealFile() { close(); }
+
+ErrorOr<Status> RealFile::status() {
+  assert(FD != -1 && "cannot stat closed file");
+  if (!S.isStatusKnown()) {
+    file_status RealStatus;
+    if (error_code EC = sys::fs::status(FD, RealStatus))
+      return EC;
+    Status NewS(RealStatus);
+    NewS.setName(S.getName());
+    S = std::move(NewS);
+  }
+  return S;
+}
+
+error_code RealFile::getBuffer(const Twine &Name,
+                               std::unique_ptr<MemoryBuffer> &Result,
+                               int64_t FileSize, bool RequiresNullTerminator) {
+  assert(FD != -1 && "cannot get buffer for closed file");
+  return MemoryBuffer::getOpenFile(FD, Name.str().c_str(), Result, FileSize,
+                                   RequiresNullTerminator);
+}
+
+// FIXME: This is terrible, we need this for ::close.
+#if !defined(_MSC_VER) && !defined(__MINGW32__)
+#include <unistd.h>
+#include <sys/uio.h>
+#else
+#include <io.h>
+#ifndef S_ISFIFO
+#define S_ISFIFO(x) (0)
+#endif
+#endif
+error_code RealFile::close() {
+  if (::close(FD))
+    return error_code(errno, system_category());
+  FD = -1;
+  return error_code::success();
+}
+
+void RealFile::setName(StringRef Name) {
+  S.setName(Name);
+}
+
+namespace {
+/// \brief The file system according to your operating system.
+class RealFileSystem : public FileSystem {
+public:
+  ErrorOr<Status> status(const Twine &Path) override;
+  error_code openFileForRead(const Twine &Path,
+                             std::unique_ptr<File> &Result) override;
+};
+} // end anonymous namespace
+
+ErrorOr<Status> RealFileSystem::status(const Twine &Path) {
+  sys::fs::file_status RealStatus;
+  if (error_code EC = sys::fs::status(Path, RealStatus))
+    return EC;
+  Status Result(RealStatus);
+  Result.setName(Path.str());
+  return Result;
+}
+
+error_code RealFileSystem::openFileForRead(const Twine &Name,
+                                           std::unique_ptr<File> &Result) {
+  int FD;
+  if (error_code EC = sys::fs::openFileForRead(Name, FD))
+    return EC;
+  Result.reset(new RealFile(FD));
+  Result->setName(Name.str());
+  return error_code::success();
+}
+
+IntrusiveRefCntPtr<FileSystem> vfs::getRealFileSystem() {
+  static IntrusiveRefCntPtr<FileSystem> FS = new RealFileSystem();
+  return FS;
+}
+
+//===-----------------------------------------------------------------------===/
+// OverlayFileSystem implementation
+//===-----------------------------------------------------------------------===/
+OverlayFileSystem::OverlayFileSystem(IntrusiveRefCntPtr<FileSystem> BaseFS) {
+  pushOverlay(BaseFS);
+}
+
+void OverlayFileSystem::pushOverlay(IntrusiveRefCntPtr<FileSystem> FS) {
+  FSList.push_back(FS);
+}
+
+ErrorOr<Status> OverlayFileSystem::status(const Twine &Path) {
+  // FIXME: handle symlinks that cross file systems
+  for (iterator I = overlays_begin(), E = overlays_end(); I != E; ++I) {
+    ErrorOr<Status> Status = (*I)->status(Path);
+    if (Status || Status.getError() != errc::no_such_file_or_directory)
+      return Status;
+  }
+  return error_code(errc::no_such_file_or_directory, system_category());
+}
+
+error_code OverlayFileSystem::openFileForRead(const llvm::Twine &Path,
+                                              std::unique_ptr<File> &Result) {
+  // FIXME: handle symlinks that cross file systems
+  for (iterator I = overlays_begin(), E = overlays_end(); I != E; ++I) {
+    error_code EC = (*I)->openFileForRead(Path, Result);
+    if (!EC || EC != errc::no_such_file_or_directory)
+      return EC;
+  }
+  return error_code(errc::no_such_file_or_directory, system_category());
+}
+
+//===-----------------------------------------------------------------------===/
+// VFSFromYAML implementation
+//===-----------------------------------------------------------------------===/
+
+// Allow DenseMap<StringRef, ...>.  This is useful below because we know all the
+// strings are literals and will outlive the map, and there is no reason to
+// store them.
+namespace llvm {
+  template<>
+  struct DenseMapInfo<StringRef> {
+    // This assumes that "" will never be a valid key.
+    static inline StringRef getEmptyKey() { return StringRef(""); }
+    static inline StringRef getTombstoneKey() { return StringRef(); }
+    static unsigned getHashValue(StringRef Val) { return HashString(Val); }
+    static bool isEqual(StringRef LHS, StringRef RHS) { return LHS == RHS; }
+  };
+}
+
+namespace {
+
+enum EntryKind {
+  EK_Directory,
+  EK_File
+};
+
+/// \brief A single file or directory in the VFS.
+class Entry {
+  EntryKind Kind;
+  std::string Name;
+
+public:
+  virtual ~Entry();
+  Entry(EntryKind K, StringRef Name) : Kind(K), Name(Name) {}
+  StringRef getName() const { return Name; }
+  EntryKind getKind() const { return Kind; }
+};
+
+class DirectoryEntry : public Entry {
+  std::vector<Entry *> Contents;
+  Status S;
+
+public:
+  virtual ~DirectoryEntry();
+  DirectoryEntry(StringRef Name, std::vector<Entry *> Contents, Status S)
+      : Entry(EK_Directory, Name), Contents(std::move(Contents)),
+        S(std::move(S)) {}
+  Status getStatus() { return S; }
+  typedef std::vector<Entry *>::iterator iterator;
+  iterator contents_begin() { return Contents.begin(); }
+  iterator contents_end() { return Contents.end(); }
+  static bool classof(const Entry *E) { return E->getKind() == EK_Directory; }
+};
+
+class FileEntry : public Entry {
+public:
+  enum NameKind {
+    NK_NotSet,
+    NK_External,
+    NK_Virtual
+  };
+private:
+  std::string ExternalContentsPath;
+  NameKind UseName;
+public:
+  FileEntry(StringRef Name, StringRef ExternalContentsPath, NameKind UseName)
+      : Entry(EK_File, Name), ExternalContentsPath(ExternalContentsPath),
+        UseName(UseName) {}
+  StringRef getExternalContentsPath() const { return ExternalContentsPath; }
+  /// \brief whether to use the external path as the name for this file.
+  bool useExternalName(bool GlobalUseExternalName) const {
+    return UseName == NK_NotSet ? GlobalUseExternalName
+                                : (UseName == NK_External);
+  }
+  static bool classof(const Entry *E) { return E->getKind() == EK_File; }
+};
+
+/// \brief A virtual file system parsed from a YAML file.
+///
+/// Currently, this class allows creating virtual directories and mapping
+/// virtual file paths to existing external files, available in \c ExternalFS.
+///
+/// The basic structure of the parsed file is:
+/// \verbatim
+/// {
+///   'version': <version number>,
+///   <optional configuration>
+///   'roots': [
+///              <directory entries>
+///            ]
+/// }
+/// \endverbatim
+///
+/// All configuration options are optional.
+///   'case-sensitive': <boolean, default=true>
+///   'use-external-names': <boolean, default=true>
+///
+/// Virtual directories are represented as
+/// \verbatim
+/// {
+///   'type': 'directory',
+///   'name': <string>,
+///   'contents': [ <file or directory entries> ]
+/// }
+/// \endverbatim
+///
+/// The default attributes for virtual directories are:
+/// \verbatim
+/// MTime = now() when created
+/// Perms = 0777
+/// User = Group = 0
+/// Size = 0
+/// UniqueID = unspecified unique value
+/// \endverbatim
+///
+/// Re-mapped files are represented as
+/// \verbatim
+/// {
+///   'type': 'file',
+///   'name': <string>,
+///   'use-external-name': <boolean> # Optional
+///   'external-contents': <path to external file>)
+/// }
+/// \endverbatim
+///
+/// and inherit their attributes from the external contents.
+///
+/// In both cases, the 'name' field may contain multiple path components (e.g.
+/// /path/to/file). However, any directory that contains more than one child
+/// must be uniquely represented by a directory entry.
+class VFSFromYAML : public vfs::FileSystem {
+  std::vector<Entry *> Roots; ///< The root(s) of the virtual file system.
+  /// \brief The file system to use for external references.
+  IntrusiveRefCntPtr<FileSystem> ExternalFS;
+
+  /// @name Configuration
+  /// @{
+
+  /// \brief Whether to perform case-sensitive comparisons.
+  ///
+  /// Currently, case-insensitive matching only works correctly with ASCII.
+  bool CaseSensitive;
+
+  /// \brief Whether to use to use the value of 'external-contents' for the
+  /// names of files.  This global value is overridable on a per-file basis.
+  bool UseExternalNames;
+  /// @}
+
+  friend class VFSFromYAMLParser;
+
+private:
+  VFSFromYAML(IntrusiveRefCntPtr<FileSystem> ExternalFS)
+      : ExternalFS(ExternalFS), CaseSensitive(true), UseExternalNames(true) {}
+
+  /// \brief Looks up \p Path in \c Roots.
+  ErrorOr<Entry *> lookupPath(const Twine &Path);
+
+  /// \brief Looks up the path <tt>[Start, End)</tt> in \p From, possibly
+  /// recursing into the contents of \p From if it is a directory.
+  ErrorOr<Entry *> lookupPath(sys::path::const_iterator Start,
+                              sys::path::const_iterator End, Entry *From);
+
+public:
+  ~VFSFromYAML();
+
+  /// \brief Parses \p Buffer, which is expected to be in YAML format and
+  /// returns a virtual file system representing its contents.
+  ///
+  /// Takes ownership of \p Buffer.
+  static VFSFromYAML *create(MemoryBuffer *Buffer,
+                             SourceMgr::DiagHandlerTy DiagHandler,
+                             void *DiagContext,
+                             IntrusiveRefCntPtr<FileSystem> ExternalFS);
+
+  ErrorOr<Status> status(const Twine &Path) override;
+  error_code openFileForRead(const Twine &Path,
+                             std::unique_ptr<File> &Result) override;
+};
+
+/// \brief A helper class to hold the common YAML parsing state.
+class VFSFromYAMLParser {
+  yaml::Stream &Stream;
+
+  void error(yaml::Node *N, const Twine &Msg) {
+    Stream.printError(N, Msg);
+  }
+
+  // false on error
+  bool parseScalarString(yaml::Node *N, StringRef &Result,
+                         SmallVectorImpl<char> &Storage) {
+    yaml::ScalarNode *S = dyn_cast<yaml::ScalarNode>(N);
+    if (!S) {
+      error(N, "expected string");
+      return false;
+    }
+    Result = S->getValue(Storage);
+    return true;
+  }
+
+  // false on error
+  bool parseScalarBool(yaml::Node *N, bool &Result) {
+    SmallString<5> Storage;
+    StringRef Value;
+    if (!parseScalarString(N, Value, Storage))
+      return false;
+
+    if (Value.equals_lower("true") || Value.equals_lower("on") ||
+        Value.equals_lower("yes") || Value == "1") {
+      Result = true;
+      return true;
+    } else if (Value.equals_lower("false") || Value.equals_lower("off") ||
+               Value.equals_lower("no") || Value == "0") {
+      Result = false;
+      return true;
+    }
+
+    error(N, "expected boolean value");
+    return false;
+  }
+
+  struct KeyStatus {
+    KeyStatus(bool Required=false) : Required(Required), Seen(false) {}
+    bool Required;
+    bool Seen;
+  };
+  typedef std::pair<StringRef, KeyStatus> KeyStatusPair;
+
+  // false on error
+  bool checkDuplicateOrUnknownKey(yaml::Node *KeyNode, StringRef Key,
+                                  DenseMap<StringRef, KeyStatus> &Keys) {
+    if (!Keys.count(Key)) {
+      error(KeyNode, "unknown key");
+      return false;
+    }
+    KeyStatus &S = Keys[Key];
+    if (S.Seen) {
+      error(KeyNode, Twine("duplicate key '") + Key + "'");
+      return false;
+    }
+    S.Seen = true;
+    return true;
+  }
+
+  // false on error
+  bool checkMissingKeys(yaml::Node *Obj, DenseMap<StringRef, KeyStatus> &Keys) {
+    for (DenseMap<StringRef, KeyStatus>::iterator I = Keys.begin(),
+         E = Keys.end();
+         I != E; ++I) {
+      if (I->second.Required && !I->second.Seen) {
+        error(Obj, Twine("missing key '") + I->first + "'");
+        return false;
+      }
+    }
+    return true;
+  }
+
+  Entry *parseEntry(yaml::Node *N) {
+    yaml::MappingNode *M = dyn_cast<yaml::MappingNode>(N);
+    if (!M) {
+      error(N, "expected mapping node for file or directory entry");
+      return NULL;
+    }
+
+    KeyStatusPair Fields[] = {
+      KeyStatusPair("name", true),
+      KeyStatusPair("type", true),
+      KeyStatusPair("contents", false),
+      KeyStatusPair("external-contents", false),
+      KeyStatusPair("use-external-name", false),
+    };
+
+    DenseMap<StringRef, KeyStatus> Keys(
+        &Fields[0], Fields + sizeof(Fields)/sizeof(Fields[0]));
+
+    bool HasContents = false; // external or otherwise
+    std::vector<Entry *> EntryArrayContents;
+    std::string ExternalContentsPath;
+    std::string Name;
+    FileEntry::NameKind UseExternalName = FileEntry::NK_NotSet;
+    EntryKind Kind;
+
+    for (yaml::MappingNode::iterator I = M->begin(), E = M->end(); I != E;
+         ++I) {
+      StringRef Key;
+      // Reuse the buffer for key and value, since we don't look at key after
+      // parsing value.
+      SmallString<256> Buffer;
+      if (!parseScalarString(I->getKey(), Key, Buffer))
+        return NULL;
+
+      if (!checkDuplicateOrUnknownKey(I->getKey(), Key, Keys))
+        return NULL;
+
+      StringRef Value;
+      if (Key == "name") {
+        if (!parseScalarString(I->getValue(), Value, Buffer))
+          return NULL;
+        Name = Value;
+      } else if (Key == "type") {
+        if (!parseScalarString(I->getValue(), Value, Buffer))
+          return NULL;
+        if (Value == "file")
+          Kind = EK_File;
+        else if (Value == "directory")
+          Kind = EK_Directory;
+        else {
+          error(I->getValue(), "unknown value for 'type'");
+          return NULL;
+        }
+      } else if (Key == "contents") {
+        if (HasContents) {
+          error(I->getKey(),
+                "entry already has 'contents' or 'external-contents'");
+          return NULL;
+        }
+        HasContents = true;
+        yaml::SequenceNode *Contents =
+            dyn_cast<yaml::SequenceNode>(I->getValue());
+        if (!Contents) {
+          // FIXME: this is only for directories, what about files?
+          error(I->getValue(), "expected array");
+          return NULL;
+        }
+
+        for (yaml::SequenceNode::iterator I = Contents->begin(),
+                                          E = Contents->end();
+             I != E; ++I) {
+          if (Entry *E = parseEntry(&*I))
+            EntryArrayContents.push_back(E);
+          else
+            return NULL;
+        }
+      } else if (Key == "external-contents") {
+        if (HasContents) {
+          error(I->getKey(),
+                "entry already has 'contents' or 'external-contents'");
+          return NULL;
+        }
+        HasContents = true;
+        if (!parseScalarString(I->getValue(), Value, Buffer))
+          return NULL;
+        ExternalContentsPath = Value;
+      } else if (Key == "use-external-name") {
+        bool Val;
+        if (!parseScalarBool(I->getValue(), Val))
+          return NULL;
+        UseExternalName = Val ? FileEntry::NK_External : FileEntry::NK_Virtual;
+      } else {
+        llvm_unreachable("key missing from Keys");
+      }
+    }
+
+    if (Stream.failed())
+      return NULL;
+
+    // check for missing keys
+    if (!HasContents) {
+      error(N, "missing key 'contents' or 'external-contents'");
+      return NULL;
+    }
+    if (!checkMissingKeys(N, Keys))
+      return NULL;
+
+    // check invalid configuration
+    if (Kind == EK_Directory && UseExternalName != FileEntry::NK_NotSet) {
+      error(N, "'use-external-name' is not supported for directories");
+      return NULL;
+    }
+
+    // Remove trailing slash(es), being careful not to remove the root path
+    StringRef Trimmed(Name);
+    size_t RootPathLen = sys::path::root_path(Trimmed).size();
+    while (Trimmed.size() > RootPathLen &&
+           sys::path::is_separator(Trimmed.back()))
+      Trimmed = Trimmed.slice(0, Trimmed.size()-1);
+    // Get the last component
+    StringRef LastComponent = sys::path::filename(Trimmed);
+
+    Entry *Result = 0;
+    switch (Kind) {
+    case EK_File:
+      Result = new FileEntry(LastComponent, std::move(ExternalContentsPath),
+                             UseExternalName);
+      break;
+    case EK_Directory:
+      Result = new DirectoryEntry(LastComponent, std::move(EntryArrayContents),
+          Status("", "", getNextVirtualUniqueID(), sys::TimeValue::now(), 0, 0,
+                 0, file_type::directory_file, sys::fs::all_all));
+      break;
+    }
+
+    StringRef Parent = sys::path::parent_path(Trimmed);
+    if (Parent.empty())
+      return Result;
+
+    // if 'name' contains multiple components, create implicit directory entries
+    for (sys::path::reverse_iterator I = sys::path::rbegin(Parent),
+                                     E = sys::path::rend(Parent);
+         I != E; ++I) {
+      Result = new DirectoryEntry(*I, llvm::makeArrayRef(Result),
+          Status("", "", getNextVirtualUniqueID(), sys::TimeValue::now(), 0, 0,
+                 0, file_type::directory_file, sys::fs::all_all));
+    }
+    return Result;
+  }
+
+public:
+  VFSFromYAMLParser(yaml::Stream &S) : Stream(S) {}
+
+  // false on error
+  bool parse(yaml::Node *Root, VFSFromYAML *FS) {
+    yaml::MappingNode *Top = dyn_cast<yaml::MappingNode>(Root);
+    if (!Top) {
+      error(Root, "expected mapping node");
+      return false;
+    }
+
+    KeyStatusPair Fields[] = {
+      KeyStatusPair("version", true),
+      KeyStatusPair("case-sensitive", false),
+      KeyStatusPair("use-external-names", false),
+      KeyStatusPair("roots", true),
+    };
+
+    DenseMap<StringRef, KeyStatus> Keys(
+        &Fields[0], Fields + sizeof(Fields)/sizeof(Fields[0]));
+
+    // Parse configuration and 'roots'
+    for (yaml::MappingNode::iterator I = Top->begin(), E = Top->end(); I != E;
+         ++I) {
+      SmallString<10> KeyBuffer;
+      StringRef Key;
+      if (!parseScalarString(I->getKey(), Key, KeyBuffer))
+        return false;
+
+      if (!checkDuplicateOrUnknownKey(I->getKey(), Key, Keys))
+        return false;
+
+      if (Key == "roots") {
+        yaml::SequenceNode *Roots = dyn_cast<yaml::SequenceNode>(I->getValue());
+        if (!Roots) {
+          error(I->getValue(), "expected array");
+          return false;
+        }
+
+        for (yaml::SequenceNode::iterator I = Roots->begin(), E = Roots->end();
+             I != E; ++I) {
+          if (Entry *E = parseEntry(&*I))
+            FS->Roots.push_back(E);
+          else
+            return false;
+        }
+      } else if (Key == "version") {
+        StringRef VersionString;
+        SmallString<4> Storage;
+        if (!parseScalarString(I->getValue(), VersionString, Storage))
+          return false;
+        int Version;
+        if (VersionString.getAsInteger<int>(10, Version)) {
+          error(I->getValue(), "expected integer");
+          return false;
+        }
+        if (Version < 0) {
+          error(I->getValue(), "invalid version number");
+          return false;
+        }
+        if (Version != 0) {
+          error(I->getValue(), "version mismatch, expected 0");
+          return false;
+        }
+      } else if (Key == "case-sensitive") {
+        if (!parseScalarBool(I->getValue(), FS->CaseSensitive))
+          return false;
+      } else if (Key == "use-external-names") {
+        if (!parseScalarBool(I->getValue(), FS->UseExternalNames))
+          return false;
+      } else {
+        llvm_unreachable("key missing from Keys");
+      }
+    }
+
+    if (Stream.failed())
+      return false;
+
+    if (!checkMissingKeys(Top, Keys))
+      return false;
+    return true;
+  }
+};
+} // end of anonymous namespace
+
+Entry::~Entry() {}
+DirectoryEntry::~DirectoryEntry() { llvm::DeleteContainerPointers(Contents); }
+
+VFSFromYAML::~VFSFromYAML() { llvm::DeleteContainerPointers(Roots); }
+
+VFSFromYAML *VFSFromYAML::create(MemoryBuffer *Buffer,
+                                 SourceMgr::DiagHandlerTy DiagHandler,
+                                 void *DiagContext,
+                                 IntrusiveRefCntPtr<FileSystem> ExternalFS) {
+
+  SourceMgr SM;
+  yaml::Stream Stream(Buffer, SM);
+
+  SM.setDiagHandler(DiagHandler, DiagContext);
+  yaml::document_iterator DI = Stream.begin();
+  yaml::Node *Root = DI->getRoot();
+  if (DI == Stream.end() || !Root) {
+    SM.PrintMessage(SMLoc(), SourceMgr::DK_Error, "expected root node");
+    return NULL;
+  }
+
+  VFSFromYAMLParser P(Stream);
+
+  std::unique_ptr<VFSFromYAML> FS(new VFSFromYAML(ExternalFS));
+  if (!P.parse(Root, FS.get()))
+    return NULL;
+
+  return FS.release();
+}
+
+ErrorOr<Entry *> VFSFromYAML::lookupPath(const Twine &Path_) {
+  SmallString<256> Path;
+  Path_.toVector(Path);
+
+  // Handle relative paths
+  if (error_code EC = sys::fs::make_absolute(Path))
+    return EC;
+
+  if (Path.empty())
+    return error_code(errc::invalid_argument, system_category());
+
+  sys::path::const_iterator Start = sys::path::begin(Path);
+  sys::path::const_iterator End = sys::path::end(Path);
+  for (std::vector<Entry *>::iterator I = Roots.begin(), E = Roots.end();
+       I != E; ++I) {
+    ErrorOr<Entry *> Result = lookupPath(Start, End, *I);
+    if (Result || Result.getError() != errc::no_such_file_or_directory)
+      return Result;
+  }
+  return error_code(errc::no_such_file_or_directory, system_category());
+}
+
+ErrorOr<Entry *> VFSFromYAML::lookupPath(sys::path::const_iterator Start,
+                                         sys::path::const_iterator End,
+                                         Entry *From) {
+  if (Start->equals("."))
+    ++Start;
+
+  // FIXME: handle ..
+  if (CaseSensitive ? !Start->equals(From->getName())
+                    : !Start->equals_lower(From->getName()))
+    // failure to match
+    return error_code(errc::no_such_file_or_directory, system_category());
+
+  ++Start;
+
+  if (Start == End) {
+    // Match!
+    return From;
+  }
+
+  DirectoryEntry *DE = dyn_cast<DirectoryEntry>(From);
+  if (!DE)
+    return error_code(errc::not_a_directory, system_category());
+
+  for (DirectoryEntry::iterator I = DE->contents_begin(),
+                                E = DE->contents_end();
+       I != E; ++I) {
+    ErrorOr<Entry *> Result = lookupPath(Start, End, *I);
+    if (Result || Result.getError() != errc::no_such_file_or_directory)
+      return Result;
+  }
+  return error_code(errc::no_such_file_or_directory, system_category());
+}
+
+ErrorOr<Status> VFSFromYAML::status(const Twine &Path) {
+  ErrorOr<Entry *> Result = lookupPath(Path);
+  if (!Result)
+    return Result.getError();
+
+  std::string PathStr(Path.str());
+  if (FileEntry *F = dyn_cast<FileEntry>(*Result)) {
+    ErrorOr<Status> S = ExternalFS->status(F->getExternalContentsPath());
+    assert(!S || S->getName() == F->getExternalContentsPath());
+    if (S && !F->useExternalName(UseExternalNames))
+      S->setName(PathStr);
+    return S;
+  } else { // directory
+    DirectoryEntry *DE = cast<DirectoryEntry>(*Result);
+    Status S = DE->getStatus();
+    S.setName(PathStr);
+    return S;
+  }
+}
+
+error_code VFSFromYAML::openFileForRead(const Twine &Path,
+                                        std::unique_ptr<vfs::File> &Result) {
+  ErrorOr<Entry *> E = lookupPath(Path);
+  if (!E)
+    return E.getError();
+
+  FileEntry *F = dyn_cast<FileEntry>(*E);
+  if (!F) // FIXME: errc::not_a_file?
+    return error_code(errc::invalid_argument, system_category());
+
+  if (error_code EC = ExternalFS->openFileForRead(F->getExternalContentsPath(),
+                                                  Result))
+    return EC;
+
+  if (!F->useExternalName(UseExternalNames))
+    Result->setName(Path.str());
+
+  return error_code::success();
+}
+
+IntrusiveRefCntPtr<FileSystem>
+vfs::getVFSFromYAML(MemoryBuffer *Buffer, SourceMgr::DiagHandlerTy DiagHandler,
+                    void *DiagContext,
+                    IntrusiveRefCntPtr<FileSystem> ExternalFS) {
+  return VFSFromYAML::create(Buffer, DiagHandler, DiagContext, ExternalFS);
+}
+
+UniqueID vfs::getNextVirtualUniqueID() {
+  static std::atomic<unsigned> UID;
+  unsigned ID = ++UID;
+  // The following assumes that uint64_t max will never collide with a real
+  // dev_t value from the OS.
+  return UniqueID(std::numeric_limits<uint64_t>::max(), ID);
+}
