149a150,155
> for (llvm::SmallVectorImpl<FileEntry *>::iterator
> V = VirtualFileEntries.begin(),
> VEnd = VirtualFileEntries.end();
> V != VEnd;
> ++V)
> delete *V;
186a193,216
> /// \brief Retrieve the directory that the given file name resides in.
> static const DirectoryEntry *getDirectoryFromFile(FileManager &FileMgr,
> const char *NameStart,
> const char *NameEnd) {
> // Figure out what directory it is in. If the string contains a / in it,
> // strip off everything after it.
> // FIXME: this logic should be in sys::Path.
> const char *SlashPos = NameEnd-1;
> while (SlashPos >= NameStart && !IS_DIR_SEPARATOR_CHAR(SlashPos[0]))
> --SlashPos;
> // Ignore duplicate //'s.
> while (SlashPos > NameStart && IS_DIR_SEPARATOR_CHAR(SlashPos[-1]))
> --SlashPos;
>
> if (SlashPos < NameStart) {
> // Use the current directory if file has no path component.
> const char *Name = ".";
> return FileMgr.getDirectory(Name, Name+1);
> } else if (SlashPos == NameEnd-1)
> return 0; // If filename ends with a /, it's a directory.
> else
> return FileMgr.getDirectory(NameStart, SlashPos);
> }
>
255,263d284
< // Figure out what directory it is in. If the string contains a / in it,
< // strip off everything after it.
< // FIXME: this logic should be in sys::Path.
< const char *SlashPos = NameEnd-1;
< while (SlashPos >= NameStart && !IS_DIR_SEPARATOR_CHAR(SlashPos[0]))
< --SlashPos;
< // Ignore duplicate //'s.
< while (SlashPos > NameStart && IS_DIR_SEPARATOR_CHAR(SlashPos[-1]))
< --SlashPos;
265,277d285
< const DirectoryEntry *DirInfo;
< if (SlashPos < NameStart) {
< // Use the current directory if file has no path component.
< const char *Name = ".";
< DirInfo = getDirectory(Name, Name+1);
< } else if (SlashPos == NameEnd-1)
< return 0; // If filename ends with a /, it's a directory.
< else
< DirInfo = getDirectory(NameStart, SlashPos);
<
< if (DirInfo == 0) // Directory doesn't exist, file can't exist.
< return 0;
<
281a290,294
> const DirectoryEntry *DirInfo
> = getDirectoryFromFile(*this, NameStart, NameEnd);
> if (DirInfo == 0) // Directory doesn't exist, file can't exist.
> return 0;
>
314a328,365
> const FileEntry *
> FileManager::getVirtualFile(const llvm::StringRef &Filename,
> off_t Size, time_t ModificationTime) {
> const char *NameStart = Filename.begin(), *NameEnd = Filename.end();
>
> ++NumFileLookups;
>
> // See if there is already an entry in the map.
> llvm::StringMapEntry<FileEntry *> &NamedFileEnt =
> FileEntries.GetOrCreateValue(NameStart, NameEnd);
>
> // See if there is already an entry in the map.
> if (NamedFileEnt.getValue())
> return NamedFileEnt.getValue() == NON_EXISTENT_FILE
> ? 0 : NamedFileEnt.getValue();
>
> ++NumFileCacheMisses;
>
> // By default, initialize it to invalid.
> NamedFileEnt.setValue(NON_EXISTENT_FILE);
>
> const DirectoryEntry *DirInfo
> = getDirectoryFromFile(*this, NameStart, NameEnd);
> if (DirInfo == 0) // Directory doesn't exist, file can't exist.
> return 0;
>
> FileEntry *UFE = new FileEntry();
> VirtualFileEntries.push_back(UFE);
> NamedFileEnt.setValue(UFE);
>
> UFE->Name = NamedFileEnt.getKeyData();
> UFE->Size = Size;
> UFE->ModTime = ModificationTime;
> UFE->Dir = DirInfo;
> UFE->UID = NextFileUID++;
> return UFE;
> }
>
330,338c381,389
< if (result != 0) {
< // Cache failed 'stat' results.
< struct stat empty;
< memset(&empty, 0, sizeof(empty));
< StatCalls[path] = StatResult(result, empty);
< }
< else if (!S_ISDIR(buf->st_mode) || llvm::sys::Path(path).isAbsolute()) {
< // Cache file 'stat' results and directories with absolutely
< // paths.
---
> // 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 FileManager
> // entries).
> if (result != 0)
> return result;
>
> // Cache file 'stat' results and directories with absolutely paths.
> if (!S_ISDIR(buf->st_mode) || llvm::sys::Path(path).isAbsolute())
340d390
< }
> for (llvm::SmallVectorImpl<FileEntry *>::iterator
> V = VirtualFileEntries.begin(),
> VEnd = VirtualFileEntries.end();
> V != VEnd;
> ++V)
> delete *V;
186a193,216
> /// \brief Retrieve the directory that the given file name resides in.
> static const DirectoryEntry *getDirectoryFromFile(FileManager &FileMgr,
> const char *NameStart,
> const char *NameEnd) {
> // Figure out what directory it is in. If the string contains a / in it,
> // strip off everything after it.
> // FIXME: this logic should be in sys::Path.
> const char *SlashPos = NameEnd-1;
> while (SlashPos >= NameStart && !IS_DIR_SEPARATOR_CHAR(SlashPos[0]))
> --SlashPos;
> // Ignore duplicate //'s.
> while (SlashPos > NameStart && IS_DIR_SEPARATOR_CHAR(SlashPos[-1]))
> --SlashPos;
>
> if (SlashPos < NameStart) {
> // Use the current directory if file has no path component.
> const char *Name = ".";
> return FileMgr.getDirectory(Name, Name+1);
> } else if (SlashPos == NameEnd-1)
> return 0; // If filename ends with a /, it's a directory.
> else
> return FileMgr.getDirectory(NameStart, SlashPos);
> }
>
255,263d284
< // Figure out what directory it is in. If the string contains a / in it,
< // strip off everything after it.
< // FIXME: this logic should be in sys::Path.
< const char *SlashPos = NameEnd-1;
< while (SlashPos >= NameStart && !IS_DIR_SEPARATOR_CHAR(SlashPos[0]))
< --SlashPos;
< // Ignore duplicate //'s.
< while (SlashPos > NameStart && IS_DIR_SEPARATOR_CHAR(SlashPos[-1]))
< --SlashPos;
265,277d285
< const DirectoryEntry *DirInfo;
< if (SlashPos < NameStart) {
< // Use the current directory if file has no path component.
< const char *Name = ".";
< DirInfo = getDirectory(Name, Name+1);
< } else if (SlashPos == NameEnd-1)
< return 0; // If filename ends with a /, it's a directory.
< else
< DirInfo = getDirectory(NameStart, SlashPos);
<
< if (DirInfo == 0) // Directory doesn't exist, file can't exist.
< return 0;
<
281a290,294
> const DirectoryEntry *DirInfo
> = getDirectoryFromFile(*this, NameStart, NameEnd);
> if (DirInfo == 0) // Directory doesn't exist, file can't exist.
> return 0;
>
314a328,365
> const FileEntry *
> FileManager::getVirtualFile(const llvm::StringRef &Filename,
> off_t Size, time_t ModificationTime) {
> const char *NameStart = Filename.begin(), *NameEnd = Filename.end();
>
> ++NumFileLookups;
>
> // See if there is already an entry in the map.
> llvm::StringMapEntry<FileEntry *> &NamedFileEnt =
> FileEntries.GetOrCreateValue(NameStart, NameEnd);
>
> // See if there is already an entry in the map.
> if (NamedFileEnt.getValue())
> return NamedFileEnt.getValue() == NON_EXISTENT_FILE
> ? 0 : NamedFileEnt.getValue();
>
> ++NumFileCacheMisses;
>
> // By default, initialize it to invalid.
> NamedFileEnt.setValue(NON_EXISTENT_FILE);
>
> const DirectoryEntry *DirInfo
> = getDirectoryFromFile(*this, NameStart, NameEnd);
> if (DirInfo == 0) // Directory doesn't exist, file can't exist.
> return 0;
>
> FileEntry *UFE = new FileEntry();
> VirtualFileEntries.push_back(UFE);
> NamedFileEnt.setValue(UFE);
>
> UFE->Name = NamedFileEnt.getKeyData();
> UFE->Size = Size;
> UFE->ModTime = ModificationTime;
> UFE->Dir = DirInfo;
> UFE->UID = NextFileUID++;
> return UFE;
> }
>
330,338c381,389
< if (result != 0) {
< // Cache failed 'stat' results.
< struct stat empty;
< memset(&empty, 0, sizeof(empty));
< StatCalls[path] = StatResult(result, empty);
< }
< else if (!S_ISDIR(buf->st_mode) || llvm::sys::Path(path).isAbsolute()) {
< // Cache file 'stat' results and directories with absolutely
< // paths.
---
> // 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 FileManager
> // entries).
> if (result != 0)
> return result;
>
> // Cache file 'stat' results and directories with absolutely paths.
> if (!S_ISDIR(buf->st_mode) || llvm::sys::Path(path).isAbsolute())
340d390
< }