Skip to content

Commit f53b8bf

Browse files
committed
[cxx-interop] Support CxxStdlib overlay for libc++ on Linux
This teaches Swift to rebuild the CxxStdlib overlay module from its interface when using a C++ standard library that is not the platform default, specifically libc++ on Linux. rdar://138838506
1 parent 7704534 commit f53b8bf

File tree

5 files changed

+29
-8
lines changed

5 files changed

+29
-8
lines changed

lib/AST/ModuleLoader.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -172,12 +172,6 @@ void ModuleLoader::findOverlayFiles(SourceLoc diagLoc, ModuleDecl *module,
172172
using namespace llvm::sys;
173173
using namespace file_types;
174174

175-
// If an overlay for CxxStdlib was requested, only proceed if compiling with
176-
// the platform-default C++ stdlib.
177-
if (module->getName() == module->getASTContext().Id_CxxStdlib &&
178-
!module->getASTContext().LangOpts.isUsingPlatformDefaultCXXStdlib())
179-
return;
180-
181175
// If cross import information is passed on command-line, prefer use that.
182176
auto &crossImports = module->getASTContext().SearchPathOpts.CrossImportInfo;
183177
auto overlays = crossImports.find(module->getNameStr());

lib/ClangImporter/ClangImporter.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4357,8 +4357,7 @@ ModuleDecl *ClangModuleUnit::getOverlayModule() const {
43574357
// the overlay for it so far, it is a split libc++ module (e.g. std_vector).
43584358
// Load the CxxStdlib overlay explicitly, if building with the
43594359
// platform-default C++ stdlib.
4360-
if (!overlay && importer::isCxxStdModule(clangModule) &&
4361-
Ctx.LangOpts.isUsingPlatformDefaultCXXStdlib()) {
4360+
if (!overlay && importer::isCxxStdModule(clangModule)) {
43624361
ImportPath::Module::Builder builder(Ctx.Id_CxxStdlib);
43634362
overlay = owner.loadModule(SourceLoc(), std::move(builder).get());
43644363
}

lib/Frontend/CompilerInvocation.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,15 @@ void CompilerInvocation::computeCXXStdlibOptions() {
398398
LangOpts.CXXStdlib = toCXXStdlibKind(cxxStdlibKind);
399399
LangOpts.PlatformDefaultCXXStdlib = toCXXStdlibKind(cxxDefaultStdlibKind);
400400
}
401+
402+
if (!LangOpts.isUsingPlatformDefaultCXXStdlib()) {
403+
// The CxxStdlib overlay was built for the platform default C++ stdlib, and
404+
// its .swiftmodule file refers to implementation-specific symbols (such as
405+
// namespace __1 in libc++, or namespace __cxx11 in libstdc++). Let's
406+
// proactively rebuild the CxxStdlib module from its .swiftinterface if a
407+
// non-default C++ stdlib is used.
408+
FrontendOpts.PreferInterfaceForModules.push_back("CxxStdlib");
409+
}
401410
}
402411

403412
void CompilerInvocation::setRuntimeResourcePath(StringRef Path) {

lib/Frontend/ModuleInterfaceLoader.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2035,6 +2035,15 @@ InterfaceSubContextDelegateImpl::InterfaceSubContextDelegateImpl(
20352035

20362036
GenericArgs.push_back(
20372037
ArgSaver.save("-cxx-interoperability-mode=" + compatVersion));
2038+
2039+
if (!langOpts.isUsingPlatformDefaultCXXStdlib() &&
2040+
langOpts.CXXStdlib == CXXStdlibKind::Libcxx) {
2041+
genericSubInvocation.getLangOptions().CXXStdlib = CXXStdlibKind::Libcxx;
2042+
genericSubInvocation.getClangImporterOptions().ExtraArgs.push_back(
2043+
"-stdlib=libc++");
2044+
GenericArgs.push_back("-Xcc");
2045+
GenericArgs.push_back("-stdlib=libc++");
2046+
}
20382047
}
20392048
}
20402049

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// This test runs another test, use-std-chrono.swift, with libc++ explicitly specified as the C++ stdlib.
2+
3+
// RUN: %empty-directory(%t)
4+
// RUN: %target-build-swift %S/use-std-chrono.swift -I %S/Inputs -o %t/exe -cxx-interoperability-mode=upcoming-swift -Xcc -stdlib=libc++
5+
// RUN: %target-codesign %t/exe
6+
// RUN: %target-run %t/exe
7+
8+
// REQUIRES: executable_test
9+
// REQUIRES: OS=linux-gnu
10+
// REQUIRES: system_wide_libcxx

0 commit comments

Comments
 (0)