diff options
Diffstat (limited to 'clang/lib/Interpreter/IncrementalAction.h')
| -rw-r--r-- | clang/lib/Interpreter/IncrementalAction.h | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/clang/lib/Interpreter/IncrementalAction.h b/clang/lib/Interpreter/IncrementalAction.h new file mode 100644 index 000000000000..725cdd0c27cf --- /dev/null +++ b/clang/lib/Interpreter/IncrementalAction.h @@ -0,0 +1,90 @@ +//===--- IncrementalAction.h - Incremental Frontend Action -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_INTERPRETER_INCREMENTALACTION_H +#define LLVM_CLANG_INTERPRETER_INCREMENTALACTION_H + +#include "clang/Frontend/FrontendActions.h" +#include "clang/Frontend/MultiplexConsumer.h" + +namespace llvm { +class Module; +} + +namespace clang { + +class Interpreter; +class CodeGenerator; + +/// A custom action enabling the incremental processing functionality. +/// +/// The usual \p FrontendAction expects one call to ExecuteAction and once it +/// sees a call to \p EndSourceFile it deletes some of the important objects +/// such as \p Preprocessor and \p Sema assuming no further input will come. +/// +/// \p IncrementalAction ensures it keep its underlying action's objects alive +/// as long as the \p IncrementalParser needs them. +/// +class IncrementalAction : public WrapperFrontendAction { +private: + bool IsTerminating = false; + Interpreter &Interp; + [[maybe_unused]] CompilerInstance &CI; + std::unique_ptr<ASTConsumer> Consumer; + + /// When CodeGen is created the first llvm::Module gets cached in many places + /// and we must keep it alive. + std::unique_ptr<llvm::Module> CachedInCodeGenModule; + +public: + IncrementalAction(CompilerInstance &Instance, llvm::LLVMContext &LLVMCtx, + llvm::Error &Err, Interpreter &I, + std::unique_ptr<ASTConsumer> Consumer = nullptr); + + FrontendAction *getWrapped() const { return WrappedAction.get(); } + + TranslationUnitKind getTranslationUnitKind() override { + return TU_Incremental; + } + + std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) override; + + void ExecuteAction() override; + + // Do not terminate after processing the input. This allows us to keep various + // clang objects alive and to incrementally grow the current TU. + void EndSourceFile() override; + + void FinalizeAction(); + + /// Cache the current CodeGen module to preserve internal references. + void CacheCodeGenModule(); + + /// Access the cached CodeGen module. + llvm::Module *getCachedCodeGenModule() const; + + /// Access the current code generator. + CodeGenerator *getCodeGen() const; + + /// Generate an LLVM module for the most recent parsed input. + std::unique_ptr<llvm::Module> GenModule(); +}; + +class InProcessPrintingASTConsumer final : public MultiplexConsumer { + Interpreter &Interp; + +public: + InProcessPrintingASTConsumer(std::unique_ptr<ASTConsumer> C, Interpreter &I); + + bool HandleTopLevelDecl(DeclGroupRef DGR) override; +}; + +} // end namespace clang + +#endif // LLVM_CLANG_INTERPRETER_INCREMENTALACTION_H |
