Author: owenca Date: 2025-11-02T22:35:50-08:00 New Revision: 3c0d4aa60156b05c5ca71a78b5f384820814f604
URL: https://github.com/llvm/llvm-project/commit/3c0d4aa60156b05c5ca71a78b5f384820814f604 DIFF: https://github.com/llvm/llvm-project/commit/3c0d4aa60156b05c5ca71a78b5f384820814f604.diff LOG: [clang-format] Handle static_assert more accurately (#166042) Used test cases from #165631. Added: Modified: clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/TokenAnnotatorTest.cpp Removed: ################################################################################ diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 8e227da2a79ab..cb41756c56bf7 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -358,11 +358,11 @@ class AnnotatingParser { Contexts.back().IsExpression = false; } else if (OpeningParen.Previous && (OpeningParen.Previous->isOneOf( - tok::kw_static_assert, tok::kw_noexcept, tok::kw_explicit, - tok::kw_while, tok::l_paren, tok::comma, TT_CastRParen, + tok::kw_noexcept, tok::kw_explicit, tok::kw_while, + tok::l_paren, tok::comma, TT_CastRParen, TT_BinaryOperator) || OpeningParen.Previous->isIf())) { - // static_assert, if and while usually contain expressions. + // if and while usually contain expressions. Contexts.back().IsExpression = true; } else if (Style.isJavaScript() && OpeningParen.Previous && (OpeningParen.Previous->is(Keywords.kw_function) || @@ -454,6 +454,11 @@ class AnnotatingParser { if (StartsObjCSelector) OpeningParen.setType(TT_ObjCSelector); + const bool IsStaticAssert = + PrevNonComment && PrevNonComment->is(tok::kw_static_assert); + if (IsStaticAssert) + Contexts.back().InStaticAssertFirstArgument = true; + // MightBeFunctionType and ProbablyFunctionType are used for // function pointer and reference types as well as Objective-C // block types: @@ -583,8 +588,12 @@ class AnnotatingParser { } // When we discover a 'new', we set CanBeExpression to 'false' in order to // parse the type correctly. Reset that after a comma. - if (CurrentToken->is(tok::comma)) - Contexts.back().CanBeExpression = true; + if (CurrentToken->is(tok::comma)) { + if (IsStaticAssert) + Contexts.back().InStaticAssertFirstArgument = false; + else + Contexts.back().CanBeExpression = true; + } if (Style.isTableGen()) { if (CurrentToken->is(tok::comma)) { @@ -2144,6 +2153,7 @@ class AnnotatingParser { bool CaretFound = false; bool InCpp11AttributeSpecifier = false; bool InCSharpAttributeSpecifier = false; + bool InStaticAssertFirstArgument = false; bool VerilogAssignmentFound = false; // Whether the braces may mean concatenation instead of structure or array // literal. @@ -2440,7 +2450,8 @@ class AnnotatingParser { } else if (Current.isPointerOrReference()) { Current.setType(determineStarAmpUsage( Current, - Contexts.back().CanBeExpression && Contexts.back().IsExpression, + (Contexts.back().CanBeExpression && Contexts.back().IsExpression) || + Contexts.back().InStaticAssertFirstArgument, Contexts.back().ContextType == Context::TemplateArgument)); } else if (Current.isOneOf(tok::minus, tok::plus, tok::caret) || (Style.isVerilog() && Current.is(tok::pipe))) { diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index 6c05feaeb13e0..815c79e68dac9 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -799,6 +799,30 @@ TEST_F(TokenAnnotatorTest, UnderstandsTemplateTemplateParameters) { EXPECT_TOKEN(Tokens[23], tok::identifier, TT_ClassHeadName); } +TEST_F(TokenAnnotatorTest, UnderstandsCommonCppTemplates) { + auto Tokens = + annotate("static_assert(std::conditional_t<A || B, C, D>::value);"); + ASSERT_EQ(Tokens.size(), 19u) << Tokens; + EXPECT_TOKEN(Tokens[5], tok::less, TT_TemplateOpener); + EXPECT_TOKEN(Tokens[13], tok::greater, TT_TemplateCloser); + + Tokens = + annotate("static_assert(std::conditional<A || B, C, D>::type::value);"); + ASSERT_EQ(Tokens.size(), 21u) << Tokens; + EXPECT_TOKEN(Tokens[5], tok::less, TT_TemplateOpener); + EXPECT_TOKEN(Tokens[13], tok::greater, TT_TemplateCloser); + + Tokens = annotate("static_assert(fancy_v<A || B>);"); + ASSERT_EQ(Tokens.size(), 11u) << Tokens; + EXPECT_TOKEN(Tokens[3], tok::less, TT_TemplateOpener); + EXPECT_TOKEN(Tokens[7], tok::greater, TT_TemplateCloser); + + Tokens = annotate("static_assert(fancy<A || B>::value);"); + ASSERT_EQ(Tokens.size(), 13u) << Tokens; + EXPECT_TOKEN(Tokens[3], tok::less, TT_TemplateOpener); + EXPECT_TOKEN(Tokens[7], tok::greater, TT_TemplateCloser); +} + TEST_F(TokenAnnotatorTest, UnderstandsWhitespaceSensitiveMacros) { FormatStyle Style = getLLVMStyle(); Style.WhitespaceSensitiveMacros.push_back("FOO"); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
