summaryrefslogtreecommitdiffstats
path: root/clang/lib/Basic/VirtualFileSystem.cpp
diff options
context:
space:
mode:
authorBruno Cardoso Lopes <bruno.cardoso@gmail.com>2016-08-12 01:51:04 +0000
committerBruno Cardoso Lopes <bruno.cardoso@gmail.com>2016-08-12 01:51:04 +0000
commit1dc8a422812cdbc23edbf4856a49a2e15d3cc591 (patch)
tree5ccf2c9dee75aa7f8485f9170860e4514d2a0dc7 /clang/lib/Basic/VirtualFileSystem.cpp
parentb40d8ad225a376d8032b261963113242a8d8102f (diff)
downloadbcm5719-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.cpp34
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();
}
OpenPOWER on IntegriCloud