Skip to content

Commit ead9644

Browse files
committed
[clang-format] Annotate noexcept, explicit specifiers as containing expressions
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 #44543 Reviewed By: owenpan, MyDeveloperDay Differential Revision: https://reviews.llvm.org/D146284
1 parent 16b7cf2 commit ead9644

File tree

3 files changed

+19
-3
lines changed

3 files changed

+19
-3
lines changed

clang/lib/Format/TokenAnnotator.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -318,9 +318,10 @@ class AnnotatingParser {
318318
// export type X = (...);
319319
Contexts.back().IsExpression = false;
320320
} else if (OpeningParen.Previous &&
321-
(OpeningParen.Previous->isOneOf(tok::kw_static_assert,
322-
tok::kw_while, tok::l_paren,
323-
tok::comma, TT_BinaryOperator) ||
321+
(OpeningParen.Previous->isOneOf(
322+
tok::kw_static_assert, tok::kw_noexcept, tok::kw_explicit,
323+
tok::kw_while, tok::l_paren, tok::comma,
324+
TT_BinaryOperator) ||
324325
OpeningParen.Previous->isIf())) {
325326
// static_assert, if and while usually contain expressions.
326327
Contexts.back().IsExpression = true;

clang/unittests/Format/FormatTest.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11592,6 +11592,10 @@ TEST_F(FormatTest, UnderstandsRvalueReferences) {
1159211592
verifyFormat("template <bool B, bool C> class A {\n"
1159311593
" static_assert(B && C, \"Something is wrong\");\n"
1159411594
"};");
11595+
verifyFormat("template <typename T> void swap() noexcept(Bar<T> && Foo<T>);");
11596+
verifyFormat("template <typename T> struct S {\n"
11597+
" explicit(Bar<T> && Foo<T>) S(const S &);\n"
11598+
"};");
1159511599
verifyGoogleFormat("#define IF(a, b, c) if (a && (b == c))");
1159611600
verifyGoogleFormat("#define WHILE(a, b, c) while (a && (b == c))");
1159711601
verifyFormat("#define A(a, b) (a && b)");

clang/unittests/Format/TokenAnnotatorTest.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,17 @@ TEST_F(TokenAnnotatorTest, UnderstandsUsesOfStarAndAmp) {
242242
"}");
243243
ASSERT_EQ(Tokens.size(), 12u) << Tokens;
244244
EXPECT_TOKEN(Tokens[7], tok::amp, TT_BinaryOperator);
245+
246+
Tokens =
247+
annotate("template <typename T> void swap() noexcept(Bar<T> && Foo<T>);");
248+
ASSERT_EQ(Tokens.size(), 23u) << Tokens;
249+
EXPECT_TOKEN(Tokens[15], tok::ampamp, TT_BinaryOperator);
250+
251+
Tokens = annotate("template <typename T> struct S {\n"
252+
" explicit(Bar<T> && Foo<T>) S(const S &);\n"
253+
"};");
254+
ASSERT_EQ(Tokens.size(), 30u) << Tokens;
255+
EXPECT_TOKEN(Tokens[14], tok::ampamp, TT_BinaryOperator);
245256
}
246257

247258
TEST_F(TokenAnnotatorTest, UnderstandsUsesOfPlusAndMinus) {

0 commit comments

Comments
 (0)