Skip to content

Conversation

@sstwcw
Copy link
Contributor

@sstwcw sstwcw commented Nov 13, 2025

before, with the options AlignConsecutiveDeclarations and AlignConsecutiveAssignments enabled

veryverylongvariablename = somethingelse;
shortervariablename      = anotherverylonglonglongvariablename + //
                      somevariablethatwastoolongtofitonthesamerow;

double i234 = 0;
auto   v    = false ? type{}
                    : type{
                     1,
                 };

after

veryverylongvariablename = somethingelse;
shortervariablename      = anotherverylonglonglongvariablename + //
                           somevariablethatwastoolongtofitonthesamerow;

double i234 = 0;
auto   v    = false ? type{}
                    : type{
                          1,
                      };

Fixes #126873.

Fixes #57612.

Previously, the part for determining whether aligning a line should move the next line relied on having a pair of tokens such as parentheses surrounding both lines. There are often no such tokens. For example in the first block above. This patch removes the requirement for those tokens.

Now the program keeps track of how the position is calculated. The alignment step moves the next line if its position is based on a column to the right of the token that gets aligned.

The column that the position of the line is based on is more detailed than the IsAligned property that the program used before this patch. It enables the program to handle cases where parts that should not usually move with the previous line and parts that should are nested like in the second block above. That is why the patch uses it instead of fake parentheses.

before, with the options `AlignConsecutiveDeclarations` and
`AlignConsecutiveAssignments` enabled

```C++
veryverylongvariablename = somethingelse;
shortervariablename      = anotherverylonglonglongvariablename + //
                      somevariablethatwastoolongtofitonthesamerow;

double i234 = 0;
auto   v    = false ? type{}
                    : type{
                     1,
                 };
```

after

```C++
veryverylongvariablename = somethingelse;
shortervariablename      = anotherverylonglonglongvariablename + //
                           somevariablethatwastoolongtofitonthesamerow;

double i234 = 0;
auto   v    = false ? type{}
                    : type{
                          1,
                      };
```

Fixes llvm#126873.

Fixes llvm#57612.

Previously, the part for determining whether aligning a line should move
the next line relied on having a pair of tokens such as parentheses
surrounding both lines.  There are often no such tokens.  For example in
the first block above.  This patch removes the requirement for those
tokens.

Now the program keeps track of how the position is calculated.  The
alignment step moves the next line if its position is based on a column
to the right of the token that gets aligned.

The column that the position of the line is based on is more detailed
than the `IsAligned` property that the program used before this patch.
It enables the program to handle cases where parts that should not
usually move with the previous line and parts that should are nested
like in the second block above.  That is why the patch uses it instead
of fake parentheses.
@llvmbot
Copy link
Member

llvmbot commented Nov 13, 2025

@llvm/pr-subscribers-clang-format

Author: None (sstwcw)

Changes

before, with the options AlignConsecutiveDeclarations and AlignConsecutiveAssignments enabled

veryverylongvariablename = somethingelse;
shortervariablename      = anotherverylonglonglongvariablename + //
                      somevariablethatwastoolongtofitonthesamerow;

double i234 = 0;
auto   v    = false ? type{}
                    : type{
                     1,
                 };

after

veryverylongvariablename = somethingelse;
shortervariablename      = anotherverylonglonglongvariablename + //
                           somevariablethatwastoolongtofitonthesamerow;

double i234 = 0;
auto   v    = false ? type{}
                    : type{
                          1,
                      };

Fixes #126873.

Fixes #57612.

Previously, the part for determining whether aligning a line should move the next line relied on having a pair of tokens such as parentheses surrounding both lines. There are often no such tokens. For example in the first block above. This patch removes the requirement for those tokens.

Now the program keeps track of how the position is calculated. The alignment step moves the next line if its position is based on a column to the right of the token that gets aligned.

The column that the position of the line is based on is more detailed than the IsAligned property that the program used before this patch. It enables the program to handle cases where parts that should not usually move with the previous line and parts that should are nested like in the second block above. That is why the patch uses it instead of fake parentheses.


Patch is 34.54 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/167979.diff

