Skip to content

Commit 9147522

Browse files
committed
[cxx-interop] Correctly generate the list of transitive dependencies for CxxStdlib overlay
This fixes a compiler error that occurred while building `CxxStdlib.swiftmodule` and other projects that use C++ interop: `error: cannot find type 'std' in scope`. The compiler was creating two distinct `swift::ModuleDecl` instances for the CxxStdlib module while building the CxxStdlib overlay: one as a main module (the module that is currently being compiled), one as a dependency of the main module. This confused the Swift name lookup logic down the road. This only happened with recent libc++. See the inline comment for more details. rdar://122815523
1 parent d1961e1 commit 9147522

File tree

1 file changed

+15
-2
lines changed

1 file changed

+15
-2
lines changed

lib/ClangImporter/ClangImporter.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4232,9 +4232,22 @@ void ClangModuleUnit::getImportedModulesForLookup(
42324232
for (auto importMod : topLevelImported) {
42334233
auto wrapper = owner.getWrapperForModule(importMod);
42344234

4235-
auto actualMod = wrapper->getOverlayModule();
4236-
if (!actualMod || actualMod == topLevelOverlay)
4235+
ModuleDecl *actualMod = nullptr;
4236+
if (owner.SwiftContext.LangOpts.EnableCXXInterop && topLevel &&
4237+
isCxxStdModule(topLevel) && wrapper->clangModule &&
4238+
isCxxStdModule(wrapper->clangModule)) {
4239+
// The CxxStdlib overlay re-exports the clang module std, which in recent
4240+
// libc++ versions re-exports top-level modules for different std headers
4241+
// (std_string, std_vector, etc). The overlay module for each of the std
4242+
// modules is the CxxStdlib module itself. Make sure we return the actual
4243+
// clang modules (std_xyz) as transitive dependencies instead of just
4244+
// CxxStdlib itself.
42374245
actualMod = wrapper->getParentModule();
4246+
} else {
4247+
actualMod = wrapper->getOverlayModule();
4248+
if (!actualMod || actualMod == topLevelOverlay)
4249+
actualMod = wrapper->getParentModule();
4250+
}
42384251

42394252
assert(actualMod && "Missing imported overlay");
42404253
imports.push_back({ImportPath::Access(), actualMod});

0 commit comments

Comments
 (0)