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