Skip to content

Commit 643c7c8

Browse files
[wasm][ClangImporter] Support wasi-libc.modulemap import with VFS
1 parent 902d75e commit 643c7c8

File tree

2 files changed

+47
-42
lines changed

2 files changed

+47
-42
lines changed

include/swift/AST/DiagnosticsClangImporter.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,8 @@ WARNING(nonmutating_without_mutable_fields,none,
118118

119119
ERROR(module_map_not_found, none, "module map file '%0' not found", (StringRef))
120120

121-
WARNING(glibc_not_found, none,
122-
"glibc not found for '%0'; C stdlib may be unavailable",
121+
WARNING(libc_not_found, none,
122+
"libc not found for '%0'; C stdlib may be unavailable",
123123
(StringRef))
124124
WARNING(libstdcxx_not_found, none,
125125
"libstdc++ not found for '%0'; C++ stdlib may be unavailable",

lib/ClangImporter/ClangIncludePaths.cpp

Lines changed: 45 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -89,18 +89,6 @@ static llvm::Optional<Path> getInjectedModuleMapPath(
8989
return path;
9090
}
9191

92-
/// Finds the glibc.modulemap file relative to the provided resource dir.
93-
///
94-
/// Note that the module map used for Glibc depends on the target we're
95-
/// compiling for, and is not included in the resource directory with the other
96-
/// implicit module maps. It's at {freebsd|linux}/{arch}/glibc.modulemap.
97-
static llvm::Optional<Path> getGlibcModuleMapPath(
98-
SearchPathOptions &Opts, const llvm::Triple &triple,
99-
const llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &vfs) {
100-
return getActualModuleMapPath("glibc.modulemap", Opts, triple,
101-
/*isArchSpecific*/ true, vfs);
102-
}
103-
10492
static llvm::Optional<Path> getLibStdCxxModuleMapPath(
10593
SearchPathOptions &opts, const llvm::Triple &triple,
10694
const llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &vfs) {
@@ -190,19 +178,20 @@ createClangArgs(const ASTContext &ctx, clang::driver::Driver &clangDriver) {
190178
return clangDriverArgs;
191179
}
192180

193-
static bool shouldInjectGlibcModulemap(const llvm::Triple &triple) {
181+
static bool shouldInjectLibcModulemap(const llvm::Triple &triple) {
194182
return triple.isOSGlibc() || triple.isOSOpenBSD() || triple.isOSFreeBSD() ||
195-
triple.isAndroid();
183+
triple.isAndroid() || triple.isOSWASI();
196184
}
197185

198-
static SmallVector<std::pair<std::string, std::string>, 2> getGlibcFileMapping(
199-
ASTContext &ctx,
200-
const llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &vfs) {
186+
static SmallVector<std::pair<std::string, std::string>, 2>
187+
getLibcFileMapping(ASTContext &ctx, StringRef modulemapFileName,
188+
std::optional<StringRef> maybeHeaderFileName,
189+
const llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &vfs) {
201190
const llvm::Triple &triple = ctx.LangOpts.Target;
202-
if (!shouldInjectGlibcModulemap(triple))
191+
if (!shouldInjectLibcModulemap(triple))
203192
return {};
204193

205-
// Extract the Glibc path from Clang driver.
194+
// Extract the libc path from Clang driver.
206195
auto clangDriver = createClangDriver(ctx, vfs);
207196
auto clangDriverArgs = createClangArgs(ctx, clangDriver);
208197

@@ -212,42 +201,47 @@ static SmallVector<std::pair<std::string, std::string>, 2> getGlibcFileMapping(
212201
clangToolchain.AddClangSystemIncludeArgs(clangDriverArgs, includeArgStrings);
213202
auto parsedIncludeArgs = parseClangDriverArgs(clangDriver, includeArgStrings);
214203

215-
// Find the include path that contains Glibc headers. We use three arbitrarily
216-
// chosen headers to determine if the include path actually contains Glibc.
204+
// Find the include path that contains libc headers. We use three arbitrarily
205+
// chosen headers to determine if the include path actually contains libc.
217206
// Ideally we would check that all of the headers referenced from the
218207
// modulemap are present.
219-
Path glibcDir;
208+
Path libcDir;
220209
if (auto dir = findFirstIncludeDir(
221210
parsedIncludeArgs, {"inttypes.h", "unistd.h", "stdint.h"}, vfs)) {
222-
glibcDir = dir.value();
211+
libcDir = dir.value();
223212
} else {
224-
ctx.Diags.diagnose(SourceLoc(), diag::glibc_not_found, triple.str());
213+
ctx.Diags.diagnose(SourceLoc(), diag::libc_not_found, triple.str());
225214
return {};
226215
}
227216

228217
Path actualModuleMapPath;
229-
if (auto path = getGlibcModuleMapPath(ctx.SearchPathOpts, triple, vfs))
218+
if (auto path = getActualModuleMapPath(modulemapFileName, ctx.SearchPathOpts,
219+
triple, /*isArchSpecific*/ true, vfs))
230220
actualModuleMapPath = path.value();
231221
else
232222
// FIXME: Emit a warning of some kind.
233223
return {};
234224

235-
// TODO: remove the SwiftGlibc.h header and reference all Glibc headers
236-
// directly from the modulemap.
237-
Path actualHeaderPath = actualModuleMapPath;
238-
llvm::sys::path::remove_filename(actualHeaderPath);
239-
llvm::sys::path::append(actualHeaderPath, "SwiftGlibc.h");
240-
241-
Path injectedModuleMapPath(glibcDir);
225+
Path injectedModuleMapPath(libcDir);
242226
llvm::sys::path::append(injectedModuleMapPath, "module.modulemap");
227+
SmallVector<std::pair<std::string, std::string>, 2> vfsMappings{
228+
{std::string(injectedModuleMapPath), std::string(actualModuleMapPath)}};
243229

244-
Path injectedHeaderPath(glibcDir);
245-
llvm::sys::path::append(injectedHeaderPath, "SwiftGlibc.h");
230+
if (maybeHeaderFileName) {
231+
// TODO: remove the SwiftGlibc.h header and reference all Glibc headers
232+
// directly from the modulemap.
233+
Path actualHeaderPath = actualModuleMapPath;
234+
llvm::sys::path::remove_filename(actualHeaderPath);
235+
llvm::sys::path::append(actualHeaderPath, maybeHeaderFileName.value());
246236

247-
return {
248-
{std::string(injectedModuleMapPath), std::string(actualModuleMapPath)},
249-
{std::string(injectedHeaderPath), std::string(actualHeaderPath)},
250-
};
237+
Path injectedHeaderPath(libcDir);
238+
llvm::sys::path::append(injectedHeaderPath, maybeHeaderFileName.value());
239+
240+
vfsMappings.push_back(
241+
{std::string(injectedHeaderPath), std::string(actualHeaderPath)});
242+
}
243+
244+
return vfsMappings;
251245
}
252246

253247
static void getLibStdCxxFileMapping(
@@ -518,8 +512,19 @@ ClangInvocationFileMapping swift::getClangInvocationFileMapping(
518512
ClangInvocationFileMapping result;
519513
if (!vfs)
520514
vfs = llvm::vfs::getRealFileSystem();
521-
// Android/BSD/Linux Mappings
522-
result.redirectedFiles.append(getGlibcFileMapping(ctx, vfs));
515+
516+
const llvm::Triple &triple = ctx.LangOpts.Target;
517+
518+
if (triple.isOSWASI()) {
519+
// WASI Mappings
520+
result.redirectedFiles.append(
521+
getLibcFileMapping(ctx, "wasi-libc.modulemap", std::nullopt, vfs));
522+
} else {
523+
// Android/BSD/Linux Mappings
524+
result.redirectedFiles.append(getLibcFileMapping(
525+
ctx, "glibc.modulemap", StringRef("SwiftGlibc.h"), vfs));
526+
}
527+
523528
if (ctx.LangOpts.EnableCXXInterop)
524529
getLibStdCxxFileMapping(result, ctx, vfs);
525530

0 commit comments

Comments
 (0)