7 Files Affected:

  • (modified) clang/lib/Format/ContinuationIndenter.cpp (+84-35)
  • (modified) clang/lib/Format/ContinuationIndenter.h (+43-8)
  • (modified) clang/lib/Format/UnwrappedLineFormatter.cpp (+3-3)
  • (modified) clang/lib/Format/WhitespaceManager.cpp (+24-19)
  • (modified) clang/lib/Format/WhitespaceManager.h (+19-6)
  • (modified) clang/unittests/Format/FormatTest.cpp (+59)
  • (modified) clang/unittests/Format/FormatTestObjC.cpp (+26)
diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp
index 9ab024a03fbd7..54f231f2d7488 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -240,6 +240,45 @@ RawStringFormatStyleManager::getEnclosingFunctionStyle(
   return It->second;
 }
 
+IndentationAndAlignment
+IndentationAndAlignment::addPadding(unsigned Spaces) const {
+  return IndentationAndAlignment(Total + Spaces, IndentedFrom);
+}
+
+IndentationAndAlignment
+IndentationAndAlignment::operator+(unsigned Spaces) const {
+  return IndentationAndAlignment(Total + Spaces, Total);
+}
+
+IndentationAndAlignment
+IndentationAndAlignment::operator-(unsigned Spaces) const {
+  return IndentationAndAlignment(Total - Spaces, Total);
+}
+
+IndentationAndAlignment &IndentationAndAlignment::operator+=(unsigned Spaces) {
+  *this = *this + Spaces;
+  return *this;
+}
+
+IndentationAndAlignment::IndentationAndAlignment(unsigned Total,
+                                                 unsigned IndentedFrom)
+    : Total(Total), IndentedFrom(IndentedFrom) {}
+
+IndentationAndAlignment::IndentationAndAlignment(unsigned Spaces)
+    : Total(Spaces), IndentedFrom(Spaces) {}
+
+bool IndentationAndAlignment::operator<(
+    const IndentationAndAlignment &Other) const {
+  if (Total != Other.Total)
+    return Total < Other.Total;
+  // The sign to use here was decided arbitrarily. This operator is mostly used
+  // when a line's indentation should be the max of 2 things. Using this sign
+  // here makes the program prefer alignment over continuation indentation. That
+  // is, it makes the alignment step that follows prefer to move the line when
+  // aligning the previous line.
+  return IndentedFrom > Other.IndentedFrom;
+}
+
 ContinuationIndenter::ContinuationIndenter(const FormatStyle &Style,
                                            const AdditionalKeywords &Keywords,
                                            const SourceManager &SourceMgr,
@@ -491,7 +530,7 @@ bool ContinuationIndenter::mustBreak(const LineState &State) {
     return true;
   }
 
-  unsigned NewLineColumn = getNewLineColumn(State);
+  unsigned NewLineColumn = getNewLineColumn(State).Total;
   if (Current.isMemberAccess() && Style.ColumnLimit != 0 &&
       State.Column + getLengthToNextOperator(Current) > Style.ColumnLimit &&
       (State.Column > NewLineColumn ||
@@ -819,8 +858,9 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
   }
 
   if (Current.is(TT_SelectorName) && !CurrentState.ObjCSelectorNameFound) {
-    unsigned MinIndent = std::max(
-        State.FirstIndent + Style.ContinuationIndentWidth, CurrentState.Indent);
+    unsigned MinIndent =
+        std::max(State.FirstIndent + Style.ContinuationIndentWidth,
+                 CurrentState.Indent.Total);
     unsigned FirstColonPos = State.Column + Spaces + Current.ColumnWidth;
     if (Current.LongestObjCSelectorName == 0)
       CurrentState.AlignColons = false;
@@ -910,7 +950,8 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
     return !Next || Next->isMemberAccess() ||
            Next->is(TT_FunctionDeclarationLParen) || IsFunctionCallParen(*Next);
   };
-  if (IsOpeningBracket(Previous) && State.Column > getNewLineColumn(State) &&
+  if (IsOpeningBracket(Previous) &&
+      State.Column > getNewLineColumn(State).Total &&
       // Don't do this for simple (no expressions) one-argument function calls
       // as that feels like needlessly wasting whitespace, e.g.:
       //
@@ -955,7 +996,7 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
     CurrentState.NoLineBreak = true;
 
   if (startsSegmentOfBuilderTypeCall(Current) &&
-      State.Column > getNewLineColumn(State)) {
+      State.Column > getNewLineColumn(State).Total) {
     CurrentState.ContainsUnwrappedBuilder = true;
   }
 
@@ -1086,7 +1127,8 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
     Penalty += Style.PenaltyBreakFirstLessLess;
   }
 
-  State.Column = getNewLineColumn(State);
+  const auto [TotalColumn, IndentedFromColumn] = getNewLineColumn(State);
+  State.Column = TotalColumn;
 
   // Add Penalty proportional to amount of whitespace away from FirstColumn
   // This tends to penalize several lines that are far-right indented,
@@ -1132,9 +1174,9 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
       } else {
         CurrentState.ColonPos =
             (shouldIndentWrappedSelectorName(Style, State.Line->Type)
-                 ? std::max(CurrentState.Indent,
+                 ? std::max(CurrentState.Indent.Total,
                             State.FirstIndent + Style.ContinuationIndentWidth)
-                 : CurrentState.Indent) +
+                 : CurrentState.Indent.Total) +
             std::max(NextNonComment->LongestObjCSelectorName,
                      NextNonComment->ColumnWidth);
       }
@@ -1155,7 +1197,7 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
     // when we consume all of the "}"'s FakeRParens at the "{".
     if (State.Stack.size() > 1) {
       State.Stack[State.Stack.size() - 2].LastSpace =
-          std::max(CurrentState.LastSpace, CurrentState.Indent) +
+          std::max(CurrentState.LastSpace, CurrentState.Indent.Total) +
           Style.ContinuationIndentWidth;
     }
   }
@@ -1196,7 +1238,8 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
                                      State.Line->Type != LT_ImportStatement &&
                                      Current.isNot(TT_LineComment);
     Whitespaces.replaceWhitespace(Current, Newlines, State.Column, State.Column,
-                                  CurrentState.IsAligned, ContinuePPDirective);
+                                  CurrentState.IsAligned, ContinuePPDirective,
+                                  IndentedFromColumn);
   }
 
   if (!Current.isTrailingComment())
