This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG82a90caa88fd: [clang-format] Correctly format goto labels
followed by blocks (authored by sstwcw).
Changed prior to commit:
https://reviews.llvm.org/D148484?vs=514249&id=518363#toc
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D148484/new/
https://reviews.llvm.org/D148484
Files:
clang/lib/Format/FormatToken.h
clang/lib/Format/TokenAnnotator.cpp
clang/lib/Format/UnwrappedLineParser.cpp
clang/unittests/Format/FormatTest.cpp
clang/unittests/Format/TokenAnnotatorTest.cpp
Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===================================================================
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -1621,7 +1621,7 @@
" 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 @@
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 @@
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
Index: clang/unittests/Format/FormatTest.cpp
===================================================================
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -2998,6 +2998,17 @@
"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_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 @@
"}\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);
Index: clang/lib/Format/UnwrappedLineParser.cpp
===================================================================
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1493,6 +1493,7 @@
}
nextToken();
if (FormatTok->is(tok::colon)) {
+ FormatTok->setFinalizedType(TT_CaseLabelColon);
parseLabel();
return;
}
@@ -1925,6 +1926,7 @@
if (!Style.isVerilog() && FormatTok->is(tok::colon) &&
!Line->MustBeDeclaration) {
Line->Tokens.begin()->Tok->MustBreakBefore = true;
+ FormatTok->setFinalizedType(TT_GotoLabelColon);
parseLabel(!Style.IndentGotoLabels);
if (HasLabel)
*HasLabel = true;
@@ -3113,7 +3115,11 @@
// FIXME: fix handling of complex expressions here.
do {
nextToken();
- } while (!eof() && !FormatTok->is(tok::colon));
+ if (FormatTok->is(tok::colon)) {
+ FormatTok->setFinalizedType(TT_CaseLabelColon);
+ break;
+ }
+ } while (!eof());
parseLabel();
}
Index: clang/lib/Format/TokenAnnotator.cpp
===================================================================
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -970,6 +970,10 @@
case tok::colon:
if (!Tok->Previous)
return false;
+ // Goto labels and case labels are already identified in
+ // UnwrappedLineParser.
+ if (Tok->isTypeFinalized())
+ break;
// Colons from ?: are handled in parseConditional().
if (Style.isJavaScript()) {
if (Contexts.back().ColonIsForRangeExpr || // colon in for loop
@@ -1008,7 +1012,7 @@
// In Verilog a case label doesn't have the case keyword. We
// assume a colon following an expression is a case label.
// Colons from ?: are annotated in parseConditional().
- Tok->setType(TT_GotoLabelColon);
+ Tok->setType(TT_CaseLabelColon);
if (Line.Level > 1 || (!Line.InPPDirective && Line.Level > 0))
--Line.Level;
}
@@ -4541,13 +4545,12 @@
Style.BitFieldColonSpacing == FormatStyle::BFCS_After;
}
if (Right.is(tok::colon)) {
- if (Right.is(TT_GotoLabelColon) ||
- (!Style.isVerilog() &&
- Line.First->isOneOf(tok::kw_default, tok::kw_case))) {
+ if (Right.is(TT_CaseLabelColon))
return Style.SpaceBeforeCaseColon;
- }
- const FormatToken *Next = Right.getNextNonComment();
- if (!Next || Next->is(tok::semi))
+ if (Right.is(TT_GotoLabelColon))
+ return false;
+ // `private:` and `public:`.
+ if (!Right.getNextNonComment())
return false;
if (Right.is(TT_ObjCMethodExpr))
return false;
Index: clang/lib/Format/FormatToken.h
===================================================================
--- clang/lib/Format/FormatToken.h
+++ clang/lib/Format/FormatToken.h
@@ -37,6 +37,8 @@
TYPE(BitFieldColon) \
TYPE(BlockComment) \
TYPE(BracedListLBrace) \
+ /* The colon at the end of a case label. */ \
+ TYPE(CaseLabelColon) \
TYPE(CastRParen) \
TYPE(ClassLBrace) \
TYPE(CompoundRequirementLBrace) \
@@ -73,8 +75,7 @@
TYPE(FunctionTypeLParen) \
/* The colons as part of a C11 _Generic selection */ \
TYPE(GenericSelectionColon) \
- /* The colon at the end of a goto label or a case label. Currently only used \
- * for Verilog. */ \
+ /* The colon at the end of a goto label. */ \
TYPE(GotoLabelColon) \
TYPE(IfMacro) \
TYPE(ImplicitStringLiteral) \
@@ -1803,7 +1804,7 @@
bool isVerilogEndOfLabel(const FormatToken &Tok) const {
const FormatToken *Next = Tok.getNextNonComment();
// In Verilog the colon in a default label is optional.
- return Tok.is(TT_GotoLabelColon) ||
+ return Tok.is(TT_CaseLabelColon) ||
(Tok.is(tok::kw_default) &&
!(Next && Next->isOneOf(tok::colon, tok::semi, kw_clocking, kw_iff,
kw_input, kw_output, kw_sequence)));
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits