Skip to content

Commit f6b2529

Browse files
NastyaVicodinHazardyKnusperkeks
authored andcommitted
[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
1 parent a7ba84a commit f6b2529

File tree

6 files changed

+139
-1
lines changed

6 files changed

+139
-1
lines changed

clang/docs/ClangFormatStyleOptions.rst

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2317,6 +2317,40 @@ the configuration (without a prefix: ``Auto``).
23172317

23182318

23192319

2320+
**BreakBeforeInlineASMColon** (``BreakBeforeInlineASMColonStyle``) :versionbadge:`clang-format 16`
2321+
The inline ASM colon style to use.
2322+
2323+
Possible values:
2324+
2325+
* ``BBIAS_Never`` (in configuration: ``Never``)
2326+
No break before inline ASM colon.
2327+
2328+
.. code-block:: c++
2329+
2330+
asm volatile("string", : : val);
2331+
2332+
* ``BBIAS_OnlyMultiline`` (in configuration: ``OnlyMultiline``)
2333+
Break before inline ASM colon if the line length is longer than column
2334+
limit.
2335+
2336+
.. code-block:: c++
2337+
2338+
asm volatile("string", : : val);
2339+
asm("cmoveq %1, %2, %[result]"
2340+
: [result] "=r"(result)
2341+
: "r"(test), "r"(new), "[result]"(old));
2342+
2343+
* ``BBIAS_Always`` (in configuration: ``Always``)
2344+
Always break before inline ASM colon.
2345+
2346+
.. code-block:: c++
2347+
2348+
asm volatile("string",
2349+
:
2350+
: val);
2351+
2352+
2353+
23202354
**BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7`
23212355
If ``true``, ternary operators will be placed after line breaks.
23222356

clang/include/clang/Format/Format.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1752,6 +1752,35 @@ struct FormatStyle {
17521752
/// \version 12
17531753
BreakBeforeConceptDeclarationsStyle BreakBeforeConceptDeclarations;
17541754

1755+
/// Different ways to break ASM parameters.
1756+
enum BreakBeforeInlineASMColonStyle : int8_t {
1757+
/// No break before inline ASM colon.
1758+
/// \code
1759+
/// asm volatile("string", : : val);
1760+
/// \endcode
1761+
BBIAS_Never,
1762+
/// Break before inline ASM colon if the line length is longer than column
1763+
/// limit.
1764+
/// \code
1765+
/// asm volatile("string", : : val);
1766+
/// asm("cmoveq %1, %2, %[result]"
1767+
/// : [result] "=r"(result)
1768+
/// : "r"(test), "r"(new), "[result]"(old));
1769+
/// \endcode
1770+
BBIAS_OnlyMultiline,
1771+
/// Always break before inline ASM colon.
1772+
/// \code
1773+
/// asm volatile("string",
1774+
/// :
1775+
/// : val);
1776+
/// \endcode
1777+
BBIAS_Always,
1778+
};
1779+
1780+
/// The inline ASM colon style to use.
1781+
/// \version 16
1782+
BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon;
1783+
17551784
/// If ``true``, ternary operators will be placed after line breaks.
17561785
/// \code
17571786
/// true:
@@ -4016,6 +4045,7 @@ struct FormatStyle {
40164045
BreakBeforeBinaryOperators == R.BreakBeforeBinaryOperators &&
40174046
BreakBeforeBraces == R.BreakBeforeBraces &&
40184047
BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations &&
4048+
BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon &&
40194049
BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators &&
40204050
BreakConstructorInitializers == R.BreakConstructorInitializers &&
40214051
BreakInheritanceList == R.BreakInheritanceList &&

clang/lib/Format/ContinuationIndenter.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,8 +352,12 @@ bool ContinuationIndenter::mustBreak(const LineState &State) {
352352
auto LambdaBodyLength = getLengthToMatchingParen(Current, State.Stack);
353353
return LambdaBodyLength > getColumnLimit(State);
354354
}
355-
if (Current.MustBreakBefore || Current.is(TT_InlineASMColon))
355+
if (Current.MustBreakBefore ||
356+
(Current.is(TT_InlineASMColon) &&
357+
(Style.BreakBeforeInlineASMColon == FormatStyle::BBIAS_Always ||
358+
Style.BreakBeforeInlineASMColon == FormatStyle::BBIAS_OnlyMultiline))) {
356359
return true;
360+
}
357361
if (CurrentState.BreakBeforeClosingBrace &&
358362
Current.closesBlockOrBlockTypeList(Style)) {
359363
return true;

clang/lib/Format/Format.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,15 @@ struct ScalarEnumerationTraits<
229229
}
230230
};
231231

232+
template <>
233+
struct ScalarEnumerationTraits<FormatStyle::BreakBeforeInlineASMColonStyle> {
234+
static void enumeration(IO &IO,
235+
FormatStyle::BreakBeforeInlineASMColonStyle &Value) {
236+
IO.enumCase(Value, "Never", FormatStyle::BBIAS_Never);
237+
IO.enumCase(Value, "OnlyMultiline", FormatStyle::BBIAS_OnlyMultiline);
238+
IO.enumCase(Value, "Always", FormatStyle::BBIAS_Always);
239+
}
240+
};
232241
template <>
233242
struct ScalarEnumerationTraits<FormatStyle::BreakConstructorInitializersStyle> {
234243
static void
@@ -827,6 +836,8 @@ template <> struct MappingTraits<FormatStyle> {
827836
IO.mapOptional("BreakBeforeConceptDeclarations",
828837
Style.BreakBeforeConceptDeclarations);
829838
IO.mapOptional("BreakBeforeBraces", Style.BreakBeforeBraces);
839+
IO.mapOptional("BreakBeforeInlineASMColon",
840+
Style.BreakBeforeInlineASMColon);
830841
IO.mapOptional("BreakBeforeTernaryOperators",
831842
Style.BreakBeforeTernaryOperators);
832843
IO.mapOptional("BreakConstructorInitializers",
@@ -1263,6 +1274,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
12631274
LLVMStyle.BreakArrays = true;
12641275
LLVMStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_None;
12651276
LLVMStyle.BreakBeforeConceptDeclarations = FormatStyle::BBCDS_Always;
1277+
LLVMStyle.BreakBeforeInlineASMColon = FormatStyle::BBIAS_OnlyMultiline;
12661278
LLVMStyle.BreakBeforeTernaryOperators = true;
12671279
LLVMStyle.BreakBeforeBraces = FormatStyle::BS_Attach;
12681280
LLVMStyle.BraceWrapping = {/*AfterCaseLabel=*/false,

clang/lib/Format/TokenAnnotator.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4443,6 +4443,11 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
44434443
}
44444444
}
44454445

4446+
if (Line.startsWith(tok::kw_asm) && Right.is(TT_InlineASMColon) &&
4447+
Style.BreakBeforeInlineASMColon == FormatStyle::BBIAS_Always) {
4448+
return true;
4449+
}
4450+
44464451
// If the last token before a '}', ']', or ')' is a comma or a trailing
44474452
// comment, the intention is to insert a line break after it in order to make
44484453
// shuffling around entries easier. Import statements, especially in

clang/unittests/Format/FormatTest.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7259,6 +7259,59 @@ TEST_F(FormatTest, AllowAllArgumentsOnNextLineDontAlign) {
72597259
format(Input, Style));
72607260
}
72617261

7262+
TEST_F(FormatTest, BreakBeforeInlineASMColon) {
7263+
FormatStyle Style = getLLVMStyle();
7264+
Style.BreakBeforeInlineASMColon = FormatStyle::BBIAS_Never;
7265+
/* Test the behaviour with long lines */
7266+
Style.ColumnLimit = 40;
7267+
verifyFormat("asm volatile(\"loooooooooooooooooooong\",\n"
7268+
" : : val);",
7269+
Style);
7270+
verifyFormat("asm volatile(\"loooooooooooooooooooong\",\n"
7271+
" : val1 : val2);",
7272+
Style);
7273+
verifyFormat("asm(\"movq\\t%%rbx, %%rsi\\n\\t\"\n"
7274+
" \"cpuid\\n\\t\"\n"
7275+
" \"xchgq\\t%%rbx %%rsi\\n\\t\",\n"
7276+
" : \"=a\" : \"a\");",
7277+
Style);
7278+
Style.ColumnLimit = 80;
7279+
verifyFormat("asm volatile(\"string\", : : val);", Style);
7280+
verifyFormat("asm volatile(\"string\", : val1 : val2);", Style);
7281+
7282+
Style.BreakBeforeInlineASMColon = FormatStyle::BBIAS_Always;
7283+
verifyFormat("asm volatile(\"string\",\n"
7284+
" :\n"
7285+
" : val);",
7286+
Style);
7287+
verifyFormat("asm volatile(\"string\",\n"
7288+
" : val1\n"
7289+
" : val2);",
7290+
Style);
7291+
/* Test the behaviour with long lines */
7292+
Style.ColumnLimit = 40;
7293+
verifyFormat("asm(\"movq\\t%%rbx, %%rsi\\n\\t\"\n"
7294+
" \"cpuid\\n\\t\"\n"
7295+
" \"xchgq\\t%%rbx, %%rsi\\n\\t\"\n"
7296+
" : \"=a\"(*rEAX)\n"
7297+
" : \"a\"(value));",
7298+
Style);
7299+
verifyFormat("asm(\"movq\\t%%rbx, %%rsi\\n\\t\"\n"
7300+
" \"cpuid\\n\\t\"\n"
7301+
" \"xchgq\\t%%rbx, %%rsi\\n\\t\"\n"
7302+
" :\n"
7303+
" : \"a\"(value));",
7304+
Style);
7305+
verifyFormat("asm volatile(\"loooooooooooooooooooong\",\n"
7306+
" :\n"
7307+
" : val);",
7308+
Style);
7309+
verifyFormat("asm volatile(\"loooooooooooooooooooong\",\n"
7310+
" : val1\n"
7311+
" : val2);",
7312+
Style);
7313+
}
7314+
72627315
TEST_F(FormatTest, BreakConstructorInitializersAfterColon) {
72637316
FormatStyle Style = getLLVMStyle();
72647317
Style.BreakConstructorInitializers = FormatStyle::BCIS_AfterColon;

0 commit comments

Comments
 (0)