Index: lib/Frontend/FrontendActions.cpp =================================================================== --- lib/Frontend/FrontendActions.cpp +++ lib/Frontend/FrontendActions.cpp @@ -209,17 +209,18 @@ std::error_code EC; SmallString<128> DirNative; llvm::sys::path::native(UmbrellaDir.Entry->getName(), DirNative); - for (llvm::sys::fs::recursive_directory_iterator Dir(DirNative, EC), - DirEnd; - Dir != DirEnd && !EC; Dir.increment(EC)) { + + vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem(); + for (vfs::recursive_directory_iterator Dir(FS, DirNative, EC), End; + Dir != End && !EC; Dir.increment(EC)) { // Check whether this entry has an extension typically associated with // headers. - if (!llvm::StringSwitch(llvm::sys::path::extension(Dir->path())) + if (!llvm::StringSwitch(llvm::sys::path::extension(Dir->getName())) .Cases(".h", ".H", ".hh", ".hpp", true) .Default(false)) continue; - const FileEntry *Header = FileMgr.getFile(Dir->path()); + const FileEntry *Header = FileMgr.getFile(Dir->getName()); // FIXME: This shouldn't happen unless there is a file system race. Is // that worth diagnosing? if (!Header) @@ -232,7 +233,7 @@ // Compute the relative path from the directory to this file. SmallVector Components; - auto PathIt = llvm::sys::path::rbegin(Dir->path()); + auto PathIt = llvm::sys::path::rbegin(Dir->getName()); for (int I = 0; I != Dir.level() + 1; ++I, ++PathIt) Components.push_back(*PathIt); SmallString<128> RelativeHeader(UmbrellaDir.NameAsWritten); Index: lib/Lex/HeaderSearch.cpp =================================================================== --- lib/Lex/HeaderSearch.cpp +++ lib/Lex/HeaderSearch.cpp @@ -1341,19 +1341,20 @@ DirNative); // Search each of the ".framework" directories to load them as modules. - for (llvm::sys::fs::directory_iterator Dir(DirNative, EC), DirEnd; + vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem(); + for (vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd; Dir != DirEnd && !EC; Dir.increment(EC)) { - if (llvm::sys::path::extension(Dir->path()) != ".framework") + if (llvm::sys::path::extension(Dir->getName()) != ".framework") continue; const DirectoryEntry *FrameworkDir = - FileMgr.getDirectory(Dir->path()); + FileMgr.getDirectory(Dir->getName()); if (!FrameworkDir) continue; // Load this framework module. - loadFrameworkModule(llvm::sys::path::stem(Dir->path()), FrameworkDir, - IsSystem); + loadFrameworkModule(llvm::sys::path::stem(Dir->getName()), + FrameworkDir, IsSystem); } continue; } @@ -1408,11 +1409,13 @@ std::error_code EC; SmallString<128> DirNative; llvm::sys::path::native(SearchDir.getDir()->getName(), DirNative); - for (llvm::sys::fs::directory_iterator Dir(DirNative, EC), DirEnd; + vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem(); + for (vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd; Dir != DirEnd && !EC; Dir.increment(EC)) { - bool IsFramework = llvm::sys::path::extension(Dir->path()) == ".framework"; + bool IsFramework = + llvm::sys::path::extension(Dir->getName()) == ".framework"; if (IsFramework == SearchDir.isFramework()) - loadModuleMapFile(Dir->path(), SearchDir.isSystemHeaderDirectory(), + loadModuleMapFile(Dir->getName(), SearchDir.isSystemHeaderDirectory(), SearchDir.isFramework()); } Index: lib/Lex/ModuleMap.cpp =================================================================== --- lib/Lex/ModuleMap.cpp +++ lib/Lex/ModuleMap.cpp @@ -711,13 +711,15 @@ = StringRef(FrameworkDir->getName()); llvm::sys::path::append(SubframeworksDirName, "Frameworks"); llvm::sys::path::native(SubframeworksDirName); - for (llvm::sys::fs::directory_iterator Dir(SubframeworksDirName, EC), DirEnd; + vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem(); + for (vfs::directory_iterator Dir = FS.dir_begin(SubframeworksDirName, EC), + DirEnd; Dir != DirEnd && !EC; Dir.increment(EC)) { - if (!StringRef(Dir->path()).endswith(".framework")) + if (!StringRef(Dir->getName()).endswith(".framework")) continue; - if (const DirectoryEntry *SubframeworkDir - = FileMgr.getDirectory(Dir->path())) { + if (const DirectoryEntry *SubframeworkDir = + FileMgr.getDirectory(Dir->getName())) { // Note: as an egregious but useful hack, we use the real path here and // check whether it is actually a subdirectory of the parent directory. // This will not be the case if the 'subframework' is actually a symlink @@ -1931,11 +1933,13 @@ // uncommonly used Tcl module on Darwin platforms. std::error_code EC; SmallVector Headers; - for (llvm::sys::fs::recursive_directory_iterator I(Dir->getName(), EC), E; + vfs::FileSystem &FS = *SourceMgr.getFileManager().getVirtualFileSystem(); + for (vfs::recursive_directory_iterator I(FS, Dir->getName(), EC), E; I != E && !EC; I.increment(EC)) { - if (const FileEntry *FE = SourceMgr.getFileManager().getFile(I->path())) { + if (const FileEntry *FE = + SourceMgr.getFileManager().getFile(I->getName())) { - Module::Header Header = {I->path(), FE}; + Module::Header Header = {I->getName(), FE}; Headers.push_back(std::move(Header)); } } Index: test/Modules/crash-vfs-umbrella-frameworks.m =================================================================== --- test/Modules/crash-vfs-umbrella-frameworks.m +++ test/Modules/crash-vfs-umbrella-frameworks.m @@ -40,3 +40,16 @@ // CHECKYAML-NEXT: 'external-contents': "/[[PATH]]/i/Frameworks/B.framework/Headers/B.h" @import I; + +// Run the reproducer script - regular exit code is enough to test it works. The +// intent here is to guarantee that the collect umbrella headers into the VFS +// can be used, testing that vfs::recursive_directory_iterator is used correctly +// Make sure to erase the include paths used to build the modules to guarantee +// that the VFS overlay won't fallback to use it. Also wipe out the module cache +// to force header search. +// +// RUN: cd %t +// RUN: rm -rf i +// RUN: rm -rf crash-vfs-umbrella-*.cache/modules/* +// RUN: chmod 755 crash-vfs-*.sh +// RUN: ./crash-vfs-*.sh