The noexcept specifier and explicit specifier can optionally include a
boolean expression to make these specifiers apply conditionally,
however, clang-format didn't set the context for the parenthesized
content of these specifiers, meaning they inherited the parent context,
which usually isn't an expressions, leading to misannotated binary
operators.
This patch applies expression context to the content of these
specifiers, making them similar to the static_assert keyword.
Fixes https://github.com/llvm/llvm-project/issues/44543
Reviewed By: owenpan, MyDeveloperDay
Differential Revision: https://reviews.llvm.org/
D146284
// export type X = (...);
Contexts.back().IsExpression = false;
} else if (OpeningParen.Previous &&
- (OpeningParen.Previous->isOneOf(tok::kw_static_assert,
- tok::kw_while, tok::l_paren,
- tok::comma, TT_BinaryOperator) ||
+ (OpeningParen.Previous->isOneOf(
+ tok::kw_static_assert, tok::kw_noexcept, tok::kw_explicit,
+ tok::kw_while, tok::l_paren, tok::comma,
+ TT_BinaryOperator) ||
OpeningParen.Previous->isIf())) {
// static_assert, if and while usually contain expressions.
Contexts.back().IsExpression = true;
verifyFormat("template <bool B, bool C> class A {\n"
" static_assert(B && C, \"Something is wrong\");\n"
"};");
+ verifyFormat("template <typename T> void swap() noexcept(Bar<T> && Foo<T>);");
+ verifyFormat("template <typename T> struct S {\n"
+ " explicit(Bar<T> && Foo<T>) S(const S &);\n"
+ "};");
verifyGoogleFormat("#define IF(a, b, c) if (a && (b == c))");
verifyGoogleFormat("#define WHILE(a, b, c) while (a && (b == c))");
verifyFormat("#define A(a, b) (a && b)");
"}");
ASSERT_EQ(Tokens.size(), 12u) << Tokens;
EXPECT_TOKEN(Tokens[7], tok::amp, TT_BinaryOperator);
+
+ Tokens =
+ annotate("template <typename T> void swap() noexcept(Bar<T> && Foo<T>);");
+ ASSERT_EQ(Tokens.size(), 23u) << Tokens;
+ EXPECT_TOKEN(Tokens[15], tok::ampamp, TT_BinaryOperator);
+
+ Tokens = annotate("template <typename T> struct S {\n"
+ " explicit(Bar<T> && Foo<T>) S(const S &);\n"
+ "};");
+ ASSERT_EQ(Tokens.size(), 30u) << Tokens;
+ EXPECT_TOKEN(Tokens[14], tok::ampamp, TT_BinaryOperator);
}
TEST_F(TokenAnnotatorTest, UnderstandsUsesOfPlusAndMinus) {