rymiel created this revision. rymiel added reviewers: HazardyKnusperkeks, owenpan, MyDeveloperDay, curdeius. Herald added a project: All. rymiel requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
In the following construction: `template <typename T> requires Foo<T> || Bar<T> auto func() -> int;` The `->` of the trailing return type was actually considered as an operator as part of the binary operation in the requires clause, with the precedence level of `PrecedenceArrowAndPeriod`, leading to fake parens being inserted in strange locations, that would never be closed. Fixes one part of https://github.com/llvm/llvm-project/issues/56213 (the rest will probably be in a separate patch) Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D134049 Files: clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/TokenAnnotatorTest.cpp Index: clang/unittests/Format/TokenAnnotatorTest.cpp =================================================================== --- clang/unittests/Format/TokenAnnotatorTest.cpp +++ clang/unittests/Format/TokenAnnotatorTest.cpp @@ -440,6 +440,13 @@ ASSERT_EQ(Tokens.size(), 18u) << Tokens; EXPECT_TOKEN(Tokens[11], tok::kw_requires, TT_RequiresClause); + Tokens = annotate("template <typename T>\n" + "requires Bar<T> || Baz<T>\n" + "auto foo(T) -> int;"); + ASSERT_EQ(Tokens.size(), 24u) << Tokens; + EXPECT_EQ(Tokens[11]->FakeLParens.size(), 0u); + EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause); + Tokens = annotate("template <typename T>\n" "struct S {\n" " void foo() const requires Bar<T>;\n" Index: clang/lib/Format/TokenAnnotator.cpp =================================================================== --- clang/lib/Format/TokenAnnotator.cpp +++ clang/lib/Format/TokenAnnotator.cpp @@ -2611,8 +2611,10 @@ } if (Current->is(TT_BinaryOperator) || Current->is(tok::comma)) return Current->getPrecedence(); - if (Current->isOneOf(tok::period, tok::arrow)) + if (Current->isOneOf(tok::period, tok::arrow) && + !Current->is(TT_TrailingReturnArrow)) { return PrecedenceArrowAndPeriod; + } if ((Style.Language == FormatStyle::LK_Java || Style.isJavaScript()) && Current->isOneOf(Keywords.kw_extends, Keywords.kw_implements, Keywords.kw_throws)) {
Index: clang/unittests/Format/TokenAnnotatorTest.cpp =================================================================== --- clang/unittests/Format/TokenAnnotatorTest.cpp +++ clang/unittests/Format/TokenAnnotatorTest.cpp @@ -440,6 +440,13 @@ ASSERT_EQ(Tokens.size(), 18u) << Tokens; EXPECT_TOKEN(Tokens[11], tok::kw_requires, TT_RequiresClause); + Tokens = annotate("template <typename T>\n" + "requires Bar<T> || Baz<T>\n" + "auto foo(T) -> int;"); + ASSERT_EQ(Tokens.size(), 24u) << Tokens; + EXPECT_EQ(Tokens[11]->FakeLParens.size(), 0u); + EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause); + Tokens = annotate("template <typename T>\n" "struct S {\n" " void foo() const requires Bar<T>;\n" Index: clang/lib/Format/TokenAnnotator.cpp =================================================================== --- clang/lib/Format/TokenAnnotator.cpp +++ clang/lib/Format/TokenAnnotator.cpp @@ -2611,8 +2611,10 @@ } if (Current->is(TT_BinaryOperator) || Current->is(tok::comma)) return Current->getPrecedence(); - if (Current->isOneOf(tok::period, tok::arrow)) + if (Current->isOneOf(tok::period, tok::arrow) && + !Current->is(TT_TrailingReturnArrow)) { return PrecedenceArrowAndPeriod; + } if ((Style.Language == FormatStyle::LK_Java || Style.isJavaScript()) && Current->isOneOf(Keywords.kw_extends, Keywords.kw_implements, Keywords.kw_throws)) {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits