diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -133,8 +133,8 @@ StringRef Text(PreviousOriginalWhitespaceEndData, SourceMgr.getCharacterData(OriginalWhitespaceStart) - PreviousOriginalWhitespaceEndData); - // Usually consecutive changes would occur in consecutive tokens. This is - // not the case however when analyzing some preprocessor runs of the + // Usually consecutive changes would occur in consecutive tokens. This + // is not the case however when analyzing some preprocessor runs of the // annotated lines. For example, in this code: // // #if A // line 1 @@ -143,17 +143,17 @@ // int i = 2; // #endif // line 3 // - // one of the runs will produce the sequence of lines marked with line 1, 2 - // and 3. So the two consecutive whitespace changes just before '// line 2' - // and before '#endif // line 3' span multiple lines and tokens: + // one of the runs will produce the sequence of lines marked with line + // 1, 2 and 3. So the two consecutive whitespace changes just before '// + // line 2' and before '#endif // line 3' span multiple lines and tokens: // // #else B{change X}[// line 2 // int i = 2; // ]{change Y}#endif // line 3 // - // For this reason, if the text between consecutive changes spans multiple - // newlines, the token length must be adjusted to the end of the original - // line of the token. + // For this reason, if the text between consecutive changes spans + // multiple newlines, the token length must be adjusted to the end of + // the original line of the token. auto NewlinePos = Text.find_first_of('\n'); if (NewlinePos == StringRef::npos) { Changes[i - 1].TokenLength = OriginalWhitespaceStartOffset - @@ -165,8 +165,8 @@ NewlinePos + Changes[i - 1].CurrentLinePrefix.size(); } - // If there are multiple changes in this token, sum up all the changes until - // the end of the line. + // If there are multiple changes in this token, sum up all the changes + // until the end of the line. if (Changes[i - 1].IsInsideToken && Changes[i - 1].NewlinesBefore == 0) LastOutsideTokenChange->TokenLength += Changes[i - 1].TokenLength + Changes[i - 1].Spaces; @@ -181,17 +181,18 @@ (Changes[i].IsInsideToken && Changes[i].Tok->is(tok::comment))) && Changes[i - 1].Tok->is(tok::comment) && // FIXME: This is a dirty hack. The problem is that - // BreakableLineCommentSection does comment reflow changes and here is - // the aligning of trailing comments. Consider the case where we reflow - // the second line up in this example: + // BreakableLineCommentSection does comment reflow changes and here + // is the aligning of trailing comments. Consider the case where we + // reflow the second line up in this example: // // // line 1 // // line 2 // // That amounts to 2 changes by BreakableLineCommentSection: - // - the first, delimited by (), for the whitespace between the tokens, - // - and second, delimited by [], for the whitespace at the beginning - // of the second token: + // - the first, delimited by (), for the whitespace between the + // tokens, + // - and second, delimited by [], for the whitespace at the + // beginning of the second token: // // // line 1( // )[// ]line 2 @@ -202,14 +203,14 @@ // // Note that the OriginalWhitespaceStart of the second change is the // same as the PreviousOriginalWhitespaceEnd of the first change. - // In this case, the below check ensures that the second change doesn't - // get treated as a trailing comment change here, since this might - // trigger additional whitespace to be wrongly inserted before "line 2" - // by the comment aligner here. + // In this case, the below check ensures that the second change + // doesn't get treated as a trailing comment change here, since this + // might trigger additional whitespace to be wrongly inserted before + // "line 2" by the comment aligner here. // - // For a proper solution we need a mechanism to say to WhitespaceManager - // that a particular change breaks the current sequence of trailing - // comments. + // For a proper solution we need a mechanism to say to + // WhitespaceManager that a particular change breaks the current + // sequence of trailing comments. OriginalWhitespaceStart != PreviousOriginalWhitespaceEnd; } // FIXME: The last token is currently not always an eof token; in those @@ -219,9 +220,9 @@ const WhitespaceManager::Change *LastBlockComment = nullptr; for (auto &Change : Changes) { - // Reset the IsTrailingComment flag for changes inside of trailing comments - // so they don't get realigned later. Comment line breaks however still need - // to be aligned. + // Reset the IsTrailingComment flag for changes inside of trailing + // comments so they don't get realigned later. Comment line breaks + // however still need to be aligned. if (Change.IsInsideToken && Change.NewlinesBefore == 0) Change.IsTrailingComment = false; Change.StartOfBlockComment = nullptr; @@ -241,9 +242,9 @@ } // Compute conditional nesting level - // Level is increased for each conditional, unless this conditional continues - // a chain of conditional, i.e. starts immediately after the colon of another - // conditional. + // Level is increased for each conditional, unless this conditional + // continues a chain of conditional, i.e. starts immediately after the colon + // of another conditional. SmallVector ScopeStack; int ConditionalsLevel = 0; for (auto &Change : Changes) { @@ -326,9 +327,9 @@ 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 - // shifted by the same amount + // 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 shifted by the same amount if (!FoundMatchOnLine && !SkipMatchCheck && Matches(Changes[i])) { FoundMatchOnLine = true; Shift = Column - Changes[i].StartOfTokenColumn; @@ -442,15 +443,15 @@ unsigned StartOfSequence = 0; unsigned EndOfSequence = 0; - // 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. + // 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(); - // 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 - // of commas. + // 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 of commas. unsigned CommasBeforeLastMatch = 0; unsigned CommasBeforeMatch = 0; @@ -492,8 +493,8 @@ (ACS != FormatStyle::ACS_AcrossEmptyLines) && (ACS != FormatStyle::ACS_AcrossEmptyLinesAndComments); - // Whether to break the alignment sequence because of a line without a - // match. + // Whether to break the alignment sequence because of a line without + // a match. bool NoMatchBreak = !FoundMatchOnLine && !(LineIsComment && @@ -504,7 +505,8 @@ AlignCurrentSequence(); // A new line starts, re-initialize line status tracking bools. - // Keep the match state if a string literal is continued on this line. + // Keep the match state if a string literal is continued on this + // line. if (i == 0 || !Changes[i].Tok->is(tok::string_literal) || !Changes[i - 1].Tok->is(tok::string_literal)) FoundMatchOnLine = false; @@ -527,8 +529,8 @@ if (!Matches(Changes[i])) continue; - // If there is more than one matching token per line, or if the number of - // preceding commas, do not match anymore, end the sequence. + // If there is more than one matching token per line, or if the number + // of preceding commas, do not match anymore, end the sequence. if (FoundMatchOnLine || CommasBeforeMatch != CommasBeforeLastMatch) AlignCurrentSequence(); @@ -542,11 +544,12 @@ int LineLengthAfter = Changes[i].TokenLength; for (unsigned j = i + 1; j != e && Changes[j].NewlinesBefore == 0; ++j) { LineLengthAfter += Changes[j].Spaces; - // Changes are generally 1:1 with the tokens, but a change could also be - // inside of a token, in which case it's counted more than once: once for - // the whitespace surrounding the token (!IsInsideToken) and once for - // each whitespace change within it (IsInsideToken). - // Therefore, changes inside of a token should only count the space. + // Changes are generally 1:1 with the tokens, but a change could + // also be inside of a token, in which case it's counted more than + // once: once for the whitespace surrounding the token + // (!IsInsideToken) and once for each whitespace change within it + // (IsInsideToken). Therefore, changes inside of a token should only + // count the space. if (!Changes[j].IsInsideToken) LineLengthAfter += Changes[j].TokenLength; } @@ -591,9 +594,9 @@ 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 - // shifted by the same amount + // 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 shifted by the same amount if (!FoundMatchOnLine && AlignMacrosMatches(Changes[I])) { FoundMatchOnLine = true; Shift = MinColumn - Changes[I].StartOfTokenColumn; @@ -671,8 +674,8 @@ (Style.AlignConsecutiveMacros != FormatStyle::ACS_AcrossEmptyLinesAndComments); - // Whether to break the alignment sequence because of a line without a - // match. + // Whether to break the alignment sequence because of a line without + // a match. bool NoMatchBreak = !FoundMatchOnLine && !(LineIsComment && ((Style.AlignConsecutiveMacros == @@ -731,6 +734,16 @@ if (&C != &Changes.back() && (&C + 1)->NewlinesBefore > 0) return false; + // Do not align operator= overloads. + if (C.Tok->Previous && C.Tok->Previous->is(tok::kw_operator)) { + auto *Next = C.Tok->Next; + while (Next && Next->NewlinesBefore == 0) { + if (Next->Tok.is(tok::l_brace)) + return false; + Next = Next->Next; + } + } + return C.Tok->is(tok::equal); }, Changes, /*StartAt=*/0, Style.AlignConsecutiveAssignments); @@ -772,7 +785,8 @@ if (C.Tok->Previous && C.Tok->Previous->is(TT_StatementAttributeLikeMacro)) return false; - // Check if there is a subsequent name that starts the same declaration. + // Check if there is a subsequent name that starts the same + // declaration. for (FormatToken *Next = C.Tok->Next; Next; Next = Next->Next) { if (Next->is(tok::comment)) continue; @@ -810,9 +824,9 @@ (C.Tok->FakeLParens.size() == 0 || C.Tok->FakeLParens.back() != prec::Conditional)); }; - // Ensure we keep alignment of wrapped operands with non-wrapped operands - // Since we actually align the operators, the wrapped operands need the - // extra offset to be properly aligned. + // Ensure we keep alignment of wrapped operands with non-wrapped + // operands Since we actually align the operators, the wrapped operands + // need the extra offset to be properly aligned. for (Change &C : Changes) { if (AlignWrappedOperand(C)) C.StartOfTokenColumn -= 2; @@ -892,8 +906,8 @@ StartOfSequence = i; } else if (BreakBeforeNext || Newlines > 1 || (ChangeMinColumn > MaxColumn || ChangeMaxColumn < MinColumn) || - // Break the comment sequence if the previous line did not end - // in a trailing comment. + // Break the comment sequence if the previous line did not + // end in a trailing comment. (Changes[i].NewlinesBefore == 1 && i > 0 && !Changes[i - 1].IsTrailingComment) || WasAlignedWithStartOfNextLine) { @@ -1167,7 +1181,8 @@ Cells.back().EndIndex = i; Cells.push_back(CellDescription{i, ++Cell, i + 1, false, nullptr}); CellCount = C.Tok->Previous->isNot(tok::comma) ? Cell + 1 : Cell; - // Go to the next non-comment and ensure there is a break in front + // Go to the next non-comment and ensure there is a break in + // front const auto *NextNonComment = C.Tok->getNextNonComment(); while (NextNonComment->is(tok::comma)) NextNonComment = NextNonComment->getNextNonComment(); @@ -1200,20 +1215,20 @@ // lines bool HasSplit = false; if (Changes[i].NewlinesBefore > 0) { - // So if we split a line previously and the tail line + this token is - // less then the column limit we remove the split here and just put - // the column start at a space past the comma + // So if we split a line previously and the tail line + this + // token is less then the column limit we remove the split here + // and just put the column start at a space past the comma // // FIXME This if branch covers the cases where the column is not - // the first column. This leads to weird pathologies like the formatting - // auto foo = Items{ + // the first column. This leads to weird pathologies like the + // formatting auto foo = Items{ // Section{ // 0, bar(), // } // }; // Well if it doesn't lead to that it's indicative that the line - // breaking should be revisited. Unfortunately alot of other options - // interact with this + // breaking should be revisited. Unfortunately alot of other + // options interact with this auto j = i - 1; if ((j - 1) > Start && Changes[j].Tok->is(tok::comma) && Changes[j - 1].NewlinesBefore > 0) { @@ -1295,8 +1310,8 @@ C.EscapedNewlineColumn); else appendNewlineText(ReplacementText, C.NewlinesBefore); - // FIXME: This assert should hold if we computed the column correctly. - // assert((int)C.StartOfTokenColumn >= C.Spaces); + // FIXME: This assert should hold if we computed the column + // correctly. assert((int)C.StartOfTokenColumn >= C.Spaces); appendIndentText( ReplacementText, C.Tok->IndentLevel, std::max(0, C.Spaces), std::max((int)C.StartOfTokenColumn, C.Spaces) - std::max(0, C.Spaces), @@ -1398,8 +1413,8 @@ unsigned WhitespaceManager::appendTabIndent(std::string &Text, unsigned Spaces, unsigned Indentation) { - // This happens, e.g. when a line in a block comment is indented less than the - // first one. + // This happens, e.g. when a line in a block comment is indented less than + // the first one. if (Indentation > Spaces) Indentation = Spaces; if (Style.TabWidth) { diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -16167,6 +16167,14 @@ verifyFormat("int oneTwoThree = 123; // comment\n" "int oneTwo = 12; // comment", Alignment); + verifyFormat("int() = default;\n" + "int &operator() = default;\n" + "int &operator=() {", + Alignment); + verifyFormat("int() = default; // comment\n" + "int &operator() = default; // comment\n" + "int &operator=() {", + Alignment); // Bug 25167 /* Uncomment when fixed