Skip to content

Commit eba8a00

Browse files
committed
[interop] Inject header files into libstdcxx.modulemap dynamically
This allows the module map we use for libstdc++ to correctly include optional headers like "any" and other C++17/20 files.
1 parent 83ebd7d commit eba8a00

File tree

9 files changed

+320
-90
lines changed

9 files changed

+320
-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
@@ -1102,8 +1102,25 @@ ClangImporter::create(ASTContext &ctx,
11021102
auto fileMapping = getClangInvocationFileMapping(ctx);
11031103
// Wrap Swift's FS to allow Clang to override the working directory
11041104
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS =
1105-
llvm::vfs::RedirectingFileSystem::create(fileMapping, true,
1106-
*ctx.SourceMgr.getFileSystem());
1105+
llvm::vfs::RedirectingFileSystem::create(
1106+
fileMapping.redirectedFiles, true, *ctx.SourceMgr.getFileSystem());
1107+
if (!fileMapping.overridenFiles.empty()) {
1108+
llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> overridenVFS =
1109+
new llvm::vfs::InMemoryFileSystem();
1110+
for (const auto &file : fileMapping.overridenFiles) {
1111+
auto contents = ctx.Allocate<char>(file.second.size() + 1);
1112+
std::copy(file.second.begin(), file.second.end(), contents.begin());
1113+
// null terminate the buffer.
1114+
contents[contents.size() - 1] = '\0';
1115+
overridenVFS->addFile(file.first, 0,
1116+
llvm::MemoryBuffer::getMemBuffer(
1117+
StringRef(contents.begin(), contents.size() - 1)));
1118+
}
1119+
llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> overlayVFS =
1120+
new llvm::vfs::OverlayFileSystem(VFS);
1121+
VFS = overlayVFS;
1122+
overlayVFS->pushOverlay(overridenVFS);
1123+
}
11071124

11081125
// Create a new Clang compiler invocation.
11091126
{

0 commit comments

Comments
 (0)