[clang] [clang-format] Fix incorrect trailing comment and escaped newlines when AlignArrayOfStructures is enabled (PR #180305)
Ben Dunkin via cfe-commits
cfe-commits at lists.llvm.org
Thu Feb 12 09:48:19 PST 2026
https://github.com/bdunkin updated https://github.com/llvm/llvm-project/pull/180305
>From a513e518d6a30e07711fd9fbff26fe99f7be5806 Mon Sep 17 00:00:00 2001
From: Ben Dunkin <bdunkin at arena.net>
Date: Fri, 6 Feb 2026 12:51:41 -0800
Subject: [PATCH 1/4] Replace all manipulation of white space change Spaces
member with setChangeSpaces which maintains the relationship between Spaces,
StartOfTokenColumn, and PreviousEndOfTokenColumn. End of line alignment logic
relies on this relationship being correct, and not maintaining it means
comment and macro alignment gets messed up.
---
clang/lib/Format/WhitespaceManager.cpp | 112 +++++++++++++++----------
clang/lib/Format/WhitespaceManager.h | 2 +
2 files changed, 69 insertions(+), 45 deletions(-)
diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp
index 947578cbff9ad..9395d0b4972a3 100644
--- a/clang/lib/Format/WhitespaceManager.cpp
+++ b/clang/lib/Format/WhitespaceManager.cpp
@@ -284,6 +284,33 @@ void WhitespaceManager::calculateLineBreakInformation() {
}
}
+// Sets the spaces in front of a Change, and updates the start/end columns of
+// subsequent tokens so that trailing comments and escaped newlines can be
+// aligned properly
+static void
+SetChangeSpaces(unsigned Start, unsigned Spaces,
+ SmallVector<WhitespaceManager::Change, 16> &Changes) {
+ WhitespaceManager::Change &FirstChange = Changes[Start];
+ const int ColumnChange = Spaces - FirstChange.Spaces;
+
+ if (ColumnChange == 0)
+ return;
+
+ FirstChange.Spaces += ColumnChange;
+ FirstChange.StartOfTokenColumn += ColumnChange;
+
+ for (unsigned i = Start + 1; i < Changes.size(); i++) {
+ WhitespaceManager::Change &C = Changes[i];
+
+ C.PreviousEndOfTokenColumn += ColumnChange;
+
+ if (C.NewlinesBefore > 0)
+ break;
+
+ C.StartOfTokenColumn += ColumnChange;
+ }
+}
+
// Align a single sequence of tokens, see AlignTokens below.
// Column - The tokens indexed in Matches are moved to this column.
// RightJustify - Whether it is the token's right end or left end that gets
@@ -295,9 +322,6 @@ AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End,
SmallVector<WhitespaceManager::Change, 16> &Changes) {
unsigned OriginalMatchColumn = 0;
int Shift = 0;
- // Set when the shift is applied anywhere in the line. Cleared when the line
- // ends.
- bool LineShifted = false;
// ScopeStack keeps track of the current scope depth. It contains the levels
// of at most 2 scopes. The first one is the one that the matched token is
@@ -348,7 +372,6 @@ AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End,
CurrentChange.IndentedFromColumn >= OriginalMatchColumn));
if (CurrentChange.NewlinesBefore > 0) {
- LineShifted = false;
if (!InsideNestedScope)
Shift = 0;
}
@@ -372,9 +395,8 @@ AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End,
if ((!Matches.empty() && Matches[0] == i) ||
(ScopeStack.size() == 1u && CurrentChange.NewlinesBefore > 0 &&
InsideNestedScope)) {
- LineShifted = true;
CurrentChange.IndentedFromColumn += Shift;
- CurrentChange.Spaces += Shift;
+ SetChangeSpaces(i, CurrentChange.Spaces + Shift, Changes);
}
// We should not remove required spaces unless we break the line before.
@@ -383,12 +405,6 @@ AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End,
static_cast<int>(Changes[i].Tok->SpacesRequiredBefore) ||
CurrentChange.Tok->is(tok::eof));
- if (LineShifted) {
- CurrentChange.StartOfTokenColumn += Shift;
- if (i + 1 != Changes.size())
- Changes[i + 1].PreviousEndOfTokenColumn += Shift;
- }
-
// If PointerAlignment is PAS_Right, keep *s or &s next to the token,
// except if the token is equal, then a space is needed.
if ((Style.PointerAlignment == FormatStyle::PAS_Right ||
@@ -409,9 +425,10 @@ AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End,
} else if (Style.PointerAlignment != FormatStyle::PAS_Right) {
continue;
}
- Changes[Previous + 1].Spaces -= Shift;
- Changes[Previous].Spaces += Shift;
- Changes[Previous].StartOfTokenColumn += Shift;
+
+ int Next = Previous + 1;
+ SetChangeSpaces(Next, Changes[Next].Spaces - Shift, Changes);
+ SetChangeSpaces(Previous, Changes[Previous].Spaces + Shift, Changes);
}
}
}
@@ -692,11 +709,9 @@ static void AlignMatchingTokenSequence(
SmallVector<WhitespaceManager::Change, 16> &Changes) {
if (StartOfSequence > 0 && StartOfSequence < EndOfSequence) {
bool FoundMatchOnLine = false;
- int Shift = 0;
for (unsigned I = StartOfSequence; I != EndOfSequence; ++I) {
if (Changes[I].NewlinesBefore > 0) {
- Shift = 0;
FoundMatchOnLine = false;
}
@@ -705,14 +720,9 @@ static void AlignMatchingTokenSequence(
// shifted by the same amount.
if (!FoundMatchOnLine && Matches(Changes[I])) {
FoundMatchOnLine = true;
- Shift = MinColumn - Changes[I].StartOfTokenColumn;
- Changes[I].Spaces += Shift;
+ int Shift = MinColumn - Changes[I].StartOfTokenColumn;
+ SetChangeSpaces(I, Changes[I].Spaces + Shift, Changes);
}
-
- assert(Shift >= 0);
- Changes[I].StartOfTokenColumn += Shift;
- if (I + 1 != Changes.size())
- Changes[I + 1].PreviousEndOfTokenColumn += Shift;
}
}
@@ -1064,7 +1074,10 @@ void WhitespaceManager::alignTrailingComments() {
// leave the comments.
if (RestoredLineLength >= Style.ColumnLimit && Style.ColumnLimit > 0)
break;
- C.Spaces = C.NewlinesBefore > 0 ? C.Tok->OriginalColumn : OriginalSpaces;
+
+ int Spaces =
+ C.NewlinesBefore > 0 ? C.Tok->OriginalColumn : OriginalSpaces;
+ setChangeSpaces(I, Spaces);
continue;
}
@@ -1185,10 +1198,8 @@ void WhitespaceManager::alignTrailingComments(unsigned Start, unsigned End,
}
if (Shift <= 0)
continue;
- Changes[i].Spaces += Shift;
- if (i + 1 != Changes.size())
- Changes[i + 1].PreviousEndOfTokenColumn += Shift;
- Changes[i].StartOfTokenColumn += Shift;
+
+ setChangeSpaces(i, Changes[i].Spaces + Shift);
}
}
@@ -1294,8 +1305,8 @@ void WhitespaceManager::alignArrayInitializersRightJustified(
do {
const FormatToken *Previous = Changes[Next->Index].Tok->Previous;
if (Previous && Previous->isNot(TT_LineComment)) {
- Changes[Next->Index].Spaces = BracePadding;
Changes[Next->Index].NewlinesBefore = 0;
+ setChangeSpaces(Next->Index, BracePadding);
}
Next = Next->NextColumnElement;
} while (Next);
@@ -1308,7 +1319,7 @@ void WhitespaceManager::alignArrayInitializersRightJustified(
Cells.begin(), CellIter, CellDescs.InitialSpaces,
CellDescs.CellCounts[0], CellDescs.CellCounts.size());
if (ThisNetWidth < MaxNetWidth)
- Changes[CellIter->Index].Spaces = (MaxNetWidth - ThisNetWidth);
+ setChangeSpaces(CellIter->Index, (MaxNetWidth - ThisNetWidth));
auto RowCount = 1U;
auto Offset = std::distance(Cells.begin(), CellIter);
for (const auto *Next = CellIter->NextColumnElement; Next;
@@ -1319,7 +1330,7 @@ void WhitespaceManager::alignArrayInitializersRightJustified(
auto *End = Start + Offset;
ThisNetWidth = getNetWidth(Start, End, CellDescs.InitialSpaces);
if (ThisNetWidth < MaxNetWidth)
- Changes[Next->Index].Spaces = (MaxNetWidth - ThisNetWidth);
+ setChangeSpaces(Next->Index, (MaxNetWidth - ThisNetWidth));
++RowCount;
}
}
@@ -1328,8 +1339,10 @@ void WhitespaceManager::alignArrayInitializersRightJustified(
calculateCellWidth(CellIter->Index, CellIter->EndIndex, true) +
NetWidth;
if (Changes[CellIter->Index].NewlinesBefore == 0) {
- Changes[CellIter->Index].Spaces = (CellWidth - (ThisWidth + NetWidth));
- Changes[CellIter->Index].Spaces += (i > 0) ? 1 : BracePadding;
+ int Spaces = (CellWidth - (ThisWidth + NetWidth));
+ Spaces += (i > 0) ? 1 : BracePadding;
+
+ setChangeSpaces(CellIter->Index, Spaces);
}
alignToStartOfCell(CellIter->Index, CellIter->EndIndex);
for (const auto *Next = CellIter->NextColumnElement; Next;
@@ -1337,8 +1350,10 @@ void WhitespaceManager::alignArrayInitializersRightJustified(
ThisWidth =
calculateCellWidth(Next->Index, Next->EndIndex, true) + NetWidth;
if (Changes[Next->Index].NewlinesBefore == 0) {
- Changes[Next->Index].Spaces = (CellWidth - ThisWidth);
- Changes[Next->Index].Spaces += (i > 0) ? 1 : BracePadding;
+ int Spaces = (CellWidth - ThisWidth);
+ Spaces += (i > 0) ? 1 : BracePadding;
+
+ setChangeSpaces(Next->Index, Spaces);
}
alignToStartOfCell(Next->Index, Next->EndIndex);
}
@@ -1360,8 +1375,9 @@ void WhitespaceManager::alignArrayInitializersLeftJustified(
// The first cell of every row needs to be against the left brace.
for (const auto *Next = CellIter; Next; Next = Next->NextColumnElement) {
auto &Change = Changes[Next->Index];
- Change.Spaces =
+ int Spaces =
Change.NewlinesBefore == 0 ? BracePadding : CellDescs.InitialSpaces;
+ setChangeSpaces(Next->Index, Spaces);
}
++CellIter;
for (auto i = 1U; i < CellDescs.CellCounts[0]; i++, ++CellIter) {
@@ -1371,10 +1387,11 @@ void WhitespaceManager::alignArrayInitializersLeftJustified(
auto ThisNetWidth =
getNetWidth(Cells.begin(), CellIter, CellDescs.InitialSpaces);
if (Changes[CellIter->Index].NewlinesBefore == 0) {
- Changes[CellIter->Index].Spaces =
+ int Spaces =
MaxNetWidth - ThisNetWidth +
(Changes[CellIter->Index].Tok->isNot(tok::r_brace) ? 1
: BracePadding);
+ setChangeSpaces(CellIter->Index, Spaces);
}
auto RowCount = 1U;
auto Offset = std::distance(Cells.begin(), CellIter);
@@ -1386,9 +1403,10 @@ void WhitespaceManager::alignArrayInitializersLeftJustified(
auto *End = Start + Offset;
auto ThisNetWidth = getNetWidth(Start, End, CellDescs.InitialSpaces);
if (Changes[Next->Index].NewlinesBefore == 0) {
- Changes[Next->Index].Spaces =
+ int Spaces =
MaxNetWidth - ThisNetWidth +
(Changes[Next->Index].Tok->isNot(tok::r_brace) ? 1 : BracePadding);
+ setChangeSpaces(Next->Index, Spaces);
}
++RowCount;
}
@@ -1466,11 +1484,11 @@ WhitespaceManager::CellDescriptions WhitespaceManager::getCells(unsigned Start,
Changes[j].Tok->isNot(tok::r_brace)) {
Changes[j].NewlinesBefore = 1;
// Account for the added token lengths
- Changes[j].Spaces = InitialSpaces - InitialTokenLength;
+ setChangeSpaces(j, InitialSpaces - InitialTokenLength);
}
} else if (C.Tok->is(tok::comment) && C.Tok->NewlinesBefore == 0) {
// Trailing comments stay at a space past the last token
- C.Spaces = Changes[i - 1].Tok->is(tok::comma) ? 1 : 2;
+ setChangeSpaces(i, Changes[i - 1].Tok->is(tok::comma) ? 1 : 2);
} else if (C.Tok->is(tok::l_brace)) {
// We need to make sure that the ending braces is aligned to the
// start of our initializer
@@ -1481,7 +1499,7 @@ WhitespaceManager::CellDescriptions WhitespaceManager::getCells(unsigned Start,
}
} else if (Depth == 0 && C.Tok->is(tok::r_brace)) {
C.NewlinesBefore = 1;
- C.Spaces = EndSpaces;
+ setChangeSpaces(i, EndSpaces);
}
if (C.Tok->StartsColumn) {
// This gets us past tokens that have been split over multiple
@@ -1509,12 +1527,12 @@ WhitespaceManager::CellDescriptions WhitespaceManager::getCells(unsigned Start,
auto LineLimit = Changes[j].Spaces + Changes[j].TokenLength;
if (LineLimit < Style.ColumnLimit) {
Changes[i].NewlinesBefore = 0;
- Changes[i].Spaces = 1;
+ setChangeSpaces(i, 1);
}
}
}
while (Changes[i].NewlinesBefore > 0 && Changes[i].Tok == C.Tok) {
- Changes[i].Spaces = InitialSpaces;
+ setChangeSpaces(i, InitialSpaces);
++i;
HasSplit = true;
}
@@ -1546,7 +1564,7 @@ void WhitespaceManager::alignToStartOfCell(unsigned Start, unsigned End) {
// is aligned to the parent
for (auto i = Start + 1; i < End; i++)
if (Changes[i].NewlinesBefore > 0)
- Changes[i].Spaces = Changes[Start].Spaces;
+ setChangeSpaces(i, Changes[Start].Spaces);
}
WhitespaceManager::CellDescriptions
@@ -1565,6 +1583,10 @@ WhitespaceManager::linkCells(CellDescriptions &&CellDesc) {
return std::move(CellDesc);
}
+void WhitespaceManager::setChangeSpaces(unsigned Start, unsigned Spaces) {
+ SetChangeSpaces(Start, Spaces, Changes);
+}
+
void WhitespaceManager::generateChanges() {
for (unsigned i = 0, e = Changes.size(); i != e; ++i) {
const Change &C = Changes[i];
diff --git a/clang/lib/Format/WhitespaceManager.h b/clang/lib/Format/WhitespaceManager.h
index 64a8f9b4fa857..ef0a8d82e6dc6 100644
--- a/clang/lib/Format/WhitespaceManager.h
+++ b/clang/lib/Format/WhitespaceManager.h
@@ -356,6 +356,8 @@ class WhitespaceManager {
/// Link the Cell pointers in the list of Cells.
static CellDescriptions linkCells(CellDescriptions &&CellDesc);
+
+ void setChangeSpaces(unsigned Start, unsigned Spaces);
/// Fill \c Replaces with the replacements for all effective changes.
void generateChanges();
>From 9e782f8b69ea1d97aa9527db4818e63d2941d218 Mon Sep 17 00:00:00 2001
From: Ben Dunkin <bdunkin at arena.net>
Date: Fri, 6 Feb 2026 16:26:45 -0800
Subject: [PATCH 2/4] Add tests for github issues that are fixed by properly
maintaining the relationship between Spaces, StartOfTokenColumn, and
PreviousEndOfTokenColumn.
---
clang/unittests/Format/FormatTest.cpp | 62 +++++++++++++++++++++++++++
1 file changed, 62 insertions(+)
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 33836e28289b4..05d4b23ea252d 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -22533,6 +22533,68 @@ TEST_F(FormatTest, CatchAlignArrayOfStructuresLeftAlignment) {
Style);
}
+TEST_F(FormatTest, AlignArrayOfStructuresGithubIssues) {
+ // https://github.com/llvm/llvm-project/issues/138151
+ // Summary: Aligning arrays of structures with UseTab: AlignWithSpaces does
+ // not use spaces to align columns
+ FormatStyle Style = getGoogleStyle();
+ Style.AlignArrayOfStructures = FormatStyle::AIAS_Left;
+ Style.UseTab = FormatStyle::UT_AlignWithSpaces;
+ Style.IndentWidth = 4;
+ Style.TabWidth = 4;
+
+ verifyFormat(
+ "std::vector<Foo> foos = {\n"
+ "\t{LONG_NAME, 0, i | j},\n"
+ "\t{LONG_NAME, 0, i | j},\n"
+ "\t{LONGER_NAME, 0, i | j},\n"
+ "\t{LONGER_NAME, 0, i },\n"
+ "\t{THIS_IS_A_VERY_LONG_NAME, 0, j },\n"
+ "\t{LONGER_NAME, THIS_IS_A_VERY_LONG_NAME, i },\n"
+ "\t{LONG_NAME, THIS_IS_A_VERY_LONG_NAME, j }\n"
+ "};\n",
+ Style);
+
+ // https://github.com/llvm/llvm-project/issues/85937
+ // Summary: Macro escaped newlines are not aligned properly when both
+ // AlignEscapedNewLines and AlignArrayOfStructures are used
+ Style = getLLVMStyleWithColumns(80);
+ Style.AlignEscapedNewlines = FormatStyle::ENAS_Left;
+ Style.AlignArrayOfStructures = FormatStyle::AIAS_Left;
+
+ verifyFormat(R"(
+#define DEFINE_COMMAND_PROCESS_TABLE(Enum) \
+ const STExample TCommand::EXPL_MAIN[] = { \
+ {Enum::GetName(), " shows help " }, \
+ {Enum::GetAttribute(), " do something "}, \
+ {Enum::GetState(), " do whatever " }, \
+ };
+)",
+ Style);
+
+ // https://github.com/llvm/llvm-project/issues/53442
+ // Summary: alignment of columns does not use spaces when UseTab:
+ // AlignWithSpaces
+ Style = getLLVMStyle();
+ Style.AlignArrayOfStructures = FormatStyle::AIAS_Left;
+ Style.IndentWidth = 4;
+ Style.TabWidth = 4;
+ Style.UseTab = FormatStyle::UT_AlignWithSpaces;
+ Style.BreakBeforeBraces = FormatStyle::BS_Allman;
+
+ verifyFormat(
+ "const map<string, int64_t> CoreReport::GetGameCountersRolloverInfo()\n"
+ "{\n"
+ "\tstatic map<string, int64_t> counterRolloverInfo{\n"
+ "\t\t{\"CashIn\", 4000000000},\n"
+ "\t\t{\"CoinIn\", 4000000000},\n"
+ "\t\t{\"QuantityMultiProgressive\", 65535 },\n"
+ "\t};\n"
+ "\treturn counterRolloverInfo;\n"
+ "}\n",
+ Style);
+}
+
TEST_F(FormatTest, UnderstandsPragmas) {
verifyFormat("#pragma omp reduction(| : var)");
verifyFormat("#pragma omp reduction(+ : var)");
>From 6d587d6b9e4502b895e749fe6b14be0cb8920fc8 Mon Sep 17 00:00:00 2001
From: Ben Dunkin <bdunkin at arena.net>
Date: Fri, 6 Feb 2026 16:43:17 -0800
Subject: [PATCH 3/4] Fix formatting
---
clang/lib/Format/WhitespaceManager.cpp | 7 +++----
clang/lib/Format/WhitespaceManager.h | 2 +-
2 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp
index 9395d0b4972a3..c3e5adc5f0b62 100644
--- a/clang/lib/Format/WhitespaceManager.cpp
+++ b/clang/lib/Format/WhitespaceManager.cpp
@@ -711,9 +711,8 @@ static void AlignMatchingTokenSequence(
bool FoundMatchOnLine = false;
for (unsigned I = StartOfSequence; I != EndOfSequence; ++I) {
- if (Changes[I].NewlinesBefore > 0) {
+ if (Changes[I].NewlinesBefore > 0)
FoundMatchOnLine = false;
- }
// If this is the first matching token to be aligned, remember by how many
// spaces it has to be shifted, so the rest of the changes on the line are
@@ -1319,7 +1318,7 @@ void WhitespaceManager::alignArrayInitializersRightJustified(
Cells.begin(), CellIter, CellDescs.InitialSpaces,
CellDescs.CellCounts[0], CellDescs.CellCounts.size());
if (ThisNetWidth < MaxNetWidth)
- setChangeSpaces(CellIter->Index, (MaxNetWidth - ThisNetWidth));
+ setChangeSpaces(CellIter->Index, MaxNetWidth - ThisNetWidth);
auto RowCount = 1U;
auto Offset = std::distance(Cells.begin(), CellIter);
for (const auto *Next = CellIter->NextColumnElement; Next;
@@ -1330,7 +1329,7 @@ void WhitespaceManager::alignArrayInitializersRightJustified(
auto *End = Start + Offset;
ThisNetWidth = getNetWidth(Start, End, CellDescs.InitialSpaces);
if (ThisNetWidth < MaxNetWidth)
- setChangeSpaces(Next->Index, (MaxNetWidth - ThisNetWidth));
+ setChangeSpaces(Next->Index, MaxNetWidth - ThisNetWidth);
++RowCount;
}
}
diff --git a/clang/lib/Format/WhitespaceManager.h b/clang/lib/Format/WhitespaceManager.h
index ef0a8d82e6dc6..9b6cde54af0af 100644
--- a/clang/lib/Format/WhitespaceManager.h
+++ b/clang/lib/Format/WhitespaceManager.h
@@ -356,7 +356,7 @@ class WhitespaceManager {
/// Link the Cell pointers in the list of Cells.
static CellDescriptions linkCells(CellDescriptions &&CellDesc);
-
+
void setChangeSpaces(unsigned Start, unsigned Spaces);
/// Fill \c Replaces with the replacements for all effective changes.
>From 9a279b44e58d8cf582bae640fe4ddb8a26f90c43 Mon Sep 17 00:00:00 2001
From: Ben Dunkin <bdunkin at arena.net>
Date: Thu, 12 Feb 2026 09:48:02 -0800
Subject: [PATCH 4/4] Address review comments.
---
clang/lib/Format/WhitespaceManager.cpp | 41 +++++++++++++++-----------
1 file changed, 24 insertions(+), 17 deletions(-)
diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp
index c3e5adc5f0b62..0a79e708269e2 100644
--- a/clang/lib/Format/WhitespaceManager.cpp
+++ b/clang/lib/Format/WhitespaceManager.cpp
@@ -286,11 +286,11 @@ void WhitespaceManager::calculateLineBreakInformation() {
// Sets the spaces in front of a Change, and updates the start/end columns of
// subsequent tokens so that trailing comments and escaped newlines can be
-// aligned properly
+// aligned properly.
static void
SetChangeSpaces(unsigned Start, unsigned Spaces,
- SmallVector<WhitespaceManager::Change, 16> &Changes) {
- WhitespaceManager::Change &FirstChange = Changes[Start];
+ MutableArrayRef<WhitespaceManager::Change> Changes) {
+ auto &FirstChange = Changes[Start];
const int ColumnChange = Spaces - FirstChange.Spaces;
if (ColumnChange == 0)
@@ -299,18 +299,28 @@ SetChangeSpaces(unsigned Start, unsigned Spaces,
FirstChange.Spaces += ColumnChange;
FirstChange.StartOfTokenColumn += ColumnChange;
- for (unsigned i = Start + 1; i < Changes.size(); i++) {
- WhitespaceManager::Change &C = Changes[i];
+ for (auto I = Start + 1; I < Changes.size(); I++) {
+ auto &Change = Changes[I];
- C.PreviousEndOfTokenColumn += ColumnChange;
+ Change.PreviousEndOfTokenColumn += ColumnChange;
- if (C.NewlinesBefore > 0)
+ if (Change.NewlinesBefore > 0)
break;
- C.StartOfTokenColumn += ColumnChange;
+ Change.StartOfTokenColumn += ColumnChange;
}
}
+// Changes the spaces in front of a change by Delta, and updates the start/end
+// columns of subsequent tokens so that trailing comments and escaped newlines
+// can be aligned properly.
+static void
+IncrementChangeSpaces(unsigned Start, int Delta,
+ MutableArrayRef<WhitespaceManager::Change> Changes) {
+ assert(Delta > 0 || (abs(Delta) <= Changes[Start].Spaces));
+ SetChangeSpaces(Start, Changes[Start].Spaces + Delta, Changes);
+}
+
// Align a single sequence of tokens, see AlignTokens below.
// Column - The tokens indexed in Matches are moved to this column.
// RightJustify - Whether it is the token's right end or left end that gets
@@ -371,10 +381,8 @@ AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End,
(CurrentChange.indentAndNestingLevel() == ScopeStack[0] &&
CurrentChange.IndentedFromColumn >= OriginalMatchColumn));
- if (CurrentChange.NewlinesBefore > 0) {
- if (!InsideNestedScope)
- Shift = 0;
- }
+ if (CurrentChange.NewlinesBefore > 0 && !InsideNestedScope)
+ Shift = 0;
// If this is the first matching token to be aligned, remember by how many
// spaces it has to be shifted, so the rest of the changes on the line are
@@ -396,7 +404,7 @@ AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End,
(ScopeStack.size() == 1u && CurrentChange.NewlinesBefore > 0 &&
InsideNestedScope)) {
CurrentChange.IndentedFromColumn += Shift;
- SetChangeSpaces(i, CurrentChange.Spaces + Shift, Changes);
+ IncrementChangeSpaces(i, Shift, Changes);
}
// We should not remove required spaces unless we break the line before.
@@ -426,9 +434,8 @@ AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End,
continue;
}
- int Next = Previous + 1;
- SetChangeSpaces(Next, Changes[Next].Spaces - Shift, Changes);
- SetChangeSpaces(Previous, Changes[Previous].Spaces + Shift, Changes);
+ IncrementChangeSpaces(Previous + 1, -Shift, Changes);
+ IncrementChangeSpaces(Previous, Shift, Changes);
}
}
}
@@ -720,7 +727,7 @@ static void AlignMatchingTokenSequence(
if (!FoundMatchOnLine && Matches(Changes[I])) {
FoundMatchOnLine = true;
int Shift = MinColumn - Changes[I].StartOfTokenColumn;
- SetChangeSpaces(I, Changes[I].Spaces + Shift, Changes);
+ IncrementChangeSpaces(I, Shift, Changes);
}
}
}
More information about the cfe-commits
mailing list