23
23
24
24
#include < chrono>
25
25
#include < ctime>
26
- #include < numeric>
27
26
28
27
using namespace swift ;
29
28
30
29
namespace {
31
30
32
- struct SwiftParseTestOptions {
33
- llvm::cl::opt<bool > SwiftParser =
34
- llvm::cl::opt<bool >(" swift-parser" , llvm::cl::desc(" Use SwiftParser" ));
31
+ enum class Executor {
32
+ SwiftParser,
33
+ LibParse,
34
+ };
35
35
36
- llvm::cl::opt<bool > LibParse =
37
- llvm::cl::opt<bool >(" lib-parse" , llvm::cl::desc(" Use libParse" ));
36
+ enum class ExecuteOptionFlag {
37
+ // / Enable body skipping
38
+ SkipBodies = 1 << 0 ,
39
+ };
40
+ using ExecuteOptions = OptionSet<ExecuteOptionFlag>;
41
+
42
+ struct SwiftParseTestOptions {
43
+ llvm::cl::list<Executor> Executors = llvm::cl::list<Executor>(
44
+ llvm::cl::desc (" Available parsers" ),
45
+ llvm::cl::values (
46
+ clEnumValN (Executor::SwiftParser, " swift-parser" , " SwiftParser" ),
47
+ clEnumValN(Executor::LibParse, " lib-parse" , " libParse" )));
38
48
39
49
llvm::cl::opt<unsigned int > Iteration = llvm::cl::opt<unsigned int >(
40
50
" n" , llvm::cl::desc(" iteration" ), llvm::cl::init(1 ));
41
51
52
+ llvm::cl::opt<bool > SkipBodies = llvm::cl::opt<bool >(
53
+ " skip-bodies" ,
54
+ llvm::cl::desc (" skip function bodies and type members if possible" ));
55
+
42
56
llvm::cl::list<std::string> InputPaths = llvm::cl::list<std::string>(
43
57
llvm::cl::Positional, llvm::cl::desc(" input paths" ));
44
58
};
45
59
46
- enum class ParseMode {
47
- SwiftParser,
48
- LibParse,
49
- };
50
-
51
60
struct LibParseExecutor {
52
61
constexpr static StringRef name = " libParse" ;
53
62
54
- static void performParse (llvm::MemoryBufferRef buffer) {
63
+ static void performParse (llvm::MemoryBufferRef buffer, ExecuteOptions opts ) {
55
64
SourceManager SM;
56
65
unsigned bufferID =
57
66
SM.addNewSourceBuffer (llvm::MemoryBuffer::getMemBuffer (buffer));
@@ -67,11 +76,9 @@ struct LibParseExecutor {
67
76
clangOpts, symbolOpts, SM, diagEngine));
68
77
69
78
SourceFile::ParsingOptions parseOpts;
70
- // Always disable body skipping because SwiftParser currently don't have it.
71
- // When SwiftParser implements delayed parsing, this should be a command
72
- // line option.
73
- parseOpts |= SourceFile::ParsingFlags::DisableDelayedBodies;
74
79
parseOpts |= SourceFile::ParsingFlags::DisablePoundIfEvaluation;
80
+ if (!opts.contains (ExecuteOptionFlag::SkipBodies))
81
+ parseOpts |= SourceFile::ParsingFlags::DisableDelayedBodies;
75
82
76
83
ModuleDecl *M = ModuleDecl::create (Identifier (), *ctx);
77
84
SourceFile *SF =
@@ -86,11 +93,14 @@ struct LibParseExecutor {
86
93
struct SwiftParserExecutor {
87
94
constexpr static StringRef name = " SwiftParser" ;
88
95
89
- static void performParse (llvm::MemoryBufferRef buffer) {
96
+ static void performParse (llvm::MemoryBufferRef buffer, ExecuteOptions opts) {
97
+ #if SWIFT_BUILD_SWIFT_SYNTAX
98
+ // TODO: Implement 'ExecuteOptionFlag::SkipBodies'
90
99
auto sourceFile = swift_ASTGen_parseSourceFile (
91
- buffer.getBufferStart (), buffer.getBufferSize (), " " ,
92
- buffer.getBufferIdentifier ().data (), nullptr );
100
+ buffer.getBufferStart (), buffer.getBufferSize (), /* moduleName= */ " " ,
101
+ buffer.getBufferIdentifier ().data (), /* ASTContext= */ nullptr );
93
102
swift_ASTGen_destroySourceFile (sourceFile);
103
+ #endif
94
104
}
95
105
};
96
106
@@ -144,7 +154,8 @@ static std::pair<Duration, Duration> measure(llvm::function_ref<void()> body) {
144
154
template <typename Executor>
145
155
static void
146
156
perform (const SmallVectorImpl<std::unique_ptr<llvm::MemoryBuffer>> &buffers,
147
- unsigned iteration, uintmax_t totalBytes, uintmax_t totalLines) {
157
+ ExecuteOptions opts, unsigned iteration, uintmax_t totalBytes,
158
+ uintmax_t totalLines) {
148
159
149
160
llvm::outs () << " ----\n " ;
150
161
llvm::outs () << " parser: " << Executor::name << " \n " ;
@@ -156,7 +167,7 @@ perform(const SmallVectorImpl<std::unique_ptr<llvm::MemoryBuffer>> &buffers,
156
167
for (unsigned i = 0 ; i < iteration; i++) {
157
168
for (auto &buffer : buffers) {
158
169
std::pair<duration_t , duration_t > elapsed = measure<duration_t >(
159
- [&] { Executor::performParse (buffer->getMemBufferRef ()); });
170
+ [&] { Executor::performParse (buffer->getMemBufferRef (), opts ); });
160
171
tDuration += elapsed.first ;
161
172
cDuration += elapsed.second ;
162
173
}
@@ -185,6 +196,9 @@ int swift_parse_test_main(ArrayRef<const char *> args, const char *argv0,
185
196
" Swift parse test\n " );
186
197
187
198
unsigned iteration = options.Iteration ;
199
+ ExecuteOptions execOptions;
200
+ if (options.SkipBodies )
201
+ execOptions |= ExecuteOptionFlag::SkipBodies;
188
202
189
203
SmallVector<std::unique_ptr<llvm::MemoryBuffer>> buffers;
190
204
loadSources (options.InputPaths , buffers);
@@ -199,11 +213,23 @@ int swift_parse_test_main(ArrayRef<const char *> args, const char *argv0,
199
213
<< llvm::format (" total bytes: %8d\n " , byteCount)
200
214
<< llvm::format (" total lines: %8d\n " , lineCount)
201
215
<< llvm::format (" iterations: %8d\n " , iteration);
202
-
203
- if (options.SwiftParser )
204
- perform<SwiftParserExecutor>(buffers, iteration, byteCount, lineCount);
205
- if (options.LibParse )
206
- perform<LibParseExecutor>(buffers, iteration, byteCount, lineCount);
216
+ for (auto mode : options.Executors ) {
217
+ switch (mode) {
218
+ case Executor::SwiftParser:
219
+ #if SWIFT_BUILD_SWIFT_SYNTAX
220
+ perform<SwiftParserExecutor>(buffers, execOptions, iteration, byteCount,
221
+ lineCount);
222
+ break ;
223
+ #else
224
+ llvm::errs () << " error: SwiftParser is not enabled\n " ;
225
+ return 1 ;
226
+ #endif
227
+ case Executor::LibParse:
228
+ perform<LibParseExecutor>(buffers, execOptions, iteration, byteCount,
229
+ lineCount);
230
+ break ;
231
+ }
232
+ }
207
233
208
234
return 0 ;
209
235
}
0 commit comments