diff options
author | sstwcw <f0gukp2nk@protonmail.com> | 2023-04-30 22:22:31 +0000 |
---|---|---|
committer | sstwcw <f0gukp2nk@protonmail.com> | 2023-04-30 22:25:48 +0000 |
commit | 82a90caa88fdc632ea2c8495ea3237065272a3a0 (patch) | |
tree | d36743a254f6286a1ee72838fc15db5bbad888e7 /clang/unittests | |
parent | 0a57d4d490a4090631e13bab17cee015fc91d4dd (diff) | |
download | llvm-82a90caa88fdc632ea2c8495ea3237065272a3a0.tar.gz |
[clang-format] Correctly format goto labels followed by blocks
There doesn't seem to be an issue on GitHub. But previously, a space
would be inserted before the goto colon in the code below.
switch (x) {
case 0:
goto_0: {
action();
break;
}
}
Previously, the colon following a goto label would be annotated as
`TT_InheritanceColon`. A goto label followed by an opening brace
wasn't recognized. It is easy to add another line to have
`spaceRequiredBefore` function recognize the case, but I believed it
is more proper to avoid doing the same thing in `UnwrappedLineParser`
and `TokenAnnotator`. So now the label colons would be labeled in
`UnwrappedLineParser`, and `spaceRequiredBefore` would rely on that.
Previously we had the type `TT_GotoLabelColon` intended for both goto
labels and case labels. But since handling of goto labels and case
labels differ somewhat, I split it into separate types for goto and
case labels.
This patch doesn't change the behavior for case labels. I added the
lines annotating case labels because they would previously be
mistakenly annotated as `TT_InheritanceColon` just like goto labels.
And since I added the annotations, the checks for the `case` and
`default` keywords in `spaceRequiredBefore` are not necessary anymore.
Reviewed By: MyDeveloperDay
Differential Revision: https://reviews.llvm.org/D148484
Diffstat (limited to 'clang/unittests')
-rw-r--r-- | clang/unittests/Format/FormatTest.cpp | 41 | ||||
-rw-r--r-- | clang/unittests/Format/TokenAnnotatorTest.cpp | 19 |
2 files changed, 58 insertions, 2 deletions
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 5db947abff8c..099a5cb91364 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -2998,6 +2998,17 @@ TEST_F(FormatTest, FormatsLabels) { "test_label:;\n" " int i = 0;\n" "}"); + verifyFormat("{\n" + " some_code();\n" + "test_label: { some_other_code(); }\n" + "}"); + verifyFormat("{\n" + " some_code();\n" + "test_label: {\n" + " some_other_code();\n" + " some_other_code();\n" + "}\n" + "}"); FormatStyle Style = getLLVMStyle(); Style.IndentGotoLabels = false; verifyFormat("void f() {\n" @@ -3022,6 +3033,23 @@ TEST_F(FormatTest, FormatsLabels) { "test_label:;\n" " int i = 0;\n" "}"); + verifyFormat("{\n" + " some_code();\n" + "test_label: { some_other_code(); }\n" + "}", + Style); + // The opening brace may either be on the same unwrapped line as the colon or + // on a separate one. The formatter should recognize both. + Style = getLLVMStyle(); + Style.BreakBeforeBraces = FormatStyle::BraceBreakingStyle::BS_Allman; + verifyFormat("{\n" + " some_code();\n" + "test_label:\n" + "{\n" + " some_other_code();\n" + "}\n" + "}", + Style); } TEST_F(FormatTest, MultiLineControlStatements) { @@ -16962,6 +16990,19 @@ TEST_F(FormatTest, ConfigurableSpaceBeforeColon) { "}\n" "}", CaseStyle); + // Goto labels should not be affected. + verifyFormat("switch (x) {\n" + "goto_label:\n" + "default :\n" + "}", + CaseStyle); + verifyFormat("switch (x) {\n" + "goto_label: { break; }\n" + "default : {\n" + " break;\n" + "}\n" + "}", + CaseStyle); FormatStyle NoSpaceStyle = getLLVMStyle(); EXPECT_EQ(NoSpaceStyle.SpaceBeforeCaseColon, false); diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index cd39661f7f8d..62a83596600e 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -1621,7 +1621,7 @@ TEST_F(TokenAnnotatorTest, UnderstandsVerilogOperators) { " x;\n" "endcase\n"); ASSERT_EQ(Tokens.size(), 10u) << Tokens; - EXPECT_TOKEN(Tokens[5], tok::colon, TT_GotoLabelColon); + EXPECT_TOKEN(Tokens[5], tok::colon, TT_CaseLabelColon); Tokens = Annotate("case (x)\n" " x ? x : x:\n" " x;\n" @@ -1629,7 +1629,7 @@ TEST_F(TokenAnnotatorTest, UnderstandsVerilogOperators) { ASSERT_EQ(Tokens.size(), 14u) << Tokens; EXPECT_TOKEN(Tokens[5], tok::question, TT_ConditionalExpr); EXPECT_TOKEN(Tokens[7], tok::colon, TT_ConditionalExpr); - EXPECT_TOKEN(Tokens[9], tok::colon, TT_GotoLabelColon); + EXPECT_TOKEN(Tokens[9], tok::colon, TT_CaseLabelColon); // Non-blocking assignments. Tokens = Annotate("a <= b;"); ASSERT_EQ(Tokens.size(), 5u) << Tokens; @@ -1752,6 +1752,21 @@ TEST_F(TokenAnnotatorTest, CSharpNullableTypes) { EXPECT_TOKEN(Tokens[1], tok::question, TT_ConditionalExpr); } +TEST_F(TokenAnnotatorTest, UnderstandsLabels) { + auto Tokens = annotate("{ x: break; }"); + ASSERT_EQ(Tokens.size(), 7u) << Tokens; + EXPECT_TOKEN(Tokens[2], tok::colon, TT_GotoLabelColon); + Tokens = annotate("{ case x: break; }"); + ASSERT_EQ(Tokens.size(), 8u) << Tokens; + EXPECT_TOKEN(Tokens[3], tok::colon, TT_CaseLabelColon); + Tokens = annotate("{ x: { break; } }"); + ASSERT_EQ(Tokens.size(), 9u) << Tokens; + EXPECT_TOKEN(Tokens[2], tok::colon, TT_GotoLabelColon); + Tokens = annotate("{ case x: { break; } }"); + ASSERT_EQ(Tokens.size(), 10u) << Tokens; + EXPECT_TOKEN(Tokens[3], tok::colon, TT_CaseLabelColon); +} + } // namespace } // namespace format } // namespace clang |