[Lldb-commits] [lldb] r345783 - [FileSystem] Extend file system and have it use the VFS.

Jonas Devlieghere via lldb-commits lldb-commits at lists.llvm.org
Wed Oct 31 14:49:27 PDT 2018


Author: jdevlieghere
Date: Wed Oct 31 14:49:27 2018
New Revision: 345783

URL: http://llvm.org/viewvc/llvm-project?rev=345783&view=rev
Log:
[FileSystem] Extend file system and have it use the VFS.

This patch extends the FileSystem class with a bunch of functions that
are currently implemented as methods of the FileSpec class. These
methods will be removed in future commits and replaced by calls to the
file system.

The new functions are operated in terms of the virtual file system which
was recently moved from clang into LLVM so it could be reused in lldb.
Because the VFS is stateful, we turned the FileSystem class into a
singleton.

Differential revision: https://reviews.llvm.org/D53532

Modified:
    lldb/trunk/include/lldb/Host/FileSystem.h
    lldb/trunk/include/lldb/Utility/FileSpec.h
    lldb/trunk/source/Core/Disassembler.cpp
    lldb/trunk/source/Core/Module.cpp
    lldb/trunk/source/Core/ModuleList.cpp
    lldb/trunk/source/Core/SourceManager.cpp
    lldb/trunk/source/Host/common/FileSystem.cpp
    lldb/trunk/source/Host/common/HostInfoBase.cpp
    lldb/trunk/source/Host/common/Symbols.cpp
    lldb/trunk/source/Host/posix/HostProcessPosix.cpp
    lldb/trunk/source/Initialization/SystemInitializerCommon.cpp
    lldb/trunk/source/Interpreter/OptionValueFileSpec.cpp
    lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
    lldb/trunk/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
    lldb/trunk/source/Plugins/Platform/Android/AdbClient.cpp
    lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
    lldb/trunk/source/Target/Platform.cpp
    lldb/trunk/unittests/Core/MangledTest.cpp
    lldb/trunk/unittests/Expression/ClangParserTest.cpp
    lldb/trunk/unittests/Host/FileSystemTest.cpp
    lldb/trunk/unittests/Host/HostInfoTest.cpp
    lldb/trunk/unittests/Host/SymbolsTest.cpp
    lldb/trunk/unittests/ObjectFile/ELF/TestObjectFileELF.cpp
    lldb/trunk/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
    lldb/trunk/unittests/Symbol/TestClangASTContext.cpp
    lldb/trunk/unittests/Symbol/TestDWARFCallFrameInfo.cpp
    lldb/trunk/unittests/SymbolFile/DWARF/SymbolFileDWARFTests.cpp
    lldb/trunk/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp
    lldb/trunk/unittests/Target/ModuleCacheTest.cpp

Modified: lldb/trunk/include/lldb/Host/FileSystem.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/FileSystem.h?rev=345783&r1=345782&r2=345783&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/FileSystem.h (original)
+++ lldb/trunk/include/lldb/Host/FileSystem.h Wed Oct 31 14:49:27 2018
@@ -12,7 +12,10 @@
 
 #include "lldb/Utility/FileSpec.h"
 #include "lldb/Utility/Status.h"
+
+#include "llvm/ADT/Optional.h"
 #include "llvm/Support/Chrono.h"
+#include "llvm/Support/VirtualFileSystem.h"
 
 #include "lldb/lldb-types.h"
 
@@ -26,17 +29,101 @@ public:
   static const char *DEV_NULL;
   static const char *PATH_CONVERSION_ERROR;
 
-  static Status Symlink(const FileSpec &src, const FileSpec &dst);
-  static Status Readlink(const FileSpec &src, FileSpec &dst);
+  FileSystem() : m_fs(llvm::vfs::getRealFileSystem()) {}
+  FileSystem(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> fs) : m_fs(fs) {}
+
+  static FileSystem &Instance();
+
+  static void Initialize();
+  static void Initialize(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> fs);
+  static void Terminate();
+
+  Status Symlink(const FileSpec &src, const FileSpec &dst);
+  Status Readlink(const FileSpec &src, FileSpec &dst);
 
-  static Status ResolveSymbolicLink(const FileSpec &src, FileSpec &dst);
+  Status ResolveSymbolicLink(const FileSpec &src, FileSpec &dst);
 
   /// Wraps ::fopen in a platform-independent way. Once opened, FILEs can be
   /// manipulated and closed with the normal ::fread, ::fclose, etc. functions.
-  static FILE *Fopen(const char *path, const char *mode);
+  FILE *Fopen(const char *path, const char *mode);
 
-  static llvm::sys::TimePoint<> GetModificationTime(const FileSpec &file_spec);
+  /// Returns the modification time of the given file.
+  /// @{
+  llvm::sys::TimePoint<> GetModificationTime(const FileSpec &file_spec) const;
+  llvm::sys::TimePoint<> GetModificationTime(const llvm::Twine &path) const;
+  /// @}
+
+  /// Returns the on-disk size of the given file in bytes.
+  /// @{
+  uint64_t GetByteSize(const FileSpec &file_spec) const;
+  uint64_t GetByteSize(const llvm::Twine &path) const;
+  /// @}
+
+  /// Return the current permissions of the given file.
+  ///
+  /// Returns a bitmask for the current permissions of the file (zero or more
+  /// of the permission bits defined in File::Permissions).
+  /// @{
+  uint32_t GetPermissions(const FileSpec &file_spec) const;
+  uint32_t GetPermissions(const llvm::Twine &path) const;
+  /// @}
+
+  /// Returns whether the given file exists.
+  /// @{
+  bool Exists(const FileSpec &file_spec) const;
+  bool Exists(const llvm::Twine &path) const;
+  /// @}
+
+  /// Returns whether the given file is readable.
+  /// @{
+  bool Readable(const FileSpec &file_spec) const;
+  bool Readable(const llvm::Twine &path) const;
+  /// @}
+
+  /// Make the given file path absolute.
+  /// @{
+  std::error_code MakeAbsolute(llvm::SmallVectorImpl<char> &path) const;
+  std::error_code MakeAbsolute(FileSpec &file_spec) const;
+  /// @}
+
+  /// Resolve path to make it canonical.
+  /// @{
+  void Resolve(llvm::SmallVectorImpl<char> &path);
+  void Resolve(FileSpec &file_spec);
+  /// @}
+
+  enum EnumerateDirectoryResult {
+    /// Enumerate next entry in the current directory.
+    eEnumerateDirectoryResultNext,
+    /// Recurse into the current entry if it is a directory or symlink, or next
+    /// if not.
+    eEnumerateDirectoryResultEnter,
+    /// Stop directory enumerations at any level.
+    eEnumerateDirectoryResultQuit
+  };
+
+  typedef EnumerateDirectoryResult (*EnumerateDirectoryCallbackType)(
+      void *baton, llvm::sys::fs::file_type file_type, llvm::StringRef);
+
+  typedef std::function<EnumerateDirectoryResult(
+      llvm::sys::fs::file_type file_type, llvm::StringRef)>
+      DirectoryCallback;
+
+  void EnumerateDirectory(llvm::Twine path, bool find_directories,
+                          bool find_files, bool find_other,
+                          EnumerateDirectoryCallbackType callback,
+                          void *callback_baton);
+
+  std::error_code GetRealPath(const llvm::Twine &path,
+                              llvm::SmallVectorImpl<char> &output) const;
+
+protected:
+  void SetFileSystem(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> fs);
+
+private:
+  static llvm::Optional<FileSystem> &InstanceImpl();
+  llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> m_fs;
 };
-}
+} // namespace lldb_private
 
 #endif

Modified: lldb/trunk/include/lldb/Utility/FileSpec.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Utility/FileSpec.h?rev=345783&r1=345782&r2=345783&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Utility/FileSpec.h (original)
+++ lldb/trunk/include/lldb/Utility/FileSpec.h Wed Oct 31 14:49:27 2018
@@ -375,6 +375,9 @@ public:
   //------------------------------------------------------------------
   bool IsAbsolute() const;
 
+  /// Temporary helper for FileSystem change.
+  void SetPath(llvm::StringRef p) { SetFile(p, false); }
+
   //------------------------------------------------------------------
   /// Extract the full path to the file.
   ///

Modified: lldb/trunk/source/Core/Disassembler.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Disassembler.cpp?rev=345783&r1=345782&r2=345783&view=diff
==============================================================================
--- lldb/trunk/source/Core/Disassembler.cpp (original)
+++ lldb/trunk/source/Core/Disassembler.cpp Wed Oct 31 14:49:27 2018
@@ -934,7 +934,7 @@ bool Instruction::TestEmulation(Stream *
     out_stream->Printf("Instruction::TestEmulation:  Missing file_name.");
     return false;
   }
-  FILE *test_file = FileSystem::Fopen(file_name, "r");
+  FILE *test_file = FileSystem::Instance().Fopen(file_name, "r");
   if (!test_file) {
     out_stream->Printf(
         "Instruction::TestEmulation: Attempt to open test file failed.");

Modified: lldb/trunk/source/Core/Module.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Module.cpp?rev=345783&r1=345782&r2=345783&view=diff
==============================================================================
--- lldb/trunk/source/Core/Module.cpp (original)
+++ lldb/trunk/source/Core/Module.cpp Wed Oct 31 14:49:27 2018
@@ -171,10 +171,10 @@ Module::Module(const ModuleSpec &module_
   }
 
   if (module_spec.GetFileSpec())
-    m_mod_time = FileSystem::GetModificationTime(module_spec.GetFileSpec());
+    m_mod_time = FileSystem::Instance().GetModificationTime(module_spec.GetFileSpec());
   else if (matching_module_spec.GetFileSpec())
     m_mod_time =
-        FileSystem::GetModificationTime(matching_module_spec.GetFileSpec());
+        FileSystem::Instance().GetModificationTime(matching_module_spec.GetFileSpec());
 
   // Copy the architecture from the actual spec if we got one back, else use
   // the one that was specified
@@ -219,7 +219,7 @@ Module::Module(const ModuleSpec &module_
 Module::Module(const FileSpec &file_spec, const ArchSpec &arch,
                const ConstString *object_name, lldb::offset_t object_offset,
                const llvm::sys::TimePoint<> &object_mod_time)
-    : m_mod_time(FileSystem::GetModificationTime(file_spec)), m_arch(arch),
+    : m_mod_time(FileSystem::Instance().GetModificationTime(file_spec)), m_arch(arch),
       m_file(file_spec), m_object_offset(object_offset),
       m_object_mod_time(object_mod_time), m_file_has_changed(false),
       m_first_file_changed_log(false) {
@@ -1062,7 +1062,7 @@ void Module::SetFileSpecAndObjectName(co
   // Container objects whose paths do not specify a file directly can call this
   // function to correct the file and object names.
   m_file = file;
-  m_mod_time = FileSystem::GetModificationTime(file);
+  m_mod_time = FileSystem::Instance().GetModificationTime(file);
   m_object_name = object_name;
 }
 
@@ -1125,7 +1125,7 @@ void Module::ReportError(const char *for
 bool Module::FileHasChanged() const {
   if (!m_file_has_changed)
     m_file_has_changed =
-        (FileSystem::GetModificationTime(m_file) != m_mod_time);
+        (FileSystem::Instance().GetModificationTime(m_file) != m_mod_time);
   return m_file_has_changed;
 }
 

Modified: lldb/trunk/source/Core/ModuleList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ModuleList.cpp?rev=345783&r1=345782&r2=345783&view=diff
==============================================================================
--- lldb/trunk/source/Core/ModuleList.cpp (original)
+++ lldb/trunk/source/Core/ModuleList.cpp Wed Oct 31 14:49:27 2018
@@ -952,7 +952,7 @@ Status ModuleList::GetSharedModule(const
       // If we didn't have a UUID in mind when looking for the object file,
       // then we should make sure the modification time hasn't changed!
       if (platform_module_spec.GetUUIDPtr() == nullptr) {
-        auto file_spec_mod_time = FileSystem::GetModificationTime(
+        auto file_spec_mod_time = FileSystem::Instance().GetModificationTime(
             located_binary_modulespec.GetFileSpec());
         if (file_spec_mod_time != llvm::sys::TimePoint<>()) {
           if (file_spec_mod_time != module_sp->GetModificationTime()) {

Modified: lldb/trunk/source/Core/SourceManager.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/SourceManager.cpp?rev=345783&r1=345782&r2=345783&view=diff
==============================================================================
--- lldb/trunk/source/Core/SourceManager.cpp (original)
+++ lldb/trunk/source/Core/SourceManager.cpp Wed Oct 31 14:49:27 2018
@@ -370,14 +370,14 @@ void SourceManager::FindLinesMatchingReg
 SourceManager::File::File(const FileSpec &file_spec,
                           lldb::DebuggerSP debugger_sp)
     : m_file_spec_orig(file_spec), m_file_spec(file_spec),
-      m_mod_time(FileSystem::GetModificationTime(file_spec)),
+      m_mod_time(FileSystem::Instance().GetModificationTime(file_spec)),
       m_debugger_wp(debugger_sp) {
   CommonInitializer(file_spec, nullptr);
 }
 
 SourceManager::File::File(const FileSpec &file_spec, Target *target)
     : m_file_spec_orig(file_spec), m_file_spec(file_spec),
-      m_mod_time(FileSystem::GetModificationTime(file_spec)),
+      m_mod_time(FileSystem::Instance().GetModificationTime(file_spec)),
       m_debugger_wp(target ? target->GetDebugger().shared_from_this()
                            : DebuggerSP()) {
   CommonInitializer(file_spec, target);
@@ -422,7 +422,7 @@ void SourceManager::File::CommonInitiali
             SymbolContext sc;
             sc_list.GetContextAtIndex(0, sc);
             m_file_spec = sc.comp_unit;
-            m_mod_time = FileSystem::GetModificationTime(m_file_spec);
+            m_mod_time = FileSystem::Instance().GetModificationTime(m_file_spec);
           }
         }
       }
@@ -435,7 +435,7 @@ void SourceManager::File::CommonInitiali
         if (target->GetSourcePathMap().FindFile(m_file_spec, new_file_spec) ||
             target->GetImages().FindSourceFile(m_file_spec, new_file_spec)) {
           m_file_spec = new_file_spec;
-          m_mod_time = FileSystem::GetModificationTime(m_file_spec);
+          m_mod_time = FileSystem::Instance().GetModificationTime(m_file_spec);
         }
       }
     }
@@ -515,7 +515,7 @@ void SourceManager::File::UpdateIfNeeded
   // TODO: use host API to sign up for file modifications to anything in our
   // source cache and only update when we determine a file has been updated.
   // For now we check each time we want to display info for the file.
-  auto curr_mod_time = FileSystem::GetModificationTime(m_file_spec);
+  auto curr_mod_time = FileSystem::Instance().GetModificationTime(m_file_spec);
 
   if (curr_mod_time != llvm::sys::TimePoint<>() &&
       m_mod_time != curr_mod_time) {

Modified: lldb/trunk/source/Host/common/FileSystem.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/FileSystem.cpp?rev=345783&r1=345782&r2=345783&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/FileSystem.cpp (original)
+++ lldb/trunk/source/Host/common/FileSystem.cpp Wed Oct 31 14:49:27 2018
@@ -9,7 +9,10 @@
 
 #include "lldb/Host/FileSystem.h"
 
+#include "lldb/Utility/TildeExpressionResolver.h"
+
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Threading.h"
 
 #include <algorithm>
 #include <fstream>
@@ -17,12 +20,160 @@
 
 using namespace lldb;
 using namespace lldb_private;
+using namespace llvm;
+
+FileSystem &FileSystem::Instance() { return *InstanceImpl(); }
+
+void FileSystem::Initialize() {
+  assert(!InstanceImpl());
+  InstanceImpl().emplace();
+}
+
+void FileSystem::Initialize(IntrusiveRefCntPtr<vfs::FileSystem> fs) {
+  assert(!InstanceImpl());
+  InstanceImpl().emplace(fs);
+}
+
+void FileSystem::Terminate() {
+  assert(InstanceImpl());
+  InstanceImpl().reset();
+}
+
+Optional<FileSystem> &FileSystem::InstanceImpl() {
+  static Optional<FileSystem> g_fs;
+  return g_fs;
+}
+
+void FileSystem::SetFileSystem(IntrusiveRefCntPtr<vfs::FileSystem> fs) {
+  m_fs = fs;
+}
+
+sys::TimePoint<>
+FileSystem::GetModificationTime(const FileSpec &file_spec) const {
+  return GetModificationTime(file_spec.GetPath());
+}
+
+sys::TimePoint<> FileSystem::GetModificationTime(const Twine &path) const {
+  ErrorOr<vfs::Status> status = m_fs->status(path);
+  if (!status)
+    return sys::TimePoint<>();
+  return status->getLastModificationTime();
+}
+
+uint64_t FileSystem::GetByteSize(const FileSpec &file_spec) const {
+  return GetByteSize(file_spec.GetPath());
+}
+
+uint64_t FileSystem::GetByteSize(const Twine &path) const {
+  ErrorOr<vfs::Status> status = m_fs->status(path);
+  if (!status)
+    return 0;
+  return status->getSize();
+}
+
+uint32_t FileSystem::GetPermissions(const FileSpec &file_spec) const {
+  return GetPermissions(file_spec.GetPath());
+}
+
+uint32_t FileSystem::GetPermissions(const Twine &path) const {
+  ErrorOr<vfs::Status> status = m_fs->status(path);
+  if (!status)
+    return sys::fs::perms::perms_not_known;
+  return status->getPermissions();
+}
+
+bool FileSystem::Exists(const Twine &path) const { return m_fs->exists(path); }
+
+bool FileSystem::Exists(const FileSpec &file_spec) const {
+  return Exists(file_spec.GetPath());
+}
+
+bool FileSystem::Readable(const Twine &path) const {
+  return GetPermissions(path) & sys::fs::perms::all_read;
+}
+
+bool FileSystem::Readable(const FileSpec &file_spec) const {
+  return Readable(file_spec.GetPath());
+}
+
+void FileSystem::EnumerateDirectory(Twine path, bool find_directories,
+                                    bool find_files, bool find_other,
+                                    EnumerateDirectoryCallbackType callback,
+                                    void *callback_baton) {
+  std::error_code EC;
+  vfs::recursive_directory_iterator Iter(*m_fs, path, EC);
+  vfs::recursive_directory_iterator End;
+  for (; Iter != End && !EC; Iter.increment(EC)) {
+    const auto &Item = *Iter;
+    ErrorOr<vfs::Status> Status = m_fs->status(Item.path());
+    if (!Status)
+      break;
+    if (!find_files && Status->isRegularFile())
+      continue;
+    if (!find_directories && Status->isDirectory())
+      continue;
+    if (!find_other && Status->isOther())
+      continue;
+
+    auto Result = callback(callback_baton, Status->getType(), Item.path());
+    if (Result == eEnumerateDirectoryResultQuit)
+      return;
+    if (Result == eEnumerateDirectoryResultNext) {
+      // Default behavior is to recurse. Opt out if the callback doesn't want
+      // this behavior.
+      Iter.no_push();
+    }
+  }
+}
+
+std::error_code FileSystem::MakeAbsolute(SmallVectorImpl<char> &path) const {
+  return m_fs->makeAbsolute(path);
+}
+
+std::error_code FileSystem::MakeAbsolute(FileSpec &file_spec) const {
+  SmallString<128> path;
+  file_spec.GetPath(path, false);
+
+  auto EC = MakeAbsolute(path);
+  if (EC)
+    return EC;
+
+  FileSpec new_file_spec(path, false, file_spec.GetPathStyle());
+  file_spec = new_file_spec;
+  return {};
+}
+
+std::error_code FileSystem::GetRealPath(const Twine &path,
+                                        SmallVectorImpl<char> &output) const {
+  return m_fs->getRealPath(path, output);
+}
+
+void FileSystem::Resolve(SmallVectorImpl<char> &path) {
+  if (path.empty())
+    return;
+
+  // Resolve tilde.
+  SmallString<128> original_path(path.begin(), path.end());
+  StandardTildeExpressionResolver Resolver;
+  Resolver.ResolveFullPath(original_path, path);
+
+  // Try making the path absolute if it exists.
+  SmallString<128> absolute_path(path.begin(), path.end());
+  MakeAbsolute(path);
+  if (!Exists(path)) {
+    path.clear();
+    path.append(original_path.begin(), original_path.end());
+  }
+}
+
+void FileSystem::Resolve(FileSpec &file_spec) {
+  // Extract path from the FileSpec.
+  SmallString<128> path;
+  file_spec.GetPath(path);
+
+  // Resolve the path.
+  Resolve(path);
 
-llvm::sys::TimePoint<>
-FileSystem::GetModificationTime(const FileSpec &file_spec) {
-  llvm::sys::fs::file_status status;
-  std::error_code ec = llvm::sys::fs::status(file_spec.GetPath(), status);
-  if (ec)
-    return llvm::sys::TimePoint<>();
-  return status.getLastModificationTime();
+  // Update the FileSpec with the resolved path.
+  file_spec.SetPath(path);
 }

Modified: lldb/trunk/source/Host/common/HostInfoBase.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/HostInfoBase.cpp?rev=345783&r1=345782&r2=345783&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/HostInfoBase.cpp (original)
+++ lldb/trunk/source/Host/common/HostInfoBase.cpp Wed Oct 31 14:49:27 2018
@@ -226,7 +226,7 @@ bool HostInfoBase::ComputeSharedLibraryD
 
   // This is necessary because when running the testsuite the shlib might be a
   // symbolic link inside the Python resource dir.
-  FileSystem::ResolveSymbolicLink(lldb_file_spec, lldb_file_spec);
+  FileSystem::Instance().ResolveSymbolicLink(lldb_file_spec, lldb_file_spec);
 
   // Remove the filename so that this FileSpec only represents the directory.
   file_spec.GetDirectory() = lldb_file_spec.GetDirectory();

Modified: lldb/trunk/source/Host/common/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/Symbols.cpp?rev=345783&r1=345782&r2=345783&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/Symbols.cpp (original)
+++ lldb/trunk/source/Host/common/Symbols.cpp Wed Oct 31 14:49:27 2018
@@ -261,7 +261,7 @@ FileSpec Symbols::LocateExecutableSymbol
     // Add module directory.
     FileSpec module_file_spec = module_spec.GetFileSpec();
     // We keep the unresolved pathname if it fails.
-    FileSystem::ResolveSymbolicLink(module_file_spec, module_file_spec);
+    FileSystem::Instance().ResolveSymbolicLink(module_file_spec, module_file_spec);
 
     const ConstString &file_dir = module_file_spec.GetDirectory();
     debug_file_search_paths.AppendIfUnique(

Modified: lldb/trunk/source/Host/posix/HostProcessPosix.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/posix/HostProcessPosix.cpp?rev=345783&r1=345782&r2=345783&view=diff
==============================================================================
--- lldb/trunk/source/Host/posix/HostProcessPosix.cpp (original)
+++ lldb/trunk/source/Host/posix/HostProcessPosix.cpp Wed Oct 31 14:49:27 2018
@@ -62,7 +62,7 @@ Status HostProcessPosix::GetMainModule(F
     return error;
   }
 
-  error = FileSystem::Readlink(FileSpec{link_path, false}, file_spec);
+  error = FileSystem::Instance().Readlink(FileSpec{link_path, false}, file_spec);
   if (!error.Success())
     return error;
 

Modified: lldb/trunk/source/Initialization/SystemInitializerCommon.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Initialization/SystemInitializerCommon.cpp?rev=345783&r1=345782&r2=345783&view=diff
==============================================================================
--- lldb/trunk/source/Initialization/SystemInitializerCommon.cpp (original)
+++ lldb/trunk/source/Initialization/SystemInitializerCommon.cpp Wed Oct 31 14:49:27 2018
@@ -15,6 +15,7 @@
 #include "Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h"
 #include "Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h"
 #include "Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h"
+#include "lldb/Host/FileSystem.h"
 #include "lldb/Host/Host.h"
 #include "lldb/Host/HostInfo.h"
 #include "lldb/Utility/Log.h"
@@ -62,6 +63,7 @@ void SystemInitializerCommon::Initialize
   }
 #endif
 
+  FileSystem::Initialize();
   Log::Initialize();
   HostInfo::Initialize();
   static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
@@ -106,4 +108,5 @@ void SystemInitializerCommon::Terminate(
 
   HostInfo::Terminate();
   Log::DisableAllLogChannels();
+  FileSystem::Terminate();
 }

Modified: lldb/trunk/source/Interpreter/OptionValueFileSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/OptionValueFileSpec.cpp?rev=345783&r1=345782&r2=345783&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/OptionValueFileSpec.cpp (original)
+++ lldb/trunk/source/Interpreter/OptionValueFileSpec.cpp Wed Oct 31 14:49:27 2018
@@ -109,7 +109,7 @@ size_t OptionValueFileSpec::AutoComplete
 
 const lldb::DataBufferSP &OptionValueFileSpec::GetFileContents() {
   if (m_current_value) {
-    const auto file_mod_time = FileSystem::GetModificationTime(m_current_value);
+    const auto file_mod_time = FileSystem::Instance().GetModificationTime(m_current_value);
     if (m_data_sp && m_data_mod_time == file_mod_time)
       return m_data_sp;
     m_data_sp = DataBufferLLVM::CreateFromPath(m_current_value.GetPath());

Modified: lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp?rev=345783&r1=345782&r2=345783&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp (original)
+++ lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp Wed Oct 31 14:49:27 2018
@@ -115,7 +115,7 @@ ModuleSP DynamicLoaderDarwin::FindTarget
     // No UUID, we must rely upon the cached module modification time and the
     // modification time of the file on disk
     if (module_sp->GetModificationTime() !=
-        FileSystem::GetModificationTime(module_sp->GetFileSpec()))
+        FileSystem::Instance().GetModificationTime(module_sp->GetFileSpec()))
       module_sp.reset();
   }
 

Modified: lldb/trunk/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp?rev=345783&r1=345782&r2=345783&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp Wed Oct 31 14:49:27 2018
@@ -461,7 +461,7 @@ size_t ObjectContainerBSDArchive::GetMod
     return 0;
 
   const size_t initial_count = specs.GetSize();
-  llvm::sys::TimePoint<> file_mod_time = FileSystem::GetModificationTime(file);
+  llvm::sys::TimePoint<> file_mod_time = FileSystem::Instance().GetModificationTime(file);
   Archive::shared_ptr archive_sp(
       Archive::FindCachedArchive(file, ArchSpec(), file_mod_time, file_offset));
   bool set_archive_arch = false;

Modified: lldb/trunk/source/Plugins/Platform/Android/AdbClient.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/Android/AdbClient.cpp?rev=345783&r1=345782&r2=345783&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/Android/AdbClient.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/Android/AdbClient.cpp Wed Oct 31 14:49:27 2018
@@ -484,7 +484,7 @@ Status AdbClient::SyncService::internalP
       return Status("Failed to send file chunk: %s", error.AsCString());
   }
   error = SendSyncRequest(
-      kDONE, llvm::sys::toTimeT(FileSystem::GetModificationTime(local_file)),
+      kDONE, llvm::sys::toTimeT(FileSystem::Instance().GetModificationTime(local_file)),
       nullptr);
   if (error.Fail())
     return error;

Modified: lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp?rev=345783&r1=345782&r2=345783&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp Wed Oct 31 14:49:27 2018
@@ -455,7 +455,7 @@ lldb::user_id_t PlatformPOSIX::GetFileSi
 
 Status PlatformPOSIX::CreateSymlink(const FileSpec &src, const FileSpec &dst) {
   if (IsHost())
-    return FileSystem::Symlink(src, dst);
+    return FileSystem::Instance().Symlink(src, dst);
   else if (m_remote_platform_sp)
     return m_remote_platform_sp->CreateSymlink(src, dst);
   else

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp?rev=345783&r1=345782&r2=345783&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp Wed Oct 31 14:49:27 2018
@@ -698,7 +698,7 @@ GDBRemoteCommunicationServerCommon::Hand
   packet.GetHexByteStringTerminatedBy(dst, ',');
   packet.GetChar(); // Skip ',' char
   packet.GetHexByteString(src);
-  Status error = FileSystem::Symlink(FileSpec{src, true}, FileSpec{dst, false});
+  Status error = FileSystem::Instance().Symlink(FileSpec{src, true}, FileSpec{dst, false});
   StreamString response;
   response.Printf("F%u,%u", error.GetError(), error.GetError());
   return SendPacketNoLock(response.GetString());

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=345783&r1=345782&r2=345783&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Wed Oct 31 14:49:27 2018
@@ -212,7 +212,7 @@ static FileSpec resolveCompDir(const cha
     return local_spec;
 
   FileSpec resolved_symlink;
-  const auto error = FileSystem::Readlink(local_spec, resolved_symlink);
+  const auto error = FileSystem::Instance().Readlink(local_spec, resolved_symlink);
   if (error.Success())
     return resolved_symlink;
 

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp?rev=345783&r1=345782&r2=345783&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp Wed Oct 31 14:49:27 2018
@@ -424,7 +424,7 @@ Module *SymbolFileDWARFDebugMap::GetModu
       FileSpec oso_file(oso_path, false);
       ConstString oso_object;
       if (oso_file.Exists()) {
-        auto oso_mod_time = FileSystem::GetModificationTime(oso_file);
+        auto oso_mod_time = FileSystem::Instance().GetModificationTime(oso_file);
         if (oso_mod_time != comp_unit_info->oso_mod_time) {
           obj_file->GetModule()->ReportError(
               "debug map object file '%s' has changed (actual time is "

Modified: lldb/trunk/source/Target/Platform.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Platform.cpp?rev=345783&r1=345782&r2=345783&view=diff
==============================================================================
--- lldb/trunk/source/Target/Platform.cpp (original)
+++ lldb/trunk/source/Target/Platform.cpp Wed Oct 31 14:49:27 2018
@@ -603,7 +603,7 @@ RecurseCopy_Callback(void *baton, llvm::
 
     FileSpec src_resolved;
 
-    rc_baton->error = FileSystem::Readlink(src, src_resolved);
+    rc_baton->error = FileSystem::Instance().Readlink(src, src_resolved);
 
     if (rc_baton->error.Fail())
       return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
@@ -733,7 +733,7 @@ Status Platform::Install(const FileSpec
     case fs::file_type::symlink_file: {
       llvm::sys::fs::remove(fixed_dst.GetPath());
       FileSpec src_resolved;
-      error = FileSystem::Readlink(src, src_resolved);
+      error = FileSystem::Instance().Readlink(src, src_resolved);
       if (error.Success())
         error = CreateSymlink(dst, src_resolved);
     } break;

Modified: lldb/trunk/unittests/Core/MangledTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Core/MangledTest.cpp?rev=345783&r1=345782&r2=345783&view=diff
==============================================================================
--- lldb/trunk/unittests/Core/MangledTest.cpp (original)
+++ lldb/trunk/unittests/Core/MangledTest.cpp Wed Oct 31 14:49:27 2018
@@ -14,6 +14,7 @@
 #include "lldb/Core/Mangled.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleSpec.h"
+#include "lldb/Host/FileSystem.h"
 #include "lldb/Host/HostInfo.h"
 #include "lldb/Symbol/SymbolContext.h"
 
@@ -61,6 +62,7 @@ TEST(MangledTest, EmptyForInvalidName) {
   }
 
 TEST(MangledTest, NameIndexes_FindFunctionSymbols) {
+  FileSystem::Initialize();
   HostInfo::Initialize();
   ObjectFileELF::Initialize();
   SymbolVendorELF::Initialize();
@@ -167,4 +169,5 @@ TEST(MangledTest, NameIndexes_FindFuncti
   SymbolVendorELF::Terminate();
   ObjectFileELF::Terminate();
   HostInfo::Terminate();
+  FileSystem::Terminate();
 }

Modified: lldb/trunk/unittests/Expression/ClangParserTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Expression/ClangParserTest.cpp?rev=345783&r1=345782&r2=345783&view=diff
==============================================================================
--- lldb/trunk/unittests/Expression/ClangParserTest.cpp (original)
+++ lldb/trunk/unittests/Expression/ClangParserTest.cpp Wed Oct 31 14:49:27 2018
@@ -9,6 +9,7 @@
 
 #include "Plugins/ExpressionParser/Clang/ClangHost.h"
 #include "TestingSupport/TestUtilities.h"
+#include "lldb/Host/FileSystem.h"
 #include "lldb/Host/HostInfo.h"
 #include "lldb/Utility/FileSpec.h"
 #include "lldb/lldb-defines.h"
@@ -18,8 +19,14 @@ using namespace lldb_private;
 
 namespace {
 struct ClangHostTest : public testing::Test {
-  static void SetUpTestCase() { HostInfo::Initialize(); }
-  static void TearDownTestCase() { HostInfo::Terminate(); }
+  static void SetUpTestCase() {
+    FileSystem::Initialize();
+    HostInfo::Initialize();
+  }
+  static void TearDownTestCase() {
+    HostInfo::Terminate();
+    FileSystem::Terminate();
+  }
 };
 } // namespace
 

Modified: lldb/trunk/unittests/Host/FileSystemTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Host/FileSystemTest.cpp?rev=345783&r1=345782&r2=345783&view=diff
==============================================================================
--- lldb/trunk/unittests/Host/FileSystemTest.cpp (original)
+++ lldb/trunk/unittests/Host/FileSystemTest.cpp Wed Oct 31 14:49:27 2018
@@ -7,13 +7,154 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
 #include "lldb/Host/FileSystem.h"
+#include "llvm/Support/Errc.h"
 
 extern const char *TestMainArgv0;
 
 using namespace lldb_private;
+using namespace llvm;
+using llvm::sys::fs::UniqueID;
+
+// Modified from llvm/unittests/Support/VirtualFileSystemTest.cpp
+namespace {
+struct DummyFile : public vfs::File {
+  vfs::Status S;
+  explicit DummyFile(vfs::Status S) : S(S) {}
+  llvm::ErrorOr<vfs::Status> status() override { return S; }
+  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
+  getBuffer(const Twine &Name, int64_t FileSize, bool RequiresNullTerminator,
+            bool IsVolatile) override {
+    llvm_unreachable("unimplemented");
+  }
+  std::error_code close() override { return std::error_code(); }
+};
+
+class DummyFileSystem : public vfs::FileSystem {
+  int FSID;   // used to produce UniqueIDs
+  int FileID; // used to produce UniqueIDs
+  std::string cwd;
+  std::map<std::string, vfs::Status> FilesAndDirs;
+
+  static int getNextFSID() {
+    static int Count = 0;
+    return Count++;
+  }
+
+public:
+  DummyFileSystem() : FSID(getNextFSID()), FileID(0) {}
+
+  ErrorOr<vfs::Status> status(const Twine &Path) override {
+    std::map<std::string, vfs::Status>::iterator I =
+        FilesAndDirs.find(Path.str());
+    if (I == FilesAndDirs.end())
+      return make_error_code(llvm::errc::no_such_file_or_directory);
+    return I->second;
+  }
+  ErrorOr<std::unique_ptr<vfs::File>>
+  openFileForRead(const Twine &Path) override {
+    auto S = status(Path);
+    if (S)
+      return std::unique_ptr<vfs::File>(new DummyFile{*S});
+    return S.getError();
+  }
+  llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const override {
+    return cwd;
+  }
+  std::error_code setCurrentWorkingDirectory(const Twine &Path) override {
+    cwd = Path.str();
+    return std::error_code();
+  }
+  // Map any symlink to "/symlink".
+  std::error_code getRealPath(const Twine &Path,
+                              SmallVectorImpl<char> &Output) const override {
+    auto I = FilesAndDirs.find(Path.str());
+    if (I == FilesAndDirs.end())
+      return make_error_code(llvm::errc::no_such_file_or_directory);
+    if (I->second.isSymlink()) {
+      Output.clear();
+      Twine("/symlink").toVector(Output);
+      return std::error_code();
+    }
+    Output.clear();
+    Path.toVector(Output);
+    return std::error_code();
+  }
+
+  struct DirIterImpl : public llvm::vfs::detail::DirIterImpl {
+    std::map<std::string, vfs::Status> &FilesAndDirs;
+    std::map<std::string, vfs::Status>::iterator I;
+    std::string Path;
+    bool isInPath(StringRef S) {
+      if (Path.size() < S.size() && S.find(Path) == 0) {
+        auto LastSep = S.find_last_of('/');
+        if (LastSep == Path.size() || LastSep == Path.size() - 1)
+          return true;
+      }
+      return false;
+    }
+    DirIterImpl(std::map<std::string, vfs::Status> &FilesAndDirs,
+                const Twine &_Path)
+        : FilesAndDirs(FilesAndDirs), I(FilesAndDirs.begin()),
+          Path(_Path.str()) {
+      for (; I != FilesAndDirs.end(); ++I) {
+        if (isInPath(I->first)) {
+          CurrentEntry =
+              vfs::directory_entry(I->second.getName(), I->second.getType());
+          break;
+        }
+      }
+    }
+    std::error_code increment() override {
+      ++I;
+      for (; I != FilesAndDirs.end(); ++I) {
+        if (isInPath(I->first)) {
+          CurrentEntry =
+              vfs::directory_entry(I->second.getName(), I->second.getType());
+          break;
+        }
+      }
+      if (I == FilesAndDirs.end())
+        CurrentEntry = vfs::directory_entry();
+      return std::error_code();
+    }
+  };
+
+  vfs::directory_iterator dir_begin(const Twine &Dir,
+                                    std::error_code &EC) override {
+    return vfs::directory_iterator(
+        std::make_shared<DirIterImpl>(FilesAndDirs, Dir));
+  }
+
+  void addEntry(StringRef Path, const vfs::Status &Status) {
+    FilesAndDirs[Path] = Status;
+  }
+
+  void addRegularFile(StringRef Path, sys::fs::perms Perms = sys::fs::all_all) {
+    vfs::Status S(Path, UniqueID(FSID, FileID++),
+                  std::chrono::system_clock::now(), 0, 0, 1024,
+                  sys::fs::file_type::regular_file, Perms);
+    addEntry(Path, S);
+  }
+
+  void addDirectory(StringRef Path, sys::fs::perms Perms = sys::fs::all_all) {
+    vfs::Status S(Path, UniqueID(FSID, FileID++),
+                  std::chrono::system_clock::now(), 0, 0, 0,
+                  sys::fs::file_type::directory_file, Perms);
+    addEntry(Path, S);
+  }
+
+  void addSymlink(StringRef Path) {
+    vfs::Status S(Path, UniqueID(FSID, FileID++),
+                  std::chrono::system_clock::now(), 0, 0, 0,
+                  sys::fs::file_type::symlink_file, sys::fs::all_all);
+    addEntry(Path, S);
+  }
+};
+} // namespace
 
 TEST(FileSystemTest, FileAndDirectoryComponents) {
   using namespace std::chrono;
@@ -26,7 +167,125 @@ TEST(FileSystemTest, FileAndDirectoryCom
 #endif
   FileSpec fs2(TestMainArgv0, resolve);
 
-  EXPECT_EQ(system_clock::time_point(), FileSystem::GetModificationTime(fs1));
+  FileSystem fs;
+
+  EXPECT_EQ(system_clock::time_point(), fs.GetModificationTime(fs1));
   EXPECT_LT(system_clock::time_point() + hours(24 * 365 * 20),
-            FileSystem::GetModificationTime(fs2));
+            fs.GetModificationTime(fs2));
+}
+
+static IntrusiveRefCntPtr<DummyFileSystem> GetSimpleDummyFS() {
+  IntrusiveRefCntPtr<DummyFileSystem> D(new DummyFileSystem());
+  D->addRegularFile("/foo");
+  D->addDirectory("/bar");
+  D->addSymlink("/baz");
+  D->addRegularFile("/qux", ~sys::fs::perms::all_read);
+  D->setCurrentWorkingDirectory("/");
+  return D;
+}
+
+TEST(FileSystemTest, Exists) {
+  FileSystem fs(GetSimpleDummyFS());
+
+  EXPECT_TRUE(fs.Exists("/foo"));
+  EXPECT_TRUE(fs.Exists(FileSpec("/foo", false, FileSpec::Style::posix)));
+}
+
+TEST(FileSystemTest, Readable) {
+  FileSystem fs(GetSimpleDummyFS());
+
+  EXPECT_TRUE(fs.Readable("/foo"));
+  EXPECT_TRUE(fs.Readable(FileSpec("/foo", false, FileSpec::Style::posix)));
+
+  EXPECT_FALSE(fs.Readable("/qux"));
+  EXPECT_FALSE(fs.Readable(FileSpec("/qux", false, FileSpec::Style::posix)));
+}
+
+TEST(FileSystemTest, GetByteSize) {
+  FileSystem fs(GetSimpleDummyFS());
+
+  EXPECT_EQ((uint64_t)1024, fs.GetByteSize("/foo"));
+  EXPECT_EQ((uint64_t)1024,
+            fs.GetByteSize(FileSpec("/foo", false, FileSpec::Style::posix)));
+}
+
+TEST(FileSystemTest, GetPermissions) {
+  FileSystem fs(GetSimpleDummyFS());
+
+  EXPECT_EQ(sys::fs::all_all, fs.GetPermissions("/foo"));
+  EXPECT_EQ(sys::fs::all_all,
+            fs.GetPermissions(FileSpec("/foo", false, FileSpec::Style::posix)));
+}
+
+TEST(FileSystemTest, MakeAbsolute) {
+  FileSystem fs(GetSimpleDummyFS());
+
+  {
+    StringRef foo_relative = "foo";
+    SmallString<16> foo(foo_relative);
+    auto EC = fs.MakeAbsolute(foo);
+    EXPECT_FALSE(EC);
+    EXPECT_TRUE(foo.equals("/foo"));
+  }
+
+  {
+    FileSpec file_spec("foo", false);
+    auto EC = fs.MakeAbsolute(file_spec);
+    EXPECT_FALSE(EC);
+    EXPECT_EQ("/foo", file_spec.GetPath());
+  }
+}
+
+TEST(FileSystemTest, Resolve) {
+  FileSystem fs(GetSimpleDummyFS());
+
+  {
+    StringRef foo_relative = "foo";
+    SmallString<16> foo(foo_relative);
+    fs.Resolve(foo);
+    EXPECT_TRUE(foo.equals("/foo"));
+  }
+
+  {
+    FileSpec file_spec("foo", false);
+    fs.Resolve(file_spec);
+    EXPECT_EQ("/foo", file_spec.GetPath());
+  }
+
+  {
+    StringRef foo_relative = "bogus";
+    SmallString<16> foo(foo_relative);
+    fs.Resolve(foo);
+    EXPECT_TRUE(foo.equals("bogus"));
+  }
+
+  {
+    FileSpec file_spec("bogus", false);
+    fs.Resolve(file_spec);
+    EXPECT_EQ("bogus", file_spec.GetPath());
+  }
+}
+
+FileSystem::EnumerateDirectoryResult
+VFSCallback(void *baton, llvm::sys::fs::file_type file_type,
+            llvm::StringRef path) {
+  auto visited = static_cast<std::vector<std::string> *>(baton);
+  visited->push_back(path.str());
+  return FileSystem::eEnumerateDirectoryResultNext;
+}
+
+TEST(FileSystemTest, EnumerateDirectory) {
+  FileSystem fs(GetSimpleDummyFS());
+
+  std::vector<std::string> visited;
+
+  constexpr bool find_directories = true;
+  constexpr bool find_files = true;
+  constexpr bool find_other = true;
+
+  fs.EnumerateDirectory("/", find_directories, find_files, find_other,
+                        VFSCallback, &visited);
+
+  EXPECT_THAT(visited,
+              testing::UnorderedElementsAre("/foo", "/bar", "/baz", "/qux"));
 }

Modified: lldb/trunk/unittests/Host/HostInfoTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Host/HostInfoTest.cpp?rev=345783&r1=345782&r2=345783&view=diff
==============================================================================
--- lldb/trunk/unittests/Host/HostInfoTest.cpp (original)
+++ lldb/trunk/unittests/Host/HostInfoTest.cpp Wed Oct 31 14:49:27 2018
@@ -8,20 +8,27 @@
 //===----------------------------------------------------------------------===//
 
 #include "lldb/Host/HostInfo.h"
-#include "lldb/lldb-defines.h"
 #include "TestingSupport/TestUtilities.h"
+#include "lldb/Host/FileSystem.h"
+#include "lldb/lldb-defines.h"
 #include "gtest/gtest.h"
 
 using namespace lldb_private;
 using namespace llvm;
 
 namespace {
-class HostInfoTest: public ::testing::Test {
-  public:
-    void SetUp() override { HostInfo::Initialize(); }
-    void TearDown() override { HostInfo::Terminate(); }
+class HostInfoTest : public ::testing::Test {
+public:
+  void SetUp() override {
+    FileSystem::Initialize();
+    HostInfo::Initialize();
+  }
+  void TearDown() override {
+    HostInfo::Terminate();
+    FileSystem::Terminate();
+  }
 };
-}
+} // namespace
 
 TEST_F(HostInfoTest, GetAugmentedArchSpec) {
   // Fully specified triple should not be changed.

Modified: lldb/trunk/unittests/Host/SymbolsTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Host/SymbolsTest.cpp?rev=345783&r1=345782&r2=345783&view=diff
==============================================================================
--- lldb/trunk/unittests/Host/SymbolsTest.cpp (original)
+++ lldb/trunk/unittests/Host/SymbolsTest.cpp Wed Oct 31 14:49:27 2018
@@ -9,20 +9,37 @@
 
 #include "gtest/gtest.h"
 
-#include "lldb/Host/Symbols.h"
 #include "lldb/Core/ModuleSpec.h"
+#include "lldb/Host/FileSystem.h"
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Host/Symbols.h"
 
 using namespace lldb_private;
 
-TEST(SymbolsTest,
-     LocateExecutableSymbolFileForUnknownExecutableAndUnknownSymbolFile) {
+namespace {
+class SymbolsTest : public ::testing::Test {
+public:
+  void SetUp() override {
+    FileSystem::Initialize();
+    HostInfo::Initialize();
+  }
+  void TearDown() override {
+    HostInfo::Terminate();
+    FileSystem::Terminate();
+  }
+};
+} // namespace
+
+TEST_F(
+    SymbolsTest,
+    TerminateLocateExecutableSymbolFileForUnknownExecutableAndUnknownSymbolFile) {
   ModuleSpec module_spec;
   FileSpec symbol_file_spec = Symbols::LocateExecutableSymbolFile(module_spec);
   EXPECT_TRUE(symbol_file_spec.GetFilename().IsEmpty());
 }
 
-TEST(SymbolsTest,
-     LocateExecutableSymbolFileForUnknownExecutableAndMissingSymbolFile) {
+TEST_F(SymbolsTest,
+       LocateExecutableSymbolFileForUnknownExecutableAndMissingSymbolFile) {
   ModuleSpec module_spec;
   // using a GUID here because the symbol file shouldn't actually exist on disk
   module_spec.GetSymbolFileSpec().SetFile(

Modified: lldb/trunk/unittests/ObjectFile/ELF/TestObjectFileELF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/ObjectFile/ELF/TestObjectFileELF.cpp?rev=345783&r1=345782&r2=345783&view=diff
==============================================================================
--- lldb/trunk/unittests/ObjectFile/ELF/TestObjectFileELF.cpp (original)
+++ lldb/trunk/unittests/ObjectFile/ELF/TestObjectFileELF.cpp Wed Oct 31 14:49:27 2018
@@ -14,6 +14,7 @@
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/Section.h"
+#include "lldb/Host/FileSystem.h"
 #include "lldb/Host/HostInfo.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/Support/Compression.h"
@@ -29,6 +30,7 @@ using namespace lldb;
 class ObjectFileELFTest : public testing::Test {
 public:
   void SetUp() override {
+    FileSystem::Initialize();
     HostInfo::Initialize();
     ObjectFileELF::Initialize();
     SymbolVendorELF::Initialize();
@@ -38,6 +40,7 @@ public:
     SymbolVendorELF::Terminate();
     ObjectFileELF::Terminate();
     HostInfo::Terminate();
+    FileSystem::Terminate();
   }
 
 protected:

Modified: lldb/trunk/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp?rev=345783&r1=345782&r2=345783&view=diff
==============================================================================
--- lldb/trunk/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp (original)
+++ lldb/trunk/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp Wed Oct 31 14:49:27 2018
@@ -7,10 +7,11 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Plugins/ScriptInterpreter/Python/lldb-python.h"
 #include "gtest/gtest.h"
 
 #include "Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h"
+#include "Plugins/ScriptInterpreter/Python/lldb-python.h"
+#include "lldb/Host/FileSystem.h"
 #include "lldb/Host/HostInfo.h"
 
 #include "PythonTestSuite.h"
@@ -18,6 +19,7 @@
 using namespace lldb_private;
 
 void PythonTestSuite::SetUp() {
+  FileSystem::Initialize();
   HostInfoBase::Initialize();
   // ScriptInterpreterPython::Initialize() depends on HostInfo being
   // initializedso it can compute the python directory etc.

Modified: lldb/trunk/unittests/Symbol/TestClangASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Symbol/TestClangASTContext.cpp?rev=345783&r1=345782&r2=345783&view=diff
==============================================================================
--- lldb/trunk/unittests/Symbol/TestClangASTContext.cpp (original)
+++ lldb/trunk/unittests/Symbol/TestClangASTContext.cpp Wed Oct 31 14:49:27 2018
@@ -13,6 +13,7 @@
 
 #include "clang/AST/DeclCXX.h"
 
+#include "lldb/Host/FileSystem.h"
 #include "lldb/Host/HostInfo.h"
 #include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Symbol/ClangUtil.h"
@@ -25,9 +26,15 @@ using namespace lldb_private;
 
 class TestClangASTContext : public testing::Test {
 public:
-  static void SetUpTestCase() { HostInfo::Initialize(); }
+  static void SetUpTestCase() {
+    FileSystem::Initialize();
+    HostInfo::Initialize();
+  }
 
-  static void TearDownTestCase() { HostInfo::Terminate(); }
+  static void TearDownTestCase() {
+    HostInfo::Terminate();
+    FileSystem::Terminate();
+  }
 
   virtual void SetUp() override {
     std::string triple = HostInfo::GetTargetTriple();
@@ -357,7 +364,7 @@ TEST_F(TestClangASTContext, TestRecordHa
   RecordDecl *empty_derived_non_empty_base_decl =
       ClangASTContext::GetAsRecordDecl(empty_derived);
   EXPECT_EQ(1u, ClangASTContext::GetNumBaseClasses(
-                   empty_derived_non_empty_base_cxx_decl, false));
+                    empty_derived_non_empty_base_cxx_decl, false));
   EXPECT_TRUE(
       ClangASTContext::RecordHasFields(empty_derived_non_empty_base_decl));
 
@@ -380,7 +387,7 @@ TEST_F(TestClangASTContext, TestRecordHa
   RecordDecl *empty_derived_non_empty_vbase_decl =
       ClangASTContext::GetAsRecordDecl(empty_derived2);
   EXPECT_EQ(1u, ClangASTContext::GetNumBaseClasses(
-                   empty_derived_non_empty_vbase_cxx_decl, false));
+                    empty_derived_non_empty_vbase_cxx_decl, false));
   EXPECT_TRUE(
       ClangASTContext::RecordHasFields(empty_derived_non_empty_vbase_decl));
 }
@@ -420,7 +427,7 @@ TEST_F(TestClangASTContext, TemplateArgu
                              clang::AutoTypeKeyword::Auto, false));
 
   CompilerType int_type(m_ast->getASTContext(), m_ast->getASTContext()->IntTy);
-  for(CompilerType t: { type, typedef_type, auto_type }) {
+  for (CompilerType t : {type, typedef_type, auto_type}) {
     SCOPED_TRACE(t.GetTypeName().AsCString());
 
     EXPECT_EQ(m_ast->GetTemplateArgumentKind(t.GetOpaqueQualType(), 0),

Modified: lldb/trunk/unittests/Symbol/TestDWARFCallFrameInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Symbol/TestDWARFCallFrameInfo.cpp?rev=345783&r1=345782&r2=345783&view=diff
==============================================================================
--- lldb/trunk/unittests/Symbol/TestDWARFCallFrameInfo.cpp (original)
+++ lldb/trunk/unittests/Symbol/TestDWARFCallFrameInfo.cpp Wed Oct 31 14:49:27 2018
@@ -8,20 +8,24 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "gtest/gtest.h"
+
 #include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
 #include "Plugins/Process/Utility/RegisterContext_x86.h"
+#include "TestingSupport/TestUtilities.h"
+
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/Section.h"
+#include "lldb/Host/FileSystem.h"
 #include "lldb/Host/HostInfo.h"
 #include "lldb/Symbol/DWARFCallFrameInfo.h"
 #include "lldb/Utility/StreamString.h"
-#include "TestingSupport/TestUtilities.h"
+
 #include "llvm/Support/FileUtilities.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Program.h"
 #include "llvm/Support/raw_ostream.h"
-#include "gtest/gtest.h"
 
 using namespace lldb_private;
 using namespace lldb;
@@ -29,6 +33,7 @@ using namespace lldb;
 class DWARFCallFrameInfoTest : public testing::Test {
 public:
   void SetUp() override {
+    FileSystem::Initialize();
     HostInfo::Initialize();
     ObjectFileELF::Initialize();
   }
@@ -36,6 +41,7 @@ public:
   void TearDown() override {
     ObjectFileELF::Terminate();
     HostInfo::Terminate();
+    FileSystem::Terminate();
   }
 
 protected:

Modified: lldb/trunk/unittests/SymbolFile/DWARF/SymbolFileDWARFTests.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/SymbolFile/DWARF/SymbolFileDWARFTests.cpp?rev=345783&r1=345782&r2=345783&view=diff
==============================================================================
--- lldb/trunk/unittests/SymbolFile/DWARF/SymbolFileDWARFTests.cpp (original)
+++ lldb/trunk/unittests/SymbolFile/DWARF/SymbolFileDWARFTests.cpp Wed Oct 31 14:49:27 2018
@@ -22,6 +22,7 @@
 #include "lldb/Core/Address.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleSpec.h"
+#include "lldb/Host/FileSystem.h"
 #include "lldb/Host/HostInfo.h"
 #include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Symbol/CompileUnit.h"
@@ -38,13 +39,14 @@ public:
 // Initialize and TearDown the plugin every time, so we get a brand new
 // AST every time so that modifications to the AST from each test don't
 // leak into the next test.
-    HostInfo::Initialize();
-    ObjectFilePECOFF::Initialize();
-    SymbolFileDWARF::Initialize();
-    ClangASTContext::Initialize();
-    SymbolFilePDB::Initialize();
+FileSystem::Initialize();
+HostInfo::Initialize();
+ObjectFilePECOFF::Initialize();
+SymbolFileDWARF::Initialize();
+ClangASTContext::Initialize();
+SymbolFilePDB::Initialize();
 
-    m_dwarf_test_exe = GetInputFilePath("test-dwarf.exe");
+m_dwarf_test_exe = GetInputFilePath("test-dwarf.exe");
   }
 
   void TearDown() override {
@@ -53,6 +55,7 @@ public:
     SymbolFileDWARF::Terminate();
     ObjectFilePECOFF::Terminate();
     HostInfo::Terminate();
+    FileSystem::Terminate();
   }
 
 protected:

Modified: lldb/trunk/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp?rev=345783&r1=345782&r2=345783&view=diff
==============================================================================
--- lldb/trunk/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp (original)
+++ lldb/trunk/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp Wed Oct 31 14:49:27 2018
@@ -22,6 +22,7 @@
 #include "lldb/Core/Address.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleSpec.h"
+#include "lldb/Host/FileSystem.h"
 #include "lldb/Host/HostInfo.h"
 #include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Symbol/CompileUnit.h"
@@ -49,6 +50,7 @@ public:
     ::CoInitializeEx(nullptr, COINIT_MULTITHREADED);
 #endif
 
+    FileSystem::Initialize();
     HostInfo::Initialize();
     ObjectFilePECOFF::Initialize();
     SymbolFileDWARF::Initialize();
@@ -65,6 +67,7 @@ public:
     SymbolFileDWARF::Terminate();
     ObjectFilePECOFF::Terminate();
     HostInfo::Terminate();
+    FileSystem::Terminate();
 
 #if defined(_MSC_VER)
     ::CoUninitialize();

Modified: lldb/trunk/unittests/Target/ModuleCacheTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Target/ModuleCacheTest.cpp?rev=345783&r1=345782&r2=345783&view=diff
==============================================================================
--- lldb/trunk/unittests/Target/ModuleCacheTest.cpp (original)
+++ lldb/trunk/unittests/Target/ModuleCacheTest.cpp Wed Oct 31 14:49:27 2018
@@ -5,12 +5,13 @@
 #include "llvm/Support/Path.h"
 
 #include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
+#include "TestingSupport/TestUtilities.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleSpec.h"
+#include "lldb/Host/FileSystem.h"
 #include "lldb/Host/HostInfo.h"
 #include "lldb/Symbol/SymbolContext.h"
 #include "lldb/Target/ModuleCache.h"
-#include "TestingSupport/TestUtilities.h"
 
 using namespace lldb_private;
 using namespace lldb;
@@ -65,6 +66,7 @@ static FileSpec GetSysrootView(FileSpec
 }
 
 void ModuleCacheTest::SetUpTestCase() {
+  FileSystem::Initialize();
   HostInfo::Initialize();
   ObjectFileELF::Initialize();
 
@@ -75,6 +77,7 @@ void ModuleCacheTest::SetUpTestCase() {
 void ModuleCacheTest::TearDownTestCase() {
   ObjectFileELF::Terminate();
   HostInfo::Terminate();
+  FileSystem::Terminate();
 }
 
 static void VerifyDiskState(const FileSpec &cache_dir, const char *hostname) {




More information about the lldb-commits mailing list