[clang] 2a73a1a - [clang-format] PR48916 PointerAlignment not working when using C++20 init-statement in for loop
via cfe-commits
cfe-commits at lists.llvm.org
Thu Dec 9 02:37:11 PST 2021
Author: mydeveloperday
Date: 2021-12-09T10:37:02Z
New Revision: 2a73a1ac57f0b7f95d3e75ef8f3dafb174ef5ccc
URL: https://github.com/llvm/llvm-project/commit/2a73a1ac57f0b7f95d3e75ef8f3dafb174ef5ccc
DIFF: https://github.com/llvm/llvm-project/commit/2a73a1ac57f0b7f95d3e75ef8f3dafb174ef5ccc.diff
LOG: [clang-format] PR48916 PointerAlignment not working when using C++20 init-statement in for loop
https://bugs.llvm.org/show_bug.cgi?id=48916
Left and Right Alignment inside a loop is misaligned.
Reviewed By: HazardyKnusperkeks, curdeius
Differential Revision: https://reviews.llvm.org/D115050
Added:
Modified:
clang/lib/Format/FormatToken.cpp
clang/lib/Format/FormatToken.h
clang/lib/Format/TokenAnnotator.cpp
clang/unittests/Format/FormatTest.cpp
Removed:
################################################################################
diff --git a/clang/lib/Format/FormatToken.cpp b/clang/lib/Format/FormatToken.cpp
index 6768f041135c7..57f8a5a45cbb0 100644
--- a/clang/lib/Format/FormatToken.cpp
+++ b/clang/lib/Format/FormatToken.cpp
@@ -70,6 +70,10 @@ bool FormatToken::isSimpleTypeSpecifier() const {
}
}
+bool FormatToken::isTypeOrIdentifier() const {
+ return isSimpleTypeSpecifier() || Tok.isOneOf(tok::kw_auto, tok::identifier);
+}
+
TokenRole::~TokenRole() {}
void TokenRole::precomputeFormattingInfos(const FormatToken *Token) {}
diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h
index 1a2858018fde5..d410ede32240d 100644
--- a/clang/lib/Format/FormatToken.h
+++ b/clang/lib/Format/FormatToken.h
@@ -521,7 +521,9 @@ struct FormatToken {
}
/// Determine whether the token is a simple-type-specifier.
- bool isSimpleTypeSpecifier() const;
+ LLVM_NODISCARD bool isSimpleTypeSpecifier() const;
+
+ LLVM_NODISCARD bool isTypeOrIdentifier() const;
bool isObjCAccessSpecifier() const {
return is(tok::at) && Next &&
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 6b7f135e32136..c0d030379ff0a 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -3021,8 +3021,14 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_Both) &&
(Left.is(TT_AttributeParen) || Left.canBePointerOrReferenceQualifier()))
return true;
+ if (Left.Tok.isLiteral())
+ return true;
+ // for (auto a = 0, b = 0; const auto & c : {1, 2, 3})
+ if (Left.isTypeOrIdentifier() && Right.Next && Right.Next->Next &&
+ Right.Next->Next->is(TT_RangeBasedForLoopColon))
+ return getTokenPointerOrReferenceAlignment(Right) !=
+ FormatStyle::PAS_Left;
return (
- Left.Tok.isLiteral() ||
(!Left.isOneOf(TT_PointerOrReference, tok::l_paren) &&
(getTokenPointerOrReferenceAlignment(Right) != FormatStyle::PAS_Left ||
(Line.IsMultiVariableDeclStmt &&
@@ -3041,18 +3047,32 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_Both) &&
Right.canBePointerOrReferenceQualifier())
return true;
- return Right.Tok.isLiteral() || Right.is(TT_BlockComment) ||
- (Right.isOneOf(Keywords.kw_override, Keywords.kw_final) &&
- !Right.is(TT_StartOfName)) ||
- (Right.is(tok::l_brace) && Right.is(BK_Block)) ||
- (!Right.isOneOf(TT_PointerOrReference, TT_ArraySubscriptLSquare,
- tok::l_paren) &&
- (getTokenPointerOrReferenceAlignment(Left) !=
- FormatStyle::PAS_Right &&
- !Line.IsMultiVariableDeclStmt) &&
- Left.Previous &&
- !Left.Previous->isOneOf(tok::l_paren, tok::coloncolon,
- tok::l_square));
+ // & 1
+ if (Right.Tok.isLiteral())
+ return true;
+ // & /* comment
+ if (Right.is(TT_BlockComment))
+ return true;
+ // foo() -> const Bar * override/final
+ if (Right.isOneOf(Keywords.kw_override, Keywords.kw_final) &&
+ !Right.is(TT_StartOfName))
+ return true;
+ // & {
+ 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() && Right.Next &&
+ Right.Next->is(TT_RangeBasedForLoopColon))
+ return getTokenPointerOrReferenceAlignment(Left) !=
+ FormatStyle::PAS_Right;
+ return !Right.isOneOf(TT_PointerOrReference, TT_ArraySubscriptLSquare,
+ tok::l_paren) &&
+ (getTokenPointerOrReferenceAlignment(Left) !=
+ FormatStyle::PAS_Right &&
+ !Line.IsMultiVariableDeclStmt) &&
+ Left.Previous &&
+ !Left.Previous->isOneOf(tok::l_paren, tok::coloncolon,
+ tok::l_square);
}
// Ensure right pointer alignment with ellipsis e.g. int *...P
if (Left.is(tok::ellipsis) && Left.Previous &&
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index cbd051f3a5e89..271acf97c3f1e 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -1924,6 +1924,22 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) {
verifyFormat("int *a = f1();", Style);
verifyFormat("int &b = f2();", Style);
verifyFormat("int &&c = f3();", Style);
+ verifyFormat("for (auto a = 0, b = 0; const auto &c : {1, 2, 3})", Style);
+ verifyFormat("for (auto a = 0, b = 0; const int &c : {1, 2, 3})", Style);
+ verifyFormat("for (auto a = 0, b = 0; const Foo &c : {1, 2, 3})", Style);
+ verifyFormat("for (auto a = 0, b = 0; const Foo *c : {1, 2, 3})", Style);
+ verifyFormat("for (int a = 0, b = 0; const auto &c : {1, 2, 3})", Style);
+ verifyFormat("for (int a = 0, b = 0; const int &c : {1, 2, 3})", Style);
+ verifyFormat("for (int a = 0, b = 0; const Foo &c : {1, 2, 3})", Style);
+ verifyFormat("for (int a = 0, b++; const auto &c : {1, 2, 3})", Style);
+ verifyFormat("for (int a = 0, b++; const int &c : {1, 2, 3})", Style);
+ verifyFormat("for (int a = 0, b++; const Foo &c : {1, 2, 3})", Style);
+ verifyFormat("for (auto x = 0; auto &c : {1, 2, 3})", Style);
+ verifyFormat("for (auto x = 0; int &c : {1, 2, 3})", Style);
+ verifyFormat("for (int x = 0; auto &c : {1, 2, 3})", Style);
+ verifyFormat("for (int x = 0; int &c : {1, 2, 3})", Style);
+ verifyFormat("for (f(); auto &c : {1, 2, 3})", Style);
+ verifyFormat("for (f(); int &c : {1, 2, 3})", Style);
Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
verifyFormat("Const unsigned int *c;\n"
@@ -1943,6 +1959,24 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) {
verifyFormat("int* a = f1();", Style);
verifyFormat("int& b = f2();", Style);
verifyFormat("int&& c = f3();", Style);
+ verifyFormat("for (auto a = 0, b = 0; const auto& c : {1, 2, 3})", Style);
+ verifyFormat("for (auto a = 0, b = 0; const int& c : {1, 2, 3})", Style);
+ verifyFormat("for (auto a = 0, b = 0; const Foo& c : {1, 2, 3})", Style);
+ verifyFormat("for (auto a = 0, b = 0; const Foo* c : {1, 2, 3})", Style);
+ verifyFormat("for (int a = 0, b = 0; const auto& c : {1, 2, 3})", Style);
+ verifyFormat("for (int a = 0, b = 0; const int& c : {1, 2, 3})", Style);
+ verifyFormat("for (int a = 0, b = 0; const Foo& c : {1, 2, 3})", Style);
+ verifyFormat("for (int a = 0, b = 0; const Foo* c : {1, 2, 3})", Style);
+ verifyFormat("for (int a = 0, b++; const auto& c : {1, 2, 3})", Style);
+ verifyFormat("for (int a = 0, b++; const int& c : {1, 2, 3})", Style);
+ verifyFormat("for (int a = 0, b++; const Foo& c : {1, 2, 3})", Style);
+ verifyFormat("for (int a = 0, b++; const Foo* c : {1, 2, 3})", Style);
+ verifyFormat("for (auto x = 0; auto& c : {1, 2, 3})", Style);
+ verifyFormat("for (auto x = 0; int& c : {1, 2, 3})", Style);
+ verifyFormat("for (int x = 0; auto& c : {1, 2, 3})", Style);
+ verifyFormat("for (int x = 0; int& c : {1, 2, 3})", Style);
+ verifyFormat("for (f(); auto& c : {1, 2, 3})", Style);
+ verifyFormat("for (f(); int& c : {1, 2, 3})", Style);
Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
verifyFormat("Const unsigned int* c;\n"
@@ -1961,6 +1995,9 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) {
verifyFormat("int *a = f1();", Style);
verifyFormat("int& b = f2();", Style);
verifyFormat("int&& c = f3();", Style);
+ verifyFormat("for (auto a = 0, b = 0; const Foo *c : {1, 2, 3})", Style);
+ verifyFormat("for (int a = 0, b = 0; const Foo *c : {1, 2, 3})", Style);
+ verifyFormat("for (int a = 0, b++; const Foo *c : {1, 2, 3})", Style);
Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
verifyFormat("Const unsigned int *c;\n"
@@ -1979,6 +2016,20 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) {
verifyFormat("int* a = f1();", Style);
verifyFormat("int & b = f2();", Style);
verifyFormat("int && c = f3();", Style);
+ verifyFormat("for (auto a = 0, b = 0; const auto & c : {1, 2, 3})", Style);
+ verifyFormat("for (auto a = 0, b = 0; const int & c : {1, 2, 3})", Style);
+ verifyFormat("for (auto a = 0, b = 0; const Foo & c : {1, 2, 3})", Style);
+ verifyFormat("for (auto a = 0, b = 0; const Foo* c : {1, 2, 3})", Style);
+ verifyFormat("for (int a = 0, b++; const auto & c : {1, 2, 3})", Style);
+ verifyFormat("for (int a = 0, b++; const int & c : {1, 2, 3})", Style);
+ verifyFormat("for (int a = 0, b++; const Foo & c : {1, 2, 3})", Style);
+ verifyFormat("for (int a = 0, b++; const Foo* c : {1, 2, 3})", Style);
+ verifyFormat("for (auto x = 0; auto & c : {1, 2, 3})", Style);
+ verifyFormat("for (auto x = 0; int & c : {1, 2, 3})", Style);
+ verifyFormat("for (int x = 0; auto & c : {1, 2, 3})", Style);
+ verifyFormat("for (int x = 0; int & c : {1, 2, 3})", Style);
+ verifyFormat("for (f(); auto & c : {1, 2, 3})", Style);
+ verifyFormat("for (f(); int & c : {1, 2, 3})", Style);
Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
verifyFormat("Const unsigned int* c;\n"
@@ -1997,6 +2048,9 @@ TEST_F(FormatTest, SeparatePointerReferenceAlignment) {
verifyFormat("int * a = f1();", Style);
verifyFormat("int &b = f2();", Style);
verifyFormat("int &&c = f3();", Style);
+ verifyFormat("for (auto a = 0, b = 0; const Foo * c : {1, 2, 3})", Style);
+ verifyFormat("for (int a = 0, b = 0; const Foo * c : {1, 2, 3})", Style);
+ verifyFormat("for (int a = 0, b++; const Foo * c : {1, 2, 3})", Style);
// FIXME: we don't handle this yet, so output may be arbitrary until it's
// specifically handled
More information about the cfe-commits
mailing list