mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Fix direct clang cc1 emit-pcm commands with vfs overlay on Windows (#85325)
Explicit module builds currently fail on Windows because direct-clang-cc1-module-build emit-pcm commands take overlaid system module map files as inputs but miss the clang VFS overlay. This change adds the overlay and fixes explicit module builds on Windows.
This commit is contained in:
@@ -75,6 +75,7 @@ namespace dependencies {
|
|||||||
namespace swift {
|
namespace swift {
|
||||||
enum class ResultConvention : uint8_t;
|
enum class ResultConvention : uint8_t;
|
||||||
class ASTContext;
|
class ASTContext;
|
||||||
|
class CASOptions;
|
||||||
class CompilerInvocation;
|
class CompilerInvocation;
|
||||||
class ClangImporterOptions;
|
class ClangImporterOptions;
|
||||||
class ClangInheritanceInfo;
|
class ClangInheritanceInfo;
|
||||||
@@ -83,6 +84,7 @@ class ClangNode;
|
|||||||
class ConcreteDeclRef;
|
class ConcreteDeclRef;
|
||||||
class Decl;
|
class Decl;
|
||||||
class DeclContext;
|
class DeclContext;
|
||||||
|
class DiagnosticEngine;
|
||||||
class EffectiveClangContext;
|
class EffectiveClangContext;
|
||||||
class EnumDecl;
|
class EnumDecl;
|
||||||
class FuncDecl;
|
class FuncDecl;
|
||||||
@@ -878,6 +880,25 @@ struct ClangInvocationFileMapping {
|
|||||||
bool requiresBuiltinHeadersInSystemModules;
|
bool requiresBuiltinHeadersInSystemModules;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ClangInvocationFileMappingContext {
|
||||||
|
public:
|
||||||
|
const LangOptions &LangOpts;
|
||||||
|
SearchPathOptions &SearchPathOpts;
|
||||||
|
ClangImporterOptions &ClangImporterOpts;
|
||||||
|
const CASOptions &CASOpts;
|
||||||
|
DiagnosticEngine &Diags;
|
||||||
|
|
||||||
|
ClangInvocationFileMappingContext(
|
||||||
|
const LangOptions &LangOpts, SearchPathOptions &SearchPathOpts,
|
||||||
|
ClangImporterOptions &ClangImporterOpts, const CASOptions &CASOpts,
|
||||||
|
DiagnosticEngine &Diags)
|
||||||
|
: LangOpts(LangOpts), SearchPathOpts(SearchPathOpts),
|
||||||
|
ClangImporterOpts(ClangImporterOpts), CASOpts(CASOpts),
|
||||||
|
Diags(Diags) {}
|
||||||
|
|
||||||
|
ClangInvocationFileMappingContext(const swift::ASTContext &Ctx);
|
||||||
|
};
|
||||||
|
|
||||||
/// On Linux, some platform libraries (glibc, libstdc++) are not modularized.
|
/// On Linux, some platform libraries (glibc, libstdc++) are not modularized.
|
||||||
/// We inject modulemaps for those libraries into their include directories
|
/// We inject modulemaps for those libraries into their include directories
|
||||||
/// to allow using them from Swift.
|
/// to allow using them from Swift.
|
||||||
@@ -885,7 +906,7 @@ struct ClangInvocationFileMapping {
|
|||||||
/// `suppressDiagnostic` prevents us from emitting warning messages when we
|
/// `suppressDiagnostic` prevents us from emitting warning messages when we
|
||||||
/// are unable to find headers.
|
/// are unable to find headers.
|
||||||
ClangInvocationFileMapping getClangInvocationFileMapping(
|
ClangInvocationFileMapping getClangInvocationFileMapping(
|
||||||
const ASTContext &ctx,
|
const ClangInvocationFileMappingContext &ctx,
|
||||||
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> vfs = nullptr,
|
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> vfs = nullptr,
|
||||||
bool suppressDiagnostic = false);
|
bool suppressDiagnostic = false);
|
||||||
|
|
||||||
@@ -893,7 +914,7 @@ ClangInvocationFileMapping getClangInvocationFileMapping(
|
|||||||
/// primarily to inject modulemaps on platforms with non-modularized
|
/// primarily to inject modulemaps on platforms with non-modularized
|
||||||
/// platform libraries.
|
/// platform libraries.
|
||||||
ClangInvocationFileMapping applyClangInvocationMapping(
|
ClangInvocationFileMapping applyClangInvocationMapping(
|
||||||
const ASTContext &ctx,
|
const ClangInvocationFileMappingContext &ctx,
|
||||||
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> baseVFS,
|
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> baseVFS,
|
||||||
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &fileSystem,
|
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &fileSystem,
|
||||||
bool suppressDiagnostics = false);
|
bool suppressDiagnostics = false);
|
||||||
|
|||||||
@@ -202,7 +202,8 @@ ClangImporter::createClangArgs(const ClangImporterOptions &ClangImporterOpts,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static SmallVector<std::pair<std::string, std::string>, 2>
|
static SmallVector<std::pair<std::string, std::string>, 2>
|
||||||
getLibcFileMapping(const ASTContext &ctx, StringRef modulemapFileName,
|
getLibcFileMapping(const ClangInvocationFileMappingContext &ctx,
|
||||||
|
StringRef modulemapFileName,
|
||||||
std::optional<ArrayRef<StringRef>> maybeHeaderFileNames,
|
std::optional<ArrayRef<StringRef>> maybeHeaderFileNames,
|
||||||
const llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &vfs,
|
const llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &vfs,
|
||||||
bool suppressDiagnostic) {
|
bool suppressDiagnostic) {
|
||||||
@@ -269,7 +270,8 @@ getLibcFileMapping(const ASTContext &ctx, StringRef modulemapFileName,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void getLibStdCxxFileMapping(
|
static void getLibStdCxxFileMapping(
|
||||||
ClangInvocationFileMapping &fileMapping, const ASTContext &ctx,
|
ClangInvocationFileMapping &fileMapping,
|
||||||
|
const ClangInvocationFileMappingContext &ctx,
|
||||||
const llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &vfs,
|
const llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &vfs,
|
||||||
bool suppressDiagnostic) {
|
bool suppressDiagnostic) {
|
||||||
assert(ctx.LangOpts.EnableCXXInterop &&
|
assert(ctx.LangOpts.EnableCXXInterop &&
|
||||||
@@ -475,7 +477,8 @@ GetPlatformAuxiliaryFile(StringRef Platform, StringRef File,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GetWindowsFileMappings(
|
void GetWindowsFileMappings(
|
||||||
ClangInvocationFileMapping &fileMapping, const ASTContext &Context,
|
ClangInvocationFileMapping &fileMapping,
|
||||||
|
const ClangInvocationFileMappingContext &Context,
|
||||||
const llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &driverVFS,
|
const llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &driverVFS,
|
||||||
bool &requiresBuiltinHeadersInSystemModules) {
|
bool &requiresBuiltinHeadersInSystemModules) {
|
||||||
const llvm::Triple &Triple = Context.LangOpts.Target;
|
const llvm::Triple &Triple = Context.LangOpts.Target;
|
||||||
@@ -615,8 +618,14 @@ void GetWindowsFileMappings(
|
|||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
ClangInvocationFileMappingContext::ClangInvocationFileMappingContext(
|
||||||
|
const swift::ASTContext &Ctx)
|
||||||
|
: ClangInvocationFileMappingContext(Ctx.LangOpts, Ctx.SearchPathOpts,
|
||||||
|
Ctx.ClangImporterOpts, Ctx.CASOpts, Ctx.Diags) {}
|
||||||
|
|
||||||
ClangInvocationFileMapping swift::getClangInvocationFileMapping(
|
ClangInvocationFileMapping swift::getClangInvocationFileMapping(
|
||||||
const ASTContext &ctx, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> vfs,
|
const ClangInvocationFileMappingContext &ctx,
|
||||||
|
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> vfs,
|
||||||
bool suppressDiagnostic) {
|
bool suppressDiagnostic) {
|
||||||
ClangInvocationFileMapping result;
|
ClangInvocationFileMapping result;
|
||||||
if (!vfs)
|
if (!vfs)
|
||||||
@@ -687,7 +696,8 @@ ClangInvocationFileMapping swift::getClangInvocationFileMapping(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClangInvocationFileMapping swift::applyClangInvocationMapping(const ASTContext &ctx,
|
ClangInvocationFileMapping swift::applyClangInvocationMapping(
|
||||||
|
const ClangInvocationFileMappingContext &ctx,
|
||||||
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> baseVFS,
|
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> baseVFS,
|
||||||
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &fileSystem,
|
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &fileSystem,
|
||||||
bool suppressDiagnostics) {
|
bool suppressDiagnostics) {
|
||||||
@@ -719,13 +729,9 @@ ClangInvocationFileMapping swift::applyClangInvocationMapping(const ASTContext &
|
|||||||
<< "' with the following contents:\n";
|
<< "' with the following contents:\n";
|
||||||
llvm::errs() << file.second << "\n";
|
llvm::errs() << file.second << "\n";
|
||||||
}
|
}
|
||||||
auto contents = ctx.Allocate<char>(file.second.size() + 1);
|
// Note MemoryBuffer is guaranteeed to be null-terminated.
|
||||||
std::copy(file.second.begin(), file.second.end(), contents.begin());
|
|
||||||
// null terminate the buffer.
|
|
||||||
contents[contents.size() - 1] = '\0';
|
|
||||||
overridenVFS->addFile(file.first, 0,
|
overridenVFS->addFile(file.first, 0,
|
||||||
llvm::MemoryBuffer::getMemBuffer(StringRef(
|
llvm::MemoryBuffer::getMemBufferCopy(file.second));
|
||||||
contents.begin(), contents.size() - 1)));
|
|
||||||
}
|
}
|
||||||
llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> overlayVFS =
|
llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> overlayVFS =
|
||||||
new llvm::vfs::OverlayFileSystem(fileSystem);
|
new llvm::vfs::OverlayFileSystem(fileSystem);
|
||||||
|
|||||||
@@ -1992,6 +1992,14 @@ ModuleDependencyInfo ModuleDependencyScanner::bridgeClangModuleDependency(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pass the -sdk flag to make the system header VFS overlay finable
|
||||||
|
// for the -direct-clang-cc1-module-build emit-pcm command on Windows.
|
||||||
|
StringRef SDKPath = ScanASTContext.SearchPathOpts.getSDKPath();
|
||||||
|
if (!SDKPath.empty()) {
|
||||||
|
swiftArgs.push_back("-sdk");
|
||||||
|
swiftArgs.push_back(SDKPath.str());
|
||||||
|
}
|
||||||
|
|
||||||
// Add args reported by the scanner.
|
// Add args reported by the scanner.
|
||||||
auto clangArgs = invocation.getCC1CommandLine();
|
auto clangArgs = invocation.getCC1CommandLine();
|
||||||
llvm::for_each(clangArgs, addClangArg);
|
llvm::for_each(clangArgs, addClangArg);
|
||||||
|
|||||||
@@ -711,6 +711,25 @@ bool CompilerInstance::setUpVirtualFileSystemOverlays() {
|
|||||||
new llvm::vfs::OverlayFileSystem(MemFS);
|
new llvm::vfs::OverlayFileSystem(MemFS);
|
||||||
OverlayVFS->pushOverlay(SourceMgr.getFileSystem());
|
OverlayVFS->pushOverlay(SourceMgr.getFileSystem());
|
||||||
SourceMgr.setFileSystem(std::move(OverlayVFS));
|
SourceMgr.setFileSystem(std::move(OverlayVFS));
|
||||||
|
} else {
|
||||||
|
// For non-caching -direct-clang-cc1-module-build emit-pcm build,
|
||||||
|
// setup the clang VFS so it can find system modulemap files
|
||||||
|
// (like vcruntime.modulemap) as an input file.
|
||||||
|
if (Invocation.getClangImporterOptions().DirectClangCC1ModuleBuild &&
|
||||||
|
Invocation.getFrontendOptions().RequestedAction ==
|
||||||
|
FrontendOptions::ActionType::EmitPCM) {
|
||||||
|
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS =
|
||||||
|
SourceMgr.getFileSystem();
|
||||||
|
ClangInvocationFileMappingContext Context(
|
||||||
|
Invocation.getLangOptions(), Invocation.getSearchPathOptions(),
|
||||||
|
Invocation.getClangImporterOptions(), Invocation.getCASOptions(),
|
||||||
|
Diagnostics);
|
||||||
|
ClangInvocationFileMapping FileMapping = applyClangInvocationMapping(
|
||||||
|
Context, nullptr, VFS, /*suppressDiagnostic=*/false);
|
||||||
|
if (!FileMapping.redirectedFiles.empty()) {
|
||||||
|
SourceMgr.setFileSystem(std::move(VFS));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ExpectedOverlay =
|
auto ExpectedOverlay =
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
module SAL [system] {
|
||||||
|
header "sal.h"
|
||||||
|
export *
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
// REQUIRES: OS=windows-msvc
|
||||||
|
|
||||||
|
// Test that the -direct-clang-cc1-module-build is able to create a module from the VC runtime with an overlaid modulemap file
|
||||||
|
|
||||||
|
// RUN: %empty-directory(%t)
|
||||||
|
// RUN: split-file %s %t
|
||||||
|
|
||||||
|
// RUN: %swift_frontend_plain -target %target-triple -module-cache-path %t/clang-module-cache -scan-dependencies -module-name Test -sdk %S/Inputs/WinSDK %t/Test.swift -o %t/deps.json
|
||||||
|
// RUN: %{python} %S/../CAS/Inputs/BuildCommandExtractor.py %t/deps.json clang:SAL > %t/SAL.cmd
|
||||||
|
// RUN: %swift_frontend_plain @%t/SAL.cmd
|
||||||
|
|
||||||
|
//--- Test.swift
|
||||||
|
import SAL
|
||||||
Reference in New Issue
Block a user