[clang] [clang-format] Add per-operator granularity for BreakBinaryOperations (PR #181051)
Sergey Subbotin via cfe-commits
cfe-commits at lists.llvm.org
Sun Feb 15 14:23:06 PST 2026
================
@@ -144,14 +144,50 @@ static bool startsNextOperand(const FormatToken &Current) {
return isAlignableBinaryOperator(Previous) && !Current.isTrailingComment();
}
+// Returns the number of operators in the chain containing \c Op.
+static unsigned getChainLength(const FormatToken &Op) {
+ const FormatToken *Last = &Op;
+ while (Last->NextOperator)
+ Last = Last->NextOperator;
+ return Last->OperatorIndex + 1;
+}
+
// Returns \c true if \c Current is a binary operation that must break.
static bool mustBreakBinaryOperation(const FormatToken &Current,
const FormatStyle &Style) {
- return Style.BreakBinaryOperations != FormatStyle::BBO_Never &&
- Current.CanBreakBefore &&
- (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None
- ? startsNextOperand
- : isAlignableBinaryOperator)(Current);
+ if (!Current.CanBreakBefore)
+ return false;
+
+ // Determine the operator token: when breaking after the operator,
+ // it is Current.Previous; when breaking before, it is Current itself.
+ bool BreakBefore = Style.BreakBeforeBinaryOperators != FormatStyle::BOS_None;
+ const FormatToken *OpToken = BreakBefore ? &Current : Current.Previous;
+
+ if (!OpToken)
+ return false;
+
+ // Check that this is an alignable binary operator.
+ if (BreakBefore) {
+ if (!isAlignableBinaryOperator(Current))
+ return false;
+ } else {
+ if (!startsNextOperand(Current))
+ return false;
+ }
+
+ // Look up per-operator rule or fall back to Default.
+ auto EffStyle =
+ Style.BreakBinaryOperations.getStyleForOperator(OpToken->TokenText);
+ if (EffStyle == FormatStyle::BBO_Never)
+ return false;
+
+ // Check MinChainLength: if the chain is too short, don't force a break.
+ unsigned MinChain = Style.BreakBinaryOperations.getMinChainLengthForOperator(
+ OpToken->TokenText);
+ if (MinChain > 0 && getChainLength(*OpToken) < MinChain)
+ return false;
+
+ return true;
----------------
ssubbotin wrote:
Done in commit 258f4f3. Simplified to a single return expression. I used `>=` rather than `>` because in commit 84d65fb I changed `getChainLength` to count operands instead of operators (so `a && b && c` = chain length 3, which is more intuitive for users configuring `MinChainLength: 3`):
```cpp
return MinChain == 0 || getChainLength(*OpToken) >= MinChain;
```
https://github.com/llvm/llvm-project/pull/181051
More information about the cfe-commits
mailing list