summaryrefslogtreecommitdiff
path: root/clang/unittests
diff options
context:
space:
mode:
authorsstwcw <f0gukp2nk@protonmail.com>2023-04-30 22:22:31 +0000
committersstwcw <f0gukp2nk@protonmail.com>2023-04-30 22:25:48 +0000
commit82a90caa88fdc632ea2c8495ea3237065272a3a0 (patch)
treed36743a254f6286a1ee72838fc15db5bbad888e7 /clang/unittests
parent0a57d4d490a4090631e13bab17cee015fc91d4dd (diff)
downloadllvm-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.cpp41
-rw-r--r--clang/unittests/Format/TokenAnnotatorTest.cpp19
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