Index: lib/Format/WhitespaceManager.cpp =================================================================== --- lib/Format/WhitespaceManager.cpp +++ lib/Format/WhitespaceManager.cpp @@ -187,7 +187,8 @@ // 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; @@ -207,9 +208,24 @@ } 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 && + Changes[previous].Tok->Type == TT_PointerOrReference; + previous--) { + Changes[previous + 1].Spaces -= Shift; + Changes[previous].Spaces += Shift; + } + } } } @@ -256,8 +272,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; @@ -350,13 +366,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.Tok->isOneOf(TT_StartOfName, @@ -518,8 +527,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 @@ -9409,9 +9409,11 @@ verifyFormat("int oneTwoThree = {0}; // comment\n" "unsigned oneTwo = 0; // comment", Alignment); + + // PAS_RIGHT 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" @@ -9432,6 +9434,141 @@ "int ll=10000;\n" "}", Alignment)); + EXPECT_EQ("void SomeFunction(int parameter = 0) {\n" + " int const i = 1;\n" + " int **j = 2, ***k;\n" + " int &k = i;\n" + " int &&l = i + j;\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;\n" + "int &k=i;\n" + "int &&l=i+j;\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)); + + // PAS_LEFT + FormatStyle AlignmentLeft = Alignment; + AlignmentLeft.PointerAlignment = FormatStyle::PAS_Left; + EXPECT_EQ("void SomeFunction(int parameter = 0) {\n" + " int const i = 1;\n" + " int* j = 2;\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;\n" + " int big = 10000;\n" + "\n" + "unsigned oneTwoThree =123;\n" + "int oneTwo = 12;\n" + " method();\n" + "float k= 2;\n" + "int ll=10000;\n" + "}", + AlignmentLeft)); + EXPECT_EQ("void SomeFunction(int parameter = 0) {\n" + " int const i = 1;\n" + " int** j = 2;\n" + " int& k = i;\n" + " int&& l = i + j;\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;\n" + "int &k=i;\n" + "int &&l=i+j;\n" + " int big = 10000;\n" + "\n" + "unsigned oneTwoThree =123;\n" + "int oneTwo = 12;\n" + " method();\n" + "float k= 2;\n" + "int ll=10000;\n" + "}", + AlignmentLeft)); + // PAS_MIDDLE + FormatStyle AlignmentMiddle = Alignment; + AlignmentMiddle.PointerAlignment = FormatStyle::PAS_Middle; + EXPECT_EQ("void SomeFunction(int parameter = 0) {\n" + " int const i = 1;\n" + " int * j = 2;\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;\n" + " int big = 10000;\n" + "\n" + "unsigned oneTwoThree =123;\n" + "int oneTwo = 12;\n" + " method();\n" + "float k= 2;\n" + "int ll=10000;\n" + "}", + AlignmentMiddle)); + EXPECT_EQ("void SomeFunction(int parameter = 0) {\n" + " int const i = 1;\n" + " int ** j = 2;\n" + " int & k = i;\n" + " int && l = i + j;\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;\n" + "int &k=i;\n" + "int &&l=i+j;\n" + " int big = 10000;\n" + "\n" + "unsigned oneTwoThree =123;\n" + "int oneTwo = 12;\n" + " method();\n" + "float k= 2;\n" + "int ll=10000;\n" + "}", + AlignmentMiddle)); + Alignment.AlignConsecutiveAssignments = false; Alignment.AlignEscapedNewlinesLeft = true; verifyFormat("#define A \\\n" @@ -9458,7 +9595,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); @@ -9562,7 +9699,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"