@@ -1340,7 +1383,8 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
   return Penalty;
 }
 
-unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) {
+IndentationAndAlignment
+ContinuationIndenter::getNewLineColumn(const LineState &State) {
   if (!State.NextToken || !State.NextToken->Previous)
     return 0;
 
@@ -1354,8 +1398,9 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) {
 
   const FormatToken &Previous = *Current.Previous;
   // If we are continuing an expression, we want to use the continuation indent.
-  unsigned ContinuationIndent =
-      std::max(CurrentState.LastSpace, CurrentState.Indent) +
+  const auto ContinuationIndent =
+      std::max(IndentationAndAlignment(CurrentState.LastSpace),
+               CurrentState.Indent) +
       Style.ContinuationIndentWidth;
   const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
   const FormatToken *NextNonComment = Previous.getNextNonComment();
@@ -1365,7 +1410,7 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) {
   // Java specific bits.
   if (Style.isJava() &&
       Current.isOneOf(Keywords.kw_implements, Keywords.kw_extends)) {
-    return std::max(CurrentState.LastSpace,
+    return std::max(IndentationAndAlignment(CurrentState.LastSpace),
                     CurrentState.Indent + Style.ContinuationIndentWidth);
   }
 
@@ -1378,7 +1423,8 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) {
 
   if (Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths &&
       State.Line->First->is(tok::kw_enum)) {
-    return (Style.IndentWidth * State.Line->First->IndentLevel) +
+    return IndentationAndAlignment(Style.IndentWidth *
+                                   State.Line->First->IndentLevel) +
            Style.IndentWidth;
   }
 
@@ -1497,7 +1543,7 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) {
       //    * not remove the 'lead' ContinuationIndentWidth
       //    * always un-indent by the operator when
       //    BreakBeforeTernaryOperators=true
-      unsigned Indent = CurrentState.Indent;
+      unsigned Indent = CurrentState.Indent.Total;
       if (Style.AlignOperands != FormatStyle::OAS_DontAlign)
         Indent -= Style.ContinuationIndentWidth;
       if (Style.BreakBeforeTernaryOperators && CurrentState.UnindentOperator)
@@ -1537,14 +1583,16 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) {
                                     TT_LeadingJavaAnnotation))) ||
       (!Style.IndentWrappedFunctionNames &&
        NextNonComment->isOneOf(tok::kw_operator, TT_FunctionDeclarationName))) {
-    return std::max(CurrentState.LastSpace, CurrentState.Indent);
+    return std::max(IndentationAndAlignment(CurrentState.LastSpace),
+                    CurrentState.Indent);
   }
   if (NextNonComment->is(TT_SelectorName)) {
     if (!CurrentState.ObjCSelectorNameFound) {
-      unsigned MinIndent = CurrentState.Indent;
+      auto MinIndent = CurrentState.Indent;
       if (shouldIndentWrappedSelectorName(Style, State.Line->Type)) {
-        MinIndent = std::max(MinIndent,
-                             State.FirstIndent + Style.ContinuationIndentWidth);
+        MinIndent =
+            std::max(MinIndent, IndentationAndAlignment(State.FirstIndent) +
+                                    Style.ContinuationIndentWidth);
       }
       // If LongestObjCSelectorName is 0, we are indenting the first
       // part of an ObjC selector (or a selector component which is
@@ -1555,10 +1603,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) {
       // component of the ObjC selector.
       //
       // In either case, we want to respect Style.IndentWrappedFunctionNames.
-      return MinIndent +
-             std::max(NextNonComment->LongestObjCSelectorName,
-                      NextNonComment->ColumnWidth) -
-             NextNonComment->ColumnWidth;
+      return MinIndent.addPadding(
+          std::max(NextNonComment->LongestObjCSelectorName,
+                   NextNonComment->ColumnWidth) -
+          NextNonComment->ColumnWidth);
     }
     if (!CurrentState.AlignColons)
       return CurrentState.Indent;
@@ -1628,7 +1676,7 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) {
     return CurrentState.Indent - NextNonComment->Tok.getLength() -
            NextNonComment->SpacesRequiredBefore;
   }
-  if (CurrentState.Indent == State.FirstIndent && PreviousNonComment &&
+  if (CurrentState.Indent.Total == State.FirstIndent && PreviousNonComment &&
       PreviousNonComment->isNoneOf(tok::r_brace, TT_CtorInitializerComma)) {
     // Ensure that we fall back to the continuation indent width instead of
     // just flushing continuations left.
@@ -1718,7 +1766,7 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
                                                   FormatStyle::BCIS_BeforeComma
                                               ? 0
                                               : 2);
-    CurrentState.NestedBlockIndent = CurrentState.Indent;
+    CurrentState.NestedBlockIndent = CurrentState.Indent.Total;
     if (Style.PackConstructorInitializers > FormatStyle::PCIS_BinPack) {
       CurrentState.AvoidBinPacking = true;
       CurrentState.BreakBeforeParameter =
@@ -1733,7 +1781,7 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
       Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon) {
     CurrentState.Indent =
         State.FirstIndent + Style.ConstructorInitializerIndentWidth;
-    CurrentState.NestedBlockIndent = CurrentState.Indent;
+    CurrentState.NestedBlockIndent = CurrentState.Indent.Total;
     if (Style.PackConstructorInitializers > FormatStyle::PCIS_BinPack)
       CurrentState.AvoidBinPacking = true;
     else
@@ -1878,7 +1926,8 @@ void ContinuationIndenter::moveStatePastFakeLParens(LineState &State,
          (Previous && Previous->isOneOf(TT_TableGenDAGArgListComma,
                                         TT_TableGenDAGArgListCommaToBreak)))) {
       NewParenState.Indent = std::max(
-          std::max(State.Column, NewParenState.Indent), CurrentState.LastSpace);
+          std::max(IndentationAndAlignment(State.Column), NewParenState.Indent),
+          IndentationAndAlignment(CurrentState.LastSpace));
     }
 
     // Special case for generic selection expressions, its comma-separated
@@ -1986,7 +2035,7 @@ void ContinuationIndenter::moveStatePastScopeOpener(LineState &State,
     return Prev->is(tok::comma);
   }(Current.MatchingParen);
 
-  unsigned NewIndent;
+  IndentationAndAlignment NewIndent = 0;
   unsigned LastSpace = CurrentState.LastSpace;
   bool AvoidBinPacking;
   bool BreakBeforeParameter = false;
