Skip to content

Commit 11e5fc8

Browse files
authored
Merge pull request #64177 from hyp/eng/libstdcxx-dynamic
[interop] Configure libstdc++ module map at runtime
2 parents b5881d9 + eba8a00 commit 11e5fc8

File tree

10 files changed

+342
-90
lines changed

10 files changed

+342
-90
lines changed

include/swift/AST/DiagnosticsClangImporter.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ WARNING(glibc_not_found, none,
124124
WARNING(libstdcxx_not_found, none,
125125
"libstdc++ not found for '%0'; C++ stdlib may be unavailable",
126126
(StringRef))
127+
WARNING(libstdcxx_modulemap_not_found, none,
128+
"module map for libstdc++ not found for '%0'; C++ stdlib may be unavailable",
129+
(StringRef))
127130

128131
WARNING(too_many_class_template_instantiations, none,
129132
"template instantiation for '%0' not imported: too many instantiations",

include/swift/ClangImporter/ClangImporter.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#define SWIFT_CLANG_IMPORTER_H
1818

1919
#include "swift/AST/ClangModuleLoader.h"
20+
#include "llvm/Support/VirtualFileSystem.h"
2021

2122
/// The maximum number of SIMD vector elements we currently try to import.
2223
#define SWIFT_MAX_IMPORTED_SIMD_ELEMENTS 4
@@ -580,6 +581,18 @@ bool requiresCPlusPlus(const clang::Module *module);
580581

581582
} // namespace importer
582583

584+
struct ClangInvocationFileMapping {
585+
SmallVector<std::pair<std::string, std::string>, 2> redirectedFiles;
586+
SmallVector<std::pair<std::string, std::string>, 1> overridenFiles;
587+
};
588+
589+
/// On Linux, some platform libraries (glibc, libstdc++) are not modularized.
590+
/// We inject modulemaps for those libraries into their include directories
591+
/// to allow using them from Swift.
592+
ClangInvocationFileMapping getClangInvocationFileMapping(
593+
ASTContext &ctx,
594+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> vfs = nullptr);
595+
583596
} // end namespace swift
584597

585598
#endif

lib/ClangImporter/ClangImporter.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1119,8 +1119,25 @@ ClangImporter::create(ASTContext &ctx,
11191119
auto fileMapping = getClangInvocationFileMapping(ctx);
11201120
// Wrap Swift's FS to allow Clang to override the working directory
11211121
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS =
1122-
llvm::vfs::RedirectingFileSystem::create(fileMapping, true,
1123-
*ctx.SourceMgr.getFileSystem());
1122+
llvm::vfs::RedirectingFileSystem::create(
1123+
fileMapping.redirectedFiles, true, *ctx.SourceMgr.getFileSystem());
1124+
if (!fileMapping.overridenFiles.empty()) {
1125+
llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> overridenVFS =
1126+
new llvm::vfs::InMemoryFileSystem();
1127+
for (const auto &file : fileMapping.overridenFiles) {
1128+
auto contents = ctx.Allocate<char>(file.second.size() + 1);
1129+
std::copy(file.second.begin(), file.second.end(), contents.begin());
1130+
// null terminate the buffer.
1131+
contents[contents.size() - 1] = '\0';
1132+
overridenVFS->addFile(file.first, 0,
1133+
llvm::MemoryBuffer::getMemBuffer(
1134+
StringRef(contents.begin(), contents.size() - 1)));
1135+
}
1136+
llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> overlayVFS =
1137+
new llvm::vfs::OverlayFileSystem(VFS);
1138+
VFS = overlayVFS;
1139+
overlayVFS->pushOverlay(overridenVFS);
1140+
}
11241141

11251142
// Create a new Clang compiler invocation.
11261143
{

0 commit comments

Comments
 (0)