diff --git a/clang/include/clang/Frontend/CompilerInstance.h b/clang/include/clang/Frontend/CompilerInstance.h index 217efa3fe756..266e0826b38f 100644 --- a/clang/include/clang/Frontend/CompilerInstance.h +++ b/clang/include/clang/Frontend/CompilerInstance.h @@ -197,6 +197,14 @@ class CompilerInstance : public ModuleLoader { /// Force an output buffer. std::unique_ptr OutputStream; + using GenModuleActionWrapperFunc = + std::function( + const FrontendOptions &, std::unique_ptr)>; + + /// 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 Listener) { DependencyCollectors.push_back(std::move(Listener)); } diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index dd774f7319bb..60914d9b2cbc 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -1214,6 +1214,9 @@ std::unique_ptr 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 Action = + std::make_unique(); + + if (auto WrapGenModuleAction = Instance.getGenModuleActionWrapper()) + Action = WrapGenModuleAction(Instance.getFrontendOpts(), + std::move(Action)); + + Instance.ExecuteAction(*Action); }, DesiredStackSize);