diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -321,6 +321,8 @@ } else if (isLambdaParameterList(&OpeningParen)) { // This is a parameter list of a lambda expression. Contexts.back().IsExpression = false; + } else if (OpeningParen.is(TT_RequiresExpressionLParen)) { + Contexts.back().IsExpression = false; } else if (Line.InPPDirective && (!OpeningParen.Previous || !OpeningParen.Previous->is(tok::identifier))) { diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -711,19 +711,50 @@ ASSERT_EQ(Tokens.size(), 15u) << Tokens; EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression); EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen); + EXPECT_TOKEN(Tokens[6], tok::star, TT_PointerOrReference); EXPECT_TOKEN(Tokens[10], tok::l_brace, TT_RequiresExpressionLBrace); Tokens = annotate("foo(requires(T const* volatile t) {});"); ASSERT_EQ(Tokens.size(), 15u) << Tokens; EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression); EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen); + EXPECT_TOKEN(Tokens[6], tok::star, TT_PointerOrReference); EXPECT_TOKEN(Tokens[10], tok::l_brace, TT_RequiresExpressionLBrace); + Tokens = annotate("foo(requires(T& t) {});"); + ASSERT_EQ(Tokens.size(), 13u) << Tokens; + EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression); + EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen); + EXPECT_TOKEN(Tokens[5], tok::amp, TT_PointerOrReference); + EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_RequiresExpressionLBrace); + + Tokens = annotate("foo(requires(T&& t) {});"); + ASSERT_EQ(Tokens.size(), 13u) << Tokens; + EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression); + EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen); + EXPECT_TOKEN(Tokens[5], tok::ampamp, TT_PointerOrReference); + EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_RequiresExpressionLBrace); + + Tokens = annotate("bool foo = requires(T& t) {};"); + ASSERT_EQ(Tokens.size(), 13u) << Tokens; + EXPECT_TOKEN(Tokens[3], tok::kw_requires, TT_RequiresExpression); + EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_RequiresExpressionLParen); + EXPECT_TOKEN(Tokens[6], tok::amp, TT_PointerOrReference); + EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_RequiresExpressionLBrace); + + Tokens = annotate("bool foo = requires(T&& t) {};"); + ASSERT_EQ(Tokens.size(), 13u) << Tokens; + EXPECT_TOKEN(Tokens[3], tok::kw_requires, TT_RequiresExpression); + EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_RequiresExpressionLParen); + EXPECT_TOKEN(Tokens[6], tok::ampamp, TT_PointerOrReference); + EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_RequiresExpressionLBrace); + Tokens = annotate("foo(requires(const typename Outer::Inner * const t) {});"); ASSERT_EQ(Tokens.size(), 21u) << Tokens; EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression); EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen); + EXPECT_TOKEN(Tokens[12], tok::star, TT_PointerOrReference); EXPECT_TOKEN(Tokens[16], tok::l_brace, TT_RequiresExpressionLBrace); Tokens = annotate("template \n"