diff options
Diffstat (limited to 'clang/lib/Basic/FileManager.cpp')
-rw-r--r-- | clang/lib/Basic/FileManager.cpp | 86 |
1 files changed, 52 insertions, 34 deletions
diff --git a/clang/lib/Basic/FileManager.cpp b/clang/lib/Basic/FileManager.cpp index 08f19fb2006..af9b2663cbf 100644 --- a/clang/lib/Basic/FileManager.cpp +++ b/clang/lib/Basic/FileManager.cpp @@ -30,6 +30,19 @@ #include <set> #include <string> +// FIXME: This is terrible, we need this for ::close. +#if !defined(_MSC_VER) && !defined(__MINGW32__) +#include <unistd.h> +#include <sys/uio.h> +#else +#include <io.h> +#ifndef S_ISFIFO +#define S_ISFIFO(x) (0) +#endif +#endif +#if defined(LLVM_ON_UNIX) +#include <limits.h> +#endif using namespace clang; // FIXME: Enhance libsystem to support inode and other fields. @@ -44,6 +57,12 @@ using namespace clang; #define NON_EXISTENT_FILE reinterpret_cast<FileEntry*>((intptr_t)-1) +FileEntry::~FileEntry() { + // If this FileEntry owns an open file descriptor that never got used, close + // it. + if (FD != -1) ::close(FD); +} + class FileManager::UniqueDirContainer { /// UniqueDirs - Cache from ID's to existing directories/files. std::map<llvm::sys::fs::UniqueID, DirectoryEntry> UniqueDirs; @@ -82,19 +101,13 @@ public: // Common logic. //===----------------------------------------------------------------------===// -FileManager::FileManager(const FileSystemOptions &FSO, - IntrusiveRefCntPtr<vfs::FileSystem> FS) - : FS(FS), FileSystemOpts(FSO), +FileManager::FileManager(const FileSystemOptions &FSO) + : FileSystemOpts(FSO), UniqueRealDirs(*new UniqueDirContainer()), UniqueRealFiles(*new UniqueFileContainer()), SeenDirEntries(64), SeenFileEntries(64), NextFileUID(0) { NumDirLookups = NumFileLookups = 0; NumDirCacheMisses = NumFileCacheMisses = 0; - - // If the caller doesn't provide a virtual file system, just grab the real - // file system. - if (!FS) - this->FS = vfs::getRealFileSystem(); } FileManager::~FileManager() { @@ -296,9 +309,10 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile, // FIXME: This will reduce the # syscalls. // Nope, there isn't. Check to see if the file exists. - vfs::File *F = 0; + int FileDescriptor = -1; FileData Data; - if (getStatValue(InterndFileName, Data, true, openFile ? &F : 0)) { + if (getStatValue(InterndFileName, Data, true, + openFile ? &FileDescriptor : 0)) { // There's no real file at the given path. if (!CacheFailure) SeenFileEntries.erase(Filename); @@ -306,7 +320,10 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile, return 0; } - assert(openFile || !F && "undesired open file"); + if (FileDescriptor != -1 && !openFile) { + close(FileDescriptor); + FileDescriptor = -1; + } // 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. @@ -316,8 +333,8 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile, NamedFileEnt.setValue(&UFE); if (UFE.getName()) { // Already have an entry with this inode, return it. // If the stat process opened the file, close it to avoid a FD leak. - if (F) - delete F; + if (FileDescriptor != -1) + close(FileDescriptor); return &UFE; } @@ -330,7 +347,7 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile, UFE.ModTime = Data.ModTime; UFE.Dir = DirInfo; UFE.UID = NextFileUID++; - UFE.File.reset(F); + UFE.FD = FileDescriptor; return &UFE; } @@ -376,8 +393,10 @@ FileManager::getVirtualFile(StringRef Filename, off_t Size, // If we had already opened this file, close it now so we don't // leak the descriptor. We're not going to use the file // descriptor anyway, since this is a virtual file. - if (UFE->File) - UFE->closeFile(); + if (UFE->FD != -1) { + close(UFE->FD); + UFE->FD = -1; + } // If we already have an entry with this inode, return it. if (UFE->getName()) @@ -395,7 +414,7 @@ FileManager::getVirtualFile(StringRef Filename, off_t Size, UFE->ModTime = ModificationTime; UFE->Dir = DirInfo; UFE->UID = NextFileUID++; - UFE->File.reset(); + UFE->FD = -1; return UFE; } @@ -425,18 +444,20 @@ getBufferForFile(const FileEntry *Entry, std::string *ErrorStr, const char *Filename = Entry->getName(); // If the file is already open, use the open file descriptor. - if (Entry->File) { - ec = Entry->File->getBuffer(Filename, Result, FileSize); + if (Entry->FD != -1) { + ec = llvm::MemoryBuffer::getOpenFile(Entry->FD, Filename, Result, FileSize); if (ErrorStr) *ErrorStr = ec.message(); - Entry->closeFile(); + + close(Entry->FD); + Entry->FD = -1; return Result.take(); } // Otherwise, open the file. if (FileSystemOpts.WorkingDir.empty()) { - ec = FS->getBufferForFile(Filename, Result, FileSize); + ec = llvm::MemoryBuffer::getFile(Filename, Result, FileSize); if (ec && ErrorStr) *ErrorStr = ec.message(); return Result.take(); @@ -444,7 +465,7 @@ getBufferForFile(const FileEntry *Entry, std::string *ErrorStr, SmallString<128> FilePath(Entry->getName()); FixupRelativePath(FilePath); - ec = FS->getBufferForFile(FilePath.str(), Result, FileSize); + ec = llvm::MemoryBuffer::getFile(FilePath.str(), Result, FileSize); if (ec && ErrorStr) *ErrorStr = ec.message(); return Result.take(); @@ -455,7 +476,7 @@ getBufferForFile(StringRef Filename, std::string *ErrorStr) { OwningPtr<llvm::MemoryBuffer> Result; llvm::error_code ec; if (FileSystemOpts.WorkingDir.empty()) { - ec = FS->getBufferForFile(Filename, Result); + ec = llvm::MemoryBuffer::getFile(Filename, Result); if (ec && ErrorStr) *ErrorStr = ec.message(); return Result.take(); @@ -463,7 +484,7 @@ getBufferForFile(StringRef Filename, std::string *ErrorStr) { SmallString<128> FilePath(Filename); FixupRelativePath(FilePath); - ec = FS->getBufferForFile(FilePath.c_str(), Result); + ec = llvm::MemoryBuffer::getFile(FilePath.c_str(), Result); if (ec && ErrorStr) *ErrorStr = ec.message(); return Result.take(); @@ -475,29 +496,26 @@ getBufferForFile(StringRef Filename, std::string *ErrorStr) { /// false if it's an existent real file. If FileDescriptor is NULL, /// do directory look-up instead of file look-up. bool FileManager::getStatValue(const char *Path, FileData &Data, bool isFile, - vfs::File **F) { + int *FileDescriptor) { // 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, Data, isFile, FileDescriptor, + StatCache.get()); SmallString<128> FilePath(Path); FixupRelativePath(FilePath); - return FileSystemStatCache::get(FilePath.c_str(), Data, isFile, F, - StatCache.get(), *FS); + return FileSystemStatCache::get(FilePath.c_str(), Data, isFile, + FileDescriptor, StatCache.get()); } bool FileManager::getNoncachedStatValue(StringRef Path, - vfs::Status &Result) { + llvm::sys::fs::file_status &Result) { SmallString<128> FilePath(Path); FixupRelativePath(FilePath); - llvm::ErrorOr<vfs::Status> S = FS->status(FilePath.c_str()); - if (!S) - return true; - Result = *S; - return false; + return llvm::sys::fs::status(FilePath.c_str(), Result); } void FileManager::invalidateCache(const FileEntry *Entry) { |