[VFS] Skip non existent files from the VFS tree
When the VFS uses a YAML file, the real file path for a
virtual file is described in the "external-contents" field. Example:
...
{
'type': 'file',
'name': 'a.h',
'external-contents': '/a/b/c/a.h'
}
Currently, when parsing umbrella directories, we use
vfs::recursive_directory_iterator to gather the header files to generate the
equivalent modules for. If the external contents for a header does not exist,
we currently are unable to build a module, since the VFS
vfs::recursive_directory_iterator will fail when it finds an entry without a
reliable real path.
Since the YAML file could be prepared ahead of time and shared among
different compiler invocations, an entry might not yet have a reliable
path in 'external-contents', breaking the iteration.
Give the VFS the capability to skip such entries whenever
'ignore-non-existent-contents' property is set in the YAML file.
rdar://problem/27531549
llvm-svn: 278457
This commit is contained in:
@@ -1778,29 +1778,47 @@ VFSFromYamlDirIterImpl::VFSFromYamlDirIterImpl(
|
||||
RedirectingDirectoryEntry::iterator Begin,
|
||||
RedirectingDirectoryEntry::iterator End, std::error_code &EC)
|
||||
: Dir(_Path.str()), FS(FS), Current(Begin), End(End) {
|
||||
if (Current != End) {
|
||||
while (Current != End) {
|
||||
SmallString<128> PathStr(Dir);
|
||||
llvm::sys::path::append(PathStr, (*Current)->getName());
|
||||
llvm::ErrorOr<vfs::Status> S = FS.status(PathStr);
|
||||
if (S)
|
||||
if (S) {
|
||||
CurrentEntry = *S;
|
||||
else
|
||||
return;
|
||||
}
|
||||
// Skip entries which do not map to a reliable external content.
|
||||
if (FS.ignoreNonExistentContents() &&
|
||||
S.getError() == llvm::errc::no_such_file_or_directory) {
|
||||
++Current;
|
||||
continue;
|
||||
} else {
|
||||
EC = S.getError();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::error_code VFSFromYamlDirIterImpl::increment() {
|
||||
assert(Current != End && "cannot iterate past end");
|
||||
if (++Current != End) {
|
||||
while (++Current != End) {
|
||||
SmallString<128> PathStr(Dir);
|
||||
llvm::sys::path::append(PathStr, (*Current)->getName());
|
||||
llvm::ErrorOr<vfs::Status> S = FS.status(PathStr);
|
||||
if (!S)
|
||||
return S.getError();
|
||||
if (!S) {
|
||||
// Skip entries which do not map to a reliable external content.
|
||||
if (FS.ignoreNonExistentContents() &&
|
||||
S.getError() == llvm::errc::no_such_file_or_directory) {
|
||||
continue;
|
||||
} else {
|
||||
return S.getError();
|
||||
}
|
||||
}
|
||||
CurrentEntry = *S;
|
||||
} else {
|
||||
CurrentEntry = Status();
|
||||
break;
|
||||
}
|
||||
|
||||
if (Current == End)
|
||||
CurrentEntry = Status();
|
||||
return std::error_code();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user