forked from OSchip/llvm-project
Reapply [VFS] Skip non existent files from the VFS tree
Reapply r278457 with test fixed to not abouse fs case sensitivity. 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: 278543
This commit is contained in:
parent
b1669ba1ed
commit
b7abde0343
|
@ -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();
|
||||
CurrentEntry = *S;
|
||||
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 {
|
||||
CurrentEntry = Status();
|
||||
return S.getError();
|
||||
}
|
||||
}
|
||||
CurrentEntry = *S;
|
||||
break;
|
||||
}
|
||||
|
||||
if (Current == End)
|
||||
CurrentEntry = Status();
|
||||
return std::error_code();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
// A.h
|
|
@ -0,0 +1 @@
|
|||
// B.h
|
|
@ -0,0 +1 @@
|
|||
// C.h
|
|
@ -0,0 +1,6 @@
|
|||
framework module Bar [extern_c] {
|
||||
umbrella "Headers"
|
||||
export *
|
||||
module * { export * }
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
'version': 0,
|
||||
'case-sensitive': 'false',
|
||||
'ignore-non-existent-contents': 'true',
|
||||
'roots': [
|
||||
{
|
||||
'type': 'directory',
|
||||
'name': "VDIR/Bar.framework/Headers",
|
||||
'contents': [
|
||||
{
|
||||
'type': 'file',
|
||||
'name': "A.h",
|
||||
'external-contents': "OUT_DIR/Bar.framework/Headers/A.h"
|
||||
},
|
||||
{
|
||||
'type': 'file',
|
||||
'name': "B.h",
|
||||
'external-contents': "OUT_DIR/Bar.framework/Headers/B.h"
|
||||
},
|
||||
{
|
||||
'type': 'file',
|
||||
'name': "C.h",
|
||||
'external-contents': "OUT_DIR/Bar.framework/Headers/C.h"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'type': 'directory',
|
||||
'name': "VDIR/Bar.framework/Modules",
|
||||
'contents': [
|
||||
{
|
||||
'type': 'file',
|
||||
'name': "module.modulemap",
|
||||
'external-contents': "OUT_DIR/Bar.framework/Modules/module.modulemap"
|
||||
}
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
// REQUIRES: crash-recovery, shell
|
||||
|
||||
// FIXME: This XFAIL is cargo-culted from crash-report.c. Do we need it?
|
||||
// XFAIL: mingw32
|
||||
|
||||
// RUN: rm -rf %t
|
||||
// RUN: mkdir -p %t/vdir %t/outdir %t/cache
|
||||
// RUN: cp -a %S/Inputs/Bar.framework %t/outdir/
|
||||
//
|
||||
// RUN: sed -e "s:VDIR:%t/vdir:g" -e "s:OUT_DIR:%t/outdir:g" %S/Inputs/bar-headers.yaml > %t/vdir/bar-headers.yaml
|
||||
// RUN: rm -f %t/outdir/Bar.framework/Headers/B.h
|
||||
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -ivfsoverlay %t/vdir/bar-headers.yaml -F %t/vdir -fsyntax-only %s
|
||||
|
||||
@import Bar;
|
Loading…
Reference in New Issue