@@ -195,9 +195,12 @@ class positional_printer
195
195
std::string cpp2_filename = {};
196
196
std::string cpp1_filename = {};
197
197
std::vector<comment> const * pcomments = {}; // Cpp2 comments data
198
+ cpp2::parser const * pparser = {};
198
199
199
200
source_position curr_pos = {}; // current (line,col) in output
200
201
int next_comment = 0 ; // index of the next comment not yet printed
202
+ bool last_was_empty = false ;
203
+ int empty_lines_suppressed = 0 ;
201
204
bool last_was_cpp2 = false ;
202
205
bool source_has_cpp2 = false ;
203
206
@@ -234,6 +237,7 @@ class positional_printer
234
237
break ;case phase1_type_defs_func_decls: phase = phase2_func_defs;
235
238
break ;default : assert (!" ICE: invalid lowering phase" );
236
239
}
240
+ next_comment = 0 ; // start over with the comments
237
241
}
238
242
239
243
std::vector<std::string*> emit_string_targets; // option to emit to string instead of out file
@@ -274,6 +278,35 @@ class positional_printer
274
278
// Otherwise, we'll actually print the string to the output file
275
279
// and update our curr_pos position
276
280
281
+ // Reject consecutive empty lines: If this line is empty
282
+ if (
283
+ s == " \n "
284
+ && curr_pos.colno <= 1
285
+ )
286
+ {
287
+ // And so was the last one, update logical position only
288
+ // and increment empty_lines_suppressed instead of printing
289
+ if (last_was_empty) {
290
+ ++curr_pos.lineno ;
291
+ curr_pos.colno = 1 ;
292
+ ++empty_lines_suppressed;
293
+ return ;
294
+ }
295
+ // If this is the first consecutive empty, remember and continue
296
+ last_was_empty = true ;
297
+ }
298
+ // Otherwise, if this line is not empty
299
+ else {
300
+ // Remember that this line was not empty
301
+ last_was_empty = false ;
302
+
303
+ // And if we did suppress any empties, emit a #line to resync
304
+ if (empty_lines_suppressed > 0 ) {
305
+ print_line_directive (curr_pos.lineno );
306
+ empty_lines_suppressed = 0 ;
307
+ }
308
+ }
309
+
277
310
// Output the string
278
311
assert (out);
279
312
*out << s;
@@ -345,41 +378,38 @@ class positional_printer
345
378
346
379
// For convenience
347
380
auto & comments = *pcomments;
348
-
349
- // Don't emit comments while in the first declarations-only pass
350
- if (phase < phase2_func_defs) {
351
- return ;
352
- }
353
-
381
+
354
382
// Add unprinted comments and blank lines as needed to catch up vertically
355
383
//
356
384
while (curr_pos.lineno < pos.lineno )
357
385
{
358
386
// If a comment goes on this line, print it
359
- assert (
360
- next_comment >= std::ssize (comments)
361
- || comments[next_comment].start .lineno >= curr_pos.lineno
362
- );
363
387
if (
364
388
next_comment < std::ssize (comments)
365
389
&& comments[next_comment].start .lineno == curr_pos.lineno
366
390
)
367
391
{
368
- // For a line comment, start it at the right indentation and print it
369
- // with a newline end
370
- if (comments[next_comment].kind == comment::comment_kind::line_comment) {
371
- print ( pad ( comments[next_comment].start .colno - curr_pos.colno + 1 ) );
372
- print ( comments[next_comment].text );
373
- assert ( comments[next_comment].text .find (" \n " ) == std::string::npos ); // we shouldn't have newlines
374
- print (" \n " );
375
- }
392
+ assert (pparser);
393
+ if (
394
+ phase == phase2_func_defs
395
+ )
396
+ {
397
+ // For a line comment, start it at the right indentation and print it
398
+ // with a newline end
399
+ if (comments[next_comment].kind == comment::comment_kind::line_comment) {
400
+ print ( pad ( comments[next_comment].start .colno - curr_pos.colno + 1 ) );
401
+ print ( comments[next_comment].text );
402
+ assert ( comments[next_comment].text .find (" \n " ) == std::string::npos ); // we shouldn't have newlines
403
+ print (" \n " );
404
+ }
376
405
377
- // For a stream comment, pad out to its column (if we haven't passed it already)
378
- // and emit it there
379
- else {
380
- print ( pad ( comments[next_comment].start .colno - curr_pos.colno ) );
381
- print ( comments[next_comment].text );
382
- assert (curr_pos.lineno <= pos.lineno ); // we shouldn't have overshot
406
+ // For a stream comment, pad out to its column (if we haven't passed it already)
407
+ // and emit it there
408
+ else {
409
+ print ( pad ( comments[next_comment].start .colno - curr_pos.colno ) );
410
+ print ( comments[next_comment].text );
411
+ assert (curr_pos.lineno <= pos.lineno ); // we shouldn't have overshot
412
+ }
383
413
}
384
414
385
415
++next_comment;
@@ -410,11 +440,20 @@ class positional_printer
410
440
// Catch up with displaying comments
411
441
flush_comments ( pos );
412
442
413
- // If we're not on the right line, move forward one line
414
- if (curr_pos.lineno < pos.lineno ) {
415
- ensure_at_start_of_new_line ();
416
- assert (curr_pos.lineno <= pos.lineno );
417
- curr_pos.lineno = pos.lineno ; // re-sync
443
+ // If we're not on the right line
444
+ if (curr_pos.lineno < pos.lineno )
445
+ {
446
+ // If we're just one away, try to move forward one line
447
+ // Note: If there are consecutive blank lines, this might
448
+ // get ignored, so we will repeat the "!= lineno" again...
449
+ if (curr_pos.lineno == pos.lineno - 1 ) {
450
+ print ( " \n " );
451
+ }
452
+ // ...here:
453
+ if (curr_pos.lineno != pos.lineno ) {
454
+ print_line_directive (pos.lineno );
455
+ }
456
+ curr_pos.lineno = pos.lineno ;
418
457
}
419
458
420
459
// Finally, align to the target column
@@ -454,6 +493,7 @@ class positional_printer
454
493
std::string cpp2_filename_,
455
494
std::string cpp1_filename_,
456
495
std::vector<comment> const & comments,
496
+ cpp2::parser const & parser,
457
497
bool has_cpp2
458
498
)
459
499
-> void
@@ -474,6 +514,7 @@ class positional_printer
474
514
out = &out_file;
475
515
}
476
516
pcomments = &comments;
517
+ pparser = &parser;
477
518
}
478
519
479
520
auto reopen ()
@@ -575,7 +616,7 @@ class positional_printer
575
616
);
576
617
577
618
// Because the blank/comment lines before a Cpp2 code section are part
578
- // of the Cpp2 section, and not printed in thedeclarations-only pass
619
+ // of the Cpp2 section, and not printed in the pre-function-definitions passes
579
620
if (
580
621
!last_was_cpp2
581
622
&& phase < phase2_func_defs
@@ -587,14 +628,14 @@ class positional_printer
587
628
// Keep track of whether the last thing we printed was Cpp2
588
629
last_was_cpp2 = true ;
589
630
590
- reset_cpp2_line_to (line);
631
+ reset_line_to (line);
591
632
}
592
633
593
634
// -----------------------------------------------------------------------
594
635
// Used when we start a new Cpp2 section, or when we emit the same item
595
636
// more than once (notably when we emit operator= more than once)
596
637
//
597
- auto reset_cpp2_line_to (lineno_t line)
638
+ auto reset_line_to (lineno_t line)
598
639
-> void
599
640
{
600
641
// Always start a Cpp2 section on its own new line
@@ -1050,6 +1091,7 @@ class cppfront
1050
1091
sourcefile,
1051
1092
cpp1_filename,
1052
1093
tokens.get_comments (),
1094
+ parser,
1053
1095
source.has_cpp2 ()
1054
1096
);
1055
1097
if (!printer.is_open ()) {
@@ -1171,6 +1213,7 @@ class cppfront
1171
1213
1172
1214
// Treat each declaration as the start of a Cpp2 section (so we get #line)
1173
1215
printer.start_cpp2 ( decl->position ().lineno );
1216
+ // printer.start_cpp2( map_iter->first /*lineno*/);
1174
1217
emit (*decl);
1175
1218
}
1176
1219
++map_iter;
@@ -1232,9 +1275,6 @@ class cppfront
1232
1275
assert (!section.second .empty ());
1233
1276
1234
1277
// Tell the printer that we're starting a Cpp2 section
1235
- // This time, we use the actual first start line of the section which includes
1236
- // the blank/comment lines at the beginning if any (whereas in the first pass
1237
- // we used the line of the first Cpp2 token in the section to skip blanks/comments)
1238
1278
printer.start_cpp2 ( section.first /* lineno*/ );
1239
1279
1240
1280
// Get the parse tree for this section and emit each forward declaration
@@ -4246,8 +4286,8 @@ class cppfront
4246
4286
)
4247
4287
-> void
4248
4288
{
4249
- auto need_to_generate_assignment = false ;
4250
- auto need_to_generate_move = false ;
4289
+ auto need_to_generate_assignment = false ;
4290
+ auto need_to_generate_move = false ;
4251
4291
4252
4292
if (
4253
4293
n.is_function ()
@@ -4811,7 +4851,7 @@ class cppfront
4811
4851
}
4812
4852
4813
4853
// Then reposition and do the recursive call
4814
- printer.reset_cpp2_line_to (n.position ().lineno );
4854
+ printer.reset_line_to (n.position ().lineno );
4815
4855
generating_assignment_from = &n;
4816
4856
emit ( n, capture_intro );
4817
4857
generating_assignment_from = {};
@@ -4827,7 +4867,7 @@ class cppfront
4827
4867
}
4828
4868
4829
4869
// Then reposition and do the recursive call
4830
- printer.reset_cpp2_line_to (n.position ().lineno );
4870
+ printer.reset_line_to (n.position ().lineno );
4831
4871
generating_move_from = &n;
4832
4872
emit ( n, capture_intro );
4833
4873
generating_move_from = {};
@@ -4900,18 +4940,17 @@ class cppfront
4900
4940
//
4901
4941
if (source_loaded)
4902
4942
{
4903
- auto out_source = std::ofstream{ sourcefile+" -source" };
4904
- source.debug_print ( out_source );
4943
+ auto out_source = std::ofstream{ sourcefile+" -source" };
4944
+ source.debug_print ( out_source );
4905
4945
4906
- auto out_tokens = std::ofstream{ sourcefile+" -tokens" };
4907
- tokens.debug_print ( out_tokens );
4946
+ auto out_tokens = std::ofstream{ sourcefile+" -tokens" };
4947
+ tokens.debug_print ( out_tokens );
4908
4948
4909
- auto out_parse = std::ofstream{ sourcefile+" -parse" };
4910
- auto tree_printer = parse_tree_printer{out_parse };
4911
- parser.visit ( tree_printer );
4949
+ auto out_parse = std::ofstream{ sourcefile+" -parse" };
4950
+ parser.debug_print ( out_parse );
4912
4951
4913
- auto out_symbols = std::ofstream{ sourcefile+" -symbols" };
4914
- sema.debug_print ( out_symbols );
4952
+ auto out_symbols = std::ofstream{ sourcefile+" -symbols" };
4953
+ sema.debug_print ( out_symbols );
4915
4954
}
4916
4955
}
4917
4956
0 commit comments