Author: Owen Pan Date: 2025-07-28T00:44:12-07:00 New Revision: 3d994468098027f9cf550c78a1c91bb266040f61
URL: https://github.com/llvm/llvm-project/commit/3d994468098027f9cf550c78a1c91bb266040f61 DIFF: https://github.com/llvm/llvm-project/commit/3d994468098027f9cf550c78a1c91bb266040f61.diff LOG: [clang-format] Fix a bug in `DerivePointerAlignment: true` (#150744) This effectively reverts a4d4859dc70c046ad928805ddeaf8fa101793394 which didn't fix the problem that `int*,` was not counted as "Left" alignment. Fixes #150327 Added: Modified: clang/lib/Format/Format.cpp clang/unittests/Format/FormatTest.cpp Removed: ################################################################################ diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index e6808f7c3bef1..063780721423f 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -2639,32 +2639,44 @@ class Formatter : public TokenAnalyzer { int countVariableAlignments(const SmallVectorImpl<AnnotatedLine *> &Lines) { int AlignmentDiff = 0; + for (const AnnotatedLine *Line : Lines) { AlignmentDiff += countVariableAlignments(Line->Children); - for (FormatToken *Tok = Line->First; Tok && Tok->Next; Tok = Tok->Next) { + + for (const auto *Tok = Line->getFirstNonComment(); Tok; Tok = Tok->Next) { if (Tok->isNot(TT_PointerOrReference)) continue; - // Don't treat space in `void foo() &&` or `void() &&` as evidence. - if (const auto *Prev = Tok->getPreviousNonComment()) { - if (Prev->is(tok::r_paren) && Prev->MatchingParen) { - if (const auto *Func = - Prev->MatchingParen->getPreviousNonComment()) { - if (Func->isOneOf(TT_FunctionDeclarationName, TT_StartOfName, - TT_OverloadedOperator) || - Func->isTypeName(LangOpts)) { - continue; - } - } - } + + const auto *Prev = Tok->Previous; + const bool PrecededByName = Prev && Prev->Tok.getIdentifierInfo(); + const bool SpaceBefore = Tok->hasWhitespaceBefore(); + + // e.g. `int **`, `int*&`, etc. + while (Tok->Next && Tok->Next->is(TT_PointerOrReference)) + Tok = Tok->Next; + + const auto *Next = Tok->Next; + const bool FollowedByName = Next && Next->Tok.getIdentifierInfo(); + const bool SpaceAfter = Next && Next->hasWhitespaceBefore(); + + if ((!PrecededByName && !FollowedByName) || + // e.g. `int * i` or `int*i` + (PrecededByName && FollowedByName && SpaceBefore == SpaceAfter)) { + continue; } - bool SpaceBefore = Tok->hasWhitespaceBefore(); - bool SpaceAfter = Tok->Next->hasWhitespaceBefore(); - if (SpaceBefore && !SpaceAfter) + + if ((PrecededByName && SpaceBefore) || + (FollowedByName && !SpaceAfter)) { + // Right alignment. ++AlignmentDiff; - if (!SpaceBefore && SpaceAfter) + } else if ((PrecededByName && !SpaceBefore) || + (FollowedByName && SpaceAfter)) { + // Left alignment. --AlignmentDiff; + } } } + return AlignmentDiff; } diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 553d9801e9d87..9c5aa11d6e58f 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -12114,7 +12114,12 @@ TEST_F(FormatTest, UnderstandsFunctionRefQualification) { "void b() const &;\n"; verifyFormat(Prefix + "int *x;", Prefix + "int* x;", DerivePointerAlignment); - verifyGoogleFormat("MACRO(int*, std::function<void() &&>);"); + constexpr StringRef Code("MACRO(int*, std::function<void() &&>);"); + verifyFormat(Code, DerivePointerAlignment); + + auto Style = getGoogleStyle(); + Style.DerivePointerAlignment = true; + verifyFormat(Code, Style); } TEST_F(FormatTest, PointerAlignmentFallback) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits