14
14
#ifndef LLVM_CLANG_INTERPRETER_INTERPRETER_H
15
15
#define LLVM_CLANG_INTERPRETER_INTERPRETER_H
16
16
17
+ #include " clang/AST/Decl.h"
17
18
#include " clang/AST/GlobalDecl.h"
18
19
#include " clang/Interpreter/PartialTranslationUnit.h"
19
20
#include " clang/Interpreter/Value.h"
21
+ #include " clang/Sema/Ownership.h"
20
22
21
23
#include " llvm/ADT/DenseMap.h"
22
24
#include " llvm/ExecutionEngine/JITSymbol.h"
@@ -36,9 +38,6 @@ class ThreadSafeContext;
36
38
namespace clang {
37
39
38
40
class CompilerInstance ;
39
- class CodeGenerator ;
40
- class CXXRecordDecl ;
41
- class Decl ;
42
41
class IncrementalExecutor ;
43
42
class IncrementalParser ;
44
43
@@ -78,45 +77,42 @@ class IncrementalCompilerBuilder {
78
77
llvm::StringRef CudaSDKPath;
79
78
};
80
79
81
- class IncrementalAction ;
82
- class InProcessPrintingASTConsumer ;
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
+ };
83
89
84
90
// / Provides top-level interfaces for incremental compilation and execution.
85
91
class Interpreter {
86
- friend class Value ;
87
- friend InProcessPrintingASTConsumer;
88
-
89
92
std::unique_ptr<llvm::orc::ThreadSafeContext> TSCtx;
90
- // / Long-lived, incremental parsing action.
91
- std::unique_ptr<IncrementalAction> Act;
92
93
std::unique_ptr<IncrementalParser> IncrParser;
93
94
std::unique_ptr<IncrementalExecutor> IncrExecutor;
95
+ std::unique_ptr<RuntimeInterfaceBuilder> RuntimeIB;
94
96
95
97
// An optional parser for CUDA offloading
96
98
std::unique_ptr<IncrementalParser> DeviceParser;
97
99
98
- // / List containing information about each incrementally parsed piece of code.
99
- std::list<PartialTranslationUnit> PTUs;
100
-
101
100
unsigned InitPTUSize = 0 ;
102
101
103
102
// This member holds the last result of the value printing. It's a class
104
103
// member because we might want to access it after more inputs. If no value
105
104
// printing happens, it's in an invalid state.
106
105
Value LastValue;
107
106
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;
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 ;
114
111
115
112
protected:
116
113
// Derived classes can use an extended interface of the Interpreter.
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 );
114
+ Interpreter (std::unique_ptr<CompilerInstance> CI, llvm::Error &Err,
115
+ std::unique_ptr<llvm::orc::LLJITBuilder> JITBuilder = nullptr );
120
116
121
117
// Create the internal IncrementalExecutor, or re-create it after calling
122
118
// ResetExecutor().
@@ -126,8 +122,15 @@ class Interpreter {
126
122
// JIT engine. In particular, it doesn't run cleanup or destructors.
127
123
void ResetExecutor ();
128
124
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
+
129
131
public:
130
132
virtual ~Interpreter ();
133
+
131
134
static llvm::Expected<std::unique_ptr<Interpreter>>
132
135
create (std::unique_ptr<CompilerInstance> CI);
133
136
static llvm::Expected<std::unique_ptr<Interpreter>>
@@ -142,6 +145,7 @@ class Interpreter {
142
145
llvm::Expected<PartialTranslationUnit &> Parse (llvm::StringRef Code);
143
146
llvm::Error Execute (PartialTranslationUnit &T);
144
147
llvm::Error ParseAndExecute (llvm::StringRef Code, Value *V = nullptr );
148
+ llvm::Expected<llvm::orc::ExecutorAddr> CompileDtorCall (CXXRecordDecl *CXXRD);
145
149
146
150
// / Undo N previous incremental inputs.
147
151
llvm::Error Undo (unsigned N = 1 );
@@ -163,6 +167,8 @@ class Interpreter {
163
167
llvm::Expected<llvm::orc::ExecutorAddr>
164
168
getSymbolAddressFromLinkerName (llvm::StringRef LinkerName) const ;
165
169
170
+ enum InterfaceKind { NoAlloc, WithAlloc, CopyArray, NewTag };
171
+
166
172
const llvm::SmallVectorImpl<Expr *> &getValuePrintingInfo () const {
167
173
return ValuePrintingInfo;
168
174
}
@@ -172,15 +178,7 @@ class Interpreter {
172
178
private:
173
179
size_t getEffectivePTUSize () const ;
174
180
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.
184
182
llvm::DenseMap<CXXRecordDecl *, llvm::orc::ExecutorAddr> Dtors;
185
183
186
184
llvm::SmallVector<Expr *, 4 > ValuePrintingInfo;
0 commit comments