Index: lib/Format/WhitespaceManager.cpp =================================================================== --- lib/Format/WhitespaceManager.cpp +++ lib/Format/WhitespaceManager.cpp @@ -160,10 +160,15 @@ } } +static bool IsPointerOrReference(tok::TokenKind Kind) { + return Kind == tok::star || Kind == tok::amp || Kind == tok::ampamp; +} + // Align a single sequence of tokens, see AlignTokens below. template static void -AlignTokenSequence(unsigned Start, unsigned End, unsigned Column, F &&Matches, +AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End, + unsigned Column, F &&Matches, SmallVector &Changes) { bool FoundMatchOnLine = false; int Shift = 0; @@ -183,9 +188,23 @@ } assert(Shift >= 0); + if (Shift == 0) + continue; + Changes[i].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 + if (Style.PointerAlignment == FormatStyle::PAS_Right && + Changes[i].Spaces != 0) { + for (int previous = i - 1; + previous >= 0 && IsPointerOrReference(Changes[previous].Kind); + previous--) { + Changes[previous + 1].Spaces -= Shift; + Changes[previous].Spaces += Shift; + } + } } } @@ -232,8 +251,8 @@ // containing any matching token to be aligned and located after such token. auto AlignCurrentSequence = [&] { if (StartOfSequence > 0 && StartOfSequence < EndOfSequence) - AlignTokenSequence(StartOfSequence, EndOfSequence, MinColumn, Matches, - Changes); + AlignTokenSequence(Style, StartOfSequence, EndOfSequence, MinColumn, + Matches, Changes); MinColumn = 0; MaxColumn = UINT_MAX; StartOfSequence = 0; @@ -328,13 +347,6 @@ if (!Style.AlignConsecutiveDeclarations) return; - // FIXME: Currently we don't handle properly the PointerAlignment: Right - // The * and & are not aligned and are left dangling. Something has to be done - // about it, but it raises the question of alignment of code like: - // const char* const* v1; - // float const* v2; - // SomeVeryLongType const& v3; - AlignTokens(Style, [](Change const &C) { return C.IsStartOfDeclName; }, Changes); } @@ -372,8 +384,7 @@ unsigned CommentColumn = SourceMgr.getSpellingColumnNumber( Changes[i].OriginalWhitespaceRange.getEnd()); for (unsigned j = i + 1; j != e; ++j) { - if (Changes[j].Kind == tok::comment || - Changes[j].Kind == tok::unknown) + if (Changes[j].Kind == tok::comment || Changes[j].Kind == tok::unknown) // Skip over comments and unknown tokens. "unknown tokens are used for // the continuation of multiline comments. continue; @@ -494,8 +505,7 @@ } } -void WhitespaceManager::storeReplacement(SourceRange Range, - StringRef Text) { +void WhitespaceManager::storeReplacement(SourceRange Range, StringRef Text) { unsigned WhitespaceLength = SourceMgr.getFileOffset(Range.getEnd()) - SourceMgr.getFileOffset(Range.getBegin()); // Don't create a replacement, if it does not change anything. Index: unittests/Format/FormatTest.cpp =================================================================== --- unittests/Format/FormatTest.cpp +++ unittests/Format/FormatTest.cpp @@ -9445,7 +9445,7 @@ Alignment); EXPECT_EQ("void SomeFunction(int parameter = 0) {\n" " int const i = 1;\n" - " int * j = 2;\n" + " int *j = 2;\n" " int big = 10000;\n" "\n" " unsigned oneTwoThree = 123;\n" @@ -9466,6 +9466,29 @@ "int ll=10000;\n" "}", Alignment)); + EXPECT_EQ("void SomeFunction(int parameter = 0) {\n" + " int const i = 1;\n" + " int **j = 2, ***k = 3;\n" + " int big = 10000;\n" + "\n" + " unsigned oneTwoThree = 123;\n" + " int oneTwo = 12;\n" + " method();\n" + " float k = 2;\n" + " int ll = 10000;\n" + "}", + format("void SomeFunction(int parameter= 0) {\n" + " int const i= 1;\n" + " int **j=2,***k=3;\n" + " int big = 10000;\n" + "\n" + "unsigned oneTwoThree =123;\n" + "int oneTwo = 12;\n" + " method();\n" + "float k= 2;\n" + "int ll=10000;\n" + "}", + Alignment)); Alignment.AlignConsecutiveAssignments = false; Alignment.AlignEscapedNewlinesLeft = true; verifyFormat("#define A \\\n" @@ -9492,7 +9515,7 @@ Alignment); verifyFormat("void SomeFunction(int parameter = 0) {\n" " int const i = 1;\n" - " int * j = 2;\n" + " int *j = 2;\n" " int big = 10000;\n" "}", Alignment); @@ -9596,7 +9619,7 @@ " float b,\n" " int c,\n" " uint32_t *d) {\n" - " int * e = 0;\n" + " int *e = 0;\n" " float f = 0;\n" " double g = 0;\n" "}\n"