forked from OSchip/llvm-project
Replace clang::FileData with llvm::vfs::Status
Summary: FileData was only ever used as a container for the values in llvm::vfs::Status, so they might as well be consolidated. The `InPCH` member was also always set to false, and unused. Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58924 llvm-svn: 355368
This commit is contained in:
parent
1c014d75b4
commit
06f64d53ae
|
@ -67,7 +67,6 @@ class FileEntry {
|
|||
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 @@ class FileEntry {
|
|||
|
||||
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 @@ public:
|
|||
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 @@ public:
|
|||
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 @@ class FileManager : public RefCountedBase<FileManager> {
|
|||
// Caching.
|
||||
std::unique_ptr<FileSystemStatCache> StatCache;
|
||||
|
||||
bool getStatValue(StringRef Path, FileData &Data, bool isFile,
|
||||
bool getStatValue(StringRef Path, llvm::vfs::Status &Status, bool isFile,
|
||||
std::unique_ptr<llvm::vfs::File> *F);
|
||||
|
||||
/// Add all ancestors of the given path (pointing to either a file
|
||||
|
|
|
@ -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 <cstdint>
|
||||
#include <ctime>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
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 @@ public:
|
|||
/// 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<llvm::vfs::File> *F,
|
||||
FileSystemStatCache *Cache, llvm::vfs::FileSystem &FS);
|
||||
|
||||
|
@ -88,7 +63,8 @@ protected:
|
|||
// FIXME: The pointer here is a non-owning/optional reference to the
|
||||
// unique_ptr. Optional<unique_ptr<vfs::File>&> 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<llvm::vfs::File> *F,
|
||||
llvm::vfs::FileSystem &FS) = 0;
|
||||
};
|
||||
|
@ -99,15 +75,16 @@ protected:
|
|||
class MemorizeStatCalls : public FileSystemStatCache {
|
||||
public:
|
||||
/// The set of stat() calls that have been seen.
|
||||
llvm::StringMap<FileData, llvm::BumpPtrAllocator> StatCalls;
|
||||
llvm::StringMap<llvm::vfs::Status, llvm::BumpPtrAllocator> StatCalls;
|
||||
|
||||
using iterator =
|
||||
llvm::StringMap<FileData, llvm::BumpPtrAllocator>::const_iterator;
|
||||
llvm::StringMap<llvm::vfs::Status,
|
||||
llvm::BumpPtrAllocator>::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<llvm::vfs::File> *F,
|
||||
llvm::vfs::FileSystem &FS) override;
|
||||
};
|
||||
|
|
|
@ -144,8 +144,8 @@ const DirectoryEntry *FileManager::getDirectory(StringRef DirName,
|
|||
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 @@ const DirectoryEntry *FileManager::getDirectory(StringRef DirName,
|
|||
// 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 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile,
|
|||
|
||||
// Check to see if the file exists.
|
||||
std::unique_ptr<llvm::vfs::File> 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 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile,
|
|||
|
||||
// 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 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile,
|
|||
// 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 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile,
|
|||
|
||||
// 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 @@ FileManager::getVirtualFile(StringRef Filename, off_t Size,
|
|||
"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 @@ FileManager::getVirtualFile(StringRef Filename, off_t Size,
|
|||
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<FileEntry>());
|
||||
UFE = VirtualFileEntries.back().get();
|
||||
|
@ -421,17 +423,18 @@ FileManager::getBufferForFile(StringRef Filename, bool isVolatile) {
|
|||
/// 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<llvm::vfs::File> *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);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,18 +21,6 @@ using namespace clang;
|
|||
|
||||
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 @@ static void copyStatusToFileData(const llvm::vfs::Status &Status,
|
|||
/// 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<llvm::vfs::File> *F,
|
||||
FileSystemStatCache *Cache,
|
||||
llvm::vfs::FileSystem &FS) {
|
||||
|
@ -51,16 +40,16 @@ bool FileSystemStatCache::get(StringRef Path, FileData &Data, bool isFile,
|
|||
|
||||
// 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<llvm::vfs::Status> Status = FS.status(Path);
|
||||
if (!Status) {
|
||||
llvm::ErrorOr<llvm::vfs::Status> 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 @@ bool FileSystemStatCache::get(StringRef Path, FileData &Data, bool isFile,
|
|||
// 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<llvm::vfs::Status> Status = (*OwnedFile)->status();
|
||||
if (Status) {
|
||||
llvm::ErrorOr<llvm::vfs::Status> 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 @@ bool FileSystemStatCache::get(StringRef Path, FileData &Data, bool isFile,
|
|||
|
||||
// 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 @@ bool FileSystemStatCache::get(StringRef Path, FileData &Data, bool isFile,
|
|||
}
|
||||
|
||||
MemorizeStatCalls::LookupResult
|
||||
MemorizeStatCalls::getStat(StringRef Path, FileData &Data, bool isFile,
|
||||
MemorizeStatCalls::getStat(StringRef Path, llvm::vfs::Status &Status,
|
||||
bool isFile,
|
||||
std::unique_ptr<llvm::vfs::File> *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 @@ MemorizeStatCalls::getStat(StringRef Path, FileData &Data, bool isFile,
|
|||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
|
|
@ -792,8 +792,6 @@ void TextDiagnostic::emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc,
|
|||
const FileEntry *FE = Loc.getFileEntry();
|
||||
if (FE && FE->isValid()) {
|
||||
emitFilename(FE->getName(), Loc.getManager());
|
||||
if (FE->isInPCH())
|
||||
OS << " (in PCH)";
|
||||
OS << ": ";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ class FakeStatCache : public FileSystemStatCache {
|
|||
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<FileData, llvm::BumpPtrAllocator> StatCalls;
|
||||
llvm::StringMap<llvm::vfs::Status, llvm::BumpPtrAllocator> StatCalls;
|
||||
|
||||
void InjectFileOrDirectory(const char *Path, ino_t INode, bool IsFile) {
|
||||
#ifndef _WIN32
|
||||
|
@ -35,15 +35,14 @@ private:
|
|||
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 @@ public:
|
|||
}
|
||||
|
||||
// Implement FileSystemStatCache::getStat().
|
||||
LookupResult getStat(StringRef Path, FileData &Data, bool isFile,
|
||||
LookupResult getStat(StringRef Path, llvm::vfs::Status &Status, bool isFile,
|
||||
std::unique_ptr<llvm::vfs::File> *F,
|
||||
llvm::vfs::FileSystem &FS) override {
|
||||
#ifndef _WIN32
|
||||
|
@ -68,7 +67,7 @@ public:
|
|||
#endif
|
||||
|
||||
if (StatCalls.count(Path) != 0) {
|
||||
Data = StatCalls[Path];
|
||||
Status = StatCalls[Path];
|
||||
return CacheExists;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue