Skip to content

Commit eb1c0e7

Browse files
committed
[Dependency Scanning] Add required additional C++ interop overlay module queries
1 parent bc17581 commit eb1c0e7

File tree

7 files changed

+62
-20
lines changed

7 files changed

+62
-20
lines changed

include/swift/AST/ModuleDependencies.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,9 @@ class ClangModuleDependencyStorage : public ModuleDependencyInfoStorageBase {
403403
/// CASID for the Root of ClangIncludeTree. Empty if not used.
404404
std::string CASClangIncludeTreeRootID;
405405

406+
/// Whether this is a "system" module.
407+
bool IsSystem;
408+
406409
ClangModuleDependencyStorage(const std::string &pcmOutputPath,
407410
const std::string &mappedPCMPath,
408411
const std::string &moduleMapFile,
@@ -412,15 +415,16 @@ class ClangModuleDependencyStorage : public ModuleDependencyInfoStorageBase {
412415
const std::vector<std::string> &capturedPCMArgs,
413416
const std::string &CASFileSystemRootID,
414417
const std::string &clangIncludeTreeRoot,
415-
const std::string &moduleCacheKey)
418+
const std::string &moduleCacheKey,
419+
bool IsSystem)
416420
: ModuleDependencyInfoStorageBase(ModuleDependencyKind::Clang,
417421
moduleCacheKey),
418422
pcmOutputPath(pcmOutputPath), mappedPCMPath(mappedPCMPath),
419423
moduleMapFile(moduleMapFile), contextHash(contextHash),
420424
buildCommandLine(buildCommandLine), fileDependencies(fileDependencies),
421425
capturedPCMArgs(capturedPCMArgs),
422426
CASFileSystemRootID(CASFileSystemRootID),
423-
CASClangIncludeTreeRootID(clangIncludeTreeRoot) {}
427+
CASClangIncludeTreeRootID(clangIncludeTreeRoot), IsSystem(IsSystem) {}
424428

425429
ModuleDependencyInfoStorageBase *clone() const override {
426430
return new ClangModuleDependencyStorage(*this);
@@ -549,11 +553,12 @@ class ModuleDependencyInfo {
549553
const std::vector<std::string> &capturedPCMArgs,
550554
const std::string &CASFileSystemRootID,
551555
const std::string &clangIncludeTreeRoot,
552-
const std::string &moduleCacheKey) {
556+
const std::string &moduleCacheKey,
557+
bool IsSystem) {
553558
return ModuleDependencyInfo(std::make_unique<ClangModuleDependencyStorage>(
554559
pcmOutputPath, mappedPCMPath, moduleMapFile, contextHash,
555560
nonPathCommandLine, fileDependencies, capturedPCMArgs,
556-
CASFileSystemRootID, clangIncludeTreeRoot, moduleCacheKey));
561+
CASFileSystemRootID, clangIncludeTreeRoot, moduleCacheKey, IsSystem));
557562
}
558563

559564
/// Describe a placeholder dependency swift module.

include/swift/ClangImporter/ClangImporter.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,11 @@ bool requiresCPlusPlus(const clang::Module *module);
665665
/// (std_vector, std_iosfwd, etc).
666666
bool isCxxStdModule(const clang::Module *module);
667667

668+
/// Returns true if the given module is one of the C++ standard library modules.
669+
/// This could be the top-level std module, or any of the libc++ split modules
670+
/// (std_vector, std_iosfwd, etc).
671+
bool isCxxStdModule(StringRef moduleName, bool IsSystem);
672+
668673
/// Returns the pointee type if the given type is a C++ `const`
669674
/// reference type, `None` otherwise.
670675
std::optional<clang::QualType>

include/swift/DependencyScan/SerializedModuleDependencyCacheFormat.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ using ContextHashIDField = IdentifierIDField;
5353

5454
/// A bit that indicates whether or not a module is a framework
5555
using IsFrameworkField = BCFixed<1>;
56+
/// A bit that indicates whether or not a module is a system module
57+
using IsSystemField = BCFixed<1>;
5658

