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,56 @@ 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
+ std::unique_ptr<llvm::orc::LLJITBuilder> JITBuilder;
99
+
100
+ // / List containing every information about every incrementally parsed piece
101
+ // / of code.
102
+ std::list<PartialTranslationUnit> PTUs;
103
+
100
104
unsigned InitPTUSize = 0 ;
101
105
102
106
// This member holds the last result of the value printing. It's a class
103
107
// member because we might want to access it after more inputs. If no value
104
108
// printing happens, it's in an invalid state.
105
109
Value LastValue;
106
110
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 ;
111
+ // The cached declaration of std::string used as a return type for the built
112
+ // trampoline. This is done in C++ to simplify the memory management for
113
+ // user-defined printing functions.
114
+ Decl *StdString = nullptr ;
115
+
116
+ // A cache for the compiled destructors used to for de-allocation of managed
117
+ // clang::Values.
118
+ llvm::DenseMap<CXXRecordDecl *, llvm::orc::ExecutorAddr> Dtors;
119
+
120
+ std::array<Expr *, 4 > ValuePrintingInfo = {0 };
121
+
122
+ // / When CodeGen is created the first llvm::Module gets cached in many places
123
+ // / and we must keep it alive.
124
+ std::unique_ptr<llvm::Module> CachedInCodeGenModule;
111
125
112
126
protected:
113
127
// Derived classes can use an extended interface of the Interpreter.
114
128
Interpreter (std::unique_ptr<CompilerInstance> CI, llvm::Error &Err,
115
- std::unique_ptr<llvm::orc::LLJITBuilder> JITBuilder = nullptr );
129
+ std::unique_ptr<llvm::orc::LLJITBuilder> JITBuilder = nullptr ,
130
+ std::unique_ptr<clang::ASTConsumer> Consumer = nullptr );
116
131
117
132
// Create the internal IncrementalExecutor, or re-create it after calling
118
133
// ResetExecutor().
@@ -122,15 +137,8 @@ class Interpreter {
122
137
// JIT engine. In particular, it doesn't run cleanup or destructors.
123
138
void ResetExecutor ();
124
139
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
140
public:
132
141
virtual ~Interpreter ();
133
-
134
142
static llvm::Expected<std::unique_ptr<Interpreter>>
135
143
create (std::unique_ptr<CompilerInstance> CI);
136
144
static llvm::Expected<std::unique_ptr<Interpreter>>
@@ -145,7 +153,6 @@ class Interpreter {
145
153
llvm::Expected<PartialTranslationUnit &> Parse (llvm::StringRef Code);
146
154
llvm::Error Execute (PartialTranslationUnit &T);
147
155
llvm::Error ParseAndExecute (llvm::StringRef Code, Value *V = nullptr );
148
- llvm::Expected<llvm::orc::ExecutorAddr> CompileDtorCall (CXXRecordDecl *CXXRD);
149
156
150
157
// / Undo N previous incremental inputs.
151
158
llvm::Error Undo (unsigned N = 1 );
@@ -167,23 +174,29 @@ class Interpreter {
167
174
llvm::Expected<llvm::orc::ExecutorAddr>
168
175
getSymbolAddressFromLinkerName (llvm::StringRef LinkerName) const ;
169
176
170
- enum InterfaceKind { NoAlloc, WithAlloc, CopyArray, NewTag };
171
-
172
- const llvm::SmallVectorImpl<Expr *> &getValuePrintingInfo () const {
173
- return ValuePrintingInfo;
174
- }
175
-
176
- Expr *SynthesizeExpr (Expr *E);
177
+ std::unique_ptr<llvm::Module> GenModule ();
177
178
178
179
private:
179
180
size_t getEffectivePTUSize () const ;
180
181
void markUserCodeStart ();
181
182
182
- llvm::DenseMap<CXXRecordDecl *, llvm::orc::ExecutorAddr> Dtors;
183
+ // / @}
184
+ // / @name Value and pretty printing support
185
+ // / @{
183
186
184
- llvm::SmallVector<Expr *, 4 > ValuePrintingInfo;
187
+ std::string ValueDataToString (const Value &V);
188
+ std::string ValueTypeToString (const Value &V) const ;
185
189
186
- std::unique_ptr<llvm::orc::LLJITBuilder> JITBuilder;
190
+ llvm::Expected<Expr *> AttachValuePrinting (Expr *E);
191
+
192
+ // When we deallocate clang::Value we need to run the destructor of the type.
193
+ // This function forces emission of the needed dtor.
194
+ llvm::Expected<llvm::orc::ExecutorAddr> CompileDtorCall (CXXRecordDecl *CXXRD);
195
+
196
+ // / @}
197
+ // / @name Code generation
198
+ // / @{
199
+ CodeGenerator *getCodeGen () const ;
187
200
};
188
201
} // namespace clang
189
202
0 commit comments