[clang] dab5e10 - [clang-format] fix nested angle brackets parse inside concept definition
Marek Kurdej via cfe-commits
cfe-commits at lists.llvm.org
Wed May 11 05:02:59 PDT 2022
Author: Sergey Semushin
Date: 2022-05-11T14:02:51+02:00
New Revision: dab5e10ea5dbc2e6314e0e7ce54a9c51fbcb44bd
URL: https://github.com/llvm/llvm-project/commit/dab5e10ea5dbc2e6314e0e7ce54a9c51fbcb44bd
DIFF: https://github.com/llvm/llvm-project/commit/dab5e10ea5dbc2e6314e0e7ce54a9c51fbcb44bd.diff
LOG: [clang-format] fix nested angle brackets parse inside concept definition
Due to how parseBracedList always stopped on the first closing angle
bracket and was used in parsing angle bracketed expression inside concept
definition, nested brackets inside concepts were parsed incorrectly.
nextToken() call before calling parseBracedList is required because
we were processing opening angle bracket inside parseBracedList second
time leading to incorrect logic after my fix.
Fixes https://github.com/llvm/llvm-project/issues/54943
Fixes https://github.com/llvm/llvm-project/issues/54837
Reviewed By: HazardyKnusperkeks, curdeius
Differential Revision: https://reviews.llvm.org/D123896
Added:
Modified:
clang/lib/Format/UnwrappedLineParser.cpp
clang/unittests/Format/FormatTest.cpp
clang/unittests/Format/TokenAnnotatorTest.cpp
Removed:
################################################################################
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index f13e3d725cbd3..f90e8fcb834c7 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -2180,7 +2180,8 @@ bool UnwrappedLineParser::parseBracedList(bool ContinueOnSemicolons,
parseBracedList();
break;
case tok::less:
- if (Style.Language == FormatStyle::LK_Proto) {
+ if (Style.Language == FormatStyle::LK_Proto ||
+ ClosingBraceKind == tok::greater) {
nextToken();
parseBracedList(/*ContinueOnSemicolons=*/false, /*IsEnum=*/false,
/*ClosingBraceKind=*/tok::greater);
@@ -3220,6 +3221,7 @@ void UnwrappedLineParser::parseConstraintExpression() {
if (!FormatTok->is(tok::less))
return;
+ nextToken();
parseBracedList(/*ContinueOnSemicolons=*/false, /*IsEnum=*/false,
/*ClosingBraceKind=*/tok::greater);
break;
@@ -3260,9 +3262,11 @@ void UnwrappedLineParser::parseConstraintExpression() {
// Read identifier with optional template declaration.
nextToken();
- if (FormatTok->is(tok::less))
+ if (FormatTok->is(tok::less)) {
+ nextToken();
parseBracedList(/*ContinueOnSemicolons=*/false, /*IsEnum=*/false,
/*ClosingBraceKind=*/tok::greater);
+ }
break;
}
} while (!eof());
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 78f7eee809c4d..8f9c7215d6193 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -24114,6 +24114,12 @@ TEST_F(FormatTest, Concepts) {
verifyFormat("template <class T, class T2>\n"
"concept Same = __is_same_as<T, T2>;");
+ verifyFormat(
+ "template <class _InIt, class _OutIt>\n"
+ "concept _Can_reread_dest =\n"
+ " std::forward_iterator<_OutIt> &&\n"
+ " std::same_as<std::iter_value_t<_InIt>, std::iter_value_t<_OutIt>>;");
+
auto Style = getLLVMStyle();
Style.BreakBeforeConceptDeclarations = FormatStyle::BBCDS_Allowed;
diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp
index 3d2c3a498c724..138cab9b6b257 100644
--- a/clang/unittests/Format/TokenAnnotatorTest.cpp
+++ b/clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -390,6 +390,18 @@ TEST_F(TokenAnnotatorTest, UnderstandsRequiresClausesAndConcepts) {
EXPECT_TOKEN(Tokens[21], tok::r_brace, TT_Unknown);
EXPECT_EQ(Tokens[21]->MatchingParen, Tokens[15]);
EXPECT_TRUE(Tokens[21]->ClosesRequiresClause);
+
+ Tokens =
+ annotate("template <class A, class B> concept C ="
+ "std::same_as<std::iter_value_t<A>, std::iter_value_t<B>>;");
+ ASSERT_EQ(Tokens.size(), 31u) << Tokens;
+ EXPECT_TOKEN(Tokens[8], tok::kw_concept, TT_Unknown);
+ EXPECT_TOKEN(Tokens[14], tok::less, TT_TemplateOpener);
+ EXPECT_TOKEN(Tokens[18], tok::less, TT_TemplateOpener);
+ EXPECT_TOKEN(Tokens[20], tok::greater, TT_TemplateCloser);
+ EXPECT_TOKEN(Tokens[25], tok::less, TT_TemplateOpener);
+ EXPECT_TOKEN(Tokens[27], tok::greater, TT_TemplateCloser);
+ EXPECT_TOKEN(Tokens[28], tok::greater, TT_TemplateCloser);
}
TEST_F(TokenAnnotatorTest, UnderstandsRequiresExpressions) {
More information about the cfe-commits
mailing list