From b857398ff9c31660c652db755dabfb708254105e Mon Sep 17 00:00:00 2001 From: Eric Liu Date: Thu, 17 May 2018 10:26:23 +0000 Subject: [PATCH] Add vfs::FileSystem::getRealPath Summary: And change `FileManager::getCanonicalName` to use getRealPath. Reviewers: bkramer Reviewed By: bkramer Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D46942 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@332590 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/VirtualFileSystem.h | 6 ++++++ lib/Basic/FileManager.cpp | 18 ++---------------- lib/Basic/VirtualFileSystem.cpp | 13 +++++++++++++ 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/include/clang/Basic/VirtualFileSystem.h b/include/clang/Basic/VirtualFileSystem.h index 813e746df2..59e33791f2 100644 --- a/include/clang/Basic/VirtualFileSystem.h +++ b/include/clang/Basic/VirtualFileSystem.h @@ -248,6 +248,12 @@ public: /// Get the working directory of this file system. virtual llvm::ErrorOr getCurrentWorkingDirectory() const = 0; + /// Gets real path of \p Path e.g. collapse all . and .. patterns, resolve + /// symlinks. For real file system, this uses `llvm::sys::fs::real_path`. + /// This returns errc::operation_not_permitted if not implemented by subclass. + virtual std::error_code getRealPath(const Twine &Path, + SmallVectorImpl &Output) const; + /// Check whether a file exists. Provided for convenience. bool exists(const Twine &Path); diff --git a/lib/Basic/FileManager.cpp b/lib/Basic/FileManager.cpp index 14a9033b20..5cbcdf4477 100644 --- a/lib/Basic/FileManager.cpp +++ b/lib/Basic/FileManager.cpp @@ -534,23 +534,9 @@ StringRef FileManager::getCanonicalName(const DirectoryEntry *Dir) { StringRef CanonicalName(Dir->getName()); -#ifdef LLVM_ON_UNIX - char CanonicalNameBuf[PATH_MAX]; - if (realpath(Dir->getName().str().c_str(), CanonicalNameBuf)) + SmallString<4096> CanonicalNameBuf; + if (!FS->getRealPath(Dir->getName(), CanonicalNameBuf)) CanonicalName = StringRef(CanonicalNameBuf).copy(CanonicalNameStorage); -#else - SmallString<256> CanonicalNameBuf(CanonicalName); - llvm::sys::fs::make_absolute(CanonicalNameBuf); - llvm::sys::path::native(CanonicalNameBuf); - // We've run into needing to remove '..' here in the wild though, so - // remove it. - // On Windows, symlinks are significantly less prevalent, so removing - // '..' is pretty safe. - // Ideally we'd have an equivalent of `realpath` and could implement - // sys::fs::canonical across all the platforms. - llvm::sys::path::remove_dots(CanonicalNameBuf, /* remove_dot_dot */ true); - CanonicalName = StringRef(CanonicalNameBuf).copy(CanonicalNameStorage); -#endif CanonicalDirNames.insert(std::make_pair(Dir, CanonicalName)); return CanonicalName; diff --git a/lib/Basic/VirtualFileSystem.cpp b/lib/Basic/VirtualFileSystem.cpp index 84684a4165..1727b7d0e7 100644 --- a/lib/Basic/VirtualFileSystem.cpp +++ b/lib/Basic/VirtualFileSystem.cpp @@ -139,6 +139,11 @@ std::error_code FileSystem::makeAbsolute(SmallVectorImpl &Path) const { return llvm::sys::fs::make_absolute(WorkingDir.get(), Path); } +std::error_code FileSystem::getRealPath(const Twine &Path, + SmallVectorImpl &Output) const { + return errc::operation_not_permitted; +} + bool FileSystem::exists(const Twine &Path) { auto Status = status(Path); return Status && Status->exists(); @@ -236,6 +241,8 @@ public: llvm::ErrorOr getCurrentWorkingDirectory() const override; std::error_code setCurrentWorkingDirectory(const Twine &Path) override; + std::error_code getRealPath(const Twine &Path, + SmallVectorImpl &Output) const override; }; } // namespace @@ -274,6 +281,12 @@ std::error_code RealFileSystem::setCurrentWorkingDirectory(const Twine &Path) { return llvm::sys::fs::set_current_path(Path); } +std::error_code +RealFileSystem::getRealPath(const Twine &Path, + SmallVectorImpl &Output) const { + return llvm::sys::fs::real_path(Path, Output); +} + IntrusiveRefCntPtr vfs::getRealFileSystem() { static IntrusiveRefCntPtr FS = new RealFileSystem(); return FS; -- 2.40.0