From: sstwcw Date: Mon, 6 Feb 2023 00:57:03 +0000 (+0000) Subject: [clang-format] Recognize Verilog non-blocking assignment X-Git-Tag: upstream/17.0.6~18532 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cad708b9a1ecbf5645706056bb7c4fc0ea4721b6;p=platform%2Fupstream%2Fllvm.git [clang-format] Recognize Verilog non-blocking assignment Reviewed By: HazardyKnusperkeks, owenpan Differential Revision: https://reviews.llvm.org/D142891 --- diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 161720e..40e1951 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1647,6 +1647,7 @@ private: bool CaretFound = false; bool InCpp11AttributeSpecifier = false; bool InCSharpAttributeSpecifier = false; + bool VerilogAssignmentFound = false; enum { Unknown, // Like the part after `:` in a constructor. @@ -1944,6 +1945,17 @@ private: (!Current.Previous || Current.Previous->isNot(tok::l_square)) && (!Current.is(tok::greater) && Style.Language != FormatStyle::LK_TextProto)) { + if (Style.isVerilog()) { + if (Current.is(tok::lessequal) && Contexts.size() == 1 && + !Contexts.back().VerilogAssignmentFound) { + // In Verilog `<=` is assignment if in its own statement. It is a + // statement instead of an expression, that is it can not be chained. + Current.ForcedPrecedence = prec::Assignment; + Current.setFinalizedType(TT_BinaryOperator); + } + if (Current.getPrecedence() == prec::Assignment) + Contexts.back().VerilogAssignmentFound = true; + } Current.setType(TT_BinaryOperator); } else if (Current.is(tok::comment)) { if (Current.TokenText.startswith("/*")) { diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index 9951906..a687594 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -838,7 +838,12 @@ void WhitespaceManager::alignConsecutiveAssignments() { return Style.AlignConsecutiveAssignments.AlignCompound ? C.Tok->getPrecedence() == prec::Assignment - : C.Tok->is(tok::equal); + : (C.Tok->is(tok::equal) || + // In Verilog the '<=' is not a compound assignment, thus + // it is aligned even when the AlignCompound option is not + // set. + (Style.isVerilog() && C.Tok->is(tok::lessequal) && + C.Tok->getPrecedence() == prec::Assignment)); }, Changes, /*StartAt=*/0, Style.AlignConsecutiveAssignments, /*RightJustify=*/true); diff --git a/clang/unittests/Format/FormatTestVerilog.cpp b/clang/unittests/Format/FormatTestVerilog.cpp index 92931d3..7931a31 100644 --- a/clang/unittests/Format/FormatTestVerilog.cpp +++ b/clang/unittests/Format/FormatTestVerilog.cpp @@ -45,6 +45,58 @@ protected: } }; +TEST_F(FormatTestVerilog, Align) { + FormatStyle Style = getLLVMStyle(FormatStyle::LK_Verilog); + Style.AlignConsecutiveAssignments.Enabled = true; + verifyFormat("x <= x;\n" + "sfdbddfbdfbb <= x;\n" + "x = x;", + Style); + verifyFormat("x = x;\n" + "sfdbddfbdfbb = x;\n" + "x = x;", + Style); + // Compound assignments are not aligned by default. '<=' is not a compound + // assignment. + verifyFormat("x <= x;\n" + "sfdbddfbdfbb <= x;", + Style); + verifyFormat("x += x;\n" + "sfdbddfbdfbb <= x;", + Style); + verifyFormat("x <<= x;\n" + "sfdbddfbdfbb <= x;", + Style); + verifyFormat("x <<<= x;\n" + "sfdbddfbdfbb <= x;", + Style); + verifyFormat("x >>= x;\n" + "sfdbddfbdfbb <= x;", + Style); + verifyFormat("x >>>= x;\n" + "sfdbddfbdfbb <= x;", + Style); + Style.AlignConsecutiveAssignments.AlignCompound = true; + verifyFormat("x <= x;\n" + "sfdbddfbdfbb <= x;", + Style); + verifyFormat("x += x;\n" + "sfdbddfbdfbb <= x;", + Style); + verifyFormat("x <<= x;\n" + "sfdbddfbdfbb <= x;", + Style); + verifyFormat("x <<<= x;\n" + "sfdbddfbdfbb <= x;", + Style); + verifyFormat("x >>= x;\n" + "sfdbddfbdfbb <= x;", + Style); + verifyFormat("x >>>= x;\n" + "sfdbddfbdfbb <= x;", + Style); +} + TEST_F(FormatTestVerilog, BasedLiteral) { verifyFormat("x = '0;"); verifyFormat("x = '1;"); diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index b27bb69..87d86ec 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -1314,6 +1314,21 @@ TEST_F(TokenAnnotatorTest, UnderstandsVerilogOperators) { EXPECT_TOKEN(Tokens[5], tok::question, TT_ConditionalExpr); EXPECT_TOKEN(Tokens[7], tok::colon, TT_ConditionalExpr); EXPECT_TOKEN(Tokens[9], tok::colon, TT_GotoLabelColon); + // Non-blocking assignments. + Tokens = Annotate("a <= b;"); + ASSERT_EQ(Tokens.size(), 5u); + EXPECT_TOKEN(Tokens[1], tok::lessequal, TT_BinaryOperator); + EXPECT_TOKEN_PRECEDENCE(Tokens[1], prec::Assignment); + Tokens = Annotate("if (a <= b) break;"); + ASSERT_EQ(Tokens.size(), 9u); + EXPECT_TOKEN(Tokens[3], tok::lessequal, TT_BinaryOperator); + EXPECT_TOKEN_PRECEDENCE(Tokens[3], prec::Relational); + Tokens = Annotate("a <= b <= a;"); + ASSERT_EQ(Tokens.size(), 7u); + EXPECT_TOKEN(Tokens[1], tok::lessequal, TT_BinaryOperator); + EXPECT_TOKEN_PRECEDENCE(Tokens[1], prec::Assignment); + EXPECT_TOKEN(Tokens[3], tok::lessequal, TT_BinaryOperator); + EXPECT_TOKEN_PRECEDENCE(Tokens[3], prec::Relational); } TEST_F(TokenAnnotatorTest, UnderstandConstructors) {