diff options
Diffstat (limited to 'lib/Basic/FileManager.cpp')
| -rw-r--r-- | lib/Basic/FileManager.cpp | 50 | 
1 files changed, 32 insertions, 18 deletions
diff --git a/lib/Basic/FileManager.cpp b/lib/Basic/FileManager.cpp index f747c534c0ed..c1f715ed0592 100644 --- a/lib/Basic/FileManager.cpp +++ b/lib/Basic/FileManager.cpp @@ -217,25 +217,26 @@ void FileManager::removeStatCache(FileSystemStatCache *statCache) {  /// \brief Retrieve the directory that the given file name resides in.  /// Filename can point to either a real file or a virtual file.  static const DirectoryEntry *getDirectoryFromFile(FileManager &FileMgr, -                                                  llvm::StringRef Filename) { +                                                  StringRef Filename, +                                                  bool CacheFailure) {    if (Filename.empty())      return NULL;    if (llvm::sys::path::is_separator(Filename[Filename.size() - 1]))      return NULL;  // If Filename is a directory. -  llvm::StringRef DirName = llvm::sys::path::parent_path(Filename); +  StringRef DirName = llvm::sys::path::parent_path(Filename);    // Use the current directory if file has no path component.    if (DirName.empty())      DirName = "."; -  return FileMgr.getDirectory(DirName); +  return FileMgr.getDirectory(DirName, CacheFailure);  }  /// Add all ancestors of the given path (pointing to either a file or  /// a directory) as virtual directories. -void FileManager::addAncestorsAsVirtualDirs(llvm::StringRef Path) { -  llvm::StringRef DirName = llvm::sys::path::parent_path(Path); +void FileManager::addAncestorsAsVirtualDirs(StringRef Path) { +  StringRef DirName = llvm::sys::path::parent_path(Path);    if (DirName.empty())      return; @@ -263,7 +264,8 @@ void FileManager::addAncestorsAsVirtualDirs(llvm::StringRef Path) {  /// (real or virtual).  This returns NULL if the directory doesn't  /// exist.  /// -const DirectoryEntry *FileManager::getDirectory(llvm::StringRef DirName) { +const DirectoryEntry *FileManager::getDirectory(StringRef DirName, +                                                bool CacheFailure) {    ++NumDirLookups;    llvm::StringMapEntry<DirectoryEntry *> &NamedDirEnt =      SeenDirEntries.GetOrCreateValue(DirName); @@ -287,6 +289,8 @@ const DirectoryEntry *FileManager::getDirectory(llvm::StringRef DirName) {    struct stat StatBuf;    if (getStatValue(InterndDirName, StatBuf, 0/*directory lookup*/)) {      // There's no real directory at the given path. +    if (!CacheFailure) +      SeenDirEntries.erase(DirName);      return 0;    } @@ -309,7 +313,8 @@ const DirectoryEntry *FileManager::getDirectory(llvm::StringRef DirName) {  /// getFile - Lookup, cache, and verify the specified file (real or  /// virtual).  This returns NULL if the file doesn't exist.  /// -const FileEntry *FileManager::getFile(llvm::StringRef Filename, bool openFile) { +const FileEntry *FileManager::getFile(StringRef Filename, bool openFile, +                                      bool CacheFailure) {    ++NumFileLookups;    // See if there is already an entry in the map. @@ -335,10 +340,15 @@ const FileEntry *FileManager::getFile(llvm::StringRef Filename, bool openFile) {    // subdirectory.  This will let us avoid having to waste time on known-to-fail    // searches when we go to find sys/bar.h, because all the search directories    // without a 'sys' subdir will get a cached failure result. -  const DirectoryEntry *DirInfo = getDirectoryFromFile(*this, Filename); -  if (DirInfo == 0)  // Directory doesn't exist, file can't exist. +  const DirectoryEntry *DirInfo = getDirectoryFromFile(*this, Filename, +                                                       CacheFailure); +  if (DirInfo == 0) {  // Directory doesn't exist, file can't exist. +    if (!CacheFailure) +      SeenFileEntries.erase(Filename); +          return 0; - +  } +      // FIXME: Use the directory info to prune this, before doing the stat syscall.    // FIXME: This will reduce the # syscalls. @@ -347,6 +357,9 @@ const FileEntry *FileManager::getFile(llvm::StringRef Filename, bool openFile) {    struct stat StatBuf;    if (getStatValue(InterndFileName, StatBuf, &FileDescriptor)) {      // There's no real file at the given path. +    if (!CacheFailure) +      SeenFileEntries.erase(Filename); +          return 0;    } @@ -381,7 +394,7 @@ const FileEntry *FileManager::getFile(llvm::StringRef Filename, bool openFile) {  }  const FileEntry * -FileManager::getVirtualFile(llvm::StringRef Filename, off_t Size, +FileManager::getVirtualFile(StringRef Filename, off_t Size,                              time_t ModificationTime) {    ++NumFileLookups; @@ -404,7 +417,8 @@ FileManager::getVirtualFile(llvm::StringRef Filename, off_t Size,    // Now that all ancestors of Filename are in the cache, the    // following call is guaranteed to find the DirectoryEntry from the    // cache. -  const DirectoryEntry *DirInfo = getDirectoryFromFile(*this, Filename); +  const DirectoryEntry *DirInfo = getDirectoryFromFile(*this, Filename, +                                                       /*CacheFailure=*/true);    assert(DirInfo &&           "The directory of a virtual file should already be in the cache."); @@ -451,8 +465,8 @@ FileManager::getVirtualFile(llvm::StringRef Filename, off_t Size,    return UFE;  } -void FileManager::FixupRelativePath(llvm::SmallVectorImpl<char> &path) const { -  llvm::StringRef pathRef(path.data(), path.size()); +void FileManager::FixupRelativePath(SmallVectorImpl<char> &path) const { +  StringRef pathRef(path.data(), path.size());    if (FileSystemOpts.WorkingDir.empty()         || llvm::sys::path::is_absolute(pathRef)) @@ -499,7 +513,7 @@ getBufferForFile(const FileEntry *Entry, std::string *ErrorStr) {  }  llvm::MemoryBuffer *FileManager:: -getBufferForFile(llvm::StringRef Filename, std::string *ErrorStr) { +getBufferForFile(StringRef Filename, std::string *ErrorStr) {    llvm::OwningPtr<llvm::MemoryBuffer> Result;    llvm::error_code ec;    if (FileSystemOpts.WorkingDir.empty()) { @@ -537,7 +551,7 @@ bool FileManager::getStatValue(const char *Path, struct stat &StatBuf,                                    StatCache.get());  } -bool FileManager::getNoncachedStatValue(llvm::StringRef Path,  +bool FileManager::getNoncachedStatValue(StringRef Path,                                           struct stat &StatBuf) {    llvm::SmallString<128> FilePath(Path);    FixupRelativePath(FilePath); @@ -546,7 +560,7 @@ bool FileManager::getNoncachedStatValue(llvm::StringRef Path,  }  void FileManager::GetUniqueIDMapping( -                   llvm::SmallVectorImpl<const FileEntry *> &UIDToFiles) const { +                   SmallVectorImpl<const FileEntry *> &UIDToFiles) const {    UIDToFiles.clear();    UIDToFiles.resize(NextFileUID); @@ -558,7 +572,7 @@ void FileManager::GetUniqueIDMapping(        UIDToFiles[FE->getValue()->getUID()] = FE->getValue();    // Map virtual file entries -  for (llvm::SmallVector<FileEntry*, 4>::const_iterator  +  for (SmallVector<FileEntry*, 4>::const_iterator            VFE = VirtualFileEntries.begin(), VFEEnd = VirtualFileEntries.end();         VFE != VFEEnd; ++VFE)      if (*VFE && *VFE != NON_EXISTENT_FILE)  | 
