Index: clang/docs/ClangFormatStyleOptions.rst =================================================================== --- clang/docs/ClangFormatStyleOptions.rst +++ clang/docs/ClangFormatStyleOptions.rst @@ -1987,6 +1987,39 @@ false: template concept ... +**BreakBeforeInlineASMColon** (``BreakBeforeInlineASMColonStyle``) + The inline ASM colon style to use. + + Possible values: + + * ``BBIAS_Never`` (in configuration: ``Never``) + No break before inline ASM colon. + + .. code-block:: c++ + + asm volatile("string", : : val); + + * ``BBIAS_OnlyMultiline`` (in configuration: ``OnlyMultiline``) + Break before inline ASM colon if the line length is longer than column limit. + + .. code-block:: c++ + + asm volatile("string", : : val); + asm("cmoveq %1, %2, %[result]" + : [result] "=r"(result) + : "r"(test), "r"(new), "[result]"(old)); + + * ``BBIAS_Always`` (in configuration: ``Always``) + Always break before inline ASM colon. + + .. code-block:: c++ + + asm volatile("string", + : + : val); + + + **BreakBeforeTernaryOperators** (``bool``) If ``true``, ternary operators will be placed after line breaks. Index: clang/include/clang/Format/Format.h =================================================================== --- clang/include/clang/Format/Format.h +++ clang/include/clang/Format/Format.h @@ -1751,6 +1751,33 @@ /// \endcode bool BreakBeforeConceptDeclarations; + /// Different ways to break ASM parameters. + enum BreakBeforeInlineASMColonStyle : unsigned char { + /// No break before inline ASM colon. + /// \code + /// asm volatile("string", : : val); + /// \endcode + BBIAS_Never, + /// Break before inline ASM colon if the line length is longer than column limit. + /// \code + /// asm volatile("string", : : val); + /// asm("cmoveq %1, %2, %[result]" + /// : [result] "=r"(result) + /// : "r"(test), "r"(new), "[result]"(old)); + /// \endcode + BBIAS_OnlyMultiline, + /// Always break before inline ASM colon. + /// \code + /// asm volatile("string", + /// : + /// : val); + /// \endcode + BBIAS_Always, + }; + + /// The inline ASM colon style to use. + BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, ternary operators will be placed after line breaks. /// \code /// true: @@ -3417,6 +3444,7 @@ BreakBeforeBinaryOperators == R.BreakBeforeBinaryOperators && BreakBeforeBraces == R.BreakBeforeBraces && BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations && + BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon && BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators && BreakConstructorInitializers == R.BreakConstructorInitializers && CompactNamespaces == R.CompactNamespaces && Index: clang/lib/Format/ContinuationIndenter.cpp =================================================================== --- clang/lib/Format/ContinuationIndenter.cpp +++ clang/lib/Format/ContinuationIndenter.cpp @@ -334,7 +334,10 @@ auto LambdaBodyLength = getLengthToMatchingParen(Current, State.Stack); return (LambdaBodyLength > getColumnLimit(State)); } - if (Current.MustBreakBefore || Current.is(TT_InlineASMColon)) + if (Current.MustBreakBefore || + (Current.is(TT_InlineASMColon) && + (Style.BreakBeforeInlineASMColon == FormatStyle::BBIAS_Always || + Style.BreakBeforeInlineASMColon == FormatStyle::BBIAS_OnlyMultiline))) return true; if (State.Stack.back().BreakBeforeClosingBrace && Current.closesBlockOrBlockTypeList(Style)) Index: clang/lib/Format/Format.cpp =================================================================== --- clang/lib/Format/Format.cpp +++ clang/lib/Format/Format.cpp @@ -243,6 +243,16 @@ } }; +template <> +struct ScalarEnumerationTraits { + static void + enumeration(IO &IO, FormatStyle::BreakBeforeInlineASMColonStyle &Value) { + IO.enumCase(Value, "Never", FormatStyle::BBIAS_Never); + IO.enumCase(Value, "OnlyMultiline", FormatStyle::BBIAS_OnlyMultiline); + IO.enumCase(Value, "Always", FormatStyle::BBIAS_Always); + } +}; + template <> struct ScalarEnumerationTraits { static void @@ -612,6 +622,9 @@ Style.BreakInheritanceList == FormatStyle::BILS_BeforeColon) Style.BreakInheritanceList = FormatStyle::BILS_BeforeComma; + IO.mapOptional("BreakBeforeInlineASMColon", + Style.BreakBeforeInlineASMColon); + IO.mapOptional("BreakBeforeTernaryOperators", Style.BreakBeforeTernaryOperators); @@ -1006,6 +1019,7 @@ LLVMStyle.BinPackParameters = true; LLVMStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_None; LLVMStyle.BreakBeforeConceptDeclarations = true; + LLVMStyle.BreakBeforeInlineASMColon = FormatStyle::BBIAS_OnlyMultiline; LLVMStyle.BreakBeforeTernaryOperators = true; LLVMStyle.BreakBeforeBraces = FormatStyle::BS_Attach; LLVMStyle.BraceWrapping = {/*AfterCaseLabel=*/false, Index: clang/lib/Format/TokenAnnotator.cpp =================================================================== --- clang/lib/Format/TokenAnnotator.cpp +++ clang/lib/Format/TokenAnnotator.cpp @@ -3602,6 +3602,9 @@ const FormatToken &Left = *Right.Previous; if (Right.NewlinesBefore > 1 && Style.MaxEmptyLinesToKeep > 0) return true; + if (Line.startsWith(tok::kw_asm) && Right.is(TT_InlineASMColon) && + Style.BreakBeforeInlineASMColon == FormatStyle::BBIAS_Always) + return true; if (Style.isCSharp()) { if (Right.is(TT_CSharpNamedArgumentColon) || Index: clang/unittests/Format/FormatTest.cpp =================================================================== --- clang/unittests/Format/FormatTest.cpp +++ clang/unittests/Format/FormatTest.cpp @@ -6240,6 +6240,43 @@ format(Input, Style)); } +TEST_F(FormatTest, BreakBeforeInlineASMColon) { + FormatStyle Style = getLLVMStyle(); + Style.BreakStringLiterals = false; + Style.BreakBeforeInlineASMColon = FormatStyle::BBIAS_Never; + /* Test the behaviour with long lines */ + Style.ColumnLimit = 40; + verifyFormat("asm volatile(\"loooooooooooooooooooong\",\n" + " : : val);", + Style); + verifyFormat("asm volatile(\"loooooooooooooooooooong\",\n" + " : val1 : val2);", + Style); + Style.ColumnLimit = 80; + verifyFormat("asm volatile(\"string\", : : val);", Style); + verifyFormat("asm volatile(\"string\", : val1 : val2);", Style); + + Style.BreakBeforeInlineASMColon = FormatStyle::BBIAS_Always; + verifyFormat("asm volatile(\"string\",\n" + " :\n" + " : val);", + Style); + verifyFormat("asm volatile(\"string\",\n" + " : val1\n" + " : val2);", + Style); + /* Test the behaviour with long lines */ + Style.ColumnLimit = 40; + verifyFormat("asm volatile(\"loooooooooooooooooooong\",\n" + " :\n" + " : val);", + Style); + verifyFormat("asm volatile(\"loooooooooooooooooooong\",\n" + " : val1\n" + " : val2);", + Style); +} + TEST_F(FormatTest, BreakConstructorInitializersAfterColon) { FormatStyle Style = getLLVMStyle(); Style.BreakConstructorInitializers = FormatStyle::BCIS_AfterColon;