5759
/// Arrays of various identifiers, distinguished for readability
5860
using IdentifierIDArryField = llvm::BCArray<IdentifierIDField>;
@@ -193,7 +195,8 @@ using ClangModuleDetailsLayout =
193195
FlagIDArrayIDField, // capturedPCMArgs
194196
IdentifierIDField, // CASFileSystemRootID
195197
IdentifierIDField, // clangIncludeTreeRoot
196-
IdentifierIDField // moduleCacheKey
198+
IdentifierIDField, // moduleCacheKey
199+
IsSystemField // isSystem
197200
>;
198201
} // namespace graph_block
199202

lib/ClangImporter/ClangImporter.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7894,14 +7894,20 @@ bool importer::requiresCPlusPlus(const clang::Module *module) {
78947894
}
78957895

78967896
bool importer::isCxxStdModule(const clang::Module *module) {
7897-
if (module->getTopLevelModuleName() == "std")
7897+
return isCxxStdModule(module->getTopLevelModuleName(),
7898+
module->getTopLevelModule()->IsSystem);
7899+
}
7900+
7901+
bool importer::isCxxStdModule(StringRef moduleName, bool IsSystem) {
7902+
if (moduleName == "std")
78987903
return true;
78997904
// In recent libc++ versions the module is split into multiple top-level
79007905
// modules (std_vector, std_utility, etc).
7901-
if (module->getTopLevelModule()->IsSystem &&
7902-
module->getTopLevelModuleName().starts_with("std_"))
7906+
if (IsSystem && moduleName.starts_with("std_")) {
7907+
if (moduleName == "std_errno_h")
7908+
return false;
79037909
return true;
7904-
7910+
}
79057911
return false;
79067912
}
79077913

lib/ClangImporter/ClangModuleDependencyScanner.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ ModuleDependencyVector ClangImporter::bridgeClangModuleDependencies(
289289
auto dependencies = ModuleDependencyInfo::forClangModule(
290290
pcmPath, mappedPCMPath, clangModuleDep.ClangModuleMapFile,
291291
clangModuleDep.ID.ContextHash, swiftArgs, fileDeps, capturedPCMArgs,
292-
RootID, IncludeTree, /*module-cache-key*/ "");
292+
RootID, IncludeTree, /*module-cache-key*/ "", clangModuleDep.IsSystem);
293293
for (const auto &moduleName : clangModuleDep.ClangModuleDeps) {
294294
dependencies.addModuleImport(moduleName.ModuleName, &alreadyAddedModules);
295295
// It is safe to assume that all dependencies of a Clang module are Clang modules.

lib/DependencyScan/ModuleDependencyCacheSerialization.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -574,12 +574,12 @@ bool ModuleDependenciesCacheDeserializer::readGraph(SwiftDependencyScanningServi
574574
cache.configureForContextHash(getContextHash());
575575
unsigned pcmOutputPathID, mappedPCMPathID, moduleMapPathID, contextHashID,
576576
commandLineArrayID, fileDependenciesArrayID, capturedPCMArgsArrayID,
577-
CASFileSystemRootID, clangIncludeTreeRootID, moduleCacheKeyID;
577+
CASFileSystemRootID, clangIncludeTreeRootID, moduleCacheKeyID, isSystem;
578578
ClangModuleDetailsLayout::readRecord(
579579
Scratch, pcmOutputPathID, mappedPCMPathID, moduleMapPathID,
580580
contextHashID, commandLineArrayID, fileDependenciesArrayID,
581581
capturedPCMArgsArrayID, CASFileSystemRootID, clangIncludeTreeRootID,
582-
moduleCacheKeyID);
582+
moduleCacheKeyID, isSystem);
583583
auto pcmOutputPath = getIdentifier(pcmOutputPathID);
584584
if (!pcmOutputPath)
585585
llvm::report_fatal_error("Bad pcm output path");
@@ -615,7 +615,7 @@ bool ModuleDependenciesCacheDeserializer::readGraph(SwiftDependencyScanningServi
615615
auto moduleDep = ModuleDependencyInfo::forClangModule(
616616
*pcmOutputPath, *mappedPCMPath, *moduleMapPath, *contextHash,
617617
*commandLineArgs, *fileDependencies, *capturedPCMArgs,
618-
*rootFileSystemID, *clangIncludeTreeRoot, *moduleCacheKey);
618+
*rootFileSystemID, *clangIncludeTreeRoot, *moduleCacheKey, isSystem);
619619

620620
// Add dependencies of this module
621621
for (const auto &moduleName : *currentModuleImports)
@@ -1064,7 +1064,7 @@ void ModuleDependenciesCacheSerializer::writeModuleInfo(
10641064
getArrayID(moduleID, ModuleIdentifierArrayKind::CapturedPCMArgs),
10651065
getIdentifier(clangDeps->CASFileSystemRootID),
10661066
getIdentifier(clangDeps->CASClangIncludeTreeRootID),
1067-
getIdentifier(clangDeps->moduleCacheKey));
1067+
getIdentifier(clangDeps->moduleCacheKey), clangDeps->IsSystem);
10681068

