[clang] a7aebd8 - [clang-format] Add option AllowShortRecordOnASingleLine (#154580)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Mar 15 02:52:34 PDT 2026
Author: Tomáš Slanina
Date: 2026-03-15T02:52:30-07:00
New Revision: a7aebd809d49fd1c8205e8f0fcdc8d97777e5103
URL: https://github.com/llvm/llvm-project/commit/a7aebd809d49fd1c8205e8f0fcdc8d97777e5103
DIFF: https://github.com/llvm/llvm-project/commit/a7aebd809d49fd1c8205e8f0fcdc8d97777e5103.diff
LOG: [clang-format] Add option AllowShortRecordOnASingleLine (#154580)
This patch supersedes PR #151970 by adding the option
``AllowShortRecordOnASingleLine`` that allows the following formatting:
```c++
struct foo {};
struct bar { int i; };
struct baz
{
int i;
int j;
int k;
};
```
---------
Co-authored-by: owenca <owenpiano at gmail.com>
Added:
Modified:
clang/docs/ClangFormatStyleOptions.rst
clang/docs/ReleaseNotes.rst
clang/include/clang/Format/Format.h
clang/lib/Format/Format.cpp
clang/lib/Format/TokenAnnotator.cpp
clang/lib/Format/UnwrappedLineFormatter.cpp
clang/lib/Format/UnwrappedLineParser.cpp
clang/unittests/Format/ConfigParseTest.cpp
clang/unittests/Format/FormatTest.cpp
Removed:
################################################################################
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index eed103340568b..342eb0bdb1279 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -2143,6 +2143,42 @@ the configuration (without a prefix: ``Auto``).
**AllowShortNamespacesOnASingleLine** (``Boolean``) :versionbadge:`clang-format 20` :ref:`¶ <AllowShortNamespacesOnASingleLine>`
If ``true``, ``namespace a { class b; }`` can be put on a single line.
+.. _AllowShortRecordOnASingleLine:
+
+**AllowShortRecordOnASingleLine** (``ShortRecordStyle``) :versionbadge:`clang-format 23` :ref:`¶ <AllowShortRecordOnASingleLine>`
+ Dependent on the value, ``struct bar { int i; };`` can be put on a single
+ line.
+
+ Possible values:
+
+ * ``SRS_Never`` (in configuration: ``Never``)
+ Never merge records into a single line.
+
+ * ``SRS_EmptyAndAttached`` (in configuration: ``EmptyAndAttached``)
+ Only merge empty records if the opening brace was not wrapped,
+ i.e. the corresponding ``BraceWrapping.After...`` option was not set.
+
+ * ``SRS_Empty`` (in configuration: ``Empty``)
+ Only merge empty records.
+
+ .. code-block:: c++
+
+ struct foo {};
+ struct bar
+ {
+ int i;
+ };
+
+ * ``SRS_Always`` (in configuration: ``Always``)
+ Merge all records that fit on a single line.
+
+ .. code-block:: c++
+
+ struct foo {};
+ struct bar { int i; };
+
+
+
.. _AlwaysBreakAfterDefinitionReturnType:
**AlwaysBreakAfterDefinitionReturnType** (``DefinitionReturnTypeBreakingStyle``) :versionbadge:`clang-format 3.7` :ref:`¶ <AlwaysBreakAfterDefinitionReturnType>`
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index bacf2761ca816..cb5d1c235951f 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -481,6 +481,7 @@ clang-format
constructor initializers after commas, keeping the colon on the same line.
- Extend ``BreakBinaryOperations`` to accept a structured configuration with
per-operator break rules and minimum chain length gating via ``PerOperator``.
+- Add ``AllowShortRecordOnASingleLine`` option and set it to ``EmptyAndAttached`` for LLVM style.
libclang
--------
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 820e2c53ebf63..45369e2e142c2 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -1064,6 +1064,36 @@ struct FormatStyle {
/// \version 20
bool AllowShortNamespacesOnASingleLine;
+ /// Different styles for merging short records (``class``,``struct``, and
+ /// ``union``).
+ enum ShortRecordStyle : int8_t {
+ /// Never merge records into a single line.
+ SRS_Never,
+ /// Only merge empty records if the opening brace was not wrapped,
+ /// i.e. the corresponding ``BraceWrapping.After...`` option was not set.
+ SRS_EmptyAndAttached,
+ /// Only merge empty records.
+ /// \code
+ /// struct foo {};
+ /// struct bar
+ /// {
+ /// int i;
+ /// };
+ /// \endcode
+ SRS_Empty,
+ /// Merge all records that fit on a single line.
+ /// \code
+ /// struct foo {};
+ /// struct bar { int i; };
+ /// \endcode
+ SRS_Always
+ };
+
+ /// Dependent on the value, ``struct bar { int i; };`` can be put on a single
+ /// line.
+ /// \version 23
+ ShortRecordStyle AllowShortRecordOnASingleLine;
+
/// Different ways to break after the function definition return type.
/// This option is **deprecated** and is retained for backwards compatibility.
enum DefinitionReturnTypeBreakingStyle : int8_t {
@@ -5888,6 +5918,7 @@ struct FormatStyle {
AllowShortLoopsOnASingleLine == R.AllowShortLoopsOnASingleLine &&
AllowShortNamespacesOnASingleLine ==
R.AllowShortNamespacesOnASingleLine &&
+ AllowShortRecordOnASingleLine == R.AllowShortRecordOnASingleLine &&
AlwaysBreakBeforeMultilineStrings ==
R.AlwaysBreakBeforeMultilineStrings &&
AttributeMacros == R.AttributeMacros &&
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index adfe4ba982453..5c5a2ff2f5049 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -779,6 +779,15 @@ template <> struct ScalarEnumerationTraits<FormatStyle::ShortLambdaStyle> {
}
};
+template <> struct ScalarEnumerationTraits<FormatStyle::ShortRecordStyle> {
+ static void enumeration(IO &IO, FormatStyle::ShortRecordStyle &Value) {
+ IO.enumCase(Value, "Never", FormatStyle::SRS_Never);
+ IO.enumCase(Value, "EmptyAndAttached", FormatStyle::SRS_EmptyAndAttached);
+ IO.enumCase(Value, "Empty", FormatStyle::SRS_Empty);
+ IO.enumCase(Value, "Always", FormatStyle::SRS_Always);
+ }
+};
+
template <> struct MappingTraits<FormatStyle::SortIncludesOptions> {
static void enumInput(IO &IO, FormatStyle::SortIncludesOptions &Value) {
IO.enumCase(Value, "Never", FormatStyle::SortIncludesOptions({}));
@@ -1196,6 +1205,8 @@ template <> struct MappingTraits<FormatStyle> {
Style.AllowShortLoopsOnASingleLine);
IO.mapOptional("AllowShortNamespacesOnASingleLine",
Style.AllowShortNamespacesOnASingleLine);
+ IO.mapOptional("AllowShortRecordOnASingleLine",
+ Style.AllowShortRecordOnASingleLine);
IO.mapOptional("AlwaysBreakAfterDefinitionReturnType",
Style.AlwaysBreakAfterDefinitionReturnType);
IO.mapOptional("AlwaysBreakBeforeMultilineStrings",
@@ -1763,6 +1774,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
LLVMStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_All;
LLVMStyle.AllowShortLoopsOnASingleLine = false;
LLVMStyle.AllowShortNamespacesOnASingleLine = false;
+ LLVMStyle.AllowShortRecordOnASingleLine = FormatStyle::SRS_EmptyAndAttached;
LLVMStyle.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_None;
LLVMStyle.AlwaysBreakBeforeMultilineStrings = false;
LLVMStyle.AttributeMacros.push_back("__capability");
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 305483e750e8f..a60e7fa3eb7f4 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -6043,12 +6043,15 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
return true;
}
- // Don't attempt to interpret struct return types as structs.
+ // Don't attempt to interpret record return types as records.
if (Right.isNot(TT_FunctionLBrace)) {
- return (Line.startsWith(tok::kw_class) &&
- Style.BraceWrapping.AfterClass) ||
- (Line.startsWith(tok::kw_struct) &&
- Style.BraceWrapping.AfterStruct);
+ return Style.AllowShortRecordOnASingleLine == FormatStyle::SRS_Never &&
+ ((Line.startsWith(tok::kw_class) &&
+ Style.BraceWrapping.AfterClass) ||
+ (Line.startsWith(tok::kw_struct) &&
+ Style.BraceWrapping.AfterStruct) ||
+ (Line.startsWith(tok::kw_union) &&
+ Style.BraceWrapping.AfterUnion));
}
}
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp
index bdfe17091136a..ef0e3123675cc 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -273,15 +273,22 @@ class LineJoiner {
}
}
+ // Try merging record blocks that have had their left brace wrapped into
+ // a single line.
+ if (NextLine.First->isOneOf(TT_ClassLBrace, TT_StructLBrace,
+ TT_UnionLBrace)) {
+ if (unsigned MergedLines = tryMergeRecord(I, E, Limit))
+ return MergedLines;
+ }
+
const auto *PreviousLine = I != AnnotatedLines.begin() ? I[-1] : nullptr;
- // Handle empty record blocks where the brace has already been wrapped.
+
+ // Handle blocks where the brace has already been wrapped.
if (PreviousLine && TheLine->Last->is(tok::l_brace) &&
TheLine->First == TheLine->Last) {
- bool EmptyBlock = NextLine.First->is(tok::r_brace);
+ const bool EmptyBlock = NextLine.First->is(tok::r_brace);
- const FormatToken *Tok = PreviousLine->First;
- if (Tok && Tok->is(tok::comment))
- Tok = Tok->getNextNonComment();
+ const FormatToken *Tok = PreviousLine->getFirstNonComment();
if (Tok && Tok->getNamespaceToken()) {
return !Style.BraceWrapping.SplitEmptyNamespace && EmptyBlock
@@ -291,9 +298,11 @@ class LineJoiner {
if (Tok && Tok->is(tok::kw_typedef))
Tok = Tok->getNextNonComment();
- if (Tok && Tok->isOneOf(tok::kw_class, tok::kw_struct, tok::kw_union,
- tok::kw_extern, Keywords.kw_interface,
- Keywords.kw_record)) {
+
+ if (Tok && Tok->isOneOf(tok::kw_class, tok::kw_struct, tok::kw_union))
+ return tryMergeRecord(I, E, Limit);
+
+ if (Tok && Tok->isOneOf(tok::kw_extern, Keywords.kw_interface)) {
return !Style.BraceWrapping.SplitEmptyRecord && EmptyBlock
? tryMergeSimpleBlock(I, E, Limit)
: 0;
@@ -486,7 +495,8 @@ class LineJoiner {
const FormatToken *PreviousPrevious =
Previous->getPreviousNonComment();
if (PreviousPrevious &&
- PreviousPrevious->isOneOf(tok::kw_class, tok::kw_struct)) {
+ PreviousPrevious->isOneOf(tok::kw_class, tok::kw_struct,
+ tok::kw_union)) {
return 0;
}
}
@@ -508,16 +518,12 @@ class LineJoiner {
} else if (TheLine->Last->is(TT_CompoundRequirementLBrace)) {
ShouldMerge = Style.AllowShortCompoundRequirementOnASingleLine;
} else if (TheLine->Last->isOneOf(TT_ClassLBrace, TT_StructLBrace,
- TT_RecordLBrace)) {
- // NOTE: We use AfterClass (whereas AfterStruct exists) for both classes
- // and structs, but it seems that wrapping is still handled correctly
- // elsewhere.
- ShouldMerge = !Style.BraceWrapping.AfterClass ||
- (NextLine.First->is(tok::r_brace) &&
- !Style.BraceWrapping.SplitEmptyRecord);
+ TT_UnionLBrace) ||
+ (TheLine->Last->is(TT_RecordLBrace) && Style.isJava())) {
+ return tryMergeRecord(I, E, Limit);
} else if (TheLine->InPPDirective ||
TheLine->First->isNoneOf(tok::kw_class, tok::kw_enum,
- tok::kw_struct, Keywords.kw_record)) {
+ tok::kw_struct, tok::kw_union)) {
// Try to merge a block with left brace unwrapped that wasn't yet
// covered.
ShouldMerge = !Style.BraceWrapping.AfterFunction ||
@@ -584,6 +590,73 @@ class LineJoiner {
return 0;
}
+ unsigned tryMergeRecord(ArrayRef<AnnotatedLine *>::const_iterator I,
+ ArrayRef<AnnotatedLine *>::const_iterator E,
+ unsigned Limit) {
+ const auto *Line = I[0];
+ const auto *NextLine = I[1];
+
+ // Current line begins both record and block, brace was not wrapped.
+ if (Line->Last->isOneOf(TT_ClassLBrace, TT_StructLBrace, TT_UnionLBrace)) {
+ auto ShouldWrapLBrace = [&](TokenType LBraceType) {
+ switch (LBraceType) {
+ case TT_ClassLBrace:
+ return Style.BraceWrapping.AfterClass;
+ case TT_StructLBrace:
+ return Style.BraceWrapping.AfterStruct;
+ case TT_UnionLBrace:
+ return Style.BraceWrapping.AfterUnion;
+ default:
+ return false;
+ }
+ };
+
+ auto TryMergeShortRecord = [&] {
+ switch (Style.AllowShortRecordOnASingleLine) {
+ case FormatStyle::SRS_Never:
+ return false;
+ case FormatStyle::SRS_Always:
+ return true;
+ default:
+ return NextLine->First->is(tok::r_brace);
+ }
+ };
+
+ if (Style.AllowShortRecordOnASingleLine != FormatStyle::SRS_Never &&
+ (!ShouldWrapLBrace(Line->Last->getType()) ||
+ (!Style.BraceWrapping.SplitEmptyRecord && TryMergeShortRecord()))) {
+ return tryMergeSimpleBlock(I, E, Limit);
+ }
+ }
+
+ // Cases where the l_brace was wrapped.
+ // Current line begins record, next line block.
+ if (NextLine->First->isOneOf(TT_ClassLBrace, TT_StructLBrace,
+ TT_UnionLBrace)) {
+ if (I + 2 == E || I[2]->First->is(tok::r_brace) ||
+ Style.AllowShortRecordOnASingleLine != FormatStyle::SRS_Always) {
+ return 0;
+ }
+
+ return tryMergeSimpleBlock(I, E, Limit);
+ }
+
+ // Previous line begins record, current line block.
+ if (I != AnnotatedLines.begin() &&
+ I[-1]->First->isOneOf(tok::kw_class, tok::kw_struct, tok::kw_union)) {
+ const bool IsEmptyBlock =
+ Line->Last->is(tok::l_brace) && NextLine->First->is(tok::r_brace);
+
+ if ((IsEmptyBlock && !Style.BraceWrapping.SplitEmptyRecord) ||
+ (!IsEmptyBlock &&
+ Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Always)) {
+ return tryMergeSimpleBlock(I, E, Limit);
+ }
+ }
+
+ return 0;
+ }
+
unsigned
tryMergeSimplePPDirective(ArrayRef<AnnotatedLine *>::const_iterator I,
ArrayRef<AnnotatedLine *>::const_iterator E,
@@ -891,10 +964,17 @@ class LineJoiner {
return 1;
} else if (Limit != 0 && !Line.startsWithNamespace() &&
!startsExternCBlock(Line)) {
- // We don't merge short records.
- if (isRecordLBrace(*Line.Last))
+ // Merge short records only when requested.
+ if (Line.Last->isOneOf(TT_EnumLBrace, TT_RecordLBrace))
return 0;
+ if (Line.Last->isOneOf(TT_ClassLBrace, TT_StructLBrace,
+ TT_UnionLBrace) &&
+ Line.Last != Line.First &&
+ Style.AllowShortRecordOnASingleLine != FormatStyle::SRS_Always) {
+ return 0;
+ }
+
// Check that we still have three lines and they fit into the limit.
if (I + 2 == E || I[2]->Type == LT_Invalid)
return 0;
@@ -946,9 +1026,17 @@ class LineJoiner {
return 0;
Limit -= 2;
unsigned MergedLines = 0;
- if (Style.AllowShortBlocksOnASingleLine != FormatStyle::SBS_Never ||
- (I[1]->First == I[1]->Last && I + 2 != E &&
- I[2]->First->is(tok::r_brace))) {
+
+ auto TryMergeBlock = [&] {
+ if (Style.AllowShortBlocksOnASingleLine != FormatStyle::SBS_Never ||
+ Style.AllowShortRecordOnASingleLine == FormatStyle::SRS_Always) {
+ return true;
+ }
+ return I[1]->First == I[1]->Last && I + 2 != E &&
+ I[2]->First->is(tok::r_brace);
+ };
+
+ if (TryMergeBlock()) {
MergedLines = tryMergeSimpleBlock(I + 1, E, Limit);
// If we managed to merge the block, count the statement header, which
// is on a separate line.
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index ddf584c6ed818..9cefe9408f0ab 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -953,7 +953,8 @@ static bool isIIFE(const UnwrappedLine &Line,
static bool ShouldBreakBeforeBrace(const FormatStyle &Style,
const FormatToken &InitialToken,
- const bool IsJavaRecord) {
+ bool IsEmptyBlock,
+ bool IsJavaRecord = false) {
if (IsJavaRecord)
return Style.BraceWrapping.AfterClass;
@@ -961,15 +962,20 @@ static bool ShouldBreakBeforeBrace(const FormatStyle &Style,
if (InitialToken.is(TT_NamespaceMacro))
Kind = tok::kw_namespace;
+ const bool WrapRecordAllowed =
+ !IsEmptyBlock ||
+ Style.AllowShortRecordOnASingleLine < FormatStyle::SRS_Empty ||
+ Style.BraceWrapping.SplitEmptyRecord;
+
switch (Kind) {
case tok::kw_namespace:
return Style.BraceWrapping.AfterNamespace;
case tok::kw_class:
- return Style.BraceWrapping.AfterClass;
+ return Style.BraceWrapping.AfterClass && WrapRecordAllowed;
case tok::kw_union:
- return Style.BraceWrapping.AfterUnion;
+ return Style.BraceWrapping.AfterUnion && WrapRecordAllowed;
case tok::kw_struct:
- return Style.BraceWrapping.AfterStruct;
+ return Style.BraceWrapping.AfterStruct && WrapRecordAllowed;
case tok::kw_enum:
return Style.BraceWrapping.AfterEnum;
default:
@@ -3208,8 +3214,10 @@ void UnwrappedLineParser::parseNamespace() {
if (FormatTok->is(tok::l_brace)) {
FormatTok->setFinalizedType(TT_NamespaceLBrace);
- if (ShouldBreakBeforeBrace(Style, InitialToken, /*IsJavaRecord=*/false))
+ if (ShouldBreakBeforeBrace(Style, InitialToken,
+ Tokens->peekNextToken()->is(tok::r_brace))) {
addUnwrappedLine();
+ }
unsigned AddLevels =
Style.NamespaceIndentation == FormatStyle::NI_All ||
@@ -3872,7 +3880,8 @@ bool UnwrappedLineParser::parseEnum() {
}
if (!Style.AllowShortEnumsOnASingleLine &&
- ShouldBreakBeforeBrace(Style, InitialToken, /*IsJavaRecord=*/false)) {
+ ShouldBreakBeforeBrace(Style, InitialToken,
+ Tokens->peekNextToken()->is(tok::r_brace))) {
addUnwrappedLine();
}
// Parse enum body.
@@ -4167,8 +4176,11 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr, bool IsJavaRecord) {
if (ParseAsExpr) {
parseChildBlock();
} else {
- if (ShouldBreakBeforeBrace(Style, InitialToken, IsJavaRecord))
+ if (ShouldBreakBeforeBrace(Style, InitialToken,
+ Tokens->peekNextToken()->is(tok::r_brace),
+ IsJavaRecord)) {
addUnwrappedLine();
+ }
unsigned AddLevels = Style.IndentAccessModifiers ? 2u : 1u;
parseBlock(/*MustBeDeclaration=*/true, AddLevels, /*MunchSemi=*/false);
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index 8cd0dd840acf8..8ae06bf339404 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -727,6 +727,16 @@ TEST(ConfigParseTest, ParsesConfiguration) {
CHECK_PARSE("AllowShortLambdasOnASingleLine: true",
AllowShortLambdasOnASingleLine, FormatStyle::SLS_All);
+ Style.AllowShortRecordOnASingleLine = FormatStyle::SRS_EmptyAndAttached;
+ CHECK_PARSE("AllowShortRecordOnASingleLine: Never",
+ AllowShortRecordOnASingleLine, FormatStyle::SRS_Never);
+ CHECK_PARSE("AllowShortRecordOnASingleLine: EmptyAndAttached",
+ AllowShortRecordOnASingleLine, FormatStyle::SRS_EmptyAndAttached);
+ CHECK_PARSE("AllowShortRecordOnASingleLine: Empty",
+ AllowShortRecordOnASingleLine, FormatStyle::SRS_Empty);
+ CHECK_PARSE("AllowShortRecordOnASingleLine: Always",
+ AllowShortRecordOnASingleLine, FormatStyle::SRS_Always);
+
Style.SpaceAroundPointerQualifiers = FormatStyle::SAPQ_Both;
CHECK_PARSE("SpaceAroundPointerQualifiers: Default",
SpaceAroundPointerQualifiers, FormatStyle::SAPQ_Default);
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 8d52e1a3b963f..56985abf12559 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -15637,6 +15637,101 @@ TEST_F(FormatTest, NeverMergeShortRecords) {
Style);
}
+TEST_F(FormatTest, AllowShortRecordOnASingleLine) {
+ auto Style = getLLVMStyle();
+ EXPECT_EQ(Style.AllowShortRecordOnASingleLine,
+ FormatStyle::SRS_EmptyAndAttached);
+
+ Style.AllowShortRecordOnASingleLine = FormatStyle::SRS_Never;
+ verifyFormat("class foo {\n"
+ "};\n"
+ "class bar {\n"
+ " int i;\n"
+ "};",
+ Style);
+ Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+ Style.BraceWrapping.AfterClass = true;
+ verifyFormat("class foo\n"
+ "{\n"
+ "};\n"
+ "class bar\n"
+ "{\n"
+ " int i;\n"
+ "};",
+ Style);
+ Style.BraceWrapping.SplitEmptyRecord = false;
+ verifyFormat("class foo\n"
+ "{};",
+ Style);
+
+ Style = getLLVMStyle();
+ Style.AllowShortRecordOnASingleLine = FormatStyle::SRS_Empty;
+ verifyFormat("class foo {};\n"
+ "class bar {\n"
+ " int i;\n"
+ "};",
+ Style);
+ Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+ Style.BraceWrapping.AfterClass = true;
+ verifyFormat("class foo\n"
+ "{\n"
+ "};\n"
+ "class bar\n"
+ "{\n"
+ " int i;\n"
+ "};",
+ Style);
+ Style.BraceWrapping.SplitEmptyRecord = false;
+ verifyFormat("class foo {};", Style);
+
+ Style = getLLVMStyle();
+ Style.AllowShortRecordOnASingleLine = FormatStyle::SRS_Always;
+ verifyFormat("class foo {};\n"
+ "class bar { int i; };",
+ Style);
+ Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+ Style.BraceWrapping.AfterClass = true;
+ verifyFormat("class foo\n"
+ "{\n"
+ "};\n"
+ "class bar { int i; };",
+ Style);
+ Style.BraceWrapping.SplitEmptyRecord = false;
+ verifyFormat("class foo {};", Style);
+
+ Style = getLLVMStyle();
+ Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Always;
+ Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+ Style.BraceWrapping.AfterClass = true;
+
+ Style.AllowShortRecordOnASingleLine = FormatStyle::SRS_Never;
+ verifyFormat("class foo\n"
+ "{ int i; };",
+ Style);
+ Style.AllowShortRecordOnASingleLine = FormatStyle::SRS_Empty;
+ verifyFormat("class foo\n"
+ "{ int i; };",
+ Style);
+ Style.AllowShortRecordOnASingleLine = FormatStyle::SRS_Always;
+ verifyFormat("class foo\n"
+ "{\n"
+ "};\n"
+ "class foo { int i; };",
+ Style);
+
+ Style = getLLVMStyle();
+ Style.BraceWrapping.SplitEmptyRecord = false;
+ Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+ Style.BraceWrapping.AfterClass = true;
+ Style.AllowShortRecordOnASingleLine = FormatStyle::SRS_Always;
+ verifyFormat("class foo\n"
+ "{\n"
+ " int i;\n"
+ " int j;\n"
+ "};",
+ Style);
+}
+
TEST_F(FormatTest, UnderstandContextOfRecordTypeKeywords) {
// Elaborate type variable declarations.
verifyFormat("struct foo a = {bar};\nint n;");
More information about the cfe-commits
mailing list