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 <[email protected]> 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;"); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
