-
Notifications
You must be signed in to change notification settings - Fork 314
Expand file tree
/
Copy pathIncrementalParser.h
More file actions
250 lines (204 loc) · 7.5 KB
/
Copy pathIncrementalParser.h
File metadata and controls
250 lines (204 loc) · 7.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
//--------------------------------------------------------------------*- C++ -*-
// CLING - the C++ LLVM-based InterpreterG :)
// author: Axel Naumann <axel@cern.ch>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------
#ifndef CLING_INCREMENTAL_PARSER_H
#define CLING_INCREMENTAL_PARSER_H
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include <vector>
#include <deque>
#include <memory>
namespace llvm {
struct GenericValue;
class MemoryBuffer;
class Module;
}
namespace clang {
class CodeGenerator;
class CompilerInstance;
class DiagnosticConsumer;
class Decl;
class FileID;
class Parser;
}
namespace cling {
class CompilationOptions;
class DeclCollector;
class ExecutionContext;
class Interpreter;
class Transaction;
class TransactionPool;
class ASTTransformer;
///\brief Responsible for the incremental parsing and compilation of input.
///
/// The class manages the entire process of compilation line-by-line by
/// appending the compiled delta to clang'a AST. It provides basic operations
/// on the already compiled code. See cling::Transaction class.
///
class IncrementalParser {
private:
// our interpreter context
// FIXME: Get rid of that back reference to the interpreter.
Interpreter* m_Interpreter;
// compiler instance.
std::unique_ptr<clang::CompilerInstance> m_CI;
// parser (incremental)
std::unique_ptr<clang::Parser> m_Parser;
// One buffer for each command line, owner by the source file manager
std::deque<std::pair<llvm::MemoryBuffer*, clang::FileID>> m_MemoryBuffers;
// file ID of the memory buffer
clang::FileID m_VirtualFileID;
// CI owns it
DeclCollector* m_Consumer;
///\brief The storage for our transactions.
///
/// We don't need the elements to be contiguous in memory, that is why we
/// don't use std::vector. We don't need to copy the elements every time the
/// capacity is exceeded.
///
std::deque<Transaction*> m_Transactions;
///\brief Number of created modules.
unsigned m_ModuleNo;
///\brief Code generator
///
std::unique_ptr<clang::CodeGenerator> m_CodeGen;
///\brief Pool of reusable block-allocated transactions.
///
std::unique_ptr<TransactionPool> m_TransactionPool;
///\brief DiagnosticConsumer instance
///
std::unique_ptr<clang::DiagnosticConsumer> m_DiagConsumer;
public:
enum EParseResult {
kSuccess,
kSuccessWithWarnings,
kFailed
};
typedef llvm::PointerIntPair<Transaction*, 2, EParseResult>
ParseResultTransaction;
IncrementalParser(Interpreter* interp, const char* llvmdir);
~IncrementalParser();
///\brief Whether the IncrementalParser is valid.
///
///\param[in] initialized - check if IncrementalParser has been initialized.
///
bool isValid(bool initialized = true) const;
bool Initialize(llvm::SmallVectorImpl<ParseResultTransaction>& result,
bool isChildInterpreter);
clang::CompilerInstance* getCI() const { return m_CI.get(); }
clang::Parser* getParser() const { return m_Parser.get(); }
clang::CodeGenerator* getCodeGenerator() const { return m_CodeGen.get(); }
bool hasCodeGenerator() const { return m_CodeGen.get(); }
clang::SourceLocation getLastMemoryBufferEndLoc() const;
/// \{
/// \name Transaction Support
///\brief Starts a transaction.
///
Transaction* beginTransaction(const CompilationOptions& Opts);
///\brief Finishes a transaction.
///
ParseResultTransaction endTransaction(Transaction* T);
///\brief Commits a transaction if it was complete. I.e pipes it
/// through the consumer chain, including codegen.
///
///\param[in] PRT - the transaction (ParseResultTransaction) to be
/// committed
///\param[in] ClearDiagClient - Reset the DiagnosticsEngine client or not
///
void commitTransaction(ParseResultTransaction& PRT,
bool ClearDiagClient = true);
///\brief Runs the consumers (e.g. CodeGen) on a non-parsed transaction.
///
///\param[in] T - the transaction to be consumed
///
void emitTransaction(Transaction* T);
///\brief Remove a Transaction from the collection of Transactions.
///
///\param[in] T - The transaction to be reverted from the AST
///
void deregisterTransaction(Transaction& T);
///\brief Returns the first transaction the incremental parser saw.
///
const Transaction* getFirstTransaction() const {
if (m_Transactions.empty())
return 0;
return m_Transactions.front();
}
///\brief Returns the last transaction the incremental parser saw.
///
Transaction* getLastTransaction() {
if (m_Transactions.empty())
return 0;
return m_Transactions.back();
}
///\brief Returns the last transaction the incremental parser saw.
///
const Transaction* getLastTransaction() const {
if (m_Transactions.empty())
return 0;
return m_Transactions.back();
}
///\brief Merge transactions after the one given.
///
///\param[in] T - transactions after which to merge
///\returns the parent transaction of the merge.
///
void mergeTransactionsAfter(const Transaction *T);
///\brief Returns the currently active transaction.
///
const Transaction* getCurrentTransaction() const;
///\brief Add a user-generated transaction.
void addTransaction(Transaction* T);
///\brief Returns the list of transactions seen by the interpreter.
/// Intentionally makes a copy - that function is meant to be use for debug
/// purposes.
///
std::vector<const Transaction*> getAllTransactions();
/// \}
///\brief Compiles the given input with the given compilation options.
///
///\param[in] input - The code to compile.
///\param[in] Opts - The compilation options to use.
///\returns the declarations that were compiled.
///
ParseResultTransaction Compile(llvm::StringRef input, const CompilationOptions& Opts);
void printTransactionStructure() const;
///\brief Runs the static initializers created by codegening a transaction.
///
///\param[in] T - the transaction for which to run the initializers.
///
bool runStaticInitOnTransaction(Transaction* T) const;
///\brief Add the trnasformers to the Incremental Parser.
///
void SetTransformers(bool isChildInterpreter);
private:
///\brief Finalizes the consumers (e.g. CodeGen) on a transaction.
///
///\param[in] T - the transaction to be finalized
///
void codeGenTransaction(Transaction* T);
///\brief Initializes a virtual file, which will be able to produce valid
/// source locations, with the proper offsets.
///
void initializeVirtualFile();
///\brief The work horse for parsing. It queries directly clang.
///
///\param[in] input - The incremental input that needs to be parsed.
///
EParseResult ParseInternal(llvm::StringRef input);
///\brief Create a unique name for the next llvm::Module
///
std::string makeModuleName();
///\brief Create a new llvm::Module
///
llvm::Module* StartModule();
};
} // end namespace cling
#endif // CLING_INCREMENTAL_PARSER_H