[clang] [clang-forma] Support `PointerAlignment: Left` for pointer to member (PR #86253)
Owen Pan via cfe-commits
cfe-commits at lists.llvm.org
Fri Mar 22 01:26:06 PDT 2024
https://github.com/owenca updated https://github.com/llvm/llvm-project/pull/86253
>From d1a3b743b808a64f022897dfd832ce9a25c8f2c0 Mon Sep 17 00:00:00 2001
From: Owen Pan <owenpiano at gmail.com>
Date: Thu, 21 Mar 2024 23:43:23 -0700
Subject: [PATCH 1/2] [clang-forma] Support `PointerAlignment: Left` for
pointer to member
Fixes #85761.
---
clang/lib/Format/TokenAnnotator.cpp | 31 ++++++++++++++++-----------
clang/unittests/Format/FormatTest.cpp | 7 +++++-
2 files changed, 25 insertions(+), 13 deletions(-)
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 94d2266555f6b9..d54a0fe4ce6748 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -4351,9 +4351,11 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
if (Left.is(tok::kw_auto) && Right.isOneOf(tok::l_paren, tok::l_brace))
return false;
+ const auto *BeforeLeft = Left.Previous;
+
// operator co_await(x)
- if (Right.is(tok::l_paren) && Left.is(tok::kw_co_await) && Left.Previous &&
- Left.Previous->is(tok::kw_operator)) {
+ if (Right.is(tok::l_paren) && Left.is(tok::kw_co_await) && BeforeLeft &&
+ BeforeLeft->is(tok::kw_operator)) {
return false;
}
// co_await (x), co_yield (x), co_return (x)
@@ -4404,8 +4406,8 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
return false;
}
if (Right.is(tok::ellipsis)) {
- return Left.Tok.isLiteral() || (Left.is(tok::identifier) && Left.Previous &&
- Left.Previous->is(tok::kw_case));
+ return Left.Tok.isLiteral() || (Left.is(tok::identifier) && BeforeLeft &&
+ BeforeLeft->is(tok::kw_case));
}
if (Left.is(tok::l_square) && Right.is(tok::amp))
return Style.SpacesInSquareBrackets;
@@ -4473,8 +4475,8 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
if (Right.is(tok::l_brace) && Right.is(BK_Block))
return true;
// for (auto a = 0, b = 0; const auto& c : {1, 2, 3})
- if (Left.Previous && Left.Previous->isTypeOrIdentifier(IsCpp) &&
- Right.Next && Right.Next->is(TT_RangeBasedForLoopColon)) {
+ if (BeforeLeft && BeforeLeft->isTypeOrIdentifier(IsCpp) && Right.Next &&
+ Right.Next->is(TT_RangeBasedForLoopColon)) {
return getTokenPointerOrReferenceAlignment(Left) !=
FormatStyle::PAS_Right;
}
@@ -4496,12 +4498,17 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
startsWithInitStatement(Line)))) {
return false;
}
- return Left.Previous && !Left.Previous->isOneOf(
- tok::l_paren, tok::coloncolon, tok::l_square);
+ if (!BeforeLeft)
+ return false;
+ if (BeforeLeft->is(tok::coloncolon)) {
+ return Left.is(tok::star) &&
+ Style.PointerAlignment != FormatStyle::PAS_Right;
+ }
+ return !BeforeLeft->isOneOf(tok::l_paren, tok::l_square);
}
// Ensure right pointer alignment with ellipsis e.g. int *...P
- if (Left.is(tok::ellipsis) && Left.Previous &&
- Left.Previous->isPointerOrReference()) {
+ if (Left.is(tok::ellipsis) && BeforeLeft &&
+ BeforeLeft->isPointerOrReference()) {
return Style.PointerAlignment != FormatStyle::PAS_Right;
}
@@ -4663,13 +4670,13 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
return Style.SpaceBeforeParensOptions.AfterFunctionDefinitionName ||
spaceRequiredBeforeParens(Right);
}
- if (!Left.Previous || !Left.Previous->isOneOf(tok::period, tok::arrow)) {
+ if (!BeforeLeft || !BeforeLeft->isOneOf(tok::period, tok::arrow)) {
if (Left.isOneOf(tok::kw_try, Keywords.kw___except, tok::kw_catch)) {
return Style.SpaceBeforeParensOptions.AfterControlStatements ||
spaceRequiredBeforeParens(Right);
}
if (Left.isOneOf(tok::kw_new, tok::kw_delete)) {
- return ((!Line.MightBeFunctionDecl || !Left.Previous) &&
+ return ((!Line.MightBeFunctionDecl || !BeforeLeft) &&
Style.SpaceBeforeParens != FormatStyle::SBPO_Never) ||
spaceRequiredBeforeParens(Right);
}
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index bea989c8c306db..cab5556af47cc0 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -11054,7 +11054,12 @@ TEST_F(FormatTest, UnderstandsPointersToMembers) {
" aaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaa));");
FormatStyle Style = getLLVMStyle();
Style.PointerAlignment = FormatStyle::PAS_Left;
- verifyFormat("typedef bool* (Class::*Member)() const;", Style);
+ verifyFormat("typedef bool* (Class::* Member)() const;", Style);
+ verifyFormat("void function(int A::* parameter, int* parameter2) {\n"
+ " int A::* variable = &A::B;\n"
+ " int* A::B;\n"
+ "}",
+ Style);
}
TEST_F(FormatTest, UnderstandsUnaryOperators) {
>From 1cccb10e4a51383ed4c2d92d279de7d6bc872e56 Mon Sep 17 00:00:00 2001
From: Owen Pan <owenpiano at gmail.com>
Date: Fri, 22 Mar 2024 01:18:05 -0700
Subject: [PATCH 2/2] Added support for `Middle` and `Right` alignments.
---
clang/lib/Format/TokenAnnotator.cpp | 6 ++-
clang/unittests/Format/FormatTest.cpp | 41 +++++++++++--------
clang/unittests/Format/QualifierFixerTest.cpp | 36 ++++++++--------
3 files changed, 46 insertions(+), 37 deletions(-)
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index d54a0fe4ce6748..53cf5b098cc676 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -4390,8 +4390,10 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
}
if (Left.is(tok::colon))
return Left.isNot(TT_ObjCMethodExpr);
- if (Left.is(tok::coloncolon))
- return false;
+ if (Left.is(tok::coloncolon)) {
+ return Right.is(tok::star) && Right.is(TT_PointerOrReference) &&
+ Style.PointerAlignment != FormatStyle::PAS_Left;
+ }
if (Left.is(tok::less) || Right.isOneOf(tok::greater, tok::less)) {
if (Style.Language == FormatStyle::LK_TextProto ||
(Style.Language == FormatStyle::LK_Proto &&
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index cab5556af47cc0..cf8d6ab691d9a0 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -3621,8 +3621,8 @@ TEST_F(FormatTest, FormatsClasses) {
" : public aaaaaaaaaaaaaaaaaaa<aaaaaaaaaaaaaaaaaaaaa,\n"
" aaaaaaaaaaaaaaaaaaaaaa> {};");
verifyFormat("template <class R, class C>\n"
- "struct Aaaaaaaaaaaaaaaaa<R (C::*)(int) const>\n"
- " : Aaaaaaaaaaaaaaaaa<R (C::*)(int)> {};");
+ "struct Aaaaaaaaaaaaaaaaa<R (C:: *)(int) const>\n"
+ " : Aaaaaaaaaaaaaaaaa<R (C:: *)(int)> {};");
verifyFormat("class ::A::B {};");
}
@@ -11034,10 +11034,10 @@ TEST_F(FormatTest, UnderstandsBinaryOperators) {
}
TEST_F(FormatTest, UnderstandsPointersToMembers) {
- verifyFormat("int A::*x;");
- verifyFormat("int (S::*func)(void *);");
- verifyFormat("void f() { int (S::*func)(void *); }");
- verifyFormat("typedef bool *(Class::*Member)() const;");
+ verifyFormat("int A:: *x;");
+ verifyFormat("int (S:: *func)(void *);");
+ verifyFormat("void f() { int (S:: *func)(void *); }");
+ verifyFormat("typedef bool *(Class:: *Member)() const;");
verifyFormat("void f() {\n"
" (a->*f)();\n"
" a->*x;\n"
@@ -11052,14 +11052,19 @@ TEST_F(FormatTest, UnderstandsPointersToMembers) {
verifyFormat(
"(aaaaaaaaaa->*bbbbbbb)(\n"
" aaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaa));");
+
FormatStyle Style = getLLVMStyle();
+ EXPECT_EQ(Style.PointerAlignment, FormatStyle::PAS_Right);
+ verifyFormat("typedef bool *(Class:: *Member)() const;", Style);
+ verifyFormat("void f(int A:: *p) { int A:: *v = &A::B; }", Style);
+
Style.PointerAlignment = FormatStyle::PAS_Left;
verifyFormat("typedef bool* (Class::* Member)() const;", Style);
- verifyFormat("void function(int A::* parameter, int* parameter2) {\n"
- " int A::* variable = &A::B;\n"
- " int* A::B;\n"
- "}",
- Style);
+ verifyFormat("void f(int A::* p) { int A::* v = &A::B; }", Style);
+
+ Style.PointerAlignment = FormatStyle::PAS_Middle;
+ verifyFormat("typedef bool * (Class:: * Member)() const;", Style);
+ verifyFormat("void f(int A:: * p) { int A:: * v = &A::B; }", Style);
}
TEST_F(FormatTest, UnderstandsUnaryOperators) {
@@ -12391,7 +12396,7 @@ TEST_F(FormatTest, FormatsFunctionTypes) {
verifyFormat("int (*func)(void *);");
verifyFormat("void f() { int (*func)(void *); }");
verifyFormat("template <class CallbackClass>\n"
- "using MyCallback = void (CallbackClass::*)(SomeObject *Data);");
+ "using Callback = void (CallbackClass:: *)(SomeObject *Data);");
verifyGoogleFormat("A<void*(int*, SomeType*)>;");
verifyGoogleFormat("void* (*a)(int);");
@@ -19154,13 +19159,13 @@ TEST_F(FormatTest, AlignConsecutiveDeclarations) {
"int bbbbbbb = 0;",
Alignment);
// http://llvm.org/PR68079
- verifyFormat("using Fn = int (A::*)();\n"
- "using RFn = int (A::*)() &;\n"
- "using RRFn = int (A::*)() &&;",
+ verifyFormat("using Fn = int (A:: *)();\n"
+ "using RFn = int (A:: *)() &;\n"
+ "using RRFn = int (A:: *)() &&;",
Alignment);
- verifyFormat("using Fn = int (A::*)();\n"
- "using RFn = int *(A::*)() &;\n"
- "using RRFn = double (A::*)() &&;",
+ verifyFormat("using Fn = int (A:: *)();\n"
+ "using RFn = int *(A:: *)() &;\n"
+ "using RRFn = double (A:: *)() &&;",
Alignment);
// PAS_Right
diff --git a/clang/unittests/Format/QualifierFixerTest.cpp b/clang/unittests/Format/QualifierFixerTest.cpp
index 43476aea66337b..792d8f3c3a9825 100644
--- a/clang/unittests/Format/QualifierFixerTest.cpp
+++ b/clang/unittests/Format/QualifierFixerTest.cpp
@@ -305,7 +305,7 @@ TEST_F(QualifierFixerTest, RightQualifier) {
verifyFormat("Foo inline static const;", "Foo inline const static;", Style);
verifyFormat("Foo inline static const;", Style);
- verifyFormat("Foo<T volatile>::Bar<Type const, 5> const volatile A::*;",
+ verifyFormat("Foo<T volatile>::Bar<Type const, 5> const volatile A:: *;",
"volatile const Foo<volatile T>::Bar<const Type, 5> A::*;",
Style);
@@ -523,14 +523,15 @@ TEST_F(QualifierFixerTest, RightQualifier) {
verifyFormat("const INTPTR a;", Style);
// Pointers to members
- verifyFormat("int S::*a;", Style);
- verifyFormat("int const S::*a;", "const int S:: *a;", Style);
- verifyFormat("int const S::*const a;", "const int S::* const a;", Style);
- verifyFormat("int A::*const A::*p1;", Style);
- verifyFormat("float (C::*p)(int);", Style);
- verifyFormat("float (C::*const p)(int);", Style);
- verifyFormat("float (C::*p)(int) const;", Style);
- verifyFormat("float const (C::*p)(int);", "const float (C::*p)(int);", Style);
+ verifyFormat("int S:: *a;", Style);
+ verifyFormat("int const S:: *a;", "const int S:: *a;", Style);
+ verifyFormat("int const S:: *const a;", "const int S::* const a;", Style);
+ verifyFormat("int A:: *const A:: *p1;", Style);
+ verifyFormat("float (C:: *p)(int);", Style);
+ verifyFormat("float (C:: *const p)(int);", Style);
+ verifyFormat("float (C:: *p)(int) const;", Style);
+ verifyFormat("float const (C:: *p)(int);", "const float (C::*p)(int);",
+ Style);
}
TEST_F(QualifierFixerTest, LeftQualifier) {
@@ -830,14 +831,15 @@ TEST_F(QualifierFixerTest, LeftQualifier) {
verifyFormat("INTPTR const a;", Style);
// Pointers to members
- verifyFormat("int S::*a;", Style);
- verifyFormat("const int S::*a;", "int const S:: *a;", Style);
- verifyFormat("const int S::*const a;", "int const S::* const a;", Style);
- verifyFormat("int A::*const A::*p1;", Style);
- verifyFormat("float (C::*p)(int);", Style);
- verifyFormat("float (C::*const p)(int);", Style);
- verifyFormat("float (C::*p)(int) const;", Style);
- verifyFormat("const float (C::*p)(int);", "float const (C::*p)(int);", Style);
+ verifyFormat("int S:: *a;", Style);
+ verifyFormat("const int S:: *a;", "int const S:: *a;", Style);
+ verifyFormat("const int S:: *const a;", "int const S::* const a;", Style);
+ verifyFormat("int A:: *const A:: *p1;", Style);
+ verifyFormat("float (C:: *p)(int);", Style);
+ verifyFormat("float (C:: *const p)(int);", Style);
+ verifyFormat("float (C:: *p)(int) const;", Style);
+ verifyFormat("const float (C:: *p)(int);", "float const (C::*p)(int);",
+ Style);
}
TEST_F(QualifierFixerTest, ConstVolatileQualifiersOrder) {
More information about the cfe-commits
mailing list