Skip to content

[clang-format] Properly indent lines inside Verilog case structure #65861

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 16 additions & 6 deletions clang/lib/Format/ContinuationIndenter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1204,12 +1204,13 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) {
CurrentState.Indent + Style.ContinuationIndentWidth);
}

// After a goto label. Usually labels are on separate lines. However
// for Verilog the labels may be only recognized by the annotator and
// thus are on the same line as the current token.
if ((Style.isVerilog() && Keywords.isVerilogEndOfLabel(Previous)) ||
(Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths &&
State.Line->First->is(tok::kw_enum))) {
// Indentation of the statement following a Verilog case label is taken care
// of in moveStateToNextToken.
if (Style.isVerilog() && Keywords.isVerilogEndOfLabel(Previous))
return State.FirstIndent;

if (Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths &&
State.Line->First->is(tok::kw_enum)) {
return (Style.IndentWidth * State.Line->First->IndentLevel) +
Style.IndentWidth;
}
Expand Down Expand Up @@ -1599,6 +1600,15 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,

State.Column += Current.ColumnWidth;
State.NextToken = State.NextToken->Next;
// Verilog case labels are on the same unwrapped lines as the statements that
// follow. TokenAnnotator identifies them and sets MustBreakBefore.
// Indentation is taken care of here. A case label can only have 1 statement
// in Verilog, so we don't have to worry about lines that follow.
if (Style.isVerilog() && State.NextToken &&
State.NextToken->MustBreakBefore &&
Keywords.isVerilogEndOfLabel(Current)) {
State.FirstIndent += Style.IndentWidth;
}

unsigned Penalty =
handleEndOfLine(Current, State, DryRun, AllowBreak, Newline);
Expand Down
47 changes: 47 additions & 0 deletions clang/unittests/Format/FormatTestVerilog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,53 @@ TEST_F(FormatTestVerilog, Case) {
verifyFormat("default:\n"
" x = '{x: x, default: 9};\n",
Style);
// When the line following the case label needs to be broken, the continuation
// should be indented correctly.
verifyFormat("case (data)\n"
" 16'd0:\n"
" result = //\n"
" 10'b0111111111;\n"
"endcase");
verifyFormat("case (data)\n"
" 16'd0, //\n"
" 16'd1:\n"
" result = //\n"
" 10'b0111111111;\n"
"endcase");
verifyFormat("case (data)\n"
" 16'd0:\n"
" result = (10'b0111111111 + //\n"
" 10'b0111111111 + //\n"
" 10'b0111111111);\n"
"endcase");
verifyFormat("case (data)\n"
" 16'd0:\n"
" result = //\n"
" (10'b0111111111 + //\n"
" 10'b0111111111 + //\n"
" 10'b0111111111);\n"
"endcase");
verifyFormat("case (data)\n"
" 16'd0:\n"
" result = //\n"
" longfunction( //\n"
" arg);\n"
"endcase");
Style = getDefaultStyle();
Style.ContinuationIndentWidth = 1;
verifyFormat("case (data)\n"
" 16'd0:\n"
" result = //\n"
" 10'b0111111111;\n"
"endcase",
Style);
verifyFormat("case (data)\n"
" 16'd0:\n"
" result = //\n"
" longfunction( //\n"
" arg);\n"
"endcase",
Style);
}

TEST_F(FormatTestVerilog, Coverage) {
Expand Down