@@ -1999,7 +2048,7 @@ void ContinuationIndenter::moveStatePastScopeOpener(LineState &State,
                   std::min(State.Column, CurrentState.NestedBlockIndent);
     } else if (Current.is(tok::l_brace)) {
       const auto Width = Style.BracedInitializerIndentWidth;
-      NewIndent = CurrentState.LastSpace +
+      NewIndent = IndentationAndAlignment(CurrentState.LastSpace) +
                   (Width < 0 ? Style.ContinuationIndentWidth : Width);
     } else {
       NewIndent = CurrentState.LastSpace + Style.ContinuationIndentWidth;
@@ -2014,9 +2063,9 @@ void ContinuationIndenter::moveStatePastScopeOpener(LineState &State,
     if (Current.ParameterCount > 1)
       NestedBlockIndent = std::max(NestedBlockIndent, State.Column + 1);
   } else {
-    NewIndent =
-        Style.ContinuationIndentWidth +
-        std::max(CurrentState.LastSpace, CurrentState.StartOfFunctionCall);
+    NewIndent = IndentationAndAlignment(std::max(
+                    CurrentState.LastSpace, CurrentState.StartOfFunctionCall)) +
+                Style.ContinuationIndentWidth;
 
     if (Style.isTableGen() && Current.is(TT_TableGenDAGArgOpenerToBreak) &&
         Style.TableGenBreakInsideDAGArg == FormatStyle::DAS_BreakElements) {
@@ -2035,7 +2084,7 @@ void ContinuationIndenter::moveStatePastScopeOpener(LineState &State,
     // FIXME: We likely want to do this for more combinations of brackets.
     if (Current.is(tok::less) && Current.ParentBracket == tok::l_paren) {
       NewIndent = std::max(NewIndent, CurrentState.Indent);
-      LastSpace = std::max(LastSpace, CurrentState.Indent);
+      LastSpace = std::max(LastSpace, CurrentState.Indent.Total);
     }
 
     // If ObjCBinPackProtocolList is unspecified, fall back to BinPackParameters
@@ -2281,7 +2330,7 @@ unsigned ContinuationIndenter::reformatRawStringLiteral(
   unsigned CurrentIndent =
       (!Newline && Current.Next && Current.Next->is(tok::r_paren))
           ? State.Stack.back().NestedBlockIndent
-          : State.Stack.back().Indent;
+          : State.Stack.back().Indent.Total;
   unsigned NextStartColumn = ContentStartsOnNewline
                                  ? CurrentIndent + Style.IndentWidth
                                  : FirstStartColumn;
diff --git a/clang/lib/Format/ContinuationIndenter.h b/clang/lib/Format/ContinuationIndenter.h
index fe957cf43721a..1554fb441dff0 100644
--- a/clang/lib/Format/ContinuationIndenter.h
+++ b/clang/lib/Format/ContinuationIndenter.h
@@ -43,6 +43,41 @@ struct RawStringFormatStyleManager {
   getEnclosingFunctionStyle(StringRef EnclosingFunction) const;
 };
 
+/// Represents the spaces at the start of a line, keeping track of what the
+/// spaces are for.
+struct IndentationAndAlignment {
+  unsigned Total;
+
+  /// The column that the position of the start of the line is calculated
+  /// from. It can be more than Total.
+  unsigned IndentedFrom;
+
+  /// Add spaces for right-justifying the token. The IndentedFrom field does not
+  /// change.
+  ///
+  /// This example in Objective-C shows why the field should not change.  The
+  /// token `xx` is right-justified with this method to align the `:`
+  /// symbols. The `:` symbols should remain aligned through the step that
+  /// aligns assignments. That step uses the IndentedFrom field to tell what
+  /// lines to move. Not changing the field in this method ensures that the 2
+  /// lines move together.
+  ///
+  /// [x //
+  ///     xxxx:0
+  ///       xx:0];
+  IndentationAndAlignment addPadding(unsigned Spaces) const;
+  /// Adding indentation is more common than padding. So the operator does that.
+  IndentationAndAlignment operator+(unsigned Spaces) const;
+  IndentationAndAlignment operator-(unsigned Spaces) const;
+  IndentationAndAlignment &operator+=(unsigned Spaces);
+
+  IndentationAndAlignment(unsigned Total, unsigned IndentedFrom);
+
+  IndentationAndAlignment(unsigned Spaces);
+
+  bool operator<(const IndentationAndAlignment &Other) const;
+};
+
 class ContinuationIndenter {
 public:
   /// Constructs a \c ContinuationIndenter to format \p Line starting in
@@ -168,7 +203,7 @@ class ContinuationIndenter {
   unsigned addTokenOnNewLine(LineState &State, bool DryRun);
 
   /// Calculate the new column for a line wrap before the next token.
-  unsigned getNewLineColumn(const LineState &State);
+  IndentationAndAlignment getNewLineColumn(const LineState &State);
 
   /// Adds a multiline token to the \p State.
   ///
@@ -195,10 +230,10 @@ class ContinuationIndenter {
 };
 
 struct ParenState {
-  ParenState(const FormatToken *Tok, unsigned Indent, unsigned LastSpace,
-             bool AvoidBinPacking, bool NoLineBreak)
+  ParenState(const FormatToken *Tok, IndentationAndAlignment Indent,
+             unsigned LastSpace, bool AvoidBinPacking, bool NoLineBreak)
       : Tok(Tok), Indent(Indent), LastSpace(LastSpace),
-        NestedBlockIndent(Indent), IsAligned(false),
+        NestedBlockIndent(Indent.Total), IsAligned(false),
         BreakBeforeClosingBrace(false), BreakBeforeClosingParen(false),
         BreakBeforeClosingAngle(false), AvoidBinPacking(AvoidBinPacking),
         BreakBeforeParameter(false), NoLineBreak(NoLineBreak),
@@ -219,7 +254,7 @@ struct ParenState {
 
   /// The position to which a specific parenthesis level needs to be
   /// indented.
-  unsigned Indent;
+  IndentationAndAlignment Indent;
 
   /// The position of the last space on each level.
   ///
@@ -356,8 +391,8 @@ struct ParenState {
   bool UnindentOperator : 1;
 
   bool operator<(const ParenState &Other) const {
-    if (Indent != Other.Indent)
-      return Indent < Other.Indent;
+    if (Indent.Total != Other.Indent.Total)
+      return Indent.Total < Other.Indent.Total;
     if (LastSpace != Other.LastSpace)
       return LastSpace < Other.LastSpace;
     if (NestedBlockIndent != Other.NestedBlockIndent)
@@ -406,7 +441,7 @@ struct ParenState {
       return IsWrappedConditional;
     if (UnindentOperator != Other.UnindentOperator)
       return UnindentOperator;
-    return false;
+    return Indent < Other.Indent;
   }
 };
 
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp
index d31d656a63fc5..913789afd9919 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -1052,8 +1052,8 @@ static void markFinalized(FormatToken *Tok) {
 static void printLineState(const LineState &State) {
   llvm::dbgs() << "State: ";
   for (const ParenState &P : State.Stack) {
-    llvm::dbgs() << (P.Tok ? P.Tok->TokenText : "F") << "|" << P.Indent << "|"
-                 << P.LastSpace << "|" << P.NestedBlockIndent << " ";
+    llvm::dbgs() << (P.Tok ? P.Tok->TokenText : "F") << "|" << P.Indent.Total
+                 << "|" << P.LastSpace << "|" << P.NestedBlockIndent << " ";
   }
   llvm::dbgs() << State.NextToken->TokenText << "\n";
 }
@@ -1111,7 +1111,7 @@ class LineFormatter {
       const ParenState &P = State.Stack.back();
 
       int AdditionalIndent =
-          P.Indent - Previous.Children[0]->Level * Style.IndentWidth;
+          P.Indent.Total - Previous.Children[0]->Level * Style.IndentWidth;
       Penalty +=
           BlockFormatter->format(Previous.Children, DryRun, AdditionalIndent,
                                  /*FixBadIndentation=*/true);
diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp
index 94ccf9eb7842a..805bb78f5c90e 100644
--- a/clang/lib/Format/WhitespaceManager.cpp
+++ b/clang/lib/Format/WhitespaceManager.cpp
@@ -35,13 +35,15 @@ WhitespaceManager::Change::Change(const FormatToken &Tok,...
[truncated]

Copy link
Contributor

@HazardyKnusperkeks HazardyKnusperkeks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice.

Comment on lines 1928 to +1930
NewParenState.Indent = std::max(
std::max(State.Column, NewParenState.Indent), CurrentState.LastSpace);
std::max(IndentationAndAlignment(State.Column), NewParenState.Indent),
IndentationAndAlignment(CurrentState.LastSpace));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
NewParenState.Indent = std::max(
std::max(State.Column, NewParenState.Indent), CurrentState.LastSpace);
std::max(IndentationAndAlignment(State.Column), NewParenState.Indent),
IndentationAndAlignment(CurrentState.LastSpace));
NewParenState.Indent = std::max({
IndentationAndAlignment(State.Column), NewParenState.Indent,
IndentationAndAlignment(CurrentState.LastSpace)});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

3 participants