[clang-format] Add BreakBeforeInlineASMColon configuration

If true, colons in ASM parameters will be placed after line breaks.

true:
asm volatile("string",
                     :
                     : val);

false:
asm volatile("string", : : val);

Differential Revision: https://reviews.llvm.org/D91950
This commit is contained in:
Anastasiia Lukianenko 2022-11-10 22:28:15 +01:00 committed by Björn Schäpers
parent a7ba84a39d
commit f6b252978c
6 changed files with 139 additions and 1 deletions

View File

@ -2317,6 +2317,40 @@ the configuration (without a prefix: ``Auto``).
**BreakBeforeInlineASMColon** (``BreakBeforeInlineASMColonStyle``) :versionbadge:`clang-format 16`
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** (``Boolean``) :versionbadge:`clang-format 3.7`
If ``true``, ternary operators will be placed after line breaks.

View File

@ -1752,6 +1752,35 @@ struct FormatStyle {
/// \version 12
BreakBeforeConceptDeclarationsStyle BreakBeforeConceptDeclarations;
/// Different ways to break ASM parameters.
enum BreakBeforeInlineASMColonStyle : int8_t {
/// 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.
/// \version 16
BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon;
/// If ``true``, ternary operators will be placed after line breaks.
/// \code
/// true:
@ -4016,6 +4045,7 @@ struct FormatStyle {
BreakBeforeBinaryOperators == R.BreakBeforeBinaryOperators &&
BreakBeforeBraces == R.BreakBeforeBraces &&
BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations &&
BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon &&
BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators &&
BreakConstructorInitializers == R.BreakConstructorInitializers &&
BreakInheritanceList == R.BreakInheritanceList &&

View File

@ -352,8 +352,12 @@ bool ContinuationIndenter::mustBreak(const LineState &State) {
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 (CurrentState.BreakBeforeClosingBrace &&
Current.closesBlockOrBlockTypeList(Style)) {
return true;

View File

@ -229,6 +229,15 @@ struct ScalarEnumerationTraits<
}
};
template <>
struct ScalarEnumerationTraits<FormatStyle::BreakBeforeInlineASMColonStyle> {
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<FormatStyle::BreakConstructorInitializersStyle> {
static void
@ -827,6 +836,8 @@ template <> struct MappingTraits<FormatStyle> {
IO.mapOptional("BreakBeforeConceptDeclarations",
Style.BreakBeforeConceptDeclarations);
IO.mapOptional("BreakBeforeBraces", Style.BreakBeforeBraces);
IO.mapOptional("BreakBeforeInlineASMColon",
Style.BreakBeforeInlineASMColon);
IO.mapOptional("BreakBeforeTernaryOperators",
Style.BreakBeforeTernaryOperators);
IO.mapOptional("BreakConstructorInitializers",
@ -1263,6 +1274,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
LLVMStyle.BreakArrays = true;
LLVMStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_None;
LLVMStyle.BreakBeforeConceptDeclarations = FormatStyle::BBCDS_Always;
LLVMStyle.BreakBeforeInlineASMColon = FormatStyle::BBIAS_OnlyMultiline;
LLVMStyle.BreakBeforeTernaryOperators = true;
LLVMStyle.BreakBeforeBraces = FormatStyle::BS_Attach;
LLVMStyle.BraceWrapping = {/*AfterCaseLabel=*/false,

View File

@ -4443,6 +4443,11 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
}
}
if (Line.startsWith(tok::kw_asm) && Right.is(TT_InlineASMColon) &&
Style.BreakBeforeInlineASMColon == FormatStyle::BBIAS_Always) {
return true;
}
// If the last token before a '}', ']', or ')' is a comma or a trailing
// comment, the intention is to insert a line break after it in order to make
// shuffling around entries easier. Import statements, especially in

View File

@ -7259,6 +7259,59 @@ TEST_F(FormatTest, AllowAllArgumentsOnNextLineDontAlign) {
format(Input, Style));
}
TEST_F(FormatTest, BreakBeforeInlineASMColon) {
FormatStyle Style = getLLVMStyle();
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);
verifyFormat("asm(\"movq\\t%%rbx, %%rsi\\n\\t\"\n"
" \"cpuid\\n\\t\"\n"
" \"xchgq\\t%%rbx %%rsi\\n\\t\",\n"
" : \"=a\" : \"a\");",
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(\"movq\\t%%rbx, %%rsi\\n\\t\"\n"
" \"cpuid\\n\\t\"\n"
" \"xchgq\\t%%rbx, %%rsi\\n\\t\"\n"
" : \"=a\"(*rEAX)\n"
" : \"a\"(value));",
Style);
verifyFormat("asm(\"movq\\t%%rbx, %%rsi\\n\\t\"\n"
" \"cpuid\\n\\t\"\n"
" \"xchgq\\t%%rbx, %%rsi\\n\\t\"\n"
" :\n"
" : \"a\"(value));",
Style);
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;