Skip to content

Commit 579dc7f

Browse files
authored
[clang-forma] Support PointerAlignment for pointers to members (#86253)
Fixes #85761.
1 parent 691b97c commit 579dc7f

File tree

3 files changed

+66
-45
lines changed

3 files changed

+66
-45
lines changed

clang/lib/Format/TokenAnnotator.cpp

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4357,9 +4357,11 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
43574357
if (Left.is(tok::kw_auto) && Right.isOneOf(tok::l_paren, tok::l_brace))
43584358
return false;
43594359

4360+
const auto *BeforeLeft = Left.Previous;
4361+
43604362
// operator co_await(x)
4361-
if (Right.is(tok::l_paren) && Left.is(tok::kw_co_await) && Left.Previous &&
4362-
Left.Previous->is(tok::kw_operator)) {
4363+
if (Right.is(tok::l_paren) && Left.is(tok::kw_co_await) && BeforeLeft &&
4364+
BeforeLeft->is(tok::kw_operator)) {
43634365
return false;
43644366
}
43654367
// co_await (x), co_yield (x), co_return (x)
@@ -4394,8 +4396,10 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
43944396
}
43954397
if (Left.is(tok::colon))
43964398
return Left.isNot(TT_ObjCMethodExpr);
4397-
if (Left.is(tok::coloncolon))
4398-
return false;
4399+
if (Left.is(tok::coloncolon)) {
4400+
return Right.is(tok::star) && Right.is(TT_PointerOrReference) &&
4401+
Style.PointerAlignment != FormatStyle::PAS_Left;
4402+
}
43994403
if (Left.is(tok::less) || Right.isOneOf(tok::greater, tok::less)) {
44004404
if (Style.Language == FormatStyle::LK_TextProto ||
44014405
(Style.Language == FormatStyle::LK_Proto &&
@@ -4410,8 +4414,8 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
44104414
return false;
44114415
}
44124416
if (Right.is(tok::ellipsis)) {
4413-
return Left.Tok.isLiteral() || (Left.is(tok::identifier) && Left.Previous &&
4414-
Left.Previous->is(tok::kw_case));
4417+
return Left.Tok.isLiteral() || (Left.is(tok::identifier) && BeforeLeft &&
4418+
BeforeLeft->is(tok::kw_case));
44154419
}
44164420
if (Left.is(tok::l_square) && Right.is(tok::amp))
44174421
return Style.SpacesInSquareBrackets;
@@ -4479,8 +4483,8 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
44794483
if (Right.is(tok::l_brace) && Right.is(BK_Block))
44804484
return true;
44814485
// for (auto a = 0, b = 0; const auto& c : {1, 2, 3})
4482-
if (Left.Previous && Left.Previous->isTypeOrIdentifier(IsCpp) &&
4483-
Right.Next && Right.Next->is(TT_RangeBasedForLoopColon)) {
4486+
if (BeforeLeft && BeforeLeft->isTypeOrIdentifier(IsCpp) && Right.Next &&
4487+
Right.Next->is(TT_RangeBasedForLoopColon)) {
44844488
return getTokenPointerOrReferenceAlignment(Left) !=
44854489
FormatStyle::PAS_Right;
44864490
}
@@ -4502,12 +4506,17 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
45024506
startsWithInitStatement(Line)))) {
45034507
return false;
45044508
}
4505-
return Left.Previous && !Left.Previous->isOneOf(
4506-
tok::l_paren, tok::coloncolon, tok::l_square);
4509+
if (!BeforeLeft)
4510+
return false;
4511+
if (BeforeLeft->is(tok::coloncolon)) {
4512+
return Left.is(tok::star) &&
4513+
Style.PointerAlignment != FormatStyle::PAS_Right;
4514+
}
4515+
return !BeforeLeft->isOneOf(tok::l_paren, tok::l_square);
45074516
}
45084517
// Ensure right pointer alignment with ellipsis e.g. int *...P
4509-
if (Left.is(tok::ellipsis) && Left.Previous &&
4510-
Left.Previous->isPointerOrReference()) {
4518+
if (Left.is(tok::ellipsis) && BeforeLeft &&
4519+
BeforeLeft->isPointerOrReference()) {
45114520
return Style.PointerAlignment != FormatStyle::PAS_Right;
45124521
}
45134522

@@ -4669,13 +4678,13 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
46694678
return Style.SpaceBeforeParensOptions.AfterFunctionDefinitionName ||
46704679
spaceRequiredBeforeParens(Right);
46714680
}
4672-
if (!Left.Previous || !Left.Previous->isOneOf(tok::period, tok::arrow)) {
4681+
if (!BeforeLeft || !BeforeLeft->isOneOf(tok::period, tok::arrow)) {
46734682
if (Left.isOneOf(tok::kw_try, Keywords.kw___except, tok::kw_catch)) {
46744683
return Style.SpaceBeforeParensOptions.AfterControlStatements ||
46754684
spaceRequiredBeforeParens(Right);
46764685
}
46774686
if (Left.isOneOf(tok::kw_new, tok::kw_delete)) {
4678-
return ((!Line.MightBeFunctionDecl || !Left.Previous) &&
4687+
return ((!Line.MightBeFunctionDecl || !BeforeLeft) &&
46794688
Style.SpaceBeforeParens != FormatStyle::SBPO_Never) ||
46804689
spaceRequiredBeforeParens(Right);
46814690
}

clang/unittests/Format/FormatTest.cpp

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3621,8 +3621,8 @@ TEST_F(FormatTest, FormatsClasses) {
36213621
" : public aaaaaaaaaaaaaaaaaaa<aaaaaaaaaaaaaaaaaaaaa,\n"
36223622
" aaaaaaaaaaaaaaaaaaaaaa> {};");
36233623
verifyFormat("template <class R, class C>\n"
3624-
"struct Aaaaaaaaaaaaaaaaa<R (C::*)(int) const>\n"
3625-
" : Aaaaaaaaaaaaaaaaa<R (C::*)(int)> {};");
3624+
"struct Aaaaaaaaaaaaaaaaa<R (C:: *)(int) const>\n"
3625+
" : Aaaaaaaaaaaaaaaaa<R (C:: *)(int)> {};");
36263626
verifyFormat("class ::A::B {};");
36273627
}
36283628

@@ -11034,10 +11034,10 @@ TEST_F(FormatTest, UnderstandsBinaryOperators) {
1103411034
}
1103511035

1103611036
TEST_F(FormatTest, UnderstandsPointersToMembers) {
11037-
verifyFormat("int A::*x;");
11038-
verifyFormat("int (S::*func)(void *);");
11039-
verifyFormat("void f() { int (S::*func)(void *); }");
11040-
verifyFormat("typedef bool *(Class::*Member)() const;");
11037+
verifyFormat("int A:: *x;");
11038+
verifyFormat("int (S:: *func)(void *);");
11039+
verifyFormat("void f() { int (S:: *func)(void *); }");
11040+
verifyFormat("typedef bool *(Class:: *Member)() const;");
1104111041
verifyFormat("void f() {\n"
1104211042
" (a->*f)();\n"
1104311043
" a->*x;\n"
@@ -11052,9 +11052,19 @@ TEST_F(FormatTest, UnderstandsPointersToMembers) {
1105211052
verifyFormat(
1105311053
"(aaaaaaaaaa->*bbbbbbb)(\n"
1105411054
" aaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaa));");
11055+
1105511056
FormatStyle Style = getLLVMStyle();
11057+
EXPECT_EQ(Style.PointerAlignment, FormatStyle::PAS_Right);
11058+
verifyFormat("typedef bool *(Class:: *Member)() const;", Style);
11059+
verifyFormat("void f(int A:: *p) { int A:: *v = &A::B; }", Style);
11060+
1105611061
Style.PointerAlignment = FormatStyle::PAS_Left;
11057-
verifyFormat("typedef bool* (Class::*Member)() const;", Style);
11062+
verifyFormat("typedef bool* (Class::* Member)() const;", Style);
11063+
verifyFormat("void f(int A::* p) { int A::* v = &A::B; }", Style);
11064+
11065+
Style.PointerAlignment = FormatStyle::PAS_Middle;
11066+
verifyFormat("typedef bool * (Class:: * Member)() const;", Style);
11067+
verifyFormat("void f(int A:: * p) { int A:: * v = &A::B; }", Style);
1105811068
}
1105911069

1106011070
TEST_F(FormatTest, UnderstandsUnaryOperators) {
@@ -12386,7 +12396,7 @@ TEST_F(FormatTest, FormatsFunctionTypes) {
1238612396
verifyFormat("int (*func)(void *);");
1238712397
verifyFormat("void f() { int (*func)(void *); }");
1238812398
verifyFormat("template <class CallbackClass>\n"
12389-
"using MyCallback = void (CallbackClass::*)(SomeObject *Data);");
12399+
"using Callback = void (CallbackClass:: *)(SomeObject *Data);");
1239012400

1239112401
verifyGoogleFormat("A<void*(int*, SomeType*)>;");
1239212402
verifyGoogleFormat("void* (*a)(int);");
@@ -19149,13 +19159,13 @@ TEST_F(FormatTest, AlignConsecutiveDeclarations) {
1914919159
"int bbbbbbb = 0;",
1915019160
Alignment);
1915119161
// http://llvm.org/PR68079
19152-
verifyFormat("using Fn = int (A::*)();\n"
19153-
"using RFn = int (A::*)() &;\n"
19154-
"using RRFn = int (A::*)() &&;",
19162+
verifyFormat("using Fn = int (A:: *)();\n"
19163+
"using RFn = int (A:: *)() &;\n"
19164+
"using RRFn = int (A:: *)() &&;",
1915519165
Alignment);
19156-
verifyFormat("using Fn = int (A::*)();\n"
19157-
"using RFn = int *(A::*)() &;\n"
19158-
"using RRFn = double (A::*)() &&;",
19166+
verifyFormat("using Fn = int (A:: *)();\n"
19167+
"using RFn = int *(A:: *)() &;\n"
19168+
"using RRFn = double (A:: *)() &&;",
1915919169
Alignment);
1916019170

1916119171
// PAS_Right

clang/unittests/Format/QualifierFixerTest.cpp

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ TEST_F(QualifierFixerTest, RightQualifier) {
305305
verifyFormat("Foo inline static const;", "Foo inline const static;", Style);
306306
verifyFormat("Foo inline static const;", Style);
307307

308-
verifyFormat("Foo<T volatile>::Bar<Type const, 5> const volatile A::*;",
308+
verifyFormat("Foo<T volatile>::Bar<Type const, 5> const volatile A:: *;",
309309
"volatile const Foo<volatile T>::Bar<const Type, 5> A::*;",
310310
Style);
311311

@@ -523,14 +523,15 @@ TEST_F(QualifierFixerTest, RightQualifier) {
523523
verifyFormat("const INTPTR a;", Style);
524524

525525
// Pointers to members
526-
verifyFormat("int S::*a;", Style);
527-
verifyFormat("int const S::*a;", "const int S:: *a;", Style);
528-
verifyFormat("int const S::*const a;", "const int S::* const a;", Style);
529-
verifyFormat("int A::*const A::*p1;", Style);
530-
verifyFormat("float (C::*p)(int);", Style);
531-
verifyFormat("float (C::*const p)(int);", Style);
532-
verifyFormat("float (C::*p)(int) const;", Style);
533-
verifyFormat("float const (C::*p)(int);", "const float (C::*p)(int);", Style);
526+
verifyFormat("int S:: *a;", Style);
527+
verifyFormat("int const S:: *a;", "const int S:: *a;", Style);
528+
verifyFormat("int const S:: *const a;", "const int S::* const a;", Style);
529+
verifyFormat("int A:: *const A:: *p1;", Style);
530+
verifyFormat("float (C:: *p)(int);", Style);
531+
verifyFormat("float (C:: *const p)(int);", Style);
532+
verifyFormat("float (C:: *p)(int) const;", Style);
533+
verifyFormat("float const (C:: *p)(int);", "const float (C::*p)(int);",
534+
Style);
534535
}
535536

536537
TEST_F(QualifierFixerTest, LeftQualifier) {
@@ -830,14 +831,15 @@ TEST_F(QualifierFixerTest, LeftQualifier) {
830831
verifyFormat("INTPTR const a;", Style);
831832

832833
// Pointers to members
833-
verifyFormat("int S::*a;", Style);
834-
verifyFormat("const int S::*a;", "int const S:: *a;", Style);
835-
verifyFormat("const int S::*const a;", "int const S::* const a;", Style);
836-
verifyFormat("int A::*const A::*p1;", Style);
837-
verifyFormat("float (C::*p)(int);", Style);
838-
verifyFormat("float (C::*const p)(int);", Style);
839-
verifyFormat("float (C::*p)(int) const;", Style);
840-
verifyFormat("const float (C::*p)(int);", "float const (C::*p)(int);", Style);
834+
verifyFormat("int S:: *a;", Style);
835+
verifyFormat("const int S:: *a;", "int const S:: *a;", Style);
836+
verifyFormat("const int S:: *const a;", "int const S::* const a;", Style);
837+
verifyFormat("int A:: *const A:: *p1;", Style);
838+
verifyFormat("float (C:: *p)(int);", Style);
839+
verifyFormat("float (C:: *const p)(int);", Style);
840+
verifyFormat("float (C:: *p)(int) const;", Style);
841+
verifyFormat("const float (C:: *p)(int);", "float const (C::*p)(int);",
842+
Style);
841843
}
842844

843845
TEST_F(QualifierFixerTest, ConstVolatileQualifiersOrder) {

0 commit comments

Comments
 (0)