Skip to content

Commit 3d99446

Browse files
authored
[clang-format] Fix a bug in DerivePointerAlignment: true (llvm#150744)
This effectively reverts a4d4859 which didn't fix the problem that `int*,` was not counted as "Left" alignment. Fixes llvm#150327
1 parent 4072a6b commit 3d99446

File tree

2 files changed

+35
-18
lines changed

2 files changed

+35
-18
lines changed

clang/lib/Format/Format.cpp

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2639,32 +2639,44 @@ class Formatter : public TokenAnalyzer {
26392639

26402640
int countVariableAlignments(const SmallVectorImpl<AnnotatedLine *> &Lines) {
26412641
int AlignmentDiff = 0;
2642+
26422643
for (const AnnotatedLine *Line : Lines) {
26432644
AlignmentDiff += countVariableAlignments(Line->Children);
2644-
for (FormatToken *Tok = Line->First; Tok && Tok->Next; Tok = Tok->Next) {
2645+
2646+
for (const auto *Tok = Line->getFirstNonComment(); Tok; Tok = Tok->Next) {
26452647
if (Tok->isNot(TT_PointerOrReference))
26462648
continue;
2647-
// Don't treat space in `void foo() &&` or `void() &&` as evidence.
2648-
if (const auto *Prev = Tok->getPreviousNonComment()) {
2649-
if (Prev->is(tok::r_paren) && Prev->MatchingParen) {
2650-
if (const auto *Func =
2651-
Prev->MatchingParen->getPreviousNonComment()) {
2652-
if (Func->isOneOf(TT_FunctionDeclarationName, TT_StartOfName,
2653-
TT_OverloadedOperator) ||
2654-
Func->isTypeName(LangOpts)) {
2655-
continue;
2656-
}
2657-
}
2658-
}
2649+
2650+
const auto *Prev = Tok->Previous;
2651+
const bool PrecededByName = Prev && Prev->Tok.getIdentifierInfo();
2652+
const bool SpaceBefore = Tok->hasWhitespaceBefore();
2653+
2654+
// e.g. `int **`, `int*&`, etc.
2655+
while (Tok->Next && Tok->Next->is(TT_PointerOrReference))
2656+
Tok = Tok->Next;
2657+
2658+
const auto *Next = Tok->Next;
2659+
const bool FollowedByName = Next && Next->Tok.getIdentifierInfo();
2660+
const bool SpaceAfter = Next && Next->hasWhitespaceBefore();
2661+
2662+
if ((!PrecededByName && !FollowedByName) ||
2663+
// e.g. `int * i` or `int*i`
2664+
(PrecededByName && FollowedByName && SpaceBefore == SpaceAfter)) {
2665+
continue;
26592666
}
2660-
bool SpaceBefore = Tok->hasWhitespaceBefore();
2661-
bool SpaceAfter = Tok->Next->hasWhitespaceBefore();
2662-
if (SpaceBefore && !SpaceAfter)
2667+
2668+
if ((PrecededByName && SpaceBefore) ||
2669+
(FollowedByName && !SpaceAfter)) {
2670+
// Right alignment.
26632671
++AlignmentDiff;
2664-
if (!SpaceBefore && SpaceAfter)
2672+
} else if ((PrecededByName && !SpaceBefore) ||
2673+
(FollowedByName && SpaceAfter)) {
2674+
// Left alignment.
26652675
--AlignmentDiff;
2676+
}
26662677
}
26672678
}
2679+
26682680
return AlignmentDiff;
26692681
}
26702682

clang/unittests/Format/FormatTest.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12114,7 +12114,12 @@ TEST_F(FormatTest, UnderstandsFunctionRefQualification) {
1211412114
"void b() const &;\n";
1211512115
verifyFormat(Prefix + "int *x;", Prefix + "int* x;", DerivePointerAlignment);
1211612116

12117-
verifyGoogleFormat("MACRO(int*, std::function<void() &&>);");
12117+
constexpr StringRef Code("MACRO(int*, std::function<void() &&>);");
12118+
verifyFormat(Code, DerivePointerAlignment);
12119+
12120+
auto Style = getGoogleStyle();
12121+
Style.DerivePointerAlignment = true;
12122+
verifyFormat(Code, Style);
1211812123
}
1211912124

1212012125
TEST_F(FormatTest, PointerAlignmentFallback) {

0 commit comments

Comments
 (0)