1//===--- IncrementalAction.h - Incremental Frontend Action -*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_CLANG_INTERPRETER_INCREMENTALACTION_H
10#define LLVM_CLANG_INTERPRETER_INCREMENTALACTION_H
11
12#include "clang/Frontend/FrontendActions.h"
13#include "clang/Frontend/MultiplexConsumer.h"
14
15namespace llvm {
16class Module;
17}
18
19namespace clang {
20
21class Interpreter;
22class CodeGenerator;
23
24/// A custom action enabling the incremental processing functionality.
25///
26/// The usual \p FrontendAction expects one call to ExecuteAction and once it
27/// sees a call to \p EndSourceFile it deletes some of the important objects
28/// such as \p Preprocessor and \p Sema assuming no further input will come.
29///
30/// \p IncrementalAction ensures it keep its underlying action's objects alive
31/// as long as the \p IncrementalParser needs them.
32///
33class IncrementalAction : public WrapperFrontendAction {
34private:
35 bool IsTerminating = false;
36 Interpreter &Interp;
37 [[maybe_unused]] CompilerInstance &CI;
38 std::unique_ptr<ASTConsumer> Consumer;
39
40 /// When CodeGen is created the first llvm::Module gets cached in many places
41 /// and we must keep it alive.
42 std::unique_ptr<llvm::Module> CachedInCodeGenModule;
43
44public:
45 IncrementalAction(CompilerInstance &Instance, llvm::LLVMContext &LLVMCtx,
46 llvm::Error &Err, Interpreter &I,
47 std::unique_ptr<ASTConsumer> Consumer = nullptr);
48
49 FrontendAction *getWrapped() const { return WrappedAction.get(); }
50
51 TranslationUnitKind getTranslationUnitKind() override {
52 return TU_Incremental;
53 }
54
55 std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
56 StringRef InFile) override;
57
58 void ExecuteAction() override;
59
60 // Do not terminate after processing the input. This allows us to keep various
61 // clang objects alive and to incrementally grow the current TU.
62 void EndSourceFile() override;
63
64 void FinalizeAction();
65
66 /// Cache the current CodeGen module to preserve internal references.
67 void CacheCodeGenModule();
68
69 /// Access the cached CodeGen module.
70 llvm::Module *getCachedCodeGenModule() const;
71
72 /// Access the current code generator.
73 CodeGenerator *getCodeGen() const;
74
75 /// Generate an LLVM module for the most recent parsed input.
76 std::unique_ptr<llvm::Module> GenModule();
77};
78
79class InProcessPrintingASTConsumer final : public MultiplexConsumer {
80 Interpreter &Interp;
81
82public:
83 InProcessPrintingASTConsumer(std::unique_ptr<ASTConsumer> C, Interpreter &I);
84
85 bool HandleTopLevelDecl(DeclGroupRef DGR) override;
86};
87
88} // end namespace clang
89
90#endif // LLVM_CLANG_INTERPRETER_INCREMENTALACTION_H
91