Skip to content

Commit 631ff40

Browse files
committed
[ClangImporter] Load the stdlib even if there is a -fmodule-map-file argument pointing to a missing file
If there is a `-fmodule-map-file` argument whose file doesn’t exist and SwiftShims is not in the module cache, we fail to build it, because clang throws an error about the missing module map. This causes SourceKit to drop all semantic functionality, even if the missing module map isn’t required. To work around this, drop all `-fmodule-map-file` arguments with missing files from the clang importer’s arguments, reporting the eror that `clang` would throw manually. Fixes rdar://77449671
1 parent bfb5ccd commit 631ff40

File tree

3 files changed

+43
-2
lines changed

3 files changed

+43
-2
lines changed

include/swift/AST/DiagnosticsClangImporter.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,5 +80,7 @@ WARNING(implicit_bridging_header_imported_from_module,none,
8080
"is deprecated and will be removed in a later version of Swift",
8181
(StringRef, Identifier))
8282

83+
ERROR(module_map_not_found, none, "module map file '%0' not found", (StringRef))
84+
8385
#define UNDEFINE_DIAGNOSTIC_MACROS
8486
#include "DefineDiagnosticMacros.h"

lib/ClangImporter/ClangImporter.cpp

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -987,8 +987,38 @@ ClangImporter::createClangInvocation(ClangImporter *importer,
987987
&tempDiagClient,
988988
/*owned*/false);
989989

990-
return clang::createInvocationFromCommandLine(invocationArgs, tempClangDiags,
991-
nullptr, false, CC1Args);
990+
auto CI = clang::createInvocationFromCommandLine(
991+
invocationArgs, tempClangDiags, nullptr, false, CC1Args);
992+
993+
if (!CI) {
994+
return CI;
995+
}
996+
997+
// FIXME: clang fails to generate a module if there is a `-fmodule-map-file`
998+
// argument pointing to a missing file.
999+
// Such missing module files occur frequently in SourceKit. If the files are
1000+
// missing, SourceKit fails to build SwiftShims (which wouldn't have required
1001+
// the missing module file), thus fails to load the stdlib and hence looses
1002+
// all semantic functionality.
1003+
// To work around this issue, drop all `-fmodule-map-file` arguments pointing
1004+
// to missing files and report the error that clang would throw manually.
1005+
// rdar://77516546 is tracking that the clang importer should be more
1006+
// resilient and provide a module even if there were building it.
1007+
auto VFS = clang::createVFSFromCompilerInvocation(
1008+
*CI, *tempClangDiags,
1009+
importer->Impl.SwiftContext.SourceMgr.getFileSystem());
1010+
std::vector<std::string> FilteredModuleMapFiles;
1011+
for (auto ModuleMapFile : CI->getFrontendOpts().ModuleMapFiles) {
1012+
if (VFS->exists(ModuleMapFile)) {
1013+
FilteredModuleMapFiles.push_back(ModuleMapFile);
1014+
} else {
1015+
importer->Impl.SwiftContext.Diags.diagnose(
1016+
SourceLoc(), diag::module_map_not_found, ModuleMapFile);
1017+
}
1018+
}
1019+
CI->getFrontendOpts().ModuleMapFiles = FilteredModuleMapFiles;
1020+
1021+
return CI;
9921022
}
9931023

9941024
std::unique_ptr<ClangImporter>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: %empty-directory(%t.mcp)
2+
// RUN: %sourcekitd-test -req=cursor -pos=6:9 %s -- -Xcc -fmodule-map-file=/some/missing/file -module-cache-path %t.mcp %s | %FileCheck %s
3+
4+
// We used to fail to load the stdlib if there is a `-fmodule-map-file` option pointing to a missing file
5+
6+
let x: String = "abc"
7+
// CHECK: source.lang.swift.ref.struct ()
8+
// CHECK: String
9+
// CHECK: s:SS

0 commit comments

Comments
 (0)