@@ -33,7 +33,7 @@ void forEachToken(const UnwrappedLine &Line, const T &Call,
33
33
FormatToken *Parent = nullptr ) {
34
34
bool First = true ;
35
35
for (const auto &N : Line.Tokens ) {
36
- Call (N.Tok , Parent, First);
36
+ Call (N.Tok , Parent, First, Line. Level );
37
37
First = false ;
38
38
for (const auto &Child : N.Children )
39
39
forEachToken (Child, Call, N.Tok );
@@ -44,26 +44,25 @@ MacroCallReconstructor::MacroCallReconstructor(
44
44
unsigned Level,
45
45
const llvm::DenseMap<FormatToken *, std::unique_ptr<UnwrappedLine>>
46
46
&ActiveExpansions)
47
- : Level (Level), IdToReconstructed(ActiveExpansions) {
47
+ : Result (Level), IdToReconstructed(ActiveExpansions) {
48
48
Result.Tokens .push_back (std::make_unique<LineNode>());
49
49
ActiveReconstructedLines.push_back (&Result);
50
50
}
51
51
52
52
void MacroCallReconstructor::addLine (const UnwrappedLine &Line) {
53
53
assert (State != Finalized);
54
54
LLVM_DEBUG (llvm::dbgs () << " MCR: new line...\n " );
55
- forEachToken (Line, [&](FormatToken *Token, FormatToken *Parent, bool First) {
56
- add (Token, Parent, First);
57
- });
55
+ forEachToken (Line, [&](FormatToken *Token, FormatToken *Parent, bool First,
56
+ unsigned Level) { add (Token, Parent, First, Level); });
58
57
assert (InProgress || finished ());
59
58
}
60
59
61
60
UnwrappedLine MacroCallReconstructor::takeResult () && {
62
61
finalize ();
63
62
assert (Result.Tokens .size () == 1 &&
64
63
Result.Tokens .front ()->Children .size () == 1 );
65
- UnwrappedLine Final =
66
- createUnwrappedLine ( *Result.Tokens .front ()->Children .front (), Level);
64
+ UnwrappedLine Final = createUnwrappedLine (
65
+ *Result.Tokens .front ()->Children .front (), Result. Level );
67
66
assert (!Final.Tokens .empty ());
68
67
return Final;
69
68
}
@@ -72,7 +71,8 @@ UnwrappedLine MacroCallReconstructor::takeResult() && {
72
71
// ExpandedParent in the incoming unwrapped line. \p First specifies whether it
73
72
// is the first token in a given unwrapped line.
74
73
void MacroCallReconstructor::add (FormatToken *Token,
75
- FormatToken *ExpandedParent, bool First) {
74
+ FormatToken *ExpandedParent, bool First,
75
+ unsigned Level) {
76
76
LLVM_DEBUG (
77
77
llvm::dbgs () << " MCR: Token: " << Token->TokenText << " , Parent: "
78
78
<< (ExpandedParent ? ExpandedParent->TokenText : " <null>" )
@@ -102,7 +102,7 @@ void MacroCallReconstructor::add(FormatToken *Token,
102
102
First = true ;
103
103
}
104
104
105
- prepareParent (ExpandedParent, First);
105
+ prepareParent (ExpandedParent, First, Level );
106
106
107
107
if (Token->MacroCtx ) {
108
108
// If this token was generated by a macro call, add the reconstructed
@@ -129,7 +129,7 @@ void MacroCallReconstructor::add(FormatToken *Token,
129
129
// is the parent of ActiveReconstructedLines.back() in the reconstructed
130
130
// unwrapped line.
131
131
void MacroCallReconstructor::prepareParent (FormatToken *ExpandedParent,
132
- bool NewLine) {
132
+ bool NewLine, unsigned Level ) {
133
133
LLVM_DEBUG ({
134
134
llvm::dbgs () << " ParentMap:\n " ;
135
135
debugParentMap ();
@@ -172,7 +172,7 @@ void MacroCallReconstructor::prepareParent(FormatToken *ExpandedParent,
172
172
}
173
173
assert (!ActiveReconstructedLines.empty ());
174
174
ActiveReconstructedLines.back ()->Tokens .back ()->Children .push_back (
175
- std::make_unique<ReconstructedLine>());
175
+ std::make_unique<ReconstructedLine>(Level ));
176
176
ActiveReconstructedLines.push_back (
177
177
&*ActiveReconstructedLines.back ()->Tokens .back ()->Children .back ());
178
178
} else if (parentLine ().Tokens .back ()->Tok != Parent) {
@@ -424,7 +424,8 @@ bool MacroCallReconstructor::processNextReconstructed() {
424
424
SpelledParentToReconstructedParent[MacroCallStructure.back ()
425
425
.ParentLastToken ] = Token;
426
426
appendToken (Token);
427
- prepareParent (Token, /* NewLine=*/ true );
427
+ prepareParent (Token, /* NewLine=*/ true ,
428
+ MacroCallStructure.back ().Line ->Level );
428
429
Token->MacroParent = true ;
429
430
return false ;
430
431
}
@@ -435,7 +436,8 @@ bool MacroCallReconstructor::processNextReconstructed() {
435
436
[MacroCallStructure.back ().Line ->Tokens .back ()->Tok ] = Token;
436
437
Token->MacroParent = true ;
437
438
appendToken (Token, MacroCallStructure.back ().Line );
438
- prepareParent (Token, /* NewLine=*/ true );
439
+ prepareParent (Token, /* NewLine=*/ true ,
440
+ MacroCallStructure.back ().Line ->Level );
439
441
return true ;
440
442
}
441
443
if (Token->is (tok::r_paren)) {
@@ -509,16 +511,36 @@ MacroCallReconstructor::createUnwrappedLine(const ReconstructedLine &Line,
509
511
for (const auto &N : Line.Tokens ) {
510
512
Result.Tokens .push_back (N->Tok );
511
513
UnwrappedLineNode &Current = Result.Tokens .back ();
512
- for (const auto &Child : N->Children ) {
513
- if (Child->Tokens .empty ())
514
- continue ;
515
- Current.Children .push_back (createUnwrappedLine (*Child, Level + 1 ));
516
- }
517
- if (Current.Children .size () == 1 &&
518
- Current.Tok ->isOneOf (tok::l_paren, tok::comma)) {
519
- Result.Tokens .splice (Result.Tokens .end (),
520
- Current.Children .front ().Tokens );
521
- Current.Children .clear ();
514
+ auto NumChildren =
515
+ std::count_if (N->Children .begin (), N->Children .end (),
516
+ [](const auto &Child) { return !Child->Tokens .empty (); });
517
+ if (NumChildren == 1 && Current.Tok ->isOneOf (tok::l_paren, tok::comma)) {
518
+ // If we only have one child, and the child is due to a macro expansion
519
+ // (either attached to a left parenthesis or comma), merge the child into
520
+ // the current line to prevent forced breaks for macro arguments.
521
+ auto *Child = std::find_if (
522
+ N->Children .begin (), N->Children .end (),
523
+ [](const auto &Child) { return !Child->Tokens .empty (); });
524
+ auto Line = createUnwrappedLine (**Child, Level);
525
+ Result.Tokens .splice (Result.Tokens .end (), Line.Tokens );
526
+ } else if (NumChildren > 0 ) {
527
+ // When there are multiple children with different indent, make sure that
528
+ // we indent them:
529
+ // 1. One level below the current line's level.
530
+ // 2. At the correct level relative to each other.
531
+ unsigned MinChildLevel =
532
+ std::min_element (N->Children .begin (), N->Children .end (),
533
+ [](const auto &E1 , const auto &E2 ) {
534
+ return E1 ->Level < E2 ->Level ;
535
+ })
536
+ ->get ()
537
+ ->Level ;
538
+ for (const auto &Child : N->Children ) {
539
+ if (Child->Tokens .empty ())
540
+ continue ;
541
+ Current.Children .push_back (createUnwrappedLine (
542
+ *Child, Level + 1 + (Child->Level - MinChildLevel)));
543
+ }
522
544
}
523
545
}
524
546
return Result;
0 commit comments