Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 21 additions & 67 deletions clang/lib/Format/WhitespaceManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,11 @@ AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End,
// right-justified. It is used to align compound assignments like `+=` and `=`.
// When RightJustify and ACS.PadOperators are true, operators in each block to
// be aligned will be padded on the left to the same length before aligning.
template <typename F>
//
// The simple check will not look at the indentaion and nesting level to recurse
// into the line for alignment. It will also not count the commas. This is e.g.
// for aligning macro definitions.
template <typename F, bool SimpleCheck = false>
static unsigned AlignTokens(const FormatStyle &Style, F &&Matches,
SmallVector<WhitespaceManager::Change, 16> &Changes,
unsigned StartAt,
Expand Down Expand Up @@ -465,9 +469,9 @@ static unsigned AlignTokens(const FormatStyle &Style, F &&Matches,

// Measure the scope level (i.e. depth of (), [], {}) of the first token, and
// abort when we hit any token in a higher scope than the starting one.
auto IndentAndNestingLevel = StartAt < Changes.size()
? Changes[StartAt].indentAndNestingLevel()
: std::tuple<unsigned, unsigned, unsigned>();
const auto IndentAndNestingLevel =
StartAt < Changes.size() ? Changes[StartAt].indentAndNestingLevel()
: std::tuple<unsigned, unsigned, unsigned>();

// Keep track of the number of commas before the matching tokens, we will only
// align a sequence of matching tokens if they are preceded by the same number
Expand Down Expand Up @@ -536,14 +540,17 @@ static unsigned AlignTokens(const FormatStyle &Style, F &&Matches,
if (CurrentChange.Tok->isNot(tok::comment))
LineIsComment = false;

if (CurrentChange.Tok->is(tok::comma)) {
++CommasBeforeMatch;
} else if (CurrentChange.indentAndNestingLevel() > IndentAndNestingLevel) {
// Call AlignTokens recursively, skipping over this scope block.
unsigned StoppedAt =
AlignTokens(Style, Matches, Changes, i, ACS, RightJustify);
i = StoppedAt - 1;
continue;
if (!SimpleCheck) {
if (CurrentChange.Tok->is(tok::comma)) {
++CommasBeforeMatch;
} else if (CurrentChange.indentAndNestingLevel() >
IndentAndNestingLevel) {
// Call AlignTokens recursively, skipping over this scope block.
const auto StoppedAt =
AlignTokens(Style, Matches, Changes, i, ACS, RightJustify);
i = StoppedAt - 1;
continue;
}
}

if (!Matches(CurrentChange))
Expand Down Expand Up @@ -683,61 +690,8 @@ void WhitespaceManager::alignConsecutiveMacros() {
return Current->Next->SpacesRequiredBefore == SpacesRequiredBefore;
};

unsigned MinColumn = 0;

// Start and end of the token sequence we're processing.
unsigned StartOfSequence = 0;
unsigned EndOfSequence = 0;

// Whether a matching token has been found on the current line.
bool FoundMatchOnLine = false;

// Whether the current line consists only of comments
bool LineIsComment = true;

unsigned I = 0;
for (unsigned E = Changes.size(); I != E; ++I) {
if (Changes[I].NewlinesBefore != 0) {
EndOfSequence = I;

// Whether to break the alignment sequence because of an empty line.
bool EmptyLineBreak = (Changes[I].NewlinesBefore > 1) &&
!Style.AlignConsecutiveMacros.AcrossEmptyLines;

// Whether to break the alignment sequence because of a line without a
// match.
bool NoMatchBreak =
!FoundMatchOnLine &&
!(LineIsComment && Style.AlignConsecutiveMacros.AcrossComments);

if (EmptyLineBreak || NoMatchBreak) {
AlignMatchingTokenSequence(StartOfSequence, EndOfSequence, MinColumn,
AlignMacrosMatches, Changes);
}

// A new line starts, re-initialize line status tracking bools.
FoundMatchOnLine = false;
LineIsComment = true;
}

if (Changes[I].Tok->isNot(tok::comment))
LineIsComment = false;

if (!AlignMacrosMatches(Changes[I]))
continue;

FoundMatchOnLine = true;

if (StartOfSequence == 0)
StartOfSequence = I;

unsigned ChangeMinColumn = Changes[I].StartOfTokenColumn;
MinColumn = std::max(MinColumn, ChangeMinColumn);
}

EndOfSequence = I;
AlignMatchingTokenSequence(StartOfSequence, EndOfSequence, MinColumn,
AlignMacrosMatches, Changes);
AlignTokens<decltype(AlignMacrosMatches) &, /*SimpleCheck=*/true>(
Style, AlignMacrosMatches, Changes, 0, Style.AlignConsecutiveMacros);
}

void WhitespaceManager::alignConsecutiveAssignments() {
Expand Down
5 changes: 5 additions & 0 deletions clang/unittests/Format/FormatTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18559,6 +18559,11 @@ TEST_F(FormatTest, AlignConsecutiveMacros) {
"#define bbbb 4\n"
"#define ccc (5)",
Style);

Style.ColumnLimit = 30;
verifyFormat("#define MY_FUNC(x) callMe(X)\n"
"#define MY_LONG_CONSTANT 17",
Style);
}

TEST_F(FormatTest, AlignConsecutiveAssignmentsAcrossEmptyLines) {
Expand Down
Loading