diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index ac62dab1b07cd..dea39174d01c5 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -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; } @@ -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); diff --git a/clang/unittests/Format/FormatTestVerilog.cpp b/clang/unittests/Format/FormatTestVerilog.cpp index 9b090aa74f714..945e06143ccc3 100644 --- a/clang/unittests/Format/FormatTestVerilog.cpp +++ b/clang/unittests/Format/FormatTestVerilog.cpp @@ -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) {