1 //===--- IncrementalParser.h - Incremental Compilation ----------*- 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 // This file implements the class which performs incremental code compilation.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_CLANG_LIB_INTERPRETER_INCREMENTALPARSER_H
14 #define LLVM_CLANG_LIB_INTERPRETER_INCREMENTALPARSER_H
15 
16 #include "clang/AST/GlobalDecl.h"
17 #include "clang/Interpreter/PartialTranslationUnit.h"
18 
19 #include "llvm/ADT/ArrayRef.h"
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/Support/Error.h"
22 
23 #include <list>
24 #include <memory>
25 namespace llvm {
26 class LLVMContext;
27 class Module;
28 } // namespace llvm
29 
30 namespace clang {
31 class ASTConsumer;
32 class CodeGenerator;
33 class CompilerInstance;
34 class IncrementalAction;
35 class Interpreter;
36 class Parser;
37 /// Provides support for incremental compilation. Keeps track of the state
38 /// changes between the subsequent incremental input.
39 ///
40 class IncrementalParser {
41 protected:
42   /// Long-lived, incremental parsing action.
43   std::unique_ptr<IncrementalAction> Act;
44 
45   /// Compiler instance performing the incremental compilation.
46   std::unique_ptr<CompilerInstance> CI;
47 
48   /// Parser.
49   std::unique_ptr<Parser> P;
50 
51   /// Consumer to process the produced top level decls. Owned by Act.
52   ASTConsumer *Consumer = nullptr;
53 
54   /// Counts the number of direct user input lines that have been parsed.
55   unsigned InputCount = 0;
56 
57   /// List containing every information about every incrementally parsed piece
58   /// of code.
59   std::list<PartialTranslationUnit> PTUs;
60 
61   /// When CodeGen is created the first llvm::Module gets cached in many places
62   /// and we must keep it alive.
63   std::unique_ptr<llvm::Module> CachedInCodeGenModule;
64 
65   IncrementalParser();
66 
67 public:
68   IncrementalParser(Interpreter &Interp,
69                     std::unique_ptr<CompilerInstance> Instance,
70                     llvm::LLVMContext &LLVMCtx, llvm::Error &Err);
71   virtual ~IncrementalParser();
72 
getCI()73   CompilerInstance *getCI() { return CI.get(); }
74   CodeGenerator *getCodeGen() const;
75 
76   /// Parses incremental input by creating an in-memory file.
77   ///\returns a \c PartialTranslationUnit which holds information about the
78   /// \c TranslationUnitDecl and \c llvm::Module corresponding to the input.
79   virtual llvm::Expected<PartialTranslationUnit &> Parse(llvm::StringRef Input);
80 
81   /// Uses the CodeGenModule mangled name cache and avoids recomputing.
82   ///\returns the mangled name of a \c GD.
83   llvm::StringRef GetMangledName(GlobalDecl GD) const;
84 
85   void CleanUpPTU(PartialTranslationUnit &PTU);
86 
getPTUs()87   std::list<PartialTranslationUnit> &getPTUs() { return PTUs; }
88 
89   std::unique_ptr<llvm::Module> GenModule();
90 
91 private:
92   llvm::Expected<PartialTranslationUnit &> ParseOrWrapTopLevelDecl();
93 };
94 } // end namespace clang
95 
96 #endif // LLVM_CLANG_LIB_INTERPRETER_INCREMENTALPARSER_H
97