2323
2424#include < chrono>
2525#include < ctime>
26- #include < numeric>
2726
2827using namespace swift ;
2928
3029namespace {
3130
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+ };
3535
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" )));
3848
3949 llvm::cl::opt<unsigned int > Iteration = llvm::cl::opt<unsigned int >(
4050 " n" , llvm::cl::desc(" iteration" ), llvm::cl::init(1 ));
4151
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+
4256 llvm::cl::list<std::string> InputPaths = llvm::cl::list<std::string>(
4357 llvm::cl::Positional, llvm::cl::desc(" input paths" ));
4458};
4559
46- enum class ParseMode {
47- SwiftParser,
48- LibParse,
49- };
50-
5160struct LibParseExecutor {
5261 constexpr static StringRef name = " libParse" ;
5362
54- static void performParse (llvm::MemoryBufferRef buffer) {
63+ static void performParse (llvm::MemoryBufferRef buffer, ExecuteOptions opts ) {
5564 SourceManager SM;
5665 unsigned bufferID =
5766 SM.addNewSourceBuffer (llvm::MemoryBuffer::getMemBuffer (buffer));
@@ -67,11 +76,9 @@ struct LibParseExecutor {
6776 clangOpts, symbolOpts, SM, diagEngine));
6877
6978 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;
7479 parseOpts |= SourceFile::ParsingFlags::DisablePoundIfEvaluation;
80+ if (!opts.contains (ExecuteOptionFlag::SkipBodies))
81+ parseOpts |= SourceFile::ParsingFlags::DisableDelayedBodies;
7582
7683 ModuleDecl *M = ModuleDecl::create (Identifier (), *ctx);
7784 SourceFile *SF =
@@ -86,11 +93,14 @@ struct LibParseExecutor {
8693struct SwiftParserExecutor {
8794 constexpr static StringRef name = " SwiftParser" ;
8895
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'
9099 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 );
93102 swift_ASTGen_destroySourceFile (sourceFile);
103+ #endif
94104 }
95105};
96106
@@ -144,7 +154,8 @@ static std::pair<Duration, Duration> measure(llvm::function_ref<void()> body) {
144154template <typename Executor>
145155static void
146156perform (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) {
148159
149160 llvm::outs () << " ----\n " ;
150161 llvm::outs () << " parser: " << Executor::name << " \n " ;
@@ -156,7 +167,7 @@ perform(const SmallVectorImpl<std::unique_ptr<llvm::MemoryBuffer>> &buffers,
156167 for (unsigned i = 0 ; i < iteration; i++) {
157168 for (auto &buffer : buffers) {
158169 std::pair<duration_t , duration_t > elapsed = measure<duration_t >(
159- [&] { Executor::performParse (buffer->getMemBufferRef ()); });
170+ [&] { Executor::performParse (buffer->getMemBufferRef (), opts ); });
160171 tDuration += elapsed.first ;
161172 cDuration += elapsed.second ;
162173 }
@@ -185,6 +196,9 @@ int swift_parse_test_main(ArrayRef<const char *> args, const char *argv0,
185196 " Swift parse test\n " );
186197
187198 unsigned iteration = options.Iteration ;
199+ ExecuteOptions execOptions;
200+ if (options.SkipBodies )
201+ execOptions |= ExecuteOptionFlag::SkipBodies;
188202
189203 SmallVector<std::unique_ptr<llvm::MemoryBuffer>> buffers;
190204 loadSources (options.InputPaths , buffers);
@@ -199,11 +213,23 @@ int swift_parse_test_main(ArrayRef<const char *> args, const char *argv0,
199213 << llvm::format (" total bytes: %8d\n " , byteCount)
200214 << llvm::format (" total lines: %8d\n " , lineCount)
201215 << 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+ }
207233
208234 return 0 ;
209235}
0 commit comments