Index: include/clang/Basic/VirtualFileSystem.h =================================================================== --- include/clang/Basic/VirtualFileSystem.h +++ include/clang/Basic/VirtualFileSystem.h @@ -340,6 +340,7 @@ Optional IsCaseSensitive; Optional IsOverlayRelative; Optional UseExternalNames; + Optional IgnoreNonExistentContents; std::string OverlayDir; public: @@ -351,6 +352,9 @@ void setUseExternalNames(bool UseExtNames) { UseExternalNames = UseExtNames; } + void setIgnoreNonExistentContents(bool IgnoreContents) { + IgnoreNonExistentContents = IgnoreContents; + } void setOverlayDir(StringRef OverlayDirectory) { IsOverlayRelative = true; OverlayDir.assign(OverlayDirectory.str()); Index: lib/Basic/VirtualFileSystem.cpp =================================================================== --- lib/Basic/VirtualFileSystem.cpp +++ lib/Basic/VirtualFileSystem.cpp @@ -801,6 +801,7 @@ /// 'case-sensitive': /// 'use-external-names': /// 'overlay-relative': +/// 'ignore-non-existent-contents': /// /// Virtual directories are represented as /// \verbatim @@ -860,6 +861,14 @@ /// \brief Whether to use to use the value of 'external-contents' for the /// names of files. This global value is overridable on a per-file basis. bool UseExternalNames = true; + + /// \brief Whether an invalid path obtained via 'external-contents' should + /// cause iteration on the VFS to stop. If 'true', the VFS should ignore + /// the entry and continue with the next. Allows YAML files to be shared + /// across multiple compiler invocations regardless of prior existent + /// paths in 'external-contents'. This global value is overridable on a + /// per-file basis. + bool IgnoreNonExistentContents = true; /// @} /// Virtual file paths and external files could be canonicalized without "..", @@ -1301,6 +1310,7 @@ KeyStatusPair("case-sensitive", false), KeyStatusPair("use-external-names", false), KeyStatusPair("overlay-relative", false), + KeyStatusPair("ignore-non-existent-contents", false), KeyStatusPair("roots", true), }; @@ -1359,6 +1369,9 @@ } else if (Key == "use-external-names") { if (!parseScalarBool(I->getValue(), FS->UseExternalNames)) return false; + } else if (Key == "ignore-non-existent-contents") { + if (!parseScalarBool(I->getValue(), FS->IgnoreNonExistentContents)) + return false; } else { llvm_unreachable("key missing from Keys"); } @@ -1619,7 +1632,7 @@ JSONWriter(llvm::raw_ostream &OS) : OS(OS) {} void write(ArrayRef Entries, Optional UseExternalNames, Optional IsCaseSensitive, Optional IsOverlayRelative, - StringRef OverlayDir); + Optional IgnoreNonExistentContents, StringRef OverlayDir); }; } @@ -1675,6 +1688,7 @@ Optional UseExternalNames, Optional IsCaseSensitive, Optional IsOverlayRelative, + Optional IgnoreNonExistentContents, StringRef OverlayDir) { using namespace llvm::sys; @@ -1692,6 +1706,9 @@ OS << " 'overlay-relative': '" << (UseOverlayRelative ? "true" : "false") << "',\n"; } + if (IgnoreNonExistentContents.hasValue()) + OS << " 'ignore-non-existent-contents': '" + << (IgnoreNonExistentContents.getValue() ? "true" : "false") << "',\n"; OS << " 'roots': [\n"; if (!Entries.empty()) { @@ -1748,7 +1765,8 @@ }); JSONWriter(OS).write(Mappings, UseExternalNames, IsCaseSensitive, - IsOverlayRelative, OverlayDir); + IsOverlayRelative, IgnoreNonExistentContents, + OverlayDir); } VFSFromYamlDirIterImpl::VFSFromYamlDirIterImpl( Index: test/VFS/Inputs/vfsoverlay2.yaml =================================================================== --- test/VFS/Inputs/vfsoverlay2.yaml +++ test/VFS/Inputs/vfsoverlay2.yaml @@ -1,5 +1,6 @@ { 'version': 0, + 'ignore-non-existent-contents': false, 'roots': [ { 'name': 'OUT_DIR', 'type': 'directory', 'contents': [