Index: cfe/trunk/include/clang/Basic/FileManager.h =================================================================== --- cfe/trunk/include/clang/Basic/FileManager.h +++ cfe/trunk/include/clang/Basic/FileManager.h @@ -67,7 +67,6 @@ unsigned UID; // A unique (small) ID for the file. llvm::sys::fs::UniqueID UniqueID; bool IsNamedPipe; - bool InPCH; bool IsValid; // Is this \c FileEntry initialized and valid? /// The open file, if it is owned by the \p FileEntry. @@ -75,7 +74,7 @@ public: FileEntry() - : UniqueID(0, 0), IsNamedPipe(false), InPCH(false), IsValid(false) + : UniqueID(0, 0), IsNamedPipe(false), IsValid(false) {} FileEntry(const FileEntry &) = delete; @@ -87,7 +86,6 @@ off_t getSize() const { return Size; } unsigned getUID() const { return UID; } const llvm::sys::fs::UniqueID &getUniqueID() const { return UniqueID; } - bool isInPCH() const { return InPCH; } time_t getModificationTime() const { return ModTime; } /// Return the directory the file lives in. @@ -108,8 +106,6 @@ bool isOpenForTests() const { return File != nullptr; } }; -struct FileData; - /// Implements support for file system lookup, file system caching, /// and directory search management. /// @@ -168,7 +164,7 @@ // Caching. std::unique_ptr StatCache; - bool getStatValue(StringRef Path, FileData &Data, bool isFile, + bool getStatValue(StringRef Path, llvm::vfs::Status &Status, bool isFile, std::unique_ptr *F); /// Add all ancestors of the given path (pointing to either a file Index: cfe/trunk/include/clang/Basic/FileSystemStatCache.h =================================================================== --- cfe/trunk/include/clang/Basic/FileSystemStatCache.h +++ cfe/trunk/include/clang/Basic/FileSystemStatCache.h @@ -19,40 +19,15 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/VirtualFileSystem.h" #include #include #include #include #include -namespace llvm { - -namespace vfs { - -class File; -class FileSystem; - -} // namespace vfs -} // namespace llvm - namespace clang { -// FIXME: should probably replace this with vfs::Status -struct FileData { - std::string Name; - uint64_t Size = 0; - time_t ModTime = 0; - llvm::sys::fs::UniqueID UniqueID; - bool IsDirectory = false; - bool IsNamedPipe = false; - bool InPCH = false; - - // FIXME: remove this when files support multiple names - bool IsVFSMapped = false; - - FileData() = default; -}; - /// Abstract interface for introducing a FileManager cache for 'stat' /// system calls, which is used by precompiled and pretokenized headers to /// improve performance. @@ -80,7 +55,7 @@ /// success for directories (not files). On a successful file lookup, the /// implementation can optionally fill in \p F with a valid \p File object and /// the client guarantees that it will close it. - static bool get(StringRef Path, FileData &Data, bool isFile, + static bool get(StringRef Path, llvm::vfs::Status &Status, bool isFile, std::unique_ptr *F, FileSystemStatCache *Cache, llvm::vfs::FileSystem &FS); @@ -88,7 +63,8 @@ // FIXME: The pointer here is a non-owning/optional reference to the // unique_ptr. Optional&> might be nicer, but // Optional needs some work to support references so this isn't possible yet. - virtual LookupResult getStat(StringRef Path, FileData &Data, bool isFile, + virtual LookupResult getStat(StringRef Path, llvm::vfs::Status &Status, + bool isFile, std::unique_ptr *F, llvm::vfs::FileSystem &FS) = 0; }; @@ -99,15 +75,16 @@ class MemorizeStatCalls : public FileSystemStatCache { public: /// The set of stat() calls that have been seen. - llvm::StringMap StatCalls; + llvm::StringMap StatCalls; using iterator = - llvm::StringMap::const_iterator; + llvm::StringMap::const_iterator; iterator begin() const { return StatCalls.begin(); } iterator end() const { return StatCalls.end(); } - LookupResult getStat(StringRef Path, FileData &Data, bool isFile, + LookupResult getStat(StringRef Path, llvm::vfs::Status &Status, bool isFile, std::unique_ptr *F, llvm::vfs::FileSystem &FS) override; }; Index: cfe/trunk/lib/Basic/FileManager.cpp =================================================================== --- cfe/trunk/lib/Basic/FileManager.cpp +++ cfe/trunk/lib/Basic/FileManager.cpp @@ -144,8 +144,8 @@ StringRef InterndDirName = NamedDirEnt.first(); // Check to see if the directory exists. - FileData Data; - if (getStatValue(InterndDirName, Data, false, nullptr /*directory lookup*/)) { + llvm::vfs::Status Status; + if (getStatValue(InterndDirName, Status, false, nullptr /*directory lookup*/)) { // There's no real directory at the given path. if (!CacheFailure) SeenDirEntries.erase(DirName); @@ -156,7 +156,7 @@ // same inode (this occurs on Unix-like systems when one dir is // symlinked to another, for example) or the same path (on // Windows). - DirectoryEntry &UDE = UniqueRealDirs[Data.UniqueID]; + DirectoryEntry &UDE = UniqueRealDirs[Status.getUniqueID()]; NamedDirEnt.second = &UDE; if (UDE.getName().empty()) { @@ -205,8 +205,8 @@ // Check to see if the file exists. std::unique_ptr F; - FileData Data; - if (getStatValue(InterndFileName, Data, true, openFile ? &F : nullptr)) { + llvm::vfs::Status Status; + if (getStatValue(InterndFileName, Status, true, openFile ? &F : nullptr)) { // There's no real file at the given path. if (!CacheFailure) SeenFileEntries.erase(Filename); @@ -218,14 +218,15 @@ // It exists. See if we have already opened a file with the same inode. // This occurs when one dir is symlinked to another, for example. - FileEntry &UFE = UniqueRealFiles[Data.UniqueID]; + FileEntry &UFE = UniqueRealFiles[Status.getUniqueID()]; NamedFileEnt.second = &UFE; // If the name returned by getStatValue is different than Filename, re-intern // the name. - if (Data.Name != Filename) { - auto &NamedFileEnt = *SeenFileEntries.insert({Data.Name, &UFE}).first; + if (Status.getName() != Filename) { + auto &NamedFileEnt = + *SeenFileEntries.insert({Status.getName(), &UFE}).first; assert(NamedFileEnt.second == &UFE && "filename from getStatValue() refers to wrong file"); InterndFileName = NamedFileEnt.first().data(); @@ -239,7 +240,7 @@ // module's structure when its headers/module map are mapped in the VFS. // We should remove this as soon as we can properly support a file having // multiple names. - if (DirInfo != UFE.Dir && Data.IsVFSMapped) + if (DirInfo != UFE.Dir && Status.IsVFSMapped) UFE.Dir = DirInfo; // Always update the name to use the last name by which a file was accessed. @@ -254,13 +255,12 @@ // Otherwise, we don't have this file yet, add it. UFE.Name = InterndFileName; - UFE.Size = Data.Size; - UFE.ModTime = Data.ModTime; + UFE.Size = Status.getSize(); + UFE.ModTime = llvm::sys::toTimeT(Status.getLastModificationTime()); UFE.Dir = DirInfo; UFE.UID = NextFileUID++; - UFE.UniqueID = Data.UniqueID; - UFE.IsNamedPipe = Data.IsNamedPipe; - UFE.InPCH = Data.InPCH; + UFE.UniqueID = Status.getUniqueID(); + UFE.IsNamedPipe = Status.getType() == llvm::sys::fs::file_type::fifo_file; UFE.File = std::move(F); UFE.IsValid = true; @@ -298,12 +298,15 @@ "The directory of a virtual file should already be in the cache."); // Check to see if the file exists. If so, drop the virtual file - FileData Data; + llvm::vfs::Status Status; const char *InterndFileName = NamedFileEnt.first().data(); - if (getStatValue(InterndFileName, Data, true, nullptr) == 0) { - Data.Size = Size; - Data.ModTime = ModificationTime; - UFE = &UniqueRealFiles[Data.UniqueID]; + if (getStatValue(InterndFileName, Status, true, nullptr) == 0) { + UFE = &UniqueRealFiles[Status.getUniqueID()]; + Status = llvm::vfs::Status( + Status.getName(), Status.getUniqueID(), + llvm::sys::toTimePoint(ModificationTime), + Status.getUser(), Status.getGroup(), Size, + Status.getType(), Status.getPermissions()); NamedFileEnt.second = UFE; @@ -317,10 +320,9 @@ if (UFE->isValid()) return UFE; - UFE->UniqueID = Data.UniqueID; - UFE->IsNamedPipe = Data.IsNamedPipe; - UFE->InPCH = Data.InPCH; - fillRealPathName(UFE, Data.Name); + UFE->UniqueID = Status.getUniqueID(); + UFE->IsNamedPipe = Status.getType() == llvm::sys::fs::file_type::fifo_file; + fillRealPathName(UFE, Status.getName()); } else { VirtualFileEntries.push_back(llvm::make_unique()); UFE = VirtualFileEntries.back().get(); @@ -421,17 +423,18 @@ /// if the path points to a virtual file or does not exist, or returns /// false if it's an existent real file. If FileDescriptor is NULL, /// do directory look-up instead of file look-up. -bool FileManager::getStatValue(StringRef Path, FileData &Data, bool isFile, +bool FileManager::getStatValue(StringRef Path, llvm::vfs::Status &Status, + bool isFile, std::unique_ptr *F) { // FIXME: FileSystemOpts shouldn't be passed in here, all paths should be // absolute! if (FileSystemOpts.WorkingDir.empty()) - return FileSystemStatCache::get(Path, Data, isFile, F,StatCache.get(), *FS); + return FileSystemStatCache::get(Path, Status, isFile, F,StatCache.get(), *FS); SmallString<128> FilePath(Path); FixupRelativePath(FilePath); - return FileSystemStatCache::get(FilePath.c_str(), Data, isFile, F, + return FileSystemStatCache::get(FilePath.c_str(), Status, isFile, F, StatCache.get(), *FS); } Index: cfe/trunk/lib/Basic/FileSystemStatCache.cpp =================================================================== --- cfe/trunk/lib/Basic/FileSystemStatCache.cpp +++ cfe/trunk/lib/Basic/FileSystemStatCache.cpp @@ -21,18 +21,6 @@ void FileSystemStatCache::anchor() {} -static void copyStatusToFileData(const llvm::vfs::Status &Status, - FileData &Data) { - Data.Name = Status.getName(); - Data.Size = Status.getSize(); - Data.ModTime = llvm::sys::toTimeT(Status.getLastModificationTime()); - Data.UniqueID = Status.getUniqueID(); - Data.IsDirectory = Status.isDirectory(); - Data.IsNamedPipe = Status.getType() == llvm::sys::fs::file_type::fifo_file; - Data.InPCH = false; - Data.IsVFSMapped = Status.IsVFSMapped; -} - /// FileSystemStatCache::get - Get the 'stat' information for the specified /// path, using the cache to accelerate it if possible. This returns true if /// the path does not exist or false if it exists. @@ -42,7 +30,8 @@ /// success for directories (not files). On a successful file lookup, the /// implementation can optionally fill in FileDescriptor with a valid /// descriptor and the client guarantees that it will close it. -bool FileSystemStatCache::get(StringRef Path, FileData &Data, bool isFile, +bool FileSystemStatCache::get(StringRef Path, llvm::vfs::Status &Status, + bool isFile, std::unique_ptr *F, FileSystemStatCache *Cache, llvm::vfs::FileSystem &FS) { @@ -51,16 +40,16 @@ // If we have a cache, use it to resolve the stat query. if (Cache) - R = Cache->getStat(Path, Data, isFile, F, FS); + R = Cache->getStat(Path, Status, isFile, F, FS); else if (isForDir || !F) { // If this is a directory or a file descriptor is not needed and we have // no cache, just go to the file system. - llvm::ErrorOr Status = FS.status(Path); - if (!Status) { + llvm::ErrorOr StatusOrErr = FS.status(Path); + if (!StatusOrErr) { R = CacheMissing; } else { R = CacheExists; - copyStatusToFileData(*Status, Data); + Status = *StatusOrErr; } } else { // Otherwise, we have to go to the filesystem. We can always just use @@ -79,10 +68,10 @@ // Otherwise, the open succeeded. Do an fstat to get the information // about the file. We'll end up returning the open file descriptor to the // client to do what they please with it. - llvm::ErrorOr Status = (*OwnedFile)->status(); - if (Status) { + llvm::ErrorOr StatusOrErr = (*OwnedFile)->status(); + if (StatusOrErr) { R = CacheExists; - copyStatusToFileData(*Status, Data); + Status = *StatusOrErr; *F = std::move(*OwnedFile); } else { // fstat rarely fails. If it does, claim the initial open didn't @@ -98,7 +87,7 @@ // If the path exists, make sure that its "directoryness" matches the clients // demands. - if (Data.IsDirectory != isForDir) { + if (Status.isDirectory() != isForDir) { // If not, close the file if opened. if (F) *F = nullptr; @@ -110,10 +99,11 @@ } MemorizeStatCalls::LookupResult -MemorizeStatCalls::getStat(StringRef Path, FileData &Data, bool isFile, +MemorizeStatCalls::getStat(StringRef Path, llvm::vfs::Status &Status, + bool isFile, std::unique_ptr *F, llvm::vfs::FileSystem &FS) { - if (get(Path, Data, isFile, F, nullptr, FS)) { + if (get(Path, Status, isFile, F, nullptr, FS)) { // Do not cache failed stats, it is easy to construct common inconsistent // situations if we do, and they are not important for PCH performance // (which currently only needs the stats to construct the initial @@ -122,8 +112,8 @@ } // Cache file 'stat' results and directories with absolutely paths. - if (!Data.IsDirectory || llvm::sys::path::is_absolute(Path)) - StatCalls[Path] = Data; + if (!Status.isDirectory() || llvm::sys::path::is_absolute(Path)) + StatCalls[Path] = Status; return CacheExists; } Index: cfe/trunk/lib/Frontend/TextDiagnostic.cpp =================================================================== --- cfe/trunk/lib/Frontend/TextDiagnostic.cpp +++ cfe/trunk/lib/Frontend/TextDiagnostic.cpp @@ -792,8 +792,6 @@ const FileEntry *FE = Loc.getFileEntry(); if (FE && FE->isValid()) { emitFilename(FE->getName(), Loc.getManager()); - if (FE->isInPCH()) - OS << " (in PCH)"; OS << ": "; } } Index: cfe/trunk/unittests/Basic/FileManagerTest.cpp =================================================================== --- cfe/trunk/unittests/Basic/FileManagerTest.cpp +++ cfe/trunk/unittests/Basic/FileManagerTest.cpp @@ -26,7 +26,7 @@ private: // Maps a file/directory path to its desired stat result. Anything // not in this map is considered to not exist in the file system. - llvm::StringMap StatCalls; + llvm::StringMap StatCalls; void InjectFileOrDirectory(const char *Path, ino_t INode, bool IsFile) { #ifndef _WIN32 @@ -35,15 +35,14 @@ Path = NormalizedPath.c_str(); #endif - FileData Data; - Data.Name = Path; - Data.Size = 0; - Data.ModTime = 0; - Data.UniqueID = llvm::sys::fs::UniqueID(1, INode); - Data.IsDirectory = !IsFile; - Data.IsNamedPipe = false; - Data.InPCH = false; - StatCalls[Path] = Data; + auto fileType = IsFile ? + llvm::sys::fs::file_type::regular_file : + llvm::sys::fs::file_type::directory_file; + llvm::vfs::Status Status(Path, llvm::sys::fs::UniqueID(1, INode), + /*MTime*/{}, /*User*/0, /*Group*/0, + /*Size*/0, fileType, + llvm::sys::fs::perms::all_all); + StatCalls[Path] = Status; } public: @@ -58,7 +57,7 @@ } // Implement FileSystemStatCache::getStat(). - LookupResult getStat(StringRef Path, FileData &Data, bool isFile, + LookupResult getStat(StringRef Path, llvm::vfs::Status &Status, bool isFile, std::unique_ptr *F, llvm::vfs::FileSystem &FS) override { #ifndef _WIN32 @@ -68,7 +67,7 @@ #endif if (StatCalls.count(Path) != 0) { - Data = StatCalls[Path]; + Status = StatCalls[Path]; return CacheExists; }