Skip to content

Commit aef9d51

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 c7b383c commit aef9d51

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
@@ -87,5 +87,7 @@ WARNING(import_multiple_mainactor_attr,none,
8787
"this attribute for global actor '%0' is invalid; the declaration already has attribute for global actor '%1'",
8888
(StringRef, StringRef))
8989

90+
ERROR(module_map_not_found, none, "module map file '%0' not found", (StringRef))
91+
9092
#define UNDEFINE_DIAGNOSTIC_MACROS
9193
#include "DefineDiagnosticMacros.h"

lib/ClangImporter/ClangImporter.cpp

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -993,8 +993,38 @@ ClangImporter::createClangInvocation(ClangImporter *importer,
993993
&tempDiagClient,
994994
/*owned*/false);
995995

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

10001030
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)