[clang] Enable wrapping the FrontendAction for module builds (#184907)

This PR upstreams a piece of infrastructure from Swift's LLVM fork. This
allows adding custom wrappers around the `FrontendAction` that compiles
Clang modules from a module map into a PCM file. This will be used to
implement modules support in the CAS-based compilation caching mode.
This commit is contained in:
Jan Svoboda 2026-03-05 15:43:35 -08:00 committed by GitHub
parent 742008d4e0
commit ca155dbea6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 27 additions and 2 deletions

View File

@ -197,6 +197,14 @@ class CompilerInstance : public ModuleLoader {
/// Force an output buffer.
std::unique_ptr<llvm::raw_pwrite_stream> OutputStream;
using GenModuleActionWrapperFunc =
std::function<std::unique_ptr<FrontendAction>(
const FrontendOptions &, std::unique_ptr<FrontendAction>)>;
/// An optional callback function used to wrap all FrontendActions
/// produced to generate imported modules before they are executed.
GenModuleActionWrapperFunc GenModuleActionWrapper;
CompilerInstance(const CompilerInstance &) = delete;
void operator=(const CompilerInstance &) = delete;
public:
@ -958,6 +966,14 @@ public:
bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override;
void setGenModuleActionWrapper(GenModuleActionWrapperFunc Wrapper) {
GenModuleActionWrapper = Wrapper;
}
GenModuleActionWrapperFunc getGenModuleActionWrapper() const {
return GenModuleActionWrapper;
}
void addDependencyCollector(std::shared_ptr<DependencyCollector> Listener) {
DependencyCollectors.push_back(std::move(Listener));
}

View File

@ -1214,6 +1214,9 @@ std::unique_ptr<CompilerInstance> CompilerInstance::cloneForModuleCompileImpl(
// Make a copy for the new instance.
Instance.FailedModules = FailedModules;
// Pass along the GenModuleActionWrapper callback.
Instance.setGenModuleActionWrapper(getGenModuleActionWrapper());
if (GetDependencyDirectives)
Instance.GetDependencyDirectives =
GetDependencyDirectives->cloneFor(Instance.getFileManager());
@ -1268,8 +1271,14 @@ bool CompilerInstance::compileModule(SourceLocation ImportLoc,
// thread so that we get a stack large enough.
bool Crashed = !llvm::CrashRecoveryContext().RunSafelyOnNewStack(
[&]() {
GenerateModuleFromModuleMapAction Action;
Instance.ExecuteAction(Action);
std::unique_ptr<FrontendAction> Action =
std::make_unique<GenerateModuleFromModuleMapAction>();
if (auto WrapGenModuleAction = Instance.getGenModuleActionWrapper())
Action = WrapGenModuleAction(Instance.getFrontendOpts(),
std::move(Action));
Instance.ExecuteAction(*Action);
},
DesiredStackSize);