Index: lib/Format/ContinuationIndenter.h =================================================================== --- lib/Format/ContinuationIndenter.h +++ lib/Format/ContinuationIndenter.h @@ -111,12 +111,12 @@ unsigned reformatRawStringLiteral(const FormatToken &Current, LineState &State, const FormatStyle &RawStringStyle, - bool DryRun); + bool DryRun, bool Newline); /// If the current token is at the end of the current line, handle /// the transition to the next line. unsigned handleEndOfLine(const FormatToken &Current, LineState &State, - bool DryRun, bool AllowBreak); + bool DryRun, bool AllowBreak, bool Newline); /// If \p Current is a raw string that is configured to be reformatted, /// return the style to be used. Index: lib/Format/ContinuationIndenter.cpp =================================================================== --- lib/Format/ContinuationIndenter.cpp +++ lib/Format/ContinuationIndenter.cpp @@ -1196,7 +1196,8 @@ State.Column += Current.ColumnWidth; State.NextToken = State.NextToken->Next; - unsigned Penalty = handleEndOfLine(Current, State, DryRun, AllowBreak); + unsigned Penalty = + handleEndOfLine(Current, State, DryRun, AllowBreak, Newline); if (Current.Role) Current.Role->formatFromToken(State, this, DryRun); @@ -1490,7 +1491,7 @@ unsigned ContinuationIndenter::reformatRawStringLiteral( const FormatToken &Current, LineState &State, - const FormatStyle &RawStringStyle, bool DryRun) { + const FormatStyle &RawStringStyle, bool DryRun, bool Newline) { unsigned StartColumn = State.Column - Current.ColumnWidth; StringRef OldDelimiter = *getRawStringDelimiter(Current.TokenText); StringRef NewDelimiter = @@ -1530,8 +1531,10 @@ // source. bool ContentStartsOnNewline = Current.TokenText[OldPrefixSize] == '\n'; // If this token is the last parameter (checked by looking if it's followed by - // `)`, the base the indent off the line's nested block indent. Otherwise, - // base the indent off the arguments indent, so we can achieve: + // `)` and is not on a newline, the base the indent off the line's nested + // block indent. Otherwise, base the indent off the arguments indent, so we + // can achieve: + // // fffffffffff(1, 2, 3, R"pb( // key1: 1 # // key2: 2)pb"); @@ -1540,11 +1543,18 @@ // R"pb( // key1: 1 # // key2: 2 + // )pb"); + // + // fffffffffff(1, 2, 3, + // R"pb( + // key1: 1 # + // key2: 2 // )pb", // 5); - unsigned CurrentIndent = (Current.Next && Current.Next->is(tok::r_paren)) - ? State.Stack.back().NestedBlockIndent - : State.Stack.back().Indent; + unsigned CurrentIndent = + (!Newline && Current.Next && Current.Next->is(tok::r_paren)) + ? State.Stack.back().NestedBlockIndent + : State.Stack.back().Indent; unsigned NextStartColumn = ContentStartsOnNewline ? CurrentIndent + Style.IndentWidth : FirstStartColumn; @@ -1646,13 +1656,14 @@ unsigned ContinuationIndenter::handleEndOfLine(const FormatToken &Current, LineState &State, bool DryRun, - bool AllowBreak) { + bool AllowBreak, bool Newline) { unsigned Penalty = 0; // Compute the raw string style to use in case this is a raw string literal // that can be reformatted. auto RawStringStyle = getRawStringStyle(Current, State); if (RawStringStyle && !Current.Finalized) { - Penalty = reformatRawStringLiteral(Current, State, *RawStringStyle, DryRun); + Penalty = reformatRawStringLiteral(Current, State, *RawStringStyle, DryRun, + Newline); } else if (Current.IsMultiline && Current.isNot(TT_BlockComment)) { // Don't break multi-line tokens other than block comments and raw string // literals. Instead, just update the state. Index: unittests/Format/FormatTestRawStrings.cpp =================================================================== --- unittests/Format/FormatTestRawStrings.cpp +++ unittests/Format/FormatTestRawStrings.cpp @@ -981,6 +981,20 @@ })test", Style)); } +TEST_F(FormatTestRawStrings, IndentsLastParamAfterNewline) { + FormatStyle Style = getRawStringPbStyleWithColumns(60); + expect_eq(R"test( +fffffffffffffffffffff("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + R"pb( + b: c + )pb");)test", + format(R"test( +fffffffffffffffffffff("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + R"pb( + b: c + )pb");)test", + Style)); +} } // end namespace } // end namespace format } // end namespace clang