14
14
#ifndef LLVM_CLANG_INTERPRETER_INTERPRETER_H
15
15
#define LLVM_CLANG_INTERPRETER_INTERPRETER_H
16
16
17
- #include " clang/AST/Decl.h"
18
17
#include " clang/AST/GlobalDecl.h"
19
18
#include " clang/Interpreter/PartialTranslationUnit.h"
20
19
#include " clang/Interpreter/Value.h"
21
- #include " clang/Sema/Ownership.h"
22
20
23
21
#include " llvm/ADT/DenseMap.h"
24
22
#include " llvm/ExecutionEngine/JITSymbol.h"
@@ -38,6 +36,9 @@ class ThreadSafeContext;
38
36
namespace clang {
39
37
40
38
class CompilerInstance ;
39
+ class CodeGenerator ;
40
+ class CXXRecordDecl ;
41
+ class Decl ;
41
42
class IncrementalExecutor ;
42
43
class IncrementalParser ;
43
44
@@ -77,42 +78,45 @@ class IncrementalCompilerBuilder {
77
78
llvm::StringRef CudaSDKPath;
78
79
};
79
80
80
- // / Generate glue code between the Interpreter's built-in runtime and user code.
81
- class RuntimeInterfaceBuilder {
82
- public:
83
- virtual ~RuntimeInterfaceBuilder () = default ;
84
-
85
- using TransformExprFunction = ExprResult(RuntimeInterfaceBuilder *Builder,
86
- Expr *, ArrayRef<Expr *>);
87
- virtual TransformExprFunction *getPrintValueTransformer () = 0;
88
- };
81
+ class IncrementalAction ;
82
+ class InProcessPrintingASTConsumer ;
89
83
90
84
// / Provides top-level interfaces for incremental compilation and execution.
91
85
class Interpreter {
86
+ friend class Value ;
87
+ friend InProcessPrintingASTConsumer;
88
+
92
89
std::unique_ptr<llvm::orc::ThreadSafeContext> TSCtx;
90
+ // / Long-lived, incremental parsing action.
91
+ std::unique_ptr<IncrementalAction> Act;
93
92
std::unique_ptr<IncrementalParser> IncrParser;
94
93
std::unique_ptr<IncrementalExecutor> IncrExecutor;
95
- std::unique_ptr<RuntimeInterfaceBuilder> RuntimeIB;
96
94
97
95
// An optional parser for CUDA offloading
98
96
std::unique_ptr<IncrementalParser> DeviceParser;
99
97
98
+ // / List containing information about each incrementally parsed piece of code.
99
+ std::list<PartialTranslationUnit> PTUs;
100
+
100
101
unsigned InitPTUSize = 0 ;
101
102
102
103
// This member holds the last result of the value printing. It's a class
103
104
// member because we might want to access it after more inputs. If no value
104
105
// printing happens, it's in an invalid state.
105
106
Value LastValue;
106
107
107
- // Add a call to an Expr to report its result. We query the function from
108
- // RuntimeInterfaceBuilder once and store it as a function pointer to avoid
109
- // frequent virtual function calls.
110
- RuntimeInterfaceBuilder::TransformExprFunction *AddPrintValueCall = nullptr ;
108
+ // / When CodeGen is created the first llvm::Module gets cached in many places
109
+ // / and we must keep it alive.
110
+ std::unique_ptr<llvm::Module> CachedInCodeGenModule;
111
+
112
+ // / Compiler instance performing the incremental compilation.
113
+ std::unique_ptr<CompilerInstance> CI;
111
114
112
115
protected:
113
116
// Derived classes can use an extended interface of the Interpreter.
114
- Interpreter (std::unique_ptr<CompilerInstance> CI, llvm::Error &Err,
115
- std::unique_ptr<llvm::orc::LLJITBuilder> JITBuilder = nullptr );
117
+ Interpreter (std::unique_ptr<CompilerInstance> Instance, llvm::Error &Err,
118
+ std::unique_ptr<llvm::orc::LLJITBuilder> JITBuilder = nullptr ,
119
+ std::unique_ptr<clang::ASTConsumer> Consumer = nullptr );
116
120
117
121
// Create the internal IncrementalExecutor, or re-create it after calling
118
122
// ResetExecutor().
@@ -122,15 +126,8 @@ class Interpreter {
122
126
// JIT engine. In particular, it doesn't run cleanup or destructors.
123
127
void ResetExecutor ();
124
128
125
- // Lazily construct the RuntimeInterfaceBuilder. The provided instance will be
126
- // used for the entire lifetime of the interpreter. The default implementation
127
- // targets the in-process __clang_Interpreter runtime. Override this to use a
128
- // custom runtime.
129
- virtual std::unique_ptr<RuntimeInterfaceBuilder> FindRuntimeInterface ();
130
-
131
129
public:
132
130
virtual ~Interpreter ();
133
-
134
131
static llvm::Expected<std::unique_ptr<Interpreter>>
135
132
create (std::unique_ptr<CompilerInstance> CI);
136
133
static llvm::Expected<std::unique_ptr<Interpreter>>
@@ -145,7 +142,6 @@ class Interpreter {
145
142
llvm::Expected<PartialTranslationUnit &> Parse (llvm::StringRef Code);
146
143
llvm::Error Execute (PartialTranslationUnit &T);
147
144
llvm::Error ParseAndExecute (llvm::StringRef Code, Value *V = nullptr );
148
- llvm::Expected<llvm::orc::ExecutorAddr> CompileDtorCall (CXXRecordDecl *CXXRD);
149
145
150
146
// / Undo N previous incremental inputs.
151
147
llvm::Error Undo (unsigned N = 1 );
@@ -167,8 +163,6 @@ class Interpreter {
167
163
llvm::Expected<llvm::orc::ExecutorAddr>
168
164
getSymbolAddressFromLinkerName (llvm::StringRef LinkerName) const ;
169
165
170
- enum InterfaceKind { NoAlloc, WithAlloc, CopyArray, NewTag };
171
-
172
166
const llvm::SmallVectorImpl<Expr *> &getValuePrintingInfo () const {
173
167
return ValuePrintingInfo;
174
168
}
@@ -178,7 +172,15 @@ class Interpreter {
178
172
private:
179
173
size_t getEffectivePTUSize () const ;
180
174
void markUserCodeStart ();
175
+ llvm::Expected<Expr *> ExtractValueFromExpr (Expr *E);
176
+ llvm::Expected<llvm::orc::ExecutorAddr> CompileDtorCall (CXXRecordDecl *CXXRD);
177
+
178
+ CodeGenerator *getCodeGen () const ;
179
+ std::unique_ptr<llvm::Module> GenModule ();
180
+ PartialTranslationUnit &RegisterPTU (TranslationUnitDecl *TU);
181
181
182
+ // A cache for the compiled destructors used to for de-allocation of managed
183
+ // clang::Values.
182
184
llvm::DenseMap<CXXRecordDecl *, llvm::orc::ExecutorAddr> Dtors;
183
185
184
186
llvm::SmallVector<Expr *, 4 > ValuePrintingInfo;
0 commit comments