diff options
author | Bruno Cardoso Lopes <bruno.cardoso@gmail.com> | 2016-08-12 01:51:04 +0000 |
---|---|---|
committer | Bruno Cardoso Lopes <bruno.cardoso@gmail.com> | 2016-08-12 01:51:04 +0000 |
commit | 1dc8a422812cdbc23edbf4856a49a2e15d3cc591 (patch) | |
tree | 5ccf2c9dee75aa7f8485f9170860e4514d2a0dc7 /clang/lib/Basic/VirtualFileSystem.cpp | |
parent | b40d8ad225a376d8032b261963113242a8d8102f (diff) | |
download | bcm5719-llvm-1dc8a422812cdbc23edbf4856a49a2e15d3cc591.tar.gz bcm5719-llvm-1dc8a422812cdbc23edbf4856a49a2e15d3cc591.zip |
[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
Diffstat (limited to 'clang/lib/Basic/VirtualFileSystem.cpp')
-rw-r--r-- | clang/lib/Basic/VirtualFileSystem.cpp | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/clang/lib/Basic/VirtualFileSystem.cpp b/clang/lib/Basic/VirtualFileSystem.cpp index 62a386b7352..a56c9115fb1 100644 --- a/clang/lib/Basic/VirtualFileSystem.cpp +++ b/clang/lib/Basic/VirtualFileSystem.cpp @@ -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(); } |