10691069
break;
10701070
}

lib/DependencyScan/ModuleDependencyScanner.cpp

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "swift/AST/TypeCheckRequests.h"
2222
#include "swift/Basic/FileTypes.h"
2323
#include "swift/Basic/PrettyStackTrace.h"
24+
#include "swift/ClangImporter/ClangImporter.h"
2425
#include "swift/DependencyScan/ModuleDependencyScanner.h"
2526
#include "swift/Frontend/ModuleInterfaceLoader.h"
2627
#include "swift/Serialization/SerializedModuleLoader.h"
@@ -774,24 +775,46 @@ void ModuleDependencyScanner::resolveSwiftOverlayDependencies(
774775
// FIXME: Once all clients know to fetch these dependencies from
775776
// `swiftOverlayDependencies`, the goal is to no longer have them in
776777
// `directDependencies` so the following will need to go away.
777-
directDependencies.insert({moduleName, cachedInfo->getKind()});
778+
directDependencies.insert({moduleName, cachedInfo->getKind()});
778779
} else {
779780
// Cache discovered module dependencies.
780781
cache.recordDependencies(lookupResult.value());
781782
if (!lookupResult.value().empty()) {
782-
swiftOverlayDependencies.insert(
783-
{moduleName, lookupResult.value()[0].first.Kind});
783+
swiftOverlayDependencies.insert({moduleName, lookupResult.value()[0].first.Kind});
784784
// FIXME: Once all clients know to fetch these dependencies from
785785
// `swiftOverlayDependencies`, the goal is to no longer have them in
786786
// `directDependencies` so the following will need to go away.
787-
directDependencies.insert(
788-
{moduleName, lookupResult.value()[0].first.Kind});
789-
}
787+
directDependencies.insert({moduleName, lookupResult.value()[0].first.Kind});
788+
}
790789
}
791790
}
792791
};
793792
for (const auto &clangDep : clangDependencies)
794793
recordResult(clangDep);
794+
795+
// C++ Interop requires additional handling
796+
if (ScanCompilerInvocation.getLangOptions().EnableCXXInterop) {
797+
for (const auto &clangDepName : clangDependencies) {
798+
// If this Clang module is a part of the C++ stdlib, and we haven't loaded
799+
// the overlay for it so far, it is a split libc++ module (e.g.
800+
// std_vector). Load the CxxStdlib overlay explicitly.
801+
const auto &clangDepInfo =
802+
cache.findDependency(clangDepName, ModuleDependencyKind::Clang)
803+
.value()
804+
->getAsClangModule();
805+
if (importer::isCxxStdModule(clangDepName, clangDepInfo->IsSystem) &&
806+
!swiftOverlayDependencies.contains(
807+
{clangDepName, ModuleDependencyKind::SwiftInterface}) &&
808+
!swiftOverlayDependencies.contains(
809+
{clangDepName, ModuleDependencyKind::SwiftBinary})) {
810+
ScanningThreadPool.async(
811+
scanForSwiftDependency,
812+
getModuleImportIdentifier(ScanASTContext.Id_CxxStdlib.str()));
813+
ScanningThreadPool.wait();
814+
recordResult(ScanASTContext.Id_CxxStdlib.str().str());
815+
}
816+
}
817+
}
795818
}
796819

797820
void ModuleDependencyScanner::discoverCrossImportOverlayDependencies(

0 commit comments

Comments
 (0)