[clang] [clang-format] Add KwBreakBeforeCaseLabel (PR #227668)

Anan Yablonko via cfe-commits cfe-commits at lists.llvm.org
Fri Oct 2 03:29:33 PDT 2026


================
@@ -281,6 +281,14 @@ class LineJoiner {
         return MergedLines;
     }
 
+    // Handle case labels preceded by a break statement
+    if (Style.KwBreakBeforeCaseLabel &&
----------------
ananski-the-3rd wrote:

ContinuationIndenter::canBreak is not called by the test cases, becasue NoLineBreakFormatter is used.

Correct me if I'm wrong, but canBreak cares about the state of a single line. As such, to make use of it we must put the `break;` and the `case` on the same unwrapped line.

The UnwrappedLineParser separates those out because of the semi between them.
I did that work, and this is how it turned out:

UnwrappedLineParser::parseStructuralElement (around line 2265)
```diff
    case tok::greater:
      nextToken();
      if (FormatTok->is(tok::l_brace))
        FormatTok->Previous->setFinalizedType(TT_TemplateCloser);
      break;
+   case tok::kw_break:
+     if (Style.CompactCaseLabels && followedByCaseLabel()) {
+       addUnwrappedLine();  // add unwrapped line for both `break;` and `case`
+       nextToken();  // consume the `break`
+     }
+     nextToken();  // consume the `break` normally if option off, or the `;` with option on
+     break;
    default:
      nextToken();
      break;
    }
  }
}
```
This kinda works, but will cause at least two issues I found:
Firstly, it disturbs code that relies on `Line->First` being a case/default, causing test to fail with:
```
@@ -4,6 +4,4 @@
   return false;
 }
-break; default: {
-  return true;
-}
+break; default : { return true; }
 }
```
So it seems to disturb LineJoiner code and parser/WhitespaceManager code. I did not dive into these yet.

Secondly, we would need to implement followedByCaseLabel in a way that is aware of the level, so that we don't get "fooled" by:
```cpp
  break; case 1:
    while (x)
      break;
  case 2:
```

Is this the direction we should take despite these issues?
Perhaps there's something I've missed that allows to make use of the canBreak without disturbing existing code?

On the other hand, I found using the line joiner rather intuitive, since that is what I picture the option is doing conceptually.

https://github.com/llvm/llvm-project/pull/227668


More information about the cfe-commits mailing list