[clang] [llvm] [clang-format]: Add `Custom` to `ShortFunctionStyle`; add new AllowShortFunctionsOnASingleLineOptions for granular setup (PR #134337)

via cfe-commits cfe-commits at lists.llvm.org
Sat Mar 14 20:38:18 PDT 2026


https://github.com/owenca updated https://github.com/llvm/llvm-project/pull/134337

>From df25a8bbfd827085265c51a44bedbf38deebbab4 Mon Sep 17 00:00:00 2001
From: Ivan Rymarchyk <>
Date: Sat, 29 Mar 2025 13:54:32 -0700
Subject: [PATCH 01/21] [clang-format]: Add `Custom` to `ShortFunctionStyle`;
 add new AllowShortFunctionsOnASingleLineOptions for granular setup
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The current clang-format configuration option AllowShortFunctionsOnASingleLine uses a single enum (ShortFunctionStyle) to control when short function definitions can be merged onto a single line. This enum provides predefined combinations of conditions (e.g., None, Empty only, Inline only, Inline including Empty, All).

This approach has limitations:

1. **Lack of Granularity:** Users cannot specify arbitrary combinations of conditions. For example, a user might want to allow merging for both empty functions and short top-level functions, but not for short functions defined within classes. This is not possible with the current enum options except by choosing All, which might merge more than desired.

2. **Inflexibility:** Adding new conditions for merging (e.g., distinguishing between member functions and constructors, handling lambdas specifically) would require adding many new combined enum values, leading to a combinatorial explosion and making the configuration complex.

3. **Implicit Behavior:** Some options imply others (e.g., Inline implies Empty), which might not always be intuitive or desired.

The goal is to replace this single-choice enum with a more flexible mechanism allowing users to specify a set of conditions that must be met for a short function to be merged onto a single line.

**Proposed Solution**

1. Introduce a new configuration option: AllowShortFunctionsOnSingleLineOptions.

2. This option will accept a list of strings, where each string represents a specific condition allowing merging.

3. **Backward Compatibility:**

    - If AllowShortFunctionsOnSingleLineOptions is present in the configuration, it takes precedence.

    - If AllowShortFunctionsOnSingleLineOptions is not present, but the old AllowShortFunctionsOnASingleLine is present, the old option should be parsed and mapped to the corresponding new semantics for compatibility.
---
 clang/docs/ClangFormatStyleOptions.rst      |  64 +++++++++++
 clang/include/clang/Format/Format.h         |  70 ++++++++++++
 clang/lib/Format/Format.cpp                 |  52 +++++++++
 clang/lib/Format/TokenAnnotator.cpp         |   7 +-
 clang/lib/Format/UnwrappedLineFormatter.cpp |   9 +-
 clang/unittests/Format/ConfigParseTest.cpp  |   6 ++
 clang/unittests/Format/FormatTest.cpp       | 111 ++++++++++++++++++++
 7 files changed, 310 insertions(+), 9 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index 9ecac68ae72bf..167701cf6585d 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -1959,6 +1959,70 @@ the configuration (without a prefix: ``Auto``).
       };
       void f() { bar(); }
 
+  * ``SFS_Custom`` (in configuration: ``Custom``)
+    Configure merge behavior using AllowShortFunctionsOnASingleLineOptions
+
+
+
+.. _AllowShortFunctionsOnASingleLineOptions:
+
+**AllowShortFunctionsOnASingleLineOptions** (``ShortFunctionMergeFlags``) :versionbadge:`clang-format 21` :ref:`¶ <AllowShortFunctionsOnASingleLineOptions>`
+  Precise control over merging short functions
+
+  If ``AllowShortFunctionsOnASingleLine`` is set to ``Custom``, use this to
+  specify behavior in different situations.
+
+  .. code-block:: yaml
+
+    # Example of usage:
+    AllowShortFunctionsOnASingleLine: Custom
+    AllowShortFunctionsOnASingleLineOptions:
+      Empty: false
+      Inline: true
+      All: false
+
+  Nested configuration flags:
+
+  Precise control over merging short functions
+
+  .. code-block:: c++
+
+    # Should be declared this way:
+    AllowShortFunctionsOnASingleLine: Custom
+    AllowShortFunctionsOnASingleLineOptions:
+      Empty: false
+      Inline: true
+      All: false
+
+  * ``bool Empty`` Only merge empty functions.
+
+    .. code-block:: c++
+
+      void f() {}
+      void f2() {
+        bar2();
+      }
+
+  * ``bool Inline`` Only merge functions defined inside a class.
+
+    .. code-block:: c++
+
+      class Foo {
+        void f() { foo(); }
+      };
+      void f() {
+        foo();
+      }
+      void f() {}
+
+  * ``bool All`` Merge all functions fitting on a single line.
+
+    .. code-block:: c++
+
+      class Foo {
+        void f() { foo(); }
+      };
+      void f() { bar(); }
 
 
 .. _AllowShortIfStatementsOnASingleLine:
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index fec47a248abb4..96b1ecab04e63 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -871,6 +871,8 @@ struct FormatStyle {
     ///   void f() { bar(); }
     /// \endcode
     SFS_All,
+    /// Configure merge behavior using AllowShortFunctionsOnASingleLineOptions
+    SFS_Custom,
   };
 
   /// Dependent on the value, ``int f() { return 0; }`` can be put on a
@@ -878,6 +880,72 @@ struct FormatStyle {
   /// \version 3.5
   ShortFunctionStyle AllowShortFunctionsOnASingleLine;
 
+  /// Precise control over merging short functions
+  /// \code
+  ///   # Should be declared this way:
+  ///   AllowShortFunctionsOnASingleLine: Custom
+  ///   AllowShortFunctionsOnASingleLineOptions:
+  ///     Empty: false
+  ///     Inline: true
+  ///     All: false
+  /// \endcode
+  struct ShortFunctionMergeFlags {
+    /// Only merge empty functions.
+    /// \code
+    ///   void f() {}
+    ///   void f2() {
+    ///     bar2();
+    ///   }
+    /// \endcode
+    bool Empty;
+    /// Only merge functions defined inside a class.
+    /// \code
+    ///   class Foo {
+    ///     void f() { foo(); }
+    ///   };
+    ///   void f() {
+    ///     foo();
+    ///   }
+    ///   void f() {}
+    /// \endcode
+    bool Inline;
+    /// Merge all functions fitting on a single line.
+    /// \code
+    ///   class Foo {
+    ///     void f() { foo(); }
+    ///   };
+    ///   void f() { bar(); }
+    /// \endcode
+    bool All;
+
+    ShortFunctionMergeFlags() : Empty(false), Inline(false), All(false) {}
+
+    ShortFunctionMergeFlags(bool Empty, bool Inline, bool All)
+        : Empty(Empty), Inline(Inline), All(All) {}
+
+    bool operator==(const ShortFunctionMergeFlags &R) const {
+      return Empty == R.Empty && Inline == R.Inline && All == R.All;
+    }
+    bool operator!=(const ShortFunctionMergeFlags &R) const {
+      return !(*this == R);
+    }
+  };
+
+  /// Precise control over merging short functions
+  ///
+  /// If ``AllowShortFunctionsOnASingleLine`` is set to ``Custom``, use this to
+  /// specify behavior in different situations.
+  /// \code{.yaml}
+  ///   # Example of usage:
+  ///   AllowShortFunctionsOnASingleLine: Custom
+  ///   AllowShortFunctionsOnASingleLineOptions:
+  ///     Empty: false
+  ///     Inline: true
+  ///     All: false
+  /// \endcode
+  /// \version 21
+  ShortFunctionMergeFlags AllowShortFunctionsOnASingleLineOptions;
+
   /// Different styles for handling short if statements.
   enum ShortIfStyle : int8_t {
     /// Never put short ifs on the same line.
@@ -5281,6 +5349,8 @@ struct FormatStyle {
            AllowShortEnumsOnASingleLine == R.AllowShortEnumsOnASingleLine &&
            AllowShortFunctionsOnASingleLine ==
                R.AllowShortFunctionsOnASingleLine &&
+           AllowShortFunctionsOnASingleLineOptions ==
+               R.AllowShortFunctionsOnASingleLineOptions &&
            AllowShortIfStatementsOnASingleLine ==
                R.AllowShortIfStatementsOnASingleLine &&
            AllowShortLambdasOnASingleLine == R.AllowShortLambdasOnASingleLine &&
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 28aea86139e0d..21f896c6e9cf0 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -622,6 +622,15 @@ template <> struct ScalarEnumerationTraits<FormatStyle::ShortFunctionStyle> {
     IO.enumCase(Value, "Inline", FormatStyle::SFS_Inline);
     IO.enumCase(Value, "InlineOnly", FormatStyle::SFS_InlineOnly);
     IO.enumCase(Value, "Empty", FormatStyle::SFS_Empty);
+    IO.enumCase(Value, "Custom", FormatStyle::SFS_Custom);
+  }
+};
+
+template <> struct MappingTraits<FormatStyle::ShortFunctionMergeFlags> {
+  static void mapping(IO &IO, FormatStyle::ShortFunctionMergeFlags &Value) {
+    IO.mapOptional("Empty", Value.Empty);
+    IO.mapOptional("Inline", Value.Inline);
+    IO.mapOptional("All", Value.All);
   }
 };
 
@@ -982,6 +991,8 @@ template <> struct MappingTraits<FormatStyle> {
                    Style.AllowShortEnumsOnASingleLine);
     IO.mapOptional("AllowShortFunctionsOnASingleLine",
                    Style.AllowShortFunctionsOnASingleLine);
+    IO.mapOptional("AllowShortFunctionsOnASingleLineOptions",
+                   Style.AllowShortFunctionsOnASingleLineOptions);
     IO.mapOptional("AllowShortIfStatementsOnASingleLine",
                    Style.AllowShortIfStatementsOnASingleLine);
     IO.mapOptional("AllowShortLambdasOnASingleLine",
@@ -1472,6 +1483,30 @@ static void expandPresetsSpacesInParens(FormatStyle &Expanded) {
   Expanded.SpacesInParensOptions = {};
 }
 
+static void expandPresetsShortFunctionsOnSingleLine(FormatStyle &Expanded) {
+  if (Expanded.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Custom)
+    return;
+  // Reset all flags
+  Expanded.AllowShortFunctionsOnASingleLineOptions = {};
+
+  if (Expanded.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_None)
+    return;
+
+  if (Expanded.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Empty ||
+      Expanded.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Inline) {
+    Expanded.AllowShortFunctionsOnASingleLineOptions.Empty = true;
+  }
+
+  if (Expanded.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Inline ||
+      Expanded.AllowShortFunctionsOnASingleLine ==
+          FormatStyle::SFS_InlineOnly) {
+    Expanded.AllowShortFunctionsOnASingleLineOptions.Inline = true;
+  }
+
+  if (Expanded.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_All)
+    Expanded.AllowShortFunctionsOnASingleLineOptions.All = true;
+}
+
 FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
   FormatStyle LLVMStyle;
   LLVMStyle.AccessModifierOffset = -2;
@@ -1501,6 +1536,8 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
   LLVMStyle.AllowShortCompoundRequirementOnASingleLine = true;
   LLVMStyle.AllowShortEnumsOnASingleLine = true;
   LLVMStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
+  LLVMStyle.AllowShortFunctionsOnASingleLineOptions = {};
+  LLVMStyle.AllowShortFunctionsOnASingleLineOptions.All = true;
   LLVMStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
   LLVMStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_All;
   LLVMStyle.AllowShortLoopsOnASingleLine = false;
@@ -1788,6 +1825,8 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
     GoogleStyle.AlignTrailingComments = {};
     GoogleStyle.AlignTrailingComments.Kind = FormatStyle::TCAS_Never;
     GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
+    GoogleStyle.AllowShortFunctionsOnASingleLineOptions = {};
+    GoogleStyle.AllowShortFunctionsOnASingleLineOptions.Empty = true;
     GoogleStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
     GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
     GoogleStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment;
@@ -1798,6 +1837,8 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
     GoogleStyle.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak;
     GoogleStyle.AlignOperands = FormatStyle::OAS_DontAlign;
     GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
+    GoogleStyle.AllowShortFunctionsOnASingleLineOptions = {};
+    GoogleStyle.AllowShortFunctionsOnASingleLineOptions.Empty = true;
     // TODO: still under discussion whether to switch to SLS_All.
     GoogleStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_Empty;
     GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
@@ -1815,6 +1856,8 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
     GoogleStyle.SpacesInContainerLiterals = false;
   } else if (Language == FormatStyle::LK_Proto) {
     GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
+    GoogleStyle.AllowShortFunctionsOnASingleLineOptions = {};
+    GoogleStyle.AllowShortFunctionsOnASingleLineOptions.Empty = true;
     GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
     // This affects protocol buffer options specifications and text protos.
     // Text protos are currently mostly formatted inside C++ raw string literals
@@ -1834,6 +1877,8 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
         tooling::IncludeStyle::IBS_Preserve;
   } else if (Language == FormatStyle::LK_CSharp) {
     GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
+    GoogleStyle.AllowShortFunctionsOnASingleLineOptions = {};
+    GoogleStyle.AllowShortFunctionsOnASingleLineOptions.Empty = true;
     GoogleStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
     GoogleStyle.BreakStringLiterals = false;
     GoogleStyle.ColumnLimit = 100;
@@ -1893,6 +1938,8 @@ FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language) {
   } else {
     ChromiumStyle.AllowAllParametersOfDeclarationOnNextLine = false;
     ChromiumStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
+    ChromiumStyle.AllowShortFunctionsOnASingleLineOptions = {};
+    ChromiumStyle.AllowShortFunctionsOnASingleLineOptions.Inline = true;
     ChromiumStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
     ChromiumStyle.AllowShortLoopsOnASingleLine = false;
     ChromiumStyle.BinPackParameters = FormatStyle::BPPS_OnePerLine;
@@ -1907,6 +1954,8 @@ FormatStyle getMozillaStyle() {
   FormatStyle MozillaStyle = getLLVMStyle();
   MozillaStyle.AllowAllParametersOfDeclarationOnNextLine = false;
   MozillaStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
+  MozillaStyle.AllowShortFunctionsOnASingleLineOptions = {};
+  MozillaStyle.AllowShortFunctionsOnASingleLineOptions.Inline = true;
   MozillaStyle.AlwaysBreakAfterDefinitionReturnType =
       FormatStyle::DRTBS_TopLevel;
   MozillaStyle.BinPackArguments = false;
@@ -1989,6 +2038,7 @@ FormatStyle getMicrosoftStyle(FormatStyle::LanguageKind Language) {
   Style.PenaltyReturnTypeOnItsOwnLine = 1000;
   Style.AllowShortEnumsOnASingleLine = false;
   Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
+  Style.AllowShortFunctionsOnASingleLineOptions = {};
   Style.AllowShortCaseLabelsOnASingleLine = false;
   Style.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
   Style.AllowShortLoopsOnASingleLine = false;
@@ -2160,6 +2210,7 @@ std::string configurationAsText(const FormatStyle &Style) {
   expandPresetsBraceWrapping(NonConstStyle);
   expandPresetsSpaceBeforeParens(NonConstStyle);
   expandPresetsSpacesInParens(NonConstStyle);
+  expandPresetsShortFunctionsOnSingleLine(NonConstStyle);
   Output << NonConstStyle;
 
   return Stream.str();
@@ -3722,6 +3773,7 @@ reformat(const FormatStyle &Style, StringRef Code,
   expandPresetsBraceWrapping(Expanded);
   expandPresetsSpaceBeforeParens(Expanded);
   expandPresetsSpacesInParens(Expanded);
+  expandPresetsShortFunctionsOnSingleLine(Expanded);
   Expanded.InsertBraces = false;
   Expanded.RemoveBracesLLVM = false;
   Expanded.RemoveParentheses = FormatStyle::RPS_Leave;
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index d87b3a6088bd8..c058354918140 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -5687,11 +5687,10 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
     if (Right.is(tok::r_brace) && Left.is(tok::l_brace) &&
         !Left.Children.empty()) {
       // Support AllowShortFunctionsOnASingleLine for JavaScript.
-      return Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_None ||
-             Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Empty ||
+      return (!Style.AllowShortFunctionsOnASingleLineOptions.Inline &&
+              !Style.AllowShortFunctionsOnASingleLineOptions.All) ||
              (Left.NestingLevel == 0 && Line.Level == 0 &&
-              Style.AllowShortFunctionsOnASingleLine &
-                  FormatStyle::SFS_InlineOnly);
+              Style.AllowShortFunctionsOnASingleLineOptions.Inline);
     }
   } else if (Style.Language == FormatStyle::LK_Java) {
     if (Right.is(tok::plus) && Left.is(tok::string_literal) && AfterRight &&
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp
index 000a5105ca407..5be28e895aab6 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -293,15 +293,14 @@ class LineJoiner {
 
     auto ShouldMergeShortFunctions = [this, &I, &NextLine, PreviousLine,
                                       TheLine]() {
-      if (Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_All)
+      if (Style.AllowShortFunctionsOnASingleLineOptions.All)
         return true;
-      if (Style.AllowShortFunctionsOnASingleLine >= FormatStyle::SFS_Empty &&
+      if (Style.AllowShortFunctionsOnASingleLineOptions.Empty &&
           NextLine.First->is(tok::r_brace)) {
         return true;
       }
 
-      if (Style.AllowShortFunctionsOnASingleLine &
-          FormatStyle::SFS_InlineOnly) {
+      if (Style.AllowShortFunctionsOnASingleLineOptions.Inline) {
         // Just checking TheLine->Level != 0 is not enough, because it
         // provokes treating functions inside indented namespaces as short.
         if (Style.isJavaScript() && TheLine->Last->is(TT_FunctionLBrace))
@@ -551,7 +550,7 @@ class LineJoiner {
 
       unsigned MergedLines = 0;
       if (MergeShortFunctions ||
-          (Style.AllowShortFunctionsOnASingleLine >= FormatStyle::SFS_Empty &&
+          (Style.AllowShortFunctionsOnASingleLineOptions.Empty &&
            NextLine.First == NextLine.Last && I + 2 != E &&
            I[2]->First->is(tok::r_brace))) {
         MergedLines = tryMergeSimpleBlock(I + 1, E, Limit);
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index 287191d04d885..54e484fcbe4cd 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -256,6 +256,9 @@ TEST(ConfigParseTest, ParsesConfigurationBools) {
   CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InConditionalStatements);
   CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InEmptyParentheses);
   CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, Other);
+  CHECK_PARSE_NESTED_BOOL(AllowShortFunctionsOnASingleLineOptions, Empty);
+  CHECK_PARSE_NESTED_BOOL(AllowShortFunctionsOnASingleLineOptions, Inline);
+  CHECK_PARSE_NESTED_BOOL(AllowShortFunctionsOnASingleLineOptions, All);
 }
 
 #undef CHECK_PARSE_BOOL
@@ -620,6 +623,9 @@ TEST(ConfigParseTest, ParsesConfiguration) {
               AllowShortFunctionsOnASingleLine, FormatStyle::SFS_Empty);
   CHECK_PARSE("AllowShortFunctionsOnASingleLine: All",
               AllowShortFunctionsOnASingleLine, FormatStyle::SFS_All);
+  CHECK_PARSE("AllowShortFunctionsOnASingleLine: Custom",
+              AllowShortFunctionsOnASingleLine, FormatStyle::SFS_Custom);
+
   // For backward compatibility:
   CHECK_PARSE("AllowShortFunctionsOnASingleLine: false",
               AllowShortFunctionsOnASingleLine, FormatStyle::SFS_None);
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 0b90bd360b758..868d4e375b953 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -15120,6 +15120,117 @@ TEST_F(FormatTest, PullInlineFunctionDefinitionsIntoSingleLine) {
                MergeInlineOnly);
 }
 
+TEST_F(FormatTest, CustomShortFunctionOptions) {
+  FormatStyle CustomEmpty = getLLVMStyle();
+  CustomEmpty.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Custom;
+  CustomEmpty.AllowShortFunctionsOnASingleLineOptions.Empty = true;
+  CustomEmpty.AllowShortFunctionsOnASingleLineOptions.Inline = false;
+  CustomEmpty.AllowShortFunctionsOnASingleLineOptions.All = false;
+
+  // Empty functions should be on a single line
+  verifyFormat("int f() {}", CustomEmpty);
+  verifyFormat("class C {\n"
+               "  int f() {}\n"
+               "};",
+               CustomEmpty);
+
+  // Non-empty functions should be multi-line
+  verifyFormat("int f() {\n"
+               "  return 42;\n"
+               "}",
+               CustomEmpty);
+  verifyFormat("class C {\n"
+               "  int f() {\n"
+               "    return 42;\n"
+               "  }\n"
+               "};",
+               CustomEmpty);
+
+  // Test with AfterFunction = true
+  CustomEmpty.BreakBeforeBraces = FormatStyle::BS_Custom;
+  CustomEmpty.BraceWrapping.AfterFunction = true;
+  verifyFormat("int f() {}", CustomEmpty);
+  verifyFormat("int g()\n"
+               "{\n"
+               "  return 42;\n"
+               "}",
+               CustomEmpty);
+
+  // Test with Inline = true, All = false
+  FormatStyle CustomInline = getLLVMStyle();
+  CustomInline.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Custom;
+  CustomInline.AllowShortFunctionsOnASingleLineOptions.Empty = false;
+  CustomInline.AllowShortFunctionsOnASingleLineOptions.Inline = true;
+  CustomInline.AllowShortFunctionsOnASingleLineOptions.All = false;
+
+  verifyFormat("class C {\n"
+               "  int f() {}\n"
+               "};",
+               CustomInline);
+
+  // Non-empty inline functions should be single-line
+  verifyFormat("class C {\n"
+               "  int f() { return 42; }\n"
+               "};",
+               CustomInline);
+
+  // Non-inline functions should be multi-line
+  verifyFormat("int f() {\n"
+               "  return 42;\n"
+               "}",
+               CustomInline);
+  verifyFormat("int g() {\n"
+               "}",
+               CustomInline);
+
+  // Test with All = true
+  FormatStyle CustomAll = getLLVMStyle();
+  CustomAll.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Custom;
+  CustomAll.AllowShortFunctionsOnASingleLineOptions.Empty = false;
+  CustomAll.AllowShortFunctionsOnASingleLineOptions.Inline = false;
+  CustomAll.AllowShortFunctionsOnASingleLineOptions.All = true;
+
+  // All functions should be on a single line if they fit
+  verifyFormat("int f() { return 42; }", CustomAll);
+  verifyFormat("int g() { return f() + h(); }", CustomAll);
+  verifyFormat("class C {\n"
+               "  int f() { return 42; }\n"
+               "};",
+               CustomAll);
+
+  verifyFormat("int f() {}", CustomAll);
+  verifyFormat("class C {\n"
+               "  int f() {}\n"
+               "};",
+               CustomAll);
+
+  // Test various combinations
+  FormatStyle CustomMixed = getLLVMStyle();
+  CustomMixed.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Custom;
+  CustomMixed.AllowShortFunctionsOnASingleLineOptions.Empty = true;
+  CustomMixed.AllowShortFunctionsOnASingleLineOptions.Inline = true;
+  CustomMixed.AllowShortFunctionsOnASingleLineOptions.All = false;
+
+  // Empty functions should be on a single line
+  verifyFormat("int f() {}", CustomMixed);
+  verifyFormat("class C {\n"
+               "  int f() {}\n"
+               "};",
+               CustomMixed);
+
+  // Inline non-empty functions should be on a single line
+  verifyFormat("class C {\n"
+               "  int f() { return 42; }\n"
+               "};",
+               CustomMixed);
+
+  // Non-inline non-empty functions should be multi-line
+  verifyFormat("int f() {\n"
+               "  return 42;\n"
+               "}",
+               CustomMixed);
+}
+
 TEST_F(FormatTest, PullInlineOnlyFunctionDefinitionsIntoSingleLine) {
   FormatStyle MergeInlineOnly = getLLVMStyle();
   MergeInlineOnly.AllowShortFunctionsOnASingleLine =

>From e9e4e92afca915bfeba3fac0227930a99a5daa34 Mon Sep 17 00:00:00 2001
From: Ivan Rymarchyk <>
Date: Fri, 4 Apr 2025 18:20:28 -0700
Subject: [PATCH 02/21] PR-134337: fixed PR comments

---
 clang/docs/ClangFormatStyleOptions.rst      | 11 +++++++----
 clang/include/clang/Format/Format.h         | 17 ++++++++++-------
 clang/lib/Format/Format.cpp                 |  6 +++---
 clang/lib/Format/TokenAnnotator.cpp         |  2 +-
 clang/lib/Format/UnwrappedLineFormatter.cpp |  2 +-
 clang/unittests/Format/ConfigParseTest.cpp  |  2 +-
 clang/unittests/Format/FormatTest.cpp       | 11 +++++++----
 7 files changed, 30 insertions(+), 21 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index 167701cf6585d..c0529dd138f59 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -1994,7 +1994,7 @@ the configuration (without a prefix: ``Auto``).
       Inline: true
       All: false
 
-  * ``bool Empty`` Only merge empty functions.
+  * ``bool Empty`` Merge top-level empty functions.
 
     .. code-block:: c++
 
@@ -2002,20 +2002,23 @@ the configuration (without a prefix: ``Auto``).
       void f2() {
         bar2();
       }
+      void f3() { /* comment */ }
 
-  * ``bool Inline`` Only merge functions defined inside a class.
+  * ``bool Inline`` Merge functions defined inside a class.
 
     .. code-block:: c++
 
       class Foo {
         void f() { foo(); }
+        void g() {}
       };
       void f() {
         foo();
       }
-      void f() {}
+      void f() {
+      }
 
-  * ``bool All`` Merge all functions fitting on a single line.
+  * ``bool Other`` Merge all functions fitting on a single line.
 
     .. code-block:: c++
 
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 96b1ecab04e63..971b978adc2c7 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -890,23 +890,26 @@ struct FormatStyle {
   ///     All: false
   /// \endcode
   struct ShortFunctionMergeFlags {
-    /// Only merge empty functions.
+    /// Merge top-level empty functions.
     /// \code
     ///   void f() {}
     ///   void f2() {
     ///     bar2();
     ///   }
+    ///   void f3() { /* comment */ }
     /// \endcode
     bool Empty;
-    /// Only merge functions defined inside a class.
+    /// Merge functions defined inside a class.
     /// \code
     ///   class Foo {
     ///     void f() { foo(); }
+    ///     void g() {}
     ///   };
     ///   void f() {
     ///     foo();
     ///   }
-    ///   void f() {}
+    ///   void f() {
+    ///   }
     /// \endcode
     bool Inline;
     /// Merge all functions fitting on a single line.
@@ -916,15 +919,15 @@ struct FormatStyle {
     ///   };
     ///   void f() { bar(); }
     /// \endcode
-    bool All;
+    bool Other;
 
-    ShortFunctionMergeFlags() : Empty(false), Inline(false), All(false) {}
+    ShortFunctionMergeFlags() : Empty(false), Inline(false), Other(false) {}
 
     ShortFunctionMergeFlags(bool Empty, bool Inline, bool All)
-        : Empty(Empty), Inline(Inline), All(All) {}
+        : Empty(Empty), Inline(Inline), Other(All) {}
 
     bool operator==(const ShortFunctionMergeFlags &R) const {
-      return Empty == R.Empty && Inline == R.Inline && All == R.All;
+      return Empty == R.Empty && Inline == R.Inline && Other == R.Other;
     }
     bool operator!=(const ShortFunctionMergeFlags &R) const {
       return !(*this == R);
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 21f896c6e9cf0..aff38f56f05e3 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -630,7 +630,7 @@ template <> struct MappingTraits<FormatStyle::ShortFunctionMergeFlags> {
   static void mapping(IO &IO, FormatStyle::ShortFunctionMergeFlags &Value) {
     IO.mapOptional("Empty", Value.Empty);
     IO.mapOptional("Inline", Value.Inline);
-    IO.mapOptional("All", Value.All);
+    IO.mapOptional("Other", Value.Other);
   }
 };
 
@@ -1504,7 +1504,7 @@ static void expandPresetsShortFunctionsOnSingleLine(FormatStyle &Expanded) {
   }
 
   if (Expanded.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_All)
-    Expanded.AllowShortFunctionsOnASingleLineOptions.All = true;
+    Expanded.AllowShortFunctionsOnASingleLineOptions.Other = true;
 }
 
 FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
@@ -1537,7 +1537,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
   LLVMStyle.AllowShortEnumsOnASingleLine = true;
   LLVMStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
   LLVMStyle.AllowShortFunctionsOnASingleLineOptions = {};
-  LLVMStyle.AllowShortFunctionsOnASingleLineOptions.All = true;
+  LLVMStyle.AllowShortFunctionsOnASingleLineOptions.Other = true;
   LLVMStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
   LLVMStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_All;
   LLVMStyle.AllowShortLoopsOnASingleLine = false;
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index c058354918140..cdf46f65e8b52 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -5688,7 +5688,7 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
         !Left.Children.empty()) {
       // Support AllowShortFunctionsOnASingleLine for JavaScript.
       return (!Style.AllowShortFunctionsOnASingleLineOptions.Inline &&
-              !Style.AllowShortFunctionsOnASingleLineOptions.All) ||
+              !Style.AllowShortFunctionsOnASingleLineOptions.Other) ||
              (Left.NestingLevel == 0 && Line.Level == 0 &&
               Style.AllowShortFunctionsOnASingleLineOptions.Inline);
     }
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp
index 5be28e895aab6..6f30bbc8a9e5f 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -293,7 +293,7 @@ class LineJoiner {
 
     auto ShouldMergeShortFunctions = [this, &I, &NextLine, PreviousLine,
                                       TheLine]() {
-      if (Style.AllowShortFunctionsOnASingleLineOptions.All)
+      if (Style.AllowShortFunctionsOnASingleLineOptions.Other)
         return true;
       if (Style.AllowShortFunctionsOnASingleLineOptions.Empty &&
           NextLine.First->is(tok::r_brace)) {
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index 54e484fcbe4cd..16ab406c9cade 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -258,7 +258,7 @@ TEST(ConfigParseTest, ParsesConfigurationBools) {
   CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, Other);
   CHECK_PARSE_NESTED_BOOL(AllowShortFunctionsOnASingleLineOptions, Empty);
   CHECK_PARSE_NESTED_BOOL(AllowShortFunctionsOnASingleLineOptions, Inline);
-  CHECK_PARSE_NESTED_BOOL(AllowShortFunctionsOnASingleLineOptions, All);
+  CHECK_PARSE_NESTED_BOOL(AllowShortFunctionsOnASingleLineOptions, Other);
 }
 
 #undef CHECK_PARSE_BOOL
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 868d4e375b953..79ee1230eb6a7 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -15125,7 +15125,7 @@ TEST_F(FormatTest, CustomShortFunctionOptions) {
   CustomEmpty.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Custom;
   CustomEmpty.AllowShortFunctionsOnASingleLineOptions.Empty = true;
   CustomEmpty.AllowShortFunctionsOnASingleLineOptions.Inline = false;
-  CustomEmpty.AllowShortFunctionsOnASingleLineOptions.All = false;
+  CustomEmpty.AllowShortFunctionsOnASingleLineOptions.Other = false;
 
   // Empty functions should be on a single line
   verifyFormat("int f() {}", CustomEmpty);
@@ -15146,6 +15146,9 @@ TEST_F(FormatTest, CustomShortFunctionOptions) {
                "};",
                CustomEmpty);
 
+  // test with comment
+  verifyFormat("void f3() { /* comment */ }", CustomEmpty);
+
   // Test with AfterFunction = true
   CustomEmpty.BreakBeforeBraces = FormatStyle::BS_Custom;
   CustomEmpty.BraceWrapping.AfterFunction = true;
@@ -15161,7 +15164,7 @@ TEST_F(FormatTest, CustomShortFunctionOptions) {
   CustomInline.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Custom;
   CustomInline.AllowShortFunctionsOnASingleLineOptions.Empty = false;
   CustomInline.AllowShortFunctionsOnASingleLineOptions.Inline = true;
-  CustomInline.AllowShortFunctionsOnASingleLineOptions.All = false;
+  CustomInline.AllowShortFunctionsOnASingleLineOptions.Other = false;
 
   verifyFormat("class C {\n"
                "  int f() {}\n"
@@ -15188,7 +15191,7 @@ TEST_F(FormatTest, CustomShortFunctionOptions) {
   CustomAll.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Custom;
   CustomAll.AllowShortFunctionsOnASingleLineOptions.Empty = false;
   CustomAll.AllowShortFunctionsOnASingleLineOptions.Inline = false;
-  CustomAll.AllowShortFunctionsOnASingleLineOptions.All = true;
+  CustomAll.AllowShortFunctionsOnASingleLineOptions.Other = true;
 
   // All functions should be on a single line if they fit
   verifyFormat("int f() { return 42; }", CustomAll);
@@ -15209,7 +15212,7 @@ TEST_F(FormatTest, CustomShortFunctionOptions) {
   CustomMixed.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Custom;
   CustomMixed.AllowShortFunctionsOnASingleLineOptions.Empty = true;
   CustomMixed.AllowShortFunctionsOnASingleLineOptions.Inline = true;
-  CustomMixed.AllowShortFunctionsOnASingleLineOptions.All = false;
+  CustomMixed.AllowShortFunctionsOnASingleLineOptions.Other = false;
 
   // Empty functions should be on a single line
   verifyFormat("int f() {}", CustomMixed);

>From b1fd41217c49400248780ba6fb7a2ac0a355937c Mon Sep 17 00:00:00 2001
From: Ivan Rymarchyk <>
Date: Mon, 7 Apr 2025 21:05:17 -0700
Subject: [PATCH 03/21] Updated configuration with new suggestion - reuse
 existing option

---
 clang/docs/ClangFormatStyleOptions.rst        |  51 ++----
 clang/include/clang/Format/Format.h           | 152 ++++++++----------
 clang/lib/Format/Format.cpp                   | 120 +++++++-------
 clang/lib/Format/TokenAnnotator.cpp           |   7 +-
 clang/lib/Format/UnwrappedLineFormatter.cpp   |   8 +-
 clang/unittests/Format/ConfigParseTest.cpp    |  38 +++--
 .../Format/DefinitionBlockSeparatorTest.cpp   |   4 +-
 clang/unittests/Format/FormatTest.cpp         | 124 +++++++++-----
 clang/unittests/Format/FormatTestCSharp.cpp   |   5 +-
 clang/unittests/Format/FormatTestJS.cpp       |  27 +++-
 clang/unittests/Format/FormatTestJava.cpp     |   5 +-
 11 files changed, 289 insertions(+), 252 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index c0529dd138f59..6f3b9f798093f 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -1905,12 +1905,16 @@ the configuration (without a prefix: ``Auto``).
   Dependent on the value, ``int f() { return 0; }`` can be put on a
   single line.
 
-  Possible values:
+  Nested configuration flags:
+
+  Different styles for merging short functions containing at most one
+  statement.
 
-  * ``SFS_None`` (in configuration: ``None``)
+  They can be read as a whole for compatibility. The choices are:
+  * ``None``
     Never merge functions into a single line.
 
-  * ``SFS_InlineOnly`` (in configuration: ``InlineOnly``)
+  * ``InlineOnly``
     Only merge functions defined inside a class. Same as ``inline``,
     except it does not implies ``empty``: i.e. top level empty functions
     are not merged either.
@@ -1926,7 +1930,7 @@ the configuration (without a prefix: ``Auto``).
       void f() {
       }
 
-  * ``SFS_Empty`` (in configuration: ``Empty``)
+  * ``Empty``
     Only merge empty functions.
 
     .. code-block:: c++
@@ -1936,7 +1940,7 @@ the configuration (without a prefix: ``Auto``).
         bar2();
       }
 
-  * ``SFS_Inline`` (in configuration: ``Inline``)
+  * ``Inline``
     Only merge functions defined inside a class. Implies ``empty``.
 
     .. code-block:: c++
@@ -1949,7 +1953,7 @@ the configuration (without a prefix: ``Auto``).
       }
       void f() {}
 
-  * ``SFS_All`` (in configuration: ``All``)
+  * ``All``
     Merge all functions fitting on a single line.
 
     .. code-block:: c++
@@ -1959,37 +1963,15 @@ the configuration (without a prefix: ``Auto``).
       };
       void f() { bar(); }
 
-  * ``SFS_Custom`` (in configuration: ``Custom``)
-    Configure merge behavior using AllowShortFunctionsOnASingleLineOptions
-
+  Also can be specified as a nested configuration flag:
 
-
-.. _AllowShortFunctionsOnASingleLineOptions:
-
-**AllowShortFunctionsOnASingleLineOptions** (``ShortFunctionMergeFlags``) :versionbadge:`clang-format 21` :ref:`¶ <AllowShortFunctionsOnASingleLineOptions>`
-  Precise control over merging short functions
-
-  If ``AllowShortFunctionsOnASingleLine`` is set to ``Custom``, use this to
-  specify behavior in different situations.
-
-  .. code-block:: yaml
+  .. code-block:: c++
 
     # Example of usage:
-    AllowShortFunctionsOnASingleLine: Custom
-    AllowShortFunctionsOnASingleLineOptions:
-      Empty: false
-      Inline: true
-      All: false
-
-  Nested configuration flags:
-
-  Precise control over merging short functions
+    AllowShortFunctionsOnASingleLine: InlineOnly
 
-  .. code-block:: c++
-
-    # Should be declared this way:
-    AllowShortFunctionsOnASingleLine: Custom
-    AllowShortFunctionsOnASingleLineOptions:
+    # or more granular control:
+    AllowShortFunctionsOnASingleLine:
       Empty: false
       Inline: true
       All: false
@@ -2018,7 +2000,8 @@ the configuration (without a prefix: ``Auto``).
       void f() {
       }
 
-  * ``bool Other`` Merge all functions fitting on a single line.
+  * ``bool Other`` Merge all functions fitting on a single line. Please note that this
+    control does not include Empty
 
     .. code-block:: c++
 
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 971b978adc2c7..2278bf3966296 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -827,69 +827,68 @@ struct FormatStyle {
 
   /// Different styles for merging short functions containing at most one
   /// statement.
-  enum ShortFunctionStyle : int8_t {
-    /// Never merge functions into a single line.
-    SFS_None,
-    /// Only merge functions defined inside a class. Same as ``inline``,
-    /// except it does not implies ``empty``: i.e. top level empty functions
-    /// are not merged either.
-    /// \code
-    ///   class Foo {
-    ///     void f() { foo(); }
-    ///   };
-    ///   void f() {
-    ///     foo();
-    ///   }
-    ///   void f() {
-    ///   }
-    /// \endcode
-    SFS_InlineOnly,
-    /// Only merge empty functions.
-    /// \code
-    ///   void f() {}
-    ///   void f2() {
-    ///     bar2();
-    ///   }
-    /// \endcode
-    SFS_Empty,
-    /// Only merge functions defined inside a class. Implies ``empty``.
-    /// \code
-    ///   class Foo {
-    ///     void f() { foo(); }
-    ///   };
-    ///   void f() {
-    ///     foo();
-    ///   }
-    ///   void f() {}
-    /// \endcode
-    SFS_Inline,
-    /// Merge all functions fitting on a single line.
-    /// \code
-    ///   class Foo {
-    ///     void f() { foo(); }
-    ///   };
-    ///   void f() { bar(); }
-    /// \endcode
-    SFS_All,
-    /// Configure merge behavior using AllowShortFunctionsOnASingleLineOptions
-    SFS_Custom,
-  };
-
-  /// Dependent on the value, ``int f() { return 0; }`` can be put on a
-  /// single line.
-  /// \version 3.5
-  ShortFunctionStyle AllowShortFunctionsOnASingleLine;
-
-  /// Precise control over merging short functions
+  ///
+  /// They can be read as a whole for compatibility. The choices are:
+  /// * ``None``
+  ///   Never merge functions into a single line.
+  ///
+  /// * ``InlineOnly``
+  ///   Only merge functions defined inside a class. Same as ``inline``,
+  ///   except it does not implies ``empty``: i.e. top level empty functions
+  ///   are not merged either.
+  ///   \code
+  ///     class Foo {
+  ///       void f() { foo(); }
+  ///     };
+  ///     void f() {
+  ///       foo();
+  ///     }
+  ///     void f() {
+  ///     }
+  ///   \endcode
+  ///
+  /// * ``Empty``
+  ///   Only merge empty functions.
+  ///   \code
+  ///     void f() {}
+  ///     void f2() {
+  ///       bar2();
+  ///     }
+  ///   \endcode
+  ///
+  /// * ``Inline``
+  ///   Only merge functions defined inside a class. Implies ``empty``.
+  ///   \code
+  ///     class Foo {
+  ///       void f() { foo(); }
+  ///     };
+  ///     void f() {
+  ///       foo();
+  ///     }
+  ///     void f() {}
+  ///   \endcode
+  ///
+  /// * ``All``
+  ///   Merge all functions fitting on a single line.
+  ///   \code
+  ///     class Foo {
+  ///       void f() { foo(); }
+  ///     };
+  ///     void f() { bar(); }
+  ///   \endcode
+  ///
+  /// Also can be specified as a nested configuration flag:
   /// \code
-  ///   # Should be declared this way:
-  ///   AllowShortFunctionsOnASingleLine: Custom
-  ///   AllowShortFunctionsOnASingleLineOptions:
+  ///   # Example of usage:
+  ///   AllowShortFunctionsOnASingleLine: InlineOnly
+  ///
+  ///   # or more granular control:
+  ///   AllowShortFunctionsOnASingleLine:
   ///     Empty: false
   ///     Inline: true
   ///     All: false
   /// \endcode
-  struct ShortFunctionMergeFlags {
+  struct ShortFunctionStyle {
     /// Merge top-level empty functions.
     /// \code
     ///   void f() {}
@@ -912,7 +911,8 @@ struct FormatStyle {
     ///   }
     /// \endcode
     bool Inline;
-    /// Merge all functions fitting on a single line.
+    /// Merge all functions fitting on a single line. Please note that this
+    /// control does not include Empty
     /// \code
     ///   class Foo {
     ///     void f() { foo(); }
@@ -921,33 +921,19 @@ struct FormatStyle {
     /// \endcode
     bool Other;
 
-    ShortFunctionMergeFlags() : Empty(false), Inline(false), Other(false) {}
-
-    ShortFunctionMergeFlags(bool Empty, bool Inline, bool All)
-        : Empty(Empty), Inline(Inline), Other(All) {}
-
-    bool operator==(const ShortFunctionMergeFlags &R) const {
+    bool operator==(const ShortFunctionStyle &R) const {
       return Empty == R.Empty && Inline == R.Inline && Other == R.Other;
     }
-    bool operator!=(const ShortFunctionMergeFlags &R) const {
-      return !(*this == R);
-    }
+    bool operator!=(const ShortFunctionStyle &R) const { return !(*this == R); }
+    ShortFunctionStyle() : Empty(false), Inline(false), Other(false) {}
+    ShortFunctionStyle(bool Empty, bool Inline, bool Other)
+        : Empty(Empty), Inline(Inline), Other(Other) {}
   };
 
-  /// Precise control over merging short functions
-  ///
-  /// If ``AllowShortFunctionsOnASingleLine`` is set to ``Custom``, use this to
-  /// specify behavior in different situations.
-  /// \code{.yaml}
-  ///   # Example of usage:
-  ///   AllowShortFunctionsOnASingleLine: Custom
-  ///   AllowShortFunctionsOnASingleLineOptions:
-  ///     Empty: false
-  ///     Inline: true
-  ///     All: false
-  /// \endcode
-  /// \version 21
-  ShortFunctionMergeFlags AllowShortFunctionsOnASingleLineOptions;
+  /// Dependent on the value, ``int f() { return 0; }`` can be put on a
+  /// single line.
+  /// \version 3.5
+  ShortFunctionStyle AllowShortFunctionsOnASingleLine;
 
   /// Different styles for handling short if statements.
   enum ShortIfStyle : int8_t {
@@ -5352,8 +5338,6 @@ struct FormatStyle {
            AllowShortEnumsOnASingleLine == R.AllowShortEnumsOnASingleLine &&
            AllowShortFunctionsOnASingleLine ==
                R.AllowShortFunctionsOnASingleLine &&
-           AllowShortFunctionsOnASingleLineOptions ==
-               R.AllowShortFunctionsOnASingleLineOptions &&
            AllowShortIfStatementsOnASingleLine ==
                R.AllowShortIfStatementsOnASingleLine &&
            AllowShortLambdasOnASingleLine == R.AllowShortLambdasOnASingleLine &&
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index aff38f56f05e3..c1a7a0a034a22 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -613,21 +613,35 @@ template <> struct ScalarEnumerationTraits<FormatStyle::ShortBlockStyle> {
   }
 };
 
-template <> struct ScalarEnumerationTraits<FormatStyle::ShortFunctionStyle> {
-  static void enumeration(IO &IO, FormatStyle::ShortFunctionStyle &Value) {
-    IO.enumCase(Value, "None", FormatStyle::SFS_None);
-    IO.enumCase(Value, "false", FormatStyle::SFS_None);
-    IO.enumCase(Value, "All", FormatStyle::SFS_All);
-    IO.enumCase(Value, "true", FormatStyle::SFS_All);
-    IO.enumCase(Value, "Inline", FormatStyle::SFS_Inline);
-    IO.enumCase(Value, "InlineOnly", FormatStyle::SFS_InlineOnly);
-    IO.enumCase(Value, "Empty", FormatStyle::SFS_Empty);
-    IO.enumCase(Value, "Custom", FormatStyle::SFS_Custom);
+template <> struct MappingTraits<FormatStyle::ShortFunctionStyle> {
+  static void enumInput(IO &IO, FormatStyle::ShortFunctionStyle &Value) {
+    IO.enumCase(Value, "None", FormatStyle::ShortFunctionStyle({}));
+    IO.enumCase(Value, "Empty",
+                FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                                 /*Inline=*/false,
+                                                 /*Other=*/false}));
+    IO.enumCase(Value, "Inline",
+                FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                                 /*Inline=*/true,
+                                                 /*Other=*/false}));
+    IO.enumCase(Value, "InlineOnly",
+                FormatStyle::ShortFunctionStyle({/*Empty=*/false,
+                                                 /*Inline=*/true,
+                                                 /*Other=*/false}));
+    IO.enumCase(Value, "All",
+                FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                                 /*Inline=*/true,
+                                                 /*Other=*/true}));
+
+    // For backward compatibility.
+    IO.enumCase(Value, "true",
+                FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                                 /*Inline=*/true,
+                                                 /*Other=*/true}));
+    IO.enumCase(Value, "false", FormatStyle::ShortFunctionStyle({}));
   }
-};
 
-template <> struct MappingTraits<FormatStyle::ShortFunctionMergeFlags> {
-  static void mapping(IO &IO, FormatStyle::ShortFunctionMergeFlags &Value) {
+  static void mapping(IO &IO, FormatStyle::ShortFunctionStyle &Value) {
     IO.mapOptional("Empty", Value.Empty);
     IO.mapOptional("Inline", Value.Inline);
     IO.mapOptional("Other", Value.Other);
@@ -991,8 +1005,6 @@ template <> struct MappingTraits<FormatStyle> {
                    Style.AllowShortEnumsOnASingleLine);
     IO.mapOptional("AllowShortFunctionsOnASingleLine",
                    Style.AllowShortFunctionsOnASingleLine);
-    IO.mapOptional("AllowShortFunctionsOnASingleLineOptions",
-                   Style.AllowShortFunctionsOnASingleLineOptions);
     IO.mapOptional("AllowShortIfStatementsOnASingleLine",
                    Style.AllowShortIfStatementsOnASingleLine);
     IO.mapOptional("AllowShortLambdasOnASingleLine",
@@ -1483,30 +1495,6 @@ static void expandPresetsSpacesInParens(FormatStyle &Expanded) {
   Expanded.SpacesInParensOptions = {};
 }
 
-static void expandPresetsShortFunctionsOnSingleLine(FormatStyle &Expanded) {
-  if (Expanded.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Custom)
-    return;
-  // Reset all flags
-  Expanded.AllowShortFunctionsOnASingleLineOptions = {};
-
-  if (Expanded.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_None)
-    return;
-
-  if (Expanded.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Empty ||
-      Expanded.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Inline) {
-    Expanded.AllowShortFunctionsOnASingleLineOptions.Empty = true;
-  }
-
-  if (Expanded.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Inline ||
-      Expanded.AllowShortFunctionsOnASingleLine ==
-          FormatStyle::SFS_InlineOnly) {
-    Expanded.AllowShortFunctionsOnASingleLineOptions.Inline = true;
-  }
-
-  if (Expanded.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_All)
-    Expanded.AllowShortFunctionsOnASingleLineOptions.Other = true;
-}
-
 FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
   FormatStyle LLVMStyle;
   LLVMStyle.AccessModifierOffset = -2;
@@ -1535,9 +1523,10 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
   LLVMStyle.AllowShortCaseLabelsOnASingleLine = false;
   LLVMStyle.AllowShortCompoundRequirementOnASingleLine = true;
   LLVMStyle.AllowShortEnumsOnASingleLine = true;
-  LLVMStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
-  LLVMStyle.AllowShortFunctionsOnASingleLineOptions = {};
-  LLVMStyle.AllowShortFunctionsOnASingleLineOptions.Other = true;
+  LLVMStyle.AllowShortFunctionsOnASingleLine =
+      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                       /*Inline=*/true,
+                                       /*Other=*/true});
   LLVMStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
   LLVMStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_All;
   LLVMStyle.AllowShortLoopsOnASingleLine = false;
@@ -1824,9 +1813,10 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
     GoogleStyle.AlignOperands = FormatStyle::OAS_DontAlign;
     GoogleStyle.AlignTrailingComments = {};
     GoogleStyle.AlignTrailingComments.Kind = FormatStyle::TCAS_Never;
-    GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
-    GoogleStyle.AllowShortFunctionsOnASingleLineOptions = {};
-    GoogleStyle.AllowShortFunctionsOnASingleLineOptions.Empty = true;
+    GoogleStyle.AllowShortFunctionsOnASingleLine =
+        FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                         /*Inline=*/false,
+                                         /*Other=*/false});
     GoogleStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
     GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
     GoogleStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment;
@@ -1836,9 +1826,10 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
   } else if (Language == FormatStyle::LK_JavaScript) {
     GoogleStyle.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak;
     GoogleStyle.AlignOperands = FormatStyle::OAS_DontAlign;
-    GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
-    GoogleStyle.AllowShortFunctionsOnASingleLineOptions = {};
-    GoogleStyle.AllowShortFunctionsOnASingleLineOptions.Empty = true;
+    GoogleStyle.AllowShortFunctionsOnASingleLine =
+        FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                         /*Inline=*/false,
+                                         /*Other=*/false});
     // TODO: still under discussion whether to switch to SLS_All.
     GoogleStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_Empty;
     GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
@@ -1855,9 +1846,10 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
     GoogleStyle.NamespaceIndentation = FormatStyle::NI_All;
     GoogleStyle.SpacesInContainerLiterals = false;
   } else if (Language == FormatStyle::LK_Proto) {
-    GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
-    GoogleStyle.AllowShortFunctionsOnASingleLineOptions = {};
-    GoogleStyle.AllowShortFunctionsOnASingleLineOptions.Empty = true;
+    GoogleStyle.AllowShortFunctionsOnASingleLine =
+        FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                         /*Inline=*/false,
+                                         /*Other=*/false});
     GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
     // This affects protocol buffer options specifications and text protos.
     // Text protos are currently mostly formatted inside C++ raw string literals
@@ -1876,9 +1868,10 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
     GoogleStyle.IncludeStyle.IncludeBlocks =
         tooling::IncludeStyle::IBS_Preserve;
   } else if (Language == FormatStyle::LK_CSharp) {
-    GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
-    GoogleStyle.AllowShortFunctionsOnASingleLineOptions = {};
-    GoogleStyle.AllowShortFunctionsOnASingleLineOptions.Empty = true;
+    GoogleStyle.AllowShortFunctionsOnASingleLine =
+        FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                         /*Inline=*/false,
+                                         /*Other=*/false});
     GoogleStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
     GoogleStyle.BreakStringLiterals = false;
     GoogleStyle.ColumnLimit = 100;
@@ -1937,9 +1930,10 @@ FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language) {
     ChromiumStyle.AllowShortLoopsOnASingleLine = false;
   } else {
     ChromiumStyle.AllowAllParametersOfDeclarationOnNextLine = false;
-    ChromiumStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
-    ChromiumStyle.AllowShortFunctionsOnASingleLineOptions = {};
-    ChromiumStyle.AllowShortFunctionsOnASingleLineOptions.Inline = true;
+    ChromiumStyle.AllowShortFunctionsOnASingleLine =
+        FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                         /*Inline=*/true,
+                                         /*Other=*/false});
     ChromiumStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
     ChromiumStyle.AllowShortLoopsOnASingleLine = false;
     ChromiumStyle.BinPackParameters = FormatStyle::BPPS_OnePerLine;
@@ -1953,9 +1947,10 @@ FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language) {
 FormatStyle getMozillaStyle() {
   FormatStyle MozillaStyle = getLLVMStyle();
   MozillaStyle.AllowAllParametersOfDeclarationOnNextLine = false;
-  MozillaStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
-  MozillaStyle.AllowShortFunctionsOnASingleLineOptions = {};
-  MozillaStyle.AllowShortFunctionsOnASingleLineOptions.Inline = true;
+  MozillaStyle.AllowShortFunctionsOnASingleLine =
+      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                       /*Inline=*/true,
+                                       /*Other=*/false});
   MozillaStyle.AlwaysBreakAfterDefinitionReturnType =
       FormatStyle::DRTBS_TopLevel;
   MozillaStyle.BinPackArguments = false;
@@ -2037,8 +2032,7 @@ FormatStyle getMicrosoftStyle(FormatStyle::LanguageKind Language) {
   Style.BraceWrapping.BeforeWhile = false;
   Style.PenaltyReturnTypeOnItsOwnLine = 1000;
   Style.AllowShortEnumsOnASingleLine = false;
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
-  Style.AllowShortFunctionsOnASingleLineOptions = {};
+  Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
   Style.AllowShortCaseLabelsOnASingleLine = false;
   Style.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
   Style.AllowShortLoopsOnASingleLine = false;
@@ -2210,7 +2204,6 @@ std::string configurationAsText(const FormatStyle &Style) {
   expandPresetsBraceWrapping(NonConstStyle);
   expandPresetsSpaceBeforeParens(NonConstStyle);
   expandPresetsSpacesInParens(NonConstStyle);
-  expandPresetsShortFunctionsOnSingleLine(NonConstStyle);
   Output << NonConstStyle;
 
   return Stream.str();
@@ -3773,7 +3766,6 @@ reformat(const FormatStyle &Style, StringRef Code,
   expandPresetsBraceWrapping(Expanded);
   expandPresetsSpaceBeforeParens(Expanded);
   expandPresetsSpacesInParens(Expanded);
-  expandPresetsShortFunctionsOnSingleLine(Expanded);
   Expanded.InsertBraces = false;
   Expanded.RemoveBracesLLVM = false;
   Expanded.RemoveParentheses = FormatStyle::RPS_Leave;
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index cdf46f65e8b52..db2f8766f8d40 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -5687,10 +5687,11 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
     if (Right.is(tok::r_brace) && Left.is(tok::l_brace) &&
         !Left.Children.empty()) {
       // Support AllowShortFunctionsOnASingleLine for JavaScript.
-      return (!Style.AllowShortFunctionsOnASingleLineOptions.Inline &&
-              !Style.AllowShortFunctionsOnASingleLineOptions.Other) ||
+      return (!Style.AllowShortFunctionsOnASingleLine.Inline &&
+              !Style.AllowShortFunctionsOnASingleLine.Other) ||
              (Left.NestingLevel == 0 && Line.Level == 0 &&
-              Style.AllowShortFunctionsOnASingleLineOptions.Inline);
+              Style.AllowShortFunctionsOnASingleLine.Inline &&
+              !Style.AllowShortFunctionsOnASingleLine.Other);
     }
   } else if (Style.Language == FormatStyle::LK_Java) {
     if (Right.is(tok::plus) && Left.is(tok::string_literal) && AfterRight &&
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp
index 6f30bbc8a9e5f..fdec849cf363a 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -293,14 +293,14 @@ class LineJoiner {
 
     auto ShouldMergeShortFunctions = [this, &I, &NextLine, PreviousLine,
                                       TheLine]() {
-      if (Style.AllowShortFunctionsOnASingleLineOptions.Other)
+      if (Style.AllowShortFunctionsOnASingleLine.Other)
         return true;
-      if (Style.AllowShortFunctionsOnASingleLineOptions.Empty &&
+      if (Style.AllowShortFunctionsOnASingleLine.Empty &&
           NextLine.First->is(tok::r_brace)) {
         return true;
       }
 
-      if (Style.AllowShortFunctionsOnASingleLineOptions.Inline) {
+      if (Style.AllowShortFunctionsOnASingleLine.Inline) {
         // Just checking TheLine->Level != 0 is not enough, because it
         // provokes treating functions inside indented namespaces as short.
         if (Style.isJavaScript() && TheLine->Last->is(TT_FunctionLBrace))
@@ -550,7 +550,7 @@ class LineJoiner {
 
       unsigned MergedLines = 0;
       if (MergeShortFunctions ||
-          (Style.AllowShortFunctionsOnASingleLineOptions.Empty &&
+          (Style.AllowShortFunctionsOnASingleLine.Empty &&
            NextLine.First == NextLine.Last && I + 2 != E &&
            I[2]->First->is(tok::r_brace))) {
         MergedLines = tryMergeSimpleBlock(I + 1, E, Limit);
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index 16ab406c9cade..c022db94cdb6a 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -256,9 +256,6 @@ TEST(ConfigParseTest, ParsesConfigurationBools) {
   CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InConditionalStatements);
   CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InEmptyParentheses);
   CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, Other);
-  CHECK_PARSE_NESTED_BOOL(AllowShortFunctionsOnASingleLineOptions, Empty);
-  CHECK_PARSE_NESTED_BOOL(AllowShortFunctionsOnASingleLineOptions, Inline);
-  CHECK_PARSE_NESTED_BOOL(AllowShortFunctionsOnASingleLineOptions, Other);
 }
 
 #undef CHECK_PARSE_BOOL
@@ -614,23 +611,40 @@ TEST(ConfigParseTest, ParsesConfiguration) {
   CHECK_PARSE("AllowShortBlocksOnASingleLine: true",
               AllowShortBlocksOnASingleLine, FormatStyle::SBS_Always);
 
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
+  // Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
   CHECK_PARSE("AllowShortFunctionsOnASingleLine: None",
-              AllowShortFunctionsOnASingleLine, FormatStyle::SFS_None);
+              AllowShortFunctionsOnASingleLine,
+              FormatStyle::ShortFunctionStyle({}));
   CHECK_PARSE("AllowShortFunctionsOnASingleLine: Inline",
-              AllowShortFunctionsOnASingleLine, FormatStyle::SFS_Inline);
+              AllowShortFunctionsOnASingleLine,
+              FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                               /*Inline=*/true,
+                                               /*Other=*/false}));
   CHECK_PARSE("AllowShortFunctionsOnASingleLine: Empty",
-              AllowShortFunctionsOnASingleLine, FormatStyle::SFS_Empty);
+              AllowShortFunctionsOnASingleLine,
+              FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                               /*Inline=*/false,
+                                               /*Other=*/false}));
   CHECK_PARSE("AllowShortFunctionsOnASingleLine: All",
-              AllowShortFunctionsOnASingleLine, FormatStyle::SFS_All);
-  CHECK_PARSE("AllowShortFunctionsOnASingleLine: Custom",
-              AllowShortFunctionsOnASingleLine, FormatStyle::SFS_Custom);
+              AllowShortFunctionsOnASingleLine,
+              FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                               /*Inline=*/true,
+                                               /*Other=*/true}));
+  CHECK_PARSE("AllowShortFunctionsOnASingleLine: InlineOnly",
+              AllowShortFunctionsOnASingleLine,
+              FormatStyle::ShortFunctionStyle({/*Empty=*/false,
+                                               /*Inline=*/true,
+                                               /*Other=*/false}));
 
   // For backward compatibility:
   CHECK_PARSE("AllowShortFunctionsOnASingleLine: false",
-              AllowShortFunctionsOnASingleLine, FormatStyle::SFS_None);
+              AllowShortFunctionsOnASingleLine,
+              FormatStyle::ShortFunctionStyle({}));
   CHECK_PARSE("AllowShortFunctionsOnASingleLine: true",
-              AllowShortFunctionsOnASingleLine, FormatStyle::SFS_All);
+              AllowShortFunctionsOnASingleLine,
+              FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                               /*Inline=*/true,
+                                               /*Other=*/true}));
 
   Style.AllowShortLambdasOnASingleLine = FormatStyle::SLS_All;
   CHECK_PARSE("AllowShortLambdasOnASingleLine: None",
diff --git a/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp b/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp
index b26b9f4f4ff62..d3d0a0b56b5a0 100644
--- a/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp
+++ b/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp
@@ -540,7 +540,7 @@ TEST_F(DefinitionBlockSeparatorTest, Leave) {
 TEST_F(DefinitionBlockSeparatorTest, CSharp) {
   FormatStyle Style = getLLVMStyle(FormatStyle::LK_CSharp);
   Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
+  Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
   Style.AllowShortEnumsOnASingleLine = false;
   verifyFormat("namespace {\r\n"
                "public class SomeTinyClass {\r\n"
@@ -581,7 +581,7 @@ TEST_F(DefinitionBlockSeparatorTest, CSharp) {
 TEST_F(DefinitionBlockSeparatorTest, JavaScript) {
   FormatStyle Style = getLLVMStyle(FormatStyle::LK_JavaScript);
   Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
+  Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
   Style.AllowShortEnumsOnASingleLine = false;
   verifyFormat("export const enum Foo {\n"
                "  A = 1,\n"
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 79ee1230eb6a7..382e9e855b622 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -388,7 +388,10 @@ TEST_F(FormatTest, RemovesEmptyLines) {
                "}  // namespace");
 
   FormatStyle Style = getLLVMStyle();
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
+  Style.AllowShortFunctionsOnASingleLine =
+      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                       /*Inline=*/true,
+                                       /*Other=*/true});
   Style.MaxEmptyLinesToKeep = 2;
   Style.BreakBeforeBraces = FormatStyle::BS_Custom;
   Style.BraceWrapping.AfterClass = true;
@@ -3377,13 +3380,16 @@ TEST_F(FormatTest, MultiLineControlStatements) {
   Style.BraceWrapping.AfterFunction = true;
   Style.BraceWrapping.AfterStruct = false;
   Style.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_MultiLine;
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
+  Style.AllowShortFunctionsOnASingleLine =
+      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                       /*Inline=*/true,
+                                       /*Other=*/true});
   Style.ColumnLimit = 80;
   verifyFormat("void shortfunction() { bar(); }", Style);
   verifyFormat("struct T shortfunction() { return bar(); }", Style);
   verifyFormat("struct T {};", Style);
 
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
+  Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
   verifyFormat("void shortfunction()\n"
                "{\n"
                "  bar();\n"
@@ -3398,7 +3404,10 @@ TEST_F(FormatTest, MultiLineControlStatements) {
 
   Style.BraceWrapping.AfterFunction = false;
   Style.BraceWrapping.AfterStruct = true;
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
+  Style.AllowShortFunctionsOnASingleLine =
+      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                       /*Inline=*/true,
+                                       /*Other=*/true});
   verifyFormat("void shortfunction() { bar(); }", Style);
   verifyFormat("struct T shortfunction() { return bar(); }", Style);
   verifyFormat("struct T\n"
@@ -3406,7 +3415,7 @@ TEST_F(FormatTest, MultiLineControlStatements) {
                "};",
                Style);
 
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
+  Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
   verifyFormat("void shortfunction() {\n"
                "  bar();\n"
                "}",
@@ -4201,7 +4210,9 @@ TEST_F(FormatTest, FormatsNamespaces) {
   FormatStyle ShortInlineFunctions = getLLVMStyle();
   ShortInlineFunctions.NamespaceIndentation = FormatStyle::NI_All;
   ShortInlineFunctions.AllowShortFunctionsOnASingleLine =
-      FormatStyle::SFS_Inline;
+      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                       /*Inline=*/true,
+                                       /*Other=*/false});
   verifyFormat("namespace {\n"
                "  void f() {\n"
                "    return;\n"
@@ -8326,7 +8337,7 @@ TEST_F(FormatTest, BreakConstructorInitializersAfterColon) {
                "};",
                Style);
 
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
+  Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
   verifyNoChange("SomeClass::Constructor() :\n"
                  "    a(a), b(b), c(c) {\n"
                  "}",
@@ -8337,7 +8348,10 @@ TEST_F(FormatTest, BreakConstructorInitializersAfterColon) {
                  Style);
 
   Style.ColumnLimit = 80;
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
+  Style.AllowShortFunctionsOnASingleLine =
+      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                       /*Inline=*/true,
+                                       /*Other=*/true});
   Style.ConstructorInitializerIndentWidth = 2;
   verifyFormat("SomeClass::Constructor() : a(a), b(b), c(c) {}", Style);
   verifyFormat("SomeClass::Constructor() :\n"
@@ -12671,7 +12685,8 @@ TEST_F(FormatTest, UnderstandsAttributes) {
   verifyFormat("__attr1(nodebug) ::qualified_type f();", CustomAttrs);
 
   // Check that these are not parsed as function declarations:
-  CustomAttrs.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
+  CustomAttrs.AllowShortFunctionsOnASingleLine =
+      FormatStyle::ShortFunctionStyle({});
   CustomAttrs.BreakBeforeBraces = FormatStyle::BS_Allman;
   verifyFormat("SomeType s(InitValue);", CustomAttrs);
   verifyFormat("SomeType s{InitValue};", CustomAttrs);
@@ -12772,7 +12787,8 @@ TEST_F(FormatTest, UnderstandsSquareAttributes) {
 
   // Make sure we do not parse attributes as lambda introducers.
   FormatStyle MultiLineFunctions = getLLVMStyle();
-  MultiLineFunctions.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
+  MultiLineFunctions.AllowShortFunctionsOnASingleLine =
+      FormatStyle::ShortFunctionStyle({});
   verifyFormat("[[unused]] int b() {\n"
                "  return 42;\n"
                "}",
@@ -14870,7 +14886,8 @@ TEST_F(FormatTest, FormatsBracedListsInColumnLayout) {
 
 TEST_F(FormatTest, PullTrivialFunctionDefinitionsIntoSingleLine) {
   FormatStyle DoNotMerge = getLLVMStyle();
-  DoNotMerge.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
+  DoNotMerge.AllowShortFunctionsOnASingleLine =
+      FormatStyle::ShortFunctionStyle({});
 
   verifyFormat("void f() { return 42; }");
   verifyFormat("void f() {\n"
@@ -14941,7 +14958,7 @@ TEST_F(FormatTest, PullTrivialFunctionDefinitionsIntoSingleLine) {
 
   FormatStyle DoNotMergeNoColumnLimit = NoColumnLimit;
   DoNotMergeNoColumnLimit.AllowShortFunctionsOnASingleLine =
-      FormatStyle::SFS_None;
+      FormatStyle::ShortFunctionStyle({});
   verifyFormat("A() : b(0) {\n"
                "}",
                DoNotMergeNoColumnLimit);
@@ -14989,7 +15006,10 @@ TEST_F(FormatTest, PullTrivialFunctionDefinitionsIntoSingleLine) {
 
 TEST_F(FormatTest, PullEmptyFunctionDefinitionsIntoSingleLine) {
   FormatStyle MergeEmptyOnly = getLLVMStyle();
-  MergeEmptyOnly.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
+  MergeEmptyOnly.AllowShortFunctionsOnASingleLine =
+      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                       /*Inline=*/false,
+                                       /*Other=*/false});
   verifyFormat("class C {\n"
                "  int f() {}\n"
                "};",
@@ -15018,7 +15038,10 @@ TEST_F(FormatTest, PullEmptyFunctionDefinitionsIntoSingleLine) {
 
 TEST_F(FormatTest, PullInlineFunctionDefinitionsIntoSingleLine) {
   FormatStyle MergeInlineOnly = getLLVMStyle();
-  MergeInlineOnly.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
+  MergeInlineOnly.AllowShortFunctionsOnASingleLine =
+      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                       /*Inline=*/true,
+                                       /*Other=*/false});
   verifyFormat("class C {\n"
                "  int f() { return 42; }\n"
                "};",
@@ -15122,10 +15145,10 @@ TEST_F(FormatTest, PullInlineFunctionDefinitionsIntoSingleLine) {
 
 TEST_F(FormatTest, CustomShortFunctionOptions) {
   FormatStyle CustomEmpty = getLLVMStyle();
-  CustomEmpty.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Custom;
-  CustomEmpty.AllowShortFunctionsOnASingleLineOptions.Empty = true;
-  CustomEmpty.AllowShortFunctionsOnASingleLineOptions.Inline = false;
-  CustomEmpty.AllowShortFunctionsOnASingleLineOptions.Other = false;
+  CustomEmpty.AllowShortFunctionsOnASingleLine =
+      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                       /*Inline=*/false,
+                                       /*Other=*/false});
 
   // Empty functions should be on a single line
   verifyFormat("int f() {}", CustomEmpty);
@@ -15161,10 +15184,10 @@ TEST_F(FormatTest, CustomShortFunctionOptions) {
 
   // Test with Inline = true, All = false
   FormatStyle CustomInline = getLLVMStyle();
-  CustomInline.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Custom;
-  CustomInline.AllowShortFunctionsOnASingleLineOptions.Empty = false;
-  CustomInline.AllowShortFunctionsOnASingleLineOptions.Inline = true;
-  CustomInline.AllowShortFunctionsOnASingleLineOptions.Other = false;
+  CustomInline.AllowShortFunctionsOnASingleLine =
+      FormatStyle::ShortFunctionStyle({/*Empty=*/false,
+                                       /*Inline=*/true,
+                                       /*Other=*/false});
 
   verifyFormat("class C {\n"
                "  int f() {}\n"
@@ -15188,10 +15211,10 @@ TEST_F(FormatTest, CustomShortFunctionOptions) {
 
   // Test with All = true
   FormatStyle CustomAll = getLLVMStyle();
-  CustomAll.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Custom;
-  CustomAll.AllowShortFunctionsOnASingleLineOptions.Empty = false;
-  CustomAll.AllowShortFunctionsOnASingleLineOptions.Inline = false;
-  CustomAll.AllowShortFunctionsOnASingleLineOptions.Other = true;
+  CustomAll.AllowShortFunctionsOnASingleLine =
+      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                       /*Inline=*/true,
+                                       /*Other=*/true});
 
   // All functions should be on a single line if they fit
   verifyFormat("int f() { return 42; }", CustomAll);
@@ -15209,10 +15232,10 @@ TEST_F(FormatTest, CustomShortFunctionOptions) {
 
   // Test various combinations
   FormatStyle CustomMixed = getLLVMStyle();
-  CustomMixed.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Custom;
-  CustomMixed.AllowShortFunctionsOnASingleLineOptions.Empty = true;
-  CustomMixed.AllowShortFunctionsOnASingleLineOptions.Inline = true;
-  CustomMixed.AllowShortFunctionsOnASingleLineOptions.Other = false;
+  CustomMixed.AllowShortFunctionsOnASingleLine =
+      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                       /*Inline=*/true,
+                                       /*Other=*/false});
 
   // Empty functions should be on a single line
   verifyFormat("int f() {}", CustomMixed);
@@ -15237,7 +15260,9 @@ TEST_F(FormatTest, CustomShortFunctionOptions) {
 TEST_F(FormatTest, PullInlineOnlyFunctionDefinitionsIntoSingleLine) {
   FormatStyle MergeInlineOnly = getLLVMStyle();
   MergeInlineOnly.AllowShortFunctionsOnASingleLine =
-      FormatStyle::SFS_InlineOnly;
+      FormatStyle::ShortFunctionStyle({/*Empty=*/false,
+                                       /*Inline=*/true,
+                                       /*Other=*/false});
   verifyFormat("class C {\n"
                "  int f() { return 42; }\n"
                "};",
@@ -15282,7 +15307,7 @@ TEST_F(FormatTest, PullInlineOnlyFunctionDefinitionsIntoSingleLine) {
 
 TEST_F(FormatTest, SplitEmptyFunction) {
   FormatStyle Style = getLLVMStyleWithColumns(40);
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
+  Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
   Style.BreakBeforeBraces = FormatStyle::BS_Custom;
   Style.BraceWrapping.AfterFunction = true;
   Style.BraceWrapping.SplitEmptyFunction = false;
@@ -15301,7 +15326,10 @@ TEST_F(FormatTest, SplitEmptyFunction) {
                "}",
                Style);
 
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
+  Style.AllowShortFunctionsOnASingleLine =
+      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                       /*Inline=*/false,
+                                       /*Other=*/false});
   verifyFormat("int f() {}", Style);
   verifyFormat("int aaaaaaaaaaaaaa(int bbbbbbbbbbbbbb)\n"
                "{}",
@@ -15312,7 +15340,10 @@ TEST_F(FormatTest, SplitEmptyFunction) {
                "}",
                Style);
 
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
+  Style.AllowShortFunctionsOnASingleLine =
+      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                       /*Inline=*/true,
+                                       /*Other=*/false});
   verifyFormat("class Foo {\n"
                "  int f() {}\n"
                "};",
@@ -15334,7 +15365,10 @@ TEST_F(FormatTest, SplitEmptyFunction) {
                "};",
                Style);
 
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
+  Style.AllowShortFunctionsOnASingleLine =
+      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                       /*Inline=*/true,
+                                       /*Other=*/true});
   verifyFormat("int f() {}", Style);
   verifyFormat("int f() { return 0; }", Style);
   verifyFormat("int aaaaaaaaaaaaaa(int bbbbbbbbbbbbbb)\n"
@@ -15349,7 +15383,7 @@ TEST_F(FormatTest, SplitEmptyFunction) {
 
 TEST_F(FormatTest, SplitEmptyFunctionButNotRecord) {
   FormatStyle Style = getLLVMStyleWithColumns(40);
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
+  Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
   Style.BreakBeforeBraces = FormatStyle::BS_Custom;
   Style.BraceWrapping.AfterFunction = true;
   Style.BraceWrapping.SplitEmptyFunction = true;
@@ -15379,7 +15413,10 @@ TEST_F(FormatTest, SplitEmptyFunctionButNotRecord) {
 
 TEST_F(FormatTest, KeepShortFunctionAfterPPElse) {
   FormatStyle Style = getLLVMStyle();
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
+  Style.AllowShortFunctionsOnASingleLine =
+      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                       /*Inline=*/true,
+                                       /*Other=*/true});
   verifyFormat("#ifdef A\n"
                "int f() {}\n"
                "#else\n"
@@ -21492,7 +21529,9 @@ TEST_F(FormatTest, WhitesmithsBraceBreaking) {
 
   // Make a few changes to the style for testing purposes
   WhitesmithsBraceStyle.AllowShortFunctionsOnASingleLine =
-      FormatStyle::SFS_Empty;
+      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                       /*Inline=*/false,
+                                       /*Other=*/false});
   WhitesmithsBraceStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_None;
 
   // FIXME: this test case can't decide whether there should be a blank line
@@ -23038,7 +23077,7 @@ TEST_F(FormatTest, BreakConstructorInitializersBeforeComma) {
                "}",
                Style);
 
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
+  Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
   verifyFormat("SomeClass::Constructor()\n"
                "    : a(a)\n"
                "    , b(b)\n"
@@ -23049,7 +23088,10 @@ TEST_F(FormatTest, BreakConstructorInitializersBeforeComma) {
                Style);
 
   Style.ColumnLimit = 80;
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
+  Style.AllowShortFunctionsOnASingleLine =
+      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                       /*Inline=*/true,
+                                       /*Other=*/true});
   Style.ConstructorInitializerIndentWidth = 2;
   verifyFormat("SomeClass::Constructor()\n"
                "  : a(a)\n"
@@ -27198,7 +27240,7 @@ TEST_F(FormatTest, FormatDecayCopy) {
 TEST_F(FormatTest, Cpp20ModulesSupport) {
   FormatStyle Style = getLLVMStyle();
   Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Never;
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
+  Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
 
   verifyFormat("export import foo;", Style);
   verifyFormat("export import foo:bar;", Style);
diff --git a/clang/unittests/Format/FormatTestCSharp.cpp b/clang/unittests/Format/FormatTestCSharp.cpp
index 151f7072e0c65..22c757509f5fb 100644
--- a/clang/unittests/Format/FormatTestCSharp.cpp
+++ b/clang/unittests/Format/FormatTestCSharp.cpp
@@ -1660,7 +1660,10 @@ TEST_F(FormatTestCSharp, EmptyShortBlock) {
 TEST_F(FormatTestCSharp, ShortFunctions) {
   FormatStyle Style = getLLVMStyle(FormatStyle::LK_CSharp);
   Style.NamespaceIndentation = FormatStyle::NI_All;
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
+  Style.AllowShortFunctionsOnASingleLine =
+      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                       /*Inline=*/true,
+                                       /*Other=*/false});
   verifyFormat("interface Interface {\n"
                "  void f() { return; }\n"
                "};",
diff --git a/clang/unittests/Format/FormatTestJS.cpp b/clang/unittests/Format/FormatTestJS.cpp
index 78c9f887a159b..2108bb21f192e 100644
--- a/clang/unittests/Format/FormatTestJS.cpp
+++ b/clang/unittests/Format/FormatTestJS.cpp
@@ -1010,7 +1010,10 @@ TEST_F(FormatTestJS, TrailingCommaInsertion) {
 
 TEST_F(FormatTestJS, FunctionLiterals) {
   FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
+  Style.AllowShortFunctionsOnASingleLine =
+      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                       /*Inline=*/true,
+                                       /*Other=*/false});
   verifyFormat("doFoo(function() {});");
   verifyFormat("doFoo(function() { return 1; });", Style);
   verifyFormat("var func = function() {\n"
@@ -1123,7 +1126,10 @@ TEST_F(FormatTestJS, DontWrapEmptyLiterals) {
 
 TEST_F(FormatTestJS, InliningFunctionLiterals) {
   FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
+  Style.AllowShortFunctionsOnASingleLine =
+      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                       /*Inline=*/true,
+                                       /*Other=*/false});
   verifyFormat("var func = function() {\n"
                "  return 1;\n"
                "};",
@@ -1138,7 +1144,10 @@ TEST_F(FormatTestJS, InliningFunctionLiterals) {
                "}",
                Style);
 
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
+  Style.AllowShortFunctionsOnASingleLine =
+      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                       /*Inline=*/true,
+                                       /*Other=*/true});
   verifyFormat("var func = function() { return 1; };", Style);
   verifyFormat("var func = doSomething(function() { return 1; });", Style);
   verifyFormat(
@@ -1149,7 +1158,7 @@ TEST_F(FormatTestJS, InliningFunctionLiterals) {
                "}",
                Style);
 
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
+  Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
   verifyFormat("var func = function() {\n"
                "  return 1;\n"
                "};",
@@ -1171,7 +1180,10 @@ TEST_F(FormatTestJS, InliningFunctionLiterals) {
                "}",
                Style);
 
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
+  Style.AllowShortFunctionsOnASingleLine =
+      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                       /*Inline=*/false,
+                                       /*Other=*/false});
   verifyFormat("var func = function() {\n"
                "  return 1;\n"
                "};",
@@ -1180,7 +1192,10 @@ TEST_F(FormatTestJS, InliningFunctionLiterals) {
 
 TEST_F(FormatTestJS, MultipleFunctionLiterals) {
   FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
+  Style.AllowShortFunctionsOnASingleLine =
+      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                       /*Inline=*/true,
+                                       /*Other=*/true});
   verifyFormat("promise.then(\n"
                "    function success() {\n"
                "      doFoo();\n"
diff --git a/clang/unittests/Format/FormatTestJava.cpp b/clang/unittests/Format/FormatTestJava.cpp
index 33998bc7ff858..bba6541395171 100644
--- a/clang/unittests/Format/FormatTestJava.cpp
+++ b/clang/unittests/Format/FormatTestJava.cpp
@@ -594,7 +594,10 @@ TEST_F(FormatTestJava, RetainsLogicalShifts) {
 
 TEST_F(FormatTestJava, ShortFunctions) {
   FormatStyle Style = getLLVMStyle(FormatStyle::LK_Java);
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
+  Style.AllowShortFunctionsOnASingleLine =
+      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+                                       /*Inline=*/true,
+                                       /*Other=*/false});
   verifyFormat("enum Enum {\n"
                "  E1,\n"
                "  E2;\n"

>From 7f80e4adcac43f3b2c393a499627a1ca4d0beaef Mon Sep 17 00:00:00 2001
From: Ivan Rymarchyk <>
Date: Tue, 8 Apr 2025 21:13:35 -0700
Subject: [PATCH 04/21] fixed documentation error

---
 clang/docs/ClangFormatStyleOptions.rst | 1 +
 clang/include/clang/Format/Format.h    | 1 +
 2 files changed, 2 insertions(+)

diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index 6f3b9f798093f..1c55b74395062 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -1911,6 +1911,7 @@ the configuration (without a prefix: ``Auto``).
   statement.
 
   They can be read as a whole for compatibility. The choices are:
+
   * ``None``
     Never merge functions into a single line.
 
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 2278bf3966296..e5c031c7b249f 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -829,6 +829,7 @@ struct FormatStyle {
   /// statement.
   ///
   /// They can be read as a whole for compatibility. The choices are:
+  ///
   /// * ``None``
   ///   Never merge functions into a single line.
   ///

>From bbe22735987f4f24d278e73df74e59ad9b246d95 Mon Sep 17 00:00:00 2001
From: Ivan Rymarchyk <>
Date: Wed, 9 Apr 2025 19:27:10 -0700
Subject: [PATCH 05/21] Fixed PR comments

---
 clang/docs/ClangFormatStyleOptions.rst     | 2 +-
 clang/include/clang/Format/Format.h        | 2 +-
 clang/lib/Format/TokenAnnotator.cpp        | 8 +++-----
 clang/unittests/Format/ConfigParseTest.cpp | 1 -
 4 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index 1c55b74395062..d67c8891a4506 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -1975,7 +1975,7 @@ the configuration (without a prefix: ``Auto``).
     AllowShortFunctionsOnASingleLine:
       Empty: false
       Inline: true
-      All: false
+      Other: false
 
   * ``bool Empty`` Merge top-level empty functions.
 
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index e5c031c7b249f..7836fa91b20a8 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -887,7 +887,7 @@ struct FormatStyle {
   ///   AllowShortFunctionsOnASingleLine:
   ///     Empty: false
   ///     Inline: true
-  ///     All: false
+  ///     Other: false
   /// \endcode
   struct ShortFunctionStyle {
     /// Merge top-level empty functions.
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index db2f8766f8d40..f85ddbe2f0523 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -5687,11 +5687,9 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
     if (Right.is(tok::r_brace) && Left.is(tok::l_brace) &&
         !Left.Children.empty()) {
       // Support AllowShortFunctionsOnASingleLine for JavaScript.
-      return (!Style.AllowShortFunctionsOnASingleLine.Inline &&
-              !Style.AllowShortFunctionsOnASingleLine.Other) ||
-             (Left.NestingLevel == 0 && Line.Level == 0 &&
-              Style.AllowShortFunctionsOnASingleLine.Inline &&
-              !Style.AllowShortFunctionsOnASingleLine.Other);
+      return !(Left.NestingLevel == 0 && Line.Level == 0
+                   ? Style.AllowShortFunctionsOnASingleLine.Other
+                   : Style.AllowShortFunctionsOnASingleLine.Inline);
     }
   } else if (Style.Language == FormatStyle::LK_Java) {
     if (Right.is(tok::plus) && Left.is(tok::string_literal) && AfterRight &&
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index c022db94cdb6a..b48dd0a737eea 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -611,7 +611,6 @@ TEST(ConfigParseTest, ParsesConfiguration) {
   CHECK_PARSE("AllowShortBlocksOnASingleLine: true",
               AllowShortBlocksOnASingleLine, FormatStyle::SBS_Always);
 
-  // Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
   CHECK_PARSE("AllowShortFunctionsOnASingleLine: None",
               AllowShortFunctionsOnASingleLine,
               FormatStyle::ShortFunctionStyle({}));

>From 5ff5810b53308fb2df457b339743991b1fcc9695 Mon Sep 17 00:00:00 2001
From: Ivan Rymarchyk <>
Date: Sun, 13 Apr 2025 15:14:16 -0700
Subject: [PATCH 06/21] marked options as deprecated

---
 clang/docs/ClangFormatStyleOptions.rst | 11 ++++++++---
 clang/include/clang/Format/Format.h    | 11 ++++++++---
 2 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index d67c8891a4506..a01b9baf482e3 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -1918,7 +1918,8 @@ the configuration (without a prefix: ``Auto``).
   * ``InlineOnly``
     Only merge functions defined inside a class. Same as ``inline``,
     except it does not implies ``empty``: i.e. top level empty functions
-    are not merged either.
+    are not merged either. This option is **deprecated** and is retained
+    for backwards compatibility. See ``Inline`` of ``ShortFunctionStyle``.
 
     .. code-block:: c++
 
@@ -1932,7 +1933,9 @@ the configuration (without a prefix: ``Auto``).
       }
 
   * ``Empty``
-    Only merge empty functions.
+    Only merge empty functions. This option is **deprecated** and is
+    retained for backwards compatibility. See ``Empty`` of
+    ``ShortFunctionStyle``.
 
     .. code-block:: c++
 
@@ -1942,7 +1945,9 @@ the configuration (without a prefix: ``Auto``).
       }
 
   * ``Inline``
-    Only merge functions defined inside a class. Implies ``empty``.
+    Only merge functions defined inside a class. Implies ``empty``. This
+    option is **deprecated** and is retained for backwards compatibility.
+    See ``Inline`` and ``Empty`` of ``ShortFunctionStyle``.
 
     .. code-block:: c++
 
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 7836fa91b20a8..448e8d0f2eb77 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -836,7 +836,8 @@ struct FormatStyle {
   /// * ``InlineOnly``
   ///   Only merge functions defined inside a class. Same as ``inline``,
   ///   except it does not implies ``empty``: i.e. top level empty functions
-  ///   are not merged either.
+  ///   are not merged either. This option is **deprecated** and is retained
+  ///   for backwards compatibility. See ``Inline`` of ``ShortFunctionStyle``.
   ///   \code
   ///     class Foo {
   ///       void f() { foo(); }
@@ -849,7 +850,9 @@ struct FormatStyle {
   ///   \endcode
   ///
   /// * ``Empty``
-  ///   Only merge empty functions.
+  ///   Only merge empty functions. This option is **deprecated** and is
+  ///   retained for backwards compatibility. See ``Empty`` of
+  ///   ``ShortFunctionStyle``.
   ///   \code
   ///     void f() {}
   ///     void f2() {
@@ -858,7 +861,9 @@ struct FormatStyle {
   ///   \endcode
   ///
   /// * ``Inline``
-  ///   Only merge functions defined inside a class. Implies ``empty``.
+  ///   Only merge functions defined inside a class. Implies ``empty``. This
+  ///   option is **deprecated** and is retained for backwards compatibility.
+  ///   See ``Inline`` and ``Empty`` of ``ShortFunctionStyle``.
   ///   \code
   ///     class Foo {
   ///       void f() { foo(); }

>From 70eafeabdff7f1f3e765f7dae29eec9c202170c8 Mon Sep 17 00:00:00 2001
From: Ivan Rymarchyk <>
Date: Tue, 15 Apr 2025 20:38:36 -0700
Subject: [PATCH 07/21] fixed PR comments

---
 clang/include/clang/Format/Format.h         | 3 +++
 clang/lib/Format/TokenAnnotator.cpp         | 2 +-
 clang/lib/Format/UnwrappedLineFormatter.cpp | 5 +++--
 3 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 448e8d0f2eb77..b56806ca2ccfa 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -934,6 +934,9 @@ struct FormatStyle {
     ShortFunctionStyle() : Empty(false), Inline(false), Other(false) {}
     ShortFunctionStyle(bool Empty, bool Inline, bool Other)
         : Empty(Empty), Inline(Inline), Other(Other) {}
+    bool isAll() const {
+      return Empty && Inline && Other;
+    }
   };
 
   /// Dependent on the value, ``int f() { return 0; }`` can be put on a
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index f85ddbe2f0523..73ff1c537d1e8 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -5688,7 +5688,7 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
         !Left.Children.empty()) {
       // Support AllowShortFunctionsOnASingleLine for JavaScript.
       return !(Left.NestingLevel == 0 && Line.Level == 0
-                   ? Style.AllowShortFunctionsOnASingleLine.Other
+                   ? Style.AllowShortFunctionsOnASingleLine.isAll()
                    : Style.AllowShortFunctionsOnASingleLine.Inline);
     }
   } else if (Style.Language == FormatStyle::LK_Java) {
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp
index fdec849cf363a..c6b9ad02a22b5 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -293,14 +293,15 @@ class LineJoiner {
 
     auto ShouldMergeShortFunctions = [this, &I, &NextLine, PreviousLine,
                                       TheLine]() {
-      if (Style.AllowShortFunctionsOnASingleLine.Other)
+      if (Style.AllowShortFunctionsOnASingleLine.isAll())
         return true;
       if (Style.AllowShortFunctionsOnASingleLine.Empty &&
           NextLine.First->is(tok::r_brace)) {
         return true;
       }
 
-      if (Style.AllowShortFunctionsOnASingleLine.Inline) {
+      if (Style.AllowShortFunctionsOnASingleLine.Inline &&
+          !Style.AllowShortFunctionsOnASingleLine.isAll()) {
         // Just checking TheLine->Level != 0 is not enough, because it
         // provokes treating functions inside indented namespaces as short.
         if (Style.isJavaScript() && TheLine->Last->is(TT_FunctionLBrace))

>From dd6493d703237cc0a1c9a8e61696482cd91edb92 Mon Sep 17 00:00:00 2001
From: Ivan Rymarchyk <>
Date: Tue, 15 Apr 2025 21:42:01 -0700
Subject: [PATCH 08/21] added usage of 'other'

---
 clang/include/clang/Format/Format.h         |  4 +-
 clang/lib/Format/UnwrappedLineFormatter.cpp | 63 +++++++++++----------
 clang/unittests/Format/FormatTest.cpp       | 20 +++++++
 3 files changed, 55 insertions(+), 32 deletions(-)

diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index b56806ca2ccfa..38b68651e0322 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -934,9 +934,7 @@ struct FormatStyle {
     ShortFunctionStyle() : Empty(false), Inline(false), Other(false) {}
     ShortFunctionStyle(bool Empty, bool Inline, bool Other)
         : Empty(Empty), Inline(Inline), Other(Other) {}
-    bool isAll() const {
-      return Empty && Inline && Other;
-    }
+    bool isAll() const { return Empty && Inline && Other; }
   };
 
   /// Dependent on the value, ``int f() { return 0; }`` can be put on a
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp
index c6b9ad02a22b5..71d53c1c60c58 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -295,47 +295,52 @@ class LineJoiner {
                                       TheLine]() {
       if (Style.AllowShortFunctionsOnASingleLine.isAll())
         return true;
-      if (Style.AllowShortFunctionsOnASingleLine.Empty &&
-          NextLine.First->is(tok::r_brace)) {
+
+      // there might be a case where empty function is in class, so need to
+      // check inline later
+      bool empty_function = NextLine.First->is(tok::r_brace);
+      if (Style.AllowShortFunctionsOnASingleLine.Empty && empty_function)
         return true;
-      }
 
-      if (Style.AllowShortFunctionsOnASingleLine.Inline &&
-          !Style.AllowShortFunctionsOnASingleLine.isAll()) {
+      if (TheLine->Level != 0) {
+        if (!Style.AllowShortFunctionsOnASingleLine.Inline)
+          return false;
+
         // Just checking TheLine->Level != 0 is not enough, because it
         // provokes treating functions inside indented namespaces as short.
         if (Style.isJavaScript() && TheLine->Last->is(TT_FunctionLBrace))
           return true;
 
-        if (TheLine->Level != 0) {
-          if (!PreviousLine)
-            return false;
-
-          // TODO: Use IndentTracker to avoid loop?
-          // Find the last line with lower level.
-          const AnnotatedLine *Line = nullptr;
-          for (auto J = I - 1; J >= AnnotatedLines.begin(); --J) {
-            assert(*J);
-            if (!(*J)->InPPDirective && !(*J)->isComment() &&
-                (*J)->Level < TheLine->Level) {
-              Line = *J;
-              break;
-            }
+        if (!PreviousLine)
+          return false;
+
+        // TODO: Use IndentTracker to avoid loop?
+        // Find the last line with lower level.
+        const AnnotatedLine *Line = nullptr;
+        for (auto J = I - 1; J >= AnnotatedLines.begin(); --J) {
+          assert(*J);
+          if (!(*J)->InPPDirective && !(*J)->isComment() &&
+              (*J)->Level < TheLine->Level) {
+            Line = *J;
+            break;
           }
+        }
 
-          if (!Line)
-            return false;
+        if (!Line)
+          return false;
 
-          // Check if the found line starts a record.
-          const auto *LastNonComment = Line->getLastNonComment();
-          // There must be another token (usually `{`), because we chose a
-          // non-PPDirective and non-comment line that has a smaller level.
-          assert(LastNonComment);
-          return isRecordLBrace(*LastNonComment);
-        }
+        // Check if the found line starts a record.
+        const auto *LastNonComment = Line->getLastNonComment();
+        // There must be another token (usually `{`), because we chose a
+        // non-PPDirective and non-comment line that has a smaller level.
+        assert(LastNonComment);
+        return isRecordLBrace(*LastNonComment);
       }
 
-      return false;
+      if (empty_function && !Style.AllowShortFunctionsOnASingleLine.Empty)
+        return false;
+
+      return Style.AllowShortFunctionsOnASingleLine.Other;
     };
 
     bool MergeShortFunctions = ShouldMergeShortFunctions();
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 382e9e855b622..b780dee7660ae 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -15255,6 +15255,26 @@ TEST_F(FormatTest, CustomShortFunctionOptions) {
                "  return 42;\n"
                "}",
                CustomMixed);
+
+  FormatStyle OnlyOther = getLLVMStyle();
+  OnlyOther.AllowShortFunctionsOnASingleLine =
+      FormatStyle::ShortFunctionStyle({/*Empty=*/false,
+                                       /*Inline=*/false,
+                                       /*Other=*/true});
+  verifyFormat("void topLevelEmpty() {\n"
+               "}",
+               OnlyOther);
+
+  verifyFormat("void topLevelNonEmpty() { return; }", OnlyOther);
+
+  verifyFormat("class C {\n"
+               "  int inlineEmpty() {\n"
+               "  }\n"
+               "  int inlineNonempty() {\n"
+               "    return 42;\n"
+               "  }\n"
+               "};",
+               OnlyOther);
 }
 
 TEST_F(FormatTest, PullInlineOnlyFunctionDefinitionsIntoSingleLine) {

>From 3c0fa142bec76b01557d5d1b0b1d235541cf2985 Mon Sep 17 00:00:00 2001
From: Ivan Rymarchyk <>
Date: Sun, 20 Apr 2025 21:08:28 -0700
Subject: [PATCH 09/21] fixed ShortFunctionStyle.Other case for JS

---
 clang/lib/Format/TokenAnnotator.cpp     | 24 ++++++++++++++++---
 clang/unittests/Format/FormatTestJS.cpp | 31 +++++++++++++++++++++++++
 2 files changed, 52 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 9ef060f83bc0b..02b5140e763cf 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -5685,9 +5685,27 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
     if (Right.is(tok::r_brace) && Left.is(tok::l_brace) &&
         !Left.Children.empty()) {
       // Support AllowShortFunctionsOnASingleLine for JavaScript.
-      return !(Left.NestingLevel == 0 && Line.Level == 0
-                   ? Style.AllowShortFunctionsOnASingleLine.isAll()
-                   : Style.AllowShortFunctionsOnASingleLine.Inline);
+      const auto &shortFuncConfig = Style.AllowShortFunctionsOnASingleLine;
+
+      // SFS_All
+      if (shortFuncConfig.isAll())
+        return false;
+
+      // SFS_None and SFS_Empty
+      if (shortFuncConfig == FormatStyle::ShortFunctionStyle{})
+        return true;
+
+      // SFS_Empty
+      if (shortFuncConfig == FormatStyle::ShortFunctionStyle{/*Empty=*/true,
+                                                             /*Inline=*/false,
+                                                             /*Other=*/false}) {
+        return true;
+      }
+
+      if (Left.NestingLevel == 0 && Line.Level == 0)
+        return shortFuncConfig.Inline && !shortFuncConfig.Other;
+
+      return shortFuncConfig.Other;
     }
   } else if (Style.isJava()) {
     if (Right.is(tok::plus) && Left.is(tok::string_literal) && AfterRight &&
diff --git a/clang/unittests/Format/FormatTestJS.cpp b/clang/unittests/Format/FormatTestJS.cpp
index cc091df1f04dc..03e55e4498fd4 100644
--- a/clang/unittests/Format/FormatTestJS.cpp
+++ b/clang/unittests/Format/FormatTestJS.cpp
@@ -1195,6 +1195,37 @@ TEST_F(FormatTestJS, InliningFunctionLiterals) {
                Style);
 }
 
+TEST_F(FormatTestJS, InliningFunctionLiteralsNew) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
+  Style.AllowShortFunctionsOnASingleLine =
+      FormatStyle::ShortFunctionStyle({/*Empty=*/false,
+                                       /*Inline=*/false,
+                                       /*Other=*/true});
+  verifyFormat("var func = function() { return 1; };", Style);
+  verifyFormat("var func = doSomething(function() {\n"
+               "  return 1;\n"
+               "});",
+               Style);
+  verifyFormat("var outer = function() {\n"
+               "  var inner = function() {\n"
+               "    return 1;\n"
+               "  }\n"
+               "};",
+               Style);
+  verifyFormat("function outer1(a, b) {\n"
+               "  function inner1(a, b) {\n"
+               "    return a;\n"
+               "  }\n"
+               "}",
+               Style);
+
+  verifyFormat("function outer1(a, b) {\n"
+               "  function inner1_empty(a, b) {\n"
+               "  }\n"
+               "}",
+               Style);
+}
+
 TEST_F(FormatTestJS, MultipleFunctionLiterals) {
   FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
   Style.AllowShortFunctionsOnASingleLine =

>From 7825f535be13082c93dc67459b37e6288266e450 Mon Sep 17 00:00:00 2001
From: Ivan Rymarchyk <>
Date: Mon, 12 May 2025 21:01:06 -0700
Subject: [PATCH 10/21] fixed first comment - simplified code

---
 clang/lib/Format/TokenAnnotator.cpp | 23 +++--------------------
 1 file changed, 3 insertions(+), 20 deletions(-)

diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 02b5140e763cf..4ee887f482606 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -5685,27 +5685,10 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
     if (Right.is(tok::r_brace) && Left.is(tok::l_brace) &&
         !Left.Children.empty()) {
       // Support AllowShortFunctionsOnASingleLine for JavaScript.
-      const auto &shortFuncConfig = Style.AllowShortFunctionsOnASingleLine;
-
-      // SFS_All
-      if (shortFuncConfig.isAll())
-        return false;
-
-      // SFS_None and SFS_Empty
-      if (shortFuncConfig == FormatStyle::ShortFunctionStyle{})
-        return true;
-
-      // SFS_Empty
-      if (shortFuncConfig == FormatStyle::ShortFunctionStyle{/*Empty=*/true,
-                                                             /*Inline=*/false,
-                                                             /*Other=*/false}) {
-        return true;
-      }
-
       if (Left.NestingLevel == 0 && Line.Level == 0)
-        return shortFuncConfig.Inline && !shortFuncConfig.Other;
-
-      return shortFuncConfig.Other;
+        return !Style.AllowShortFunctionsOnASingleLine.Other;
+      
+      return !Style.AllowShortFunctionsOnASingleLine.Inline;
     }
   } else if (Style.isJava()) {
     if (Right.is(tok::plus) && Left.is(tok::string_literal) && AfterRight &&

>From 9dbd674f61971a8faed32363effecfb82db12734 Mon Sep 17 00:00:00 2001
From: Ivan Rymarchyk <>
Date: Mon, 12 May 2025 21:07:54 -0700
Subject: [PATCH 11/21] removed code related to Only Other option

---
 .gitignore                                  |  1 +
 clang/lib/Format/TokenAnnotator.cpp         |  2 +-
 clang/lib/Format/UnwrappedLineFormatter.cpp | 71 ++++++++++-----------
 clang/unittests/Format/FormatTest.cpp       | 20 ------
 4 files changed, 35 insertions(+), 59 deletions(-)

diff --git a/.gitignore b/.gitignore
index a84268a7f6863..2b4aa551d06c0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -73,3 +73,4 @@ pythonenv*
 /clang/utils/analyzer/projects/*/RefScanBuildResults
 # automodapi puts generated documentation files here.
 /lldb/docs/python_api/
+clang-build/
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 4ee887f482606..1455c21fa7d7f 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -5687,7 +5687,7 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
       // Support AllowShortFunctionsOnASingleLine for JavaScript.
       if (Left.NestingLevel == 0 && Line.Level == 0)
         return !Style.AllowShortFunctionsOnASingleLine.Other;
-      
+
       return !Style.AllowShortFunctionsOnASingleLine.Inline;
     }
   } else if (Style.isJava()) {
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp
index 5866d33572116..8e344c820e119 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -294,56 +294,51 @@ class LineJoiner {
       if (Style.AllowShortFunctionsOnASingleLine.isAll())
         return true;
 
-      // there might be a case where empty function is in class, so need to
-      // check inline later
-      bool empty_function = NextLine.First->is(tok::r_brace);
-      if (Style.AllowShortFunctionsOnASingleLine.Empty && empty_function)
+      if (Style.AllowShortFunctionsOnASingleLine.Empty &&
+          NextLine.First->is(tok::r_brace)) {
         return true;
+      }
 
-      if (TheLine->Level != 0) {
-        if (!Style.AllowShortFunctionsOnASingleLine.Inline)
-          return false;
-
+      if (Style.AllowShortFunctionsOnASingleLine.Inline) {
         // Just checking TheLine->Level != 0 is not enough, because it
         // provokes treating functions inside indented namespaces as short.
         if (Style.isJavaScript() && TheLine->Last->is(TT_FunctionLBrace))
           return true;
 
-        if (!PreviousLine)
-          return false;
-
-        // TODO: Use IndentTracker to avoid loop?
-        // Find the last line with lower level.
-        const AnnotatedLine *Line = nullptr;
-        for (auto J = I - 1; J >= AnnotatedLines.begin(); --J) {
-          assert(*J);
-          if ((*J)->InPPDirective || (*J)->isComment() ||
-              (*J)->Level > TheLine->Level) {
-            continue;
-          }
-          if ((*J)->Level < TheLine->Level ||
-              (Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths &&
-               (*J)->First->is(tok::l_brace))) {
-            Line = *J;
-            break;
+        if (TheLine->Level != 0) {
+          if (!PreviousLine)
+            return false;
+
+          // TODO: Use IndentTracker to avoid loop?
+          // Find the last line with lower level.
+          const AnnotatedLine *Line = nullptr;
+          for (auto J = I - 1; J >= AnnotatedLines.begin(); --J) {
+            assert(*J);
+            if ((*J)->InPPDirective || (*J)->isComment() ||
+                (*J)->Level > TheLine->Level) {
+              continue;
+            }
+            if ((*J)->Level < TheLine->Level ||
+                (Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths &&
+                 (*J)->First->is(tok::l_brace))) {
+              Line = *J;
+              break;
+            }
           }
-        }
 
-        if (!Line)
-          return false;
+          if (!Line)
+            return false;
 
-        // Check if the found line starts a record.
-        const auto *LastNonComment = Line->getLastNonComment();
-        // There must be another token (usually `{`), because we chose a
-        // non-PPDirective and non-comment line that has a smaller level.
-        assert(LastNonComment);
-        return isRecordLBrace(*LastNonComment);
+          // Check if the found line starts a record.
+          const auto *LastNonComment = Line->getLastNonComment();
+          // There must be another token (usually `{`), because we chose a
+          // non-PPDirective and non-comment line that has a smaller level.
+          assert(LastNonComment);
+          return isRecordLBrace(*LastNonComment);
+        }
       }
 
-      if (empty_function && !Style.AllowShortFunctionsOnASingleLine.Empty)
-        return false;
-
-      return Style.AllowShortFunctionsOnASingleLine.Other;
+      return false;
     };
 
     bool MergeShortFunctions = ShouldMergeShortFunctions();
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index c84c0510cce0f..ed1582d3417c4 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -15255,26 +15255,6 @@ TEST_F(FormatTest, CustomShortFunctionOptions) {
                "  return 42;\n"
                "}",
                CustomMixed);
-
-  FormatStyle OnlyOther = getLLVMStyle();
-  OnlyOther.AllowShortFunctionsOnASingleLine =
-      FormatStyle::ShortFunctionStyle({/*Empty=*/false,
-                                       /*Inline=*/false,
-                                       /*Other=*/true});
-  verifyFormat("void topLevelEmpty() {\n"
-               "}",
-               OnlyOther);
-
-  verifyFormat("void topLevelNonEmpty() { return; }", OnlyOther);
-
-  verifyFormat("class C {\n"
-               "  int inlineEmpty() {\n"
-               "  }\n"
-               "  int inlineNonempty() {\n"
-               "    return 42;\n"
-               "  }\n"
-               "};",
-               OnlyOther);
 }
 
 TEST_F(FormatTest, PullInlineOnlyFunctionDefinitionsIntoSingleLine) {

>From 9917b99411affd232ccf9a2409aedb1e73d287d6 Mon Sep 17 00:00:00 2001
From: Ivan Rymarchyk <>
Date: Sat, 17 May 2025 14:13:53 -0700
Subject: [PATCH 12/21] fixed PR comments

---
 .gitignore                                  |  1 -
 clang/include/clang/Format/Format.h         | 12 ++++
 clang/lib/Format/Format.cpp                 | 46 +++----------
 clang/lib/Format/UnwrappedLineFormatter.cpp |  3 +-
 clang/unittests/Format/ConfigParseTest.cpp  | 20 ++----
 clang/unittests/Format/FormatTest.cpp       | 76 ++++++---------------
 clang/unittests/Format/FormatTestCSharp.cpp |  4 +-
 clang/unittests/Format/FormatTestJS.cpp     | 26 ++-----
 clang/unittests/Format/FormatTestJava.cpp   |  4 +-
 9 files changed, 61 insertions(+), 131 deletions(-)

diff --git a/.gitignore b/.gitignore
index 2b4aa551d06c0..a84268a7f6863 100644
--- a/.gitignore
+++ b/.gitignore
@@ -73,4 +73,3 @@ pythonenv*
 /clang/utils/analyzer/projects/*/RefScanBuildResults
 # automodapi puts generated documentation files here.
 /lldb/docs/python_api/
-clang-build/
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 7ee954606718b..af88588fd164a 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -935,6 +935,18 @@ struct FormatStyle {
     ShortFunctionStyle(bool Empty, bool Inline, bool Other)
         : Empty(Empty), Inline(Inline), Other(Other) {}
     bool isAll() const { return Empty && Inline && Other; }
+    static ShortFunctionStyle setEmptyOnly() {
+      return ShortFunctionStyle(true, false, false);
+    }
+    static ShortFunctionStyle setEmptyAndInline() {
+      return ShortFunctionStyle(true, true, false);
+    }
+    static ShortFunctionStyle setInlineOnly() {
+      return ShortFunctionStyle(false, true, false);
+    }
+    static ShortFunctionStyle setAll() {
+      return ShortFunctionStyle(true, true, true);
+    }
   };
 
   /// Dependent on the value, ``int f() { return 0; }`` can be put on a
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 859b19fe7d3e4..bd439eca7ace9 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -626,27 +626,17 @@ template <> struct MappingTraits<FormatStyle::ShortFunctionStyle> {
   static void enumInput(IO &IO, FormatStyle::ShortFunctionStyle &Value) {
     IO.enumCase(Value, "None", FormatStyle::ShortFunctionStyle({}));
     IO.enumCase(Value, "Empty",
-                FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                                 /*Inline=*/false,
-                                                 /*Other=*/false}));
+                FormatStyle::ShortFunctionStyle::setEmptyOnly());
     IO.enumCase(Value, "Inline",
                 FormatStyle::ShortFunctionStyle({/*Empty=*/true,
                                                  /*Inline=*/true,
                                                  /*Other=*/false}));
     IO.enumCase(Value, "InlineOnly",
-                FormatStyle::ShortFunctionStyle({/*Empty=*/false,
-                                                 /*Inline=*/true,
-                                                 /*Other=*/false}));
-    IO.enumCase(Value, "All",
-                FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                                 /*Inline=*/true,
-                                                 /*Other=*/true}));
+                FormatStyle::ShortFunctionStyle::setInlineOnly());
+    IO.enumCase(Value, "All", FormatStyle::ShortFunctionStyle::setAll());
 
     // For backward compatibility.
-    IO.enumCase(Value, "true",
-                FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                                 /*Inline=*/true,
-                                                 /*Other=*/true}));
+    IO.enumCase(Value, "true", FormatStyle::ShortFunctionStyle::setAll());
     IO.enumCase(Value, "false", FormatStyle::ShortFunctionStyle({}));
   }
 
@@ -1534,9 +1524,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
   LLVMStyle.AllowShortCompoundRequirementOnASingleLine = true;
   LLVMStyle.AllowShortEnumsOnASingleLine = true;
   LLVMStyle.AllowShortFunctionsOnASingleLine =
-      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                       /*Inline=*/true,
-                                       /*Other=*/true});
+      FormatStyle::ShortFunctionStyle::setAll();
   LLVMStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
   LLVMStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_All;
   LLVMStyle.AllowShortLoopsOnASingleLine = false;
@@ -1825,9 +1813,7 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
     GoogleStyle.AlignTrailingComments = {};
     GoogleStyle.AlignTrailingComments.Kind = FormatStyle::TCAS_Never;
     GoogleStyle.AllowShortFunctionsOnASingleLine =
-        FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                         /*Inline=*/false,
-                                         /*Other=*/false});
+        FormatStyle::ShortFunctionStyle::setEmptyOnly();
     GoogleStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
     GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
     GoogleStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment;
@@ -1838,9 +1824,7 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
     GoogleStyle.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak;
     GoogleStyle.AlignOperands = FormatStyle::OAS_DontAlign;
     GoogleStyle.AllowShortFunctionsOnASingleLine =
-        FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                         /*Inline=*/false,
-                                         /*Other=*/false});
+        FormatStyle::ShortFunctionStyle::setEmptyOnly();
     // TODO: still under discussion whether to switch to SLS_All.
     GoogleStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_Empty;
     GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
@@ -1858,9 +1842,7 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
     GoogleStyle.SpacesInContainerLiterals = false;
   } else if (Language == FormatStyle::LK_Proto) {
     GoogleStyle.AllowShortFunctionsOnASingleLine =
-        FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                         /*Inline=*/false,
-                                         /*Other=*/false});
+        FormatStyle::ShortFunctionStyle::setEmptyOnly();
     GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
     // This affects protocol buffer options specifications and text protos.
     // Text protos are currently mostly formatted inside C++ raw string literals
@@ -1880,9 +1862,7 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
         tooling::IncludeStyle::IBS_Preserve;
   } else if (Language == FormatStyle::LK_CSharp) {
     GoogleStyle.AllowShortFunctionsOnASingleLine =
-        FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                         /*Inline=*/false,
-                                         /*Other=*/false});
+        FormatStyle::ShortFunctionStyle::setEmptyOnly();
     GoogleStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
     GoogleStyle.BreakStringLiterals = false;
     GoogleStyle.ColumnLimit = 100;
@@ -1942,9 +1922,7 @@ FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language) {
   } else {
     ChromiumStyle.AllowAllParametersOfDeclarationOnNextLine = false;
     ChromiumStyle.AllowShortFunctionsOnASingleLine =
-        FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                         /*Inline=*/true,
-                                         /*Other=*/false});
+        FormatStyle::ShortFunctionStyle::setEmptyAndInline();
     ChromiumStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
     ChromiumStyle.AllowShortLoopsOnASingleLine = false;
     ChromiumStyle.BinPackParameters = FormatStyle::BPPS_OnePerLine;
@@ -1959,9 +1937,7 @@ FormatStyle getMozillaStyle() {
   FormatStyle MozillaStyle = getLLVMStyle();
   MozillaStyle.AllowAllParametersOfDeclarationOnNextLine = false;
   MozillaStyle.AllowShortFunctionsOnASingleLine =
-      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                       /*Inline=*/true,
-                                       /*Other=*/false});
+      FormatStyle::ShortFunctionStyle::setEmptyAndInline();
   MozillaStyle.AlwaysBreakAfterDefinitionReturnType =
       FormatStyle::DRTBS_TopLevel;
   MozillaStyle.BinPackArguments = false;
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp
index 8e344c820e119..722690108d2fa 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -299,7 +299,8 @@ class LineJoiner {
         return true;
       }
 
-      if (Style.AllowShortFunctionsOnASingleLine.Inline) {
+      if (Style.AllowShortFunctionsOnASingleLine.Inline &&
+          !Style.AllowShortFunctionsOnASingleLine.Other) {
         // Just checking TheLine->Level != 0 is not enough, because it
         // provokes treating functions inside indented namespaces as short.
         if (Style.isJavaScript() && TheLine->Last->is(TT_FunctionLBrace))
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index 6612c3672837d..96686761cb9d6 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -624,24 +624,16 @@ TEST(ConfigParseTest, ParsesConfiguration) {
               FormatStyle::ShortFunctionStyle({}));
   CHECK_PARSE("AllowShortFunctionsOnASingleLine: Inline",
               AllowShortFunctionsOnASingleLine,
-              FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                               /*Inline=*/true,
-                                               /*Other=*/false}));
+              FormatStyle::ShortFunctionStyle::setEmptyAndInline());
   CHECK_PARSE("AllowShortFunctionsOnASingleLine: Empty",
               AllowShortFunctionsOnASingleLine,
-              FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                               /*Inline=*/false,
-                                               /*Other=*/false}));
+              FormatStyle::ShortFunctionStyle::setEmptyOnly());
   CHECK_PARSE("AllowShortFunctionsOnASingleLine: All",
               AllowShortFunctionsOnASingleLine,
-              FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                               /*Inline=*/true,
-                                               /*Other=*/true}));
+              FormatStyle::ShortFunctionStyle::setAll());
   CHECK_PARSE("AllowShortFunctionsOnASingleLine: InlineOnly",
               AllowShortFunctionsOnASingleLine,
-              FormatStyle::ShortFunctionStyle({/*Empty=*/false,
-                                               /*Inline=*/true,
-                                               /*Other=*/false}));
+              FormatStyle::ShortFunctionStyle::setInlineOnly());
 
   // For backward compatibility:
   CHECK_PARSE("AllowShortFunctionsOnASingleLine: false",
@@ -649,9 +641,7 @@ TEST(ConfigParseTest, ParsesConfiguration) {
               FormatStyle::ShortFunctionStyle({}));
   CHECK_PARSE("AllowShortFunctionsOnASingleLine: true",
               AllowShortFunctionsOnASingleLine,
-              FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                               /*Inline=*/true,
-                                               /*Other=*/true}));
+              FormatStyle::ShortFunctionStyle::setAll());
 
   Style.AllowShortLambdasOnASingleLine = FormatStyle::SLS_All;
   CHECK_PARSE("AllowShortLambdasOnASingleLine: None",
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index ed1582d3417c4..c90f002fec63b 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -389,9 +389,7 @@ TEST_F(FormatTest, RemovesEmptyLines) {
 
   FormatStyle Style = getLLVMStyle();
   Style.AllowShortFunctionsOnASingleLine =
-      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                       /*Inline=*/true,
-                                       /*Other=*/true});
+      FormatStyle::ShortFunctionStyle::setAll();
   Style.MaxEmptyLinesToKeep = 2;
   Style.BreakBeforeBraces = FormatStyle::BS_Custom;
   Style.BraceWrapping.AfterClass = true;
@@ -3381,9 +3379,7 @@ TEST_F(FormatTest, MultiLineControlStatements) {
   Style.BraceWrapping.AfterStruct = false;
   Style.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_MultiLine;
   Style.AllowShortFunctionsOnASingleLine =
-      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                       /*Inline=*/true,
-                                       /*Other=*/true});
+      FormatStyle::ShortFunctionStyle::setAll();
   Style.ColumnLimit = 80;
   verifyFormat("void shortfunction() { bar(); }", Style);
   verifyFormat("struct T shortfunction() { return bar(); }", Style);
@@ -3405,9 +3401,7 @@ TEST_F(FormatTest, MultiLineControlStatements) {
   Style.BraceWrapping.AfterFunction = false;
   Style.BraceWrapping.AfterStruct = true;
   Style.AllowShortFunctionsOnASingleLine =
-      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                       /*Inline=*/true,
-                                       /*Other=*/true});
+      FormatStyle::ShortFunctionStyle::setAll();
   verifyFormat("void shortfunction() { bar(); }", Style);
   verifyFormat("struct T shortfunction() { return bar(); }", Style);
   verifyFormat("struct T\n"
@@ -4210,9 +4204,7 @@ TEST_F(FormatTest, FormatsNamespaces) {
   FormatStyle ShortInlineFunctions = getLLVMStyle();
   ShortInlineFunctions.NamespaceIndentation = FormatStyle::NI_All;
   ShortInlineFunctions.AllowShortFunctionsOnASingleLine =
-      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                       /*Inline=*/true,
-                                       /*Other=*/false});
+      FormatStyle::ShortFunctionStyle::setEmptyAndInline();
   verifyFormat("namespace {\n"
                "  void f() {\n"
                "    return;\n"
@@ -8349,9 +8341,7 @@ TEST_F(FormatTest, BreakConstructorInitializersAfterColon) {
 
   Style.ColumnLimit = 80;
   Style.AllowShortFunctionsOnASingleLine =
-      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                       /*Inline=*/true,
-                                       /*Other=*/true});
+      FormatStyle::ShortFunctionStyle::setAll();
   Style.ConstructorInitializerIndentWidth = 2;
   verifyFormat("SomeClass::Constructor() : a(a), b(b), c(c) {}", Style);
   verifyFormat("SomeClass::Constructor() :\n"
@@ -15007,9 +14997,7 @@ TEST_F(FormatTest, PullTrivialFunctionDefinitionsIntoSingleLine) {
 TEST_F(FormatTest, PullEmptyFunctionDefinitionsIntoSingleLine) {
   FormatStyle MergeEmptyOnly = getLLVMStyle();
   MergeEmptyOnly.AllowShortFunctionsOnASingleLine =
-      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                       /*Inline=*/false,
-                                       /*Other=*/false});
+      FormatStyle::ShortFunctionStyle::setEmptyOnly();
   verifyFormat("class C {\n"
                "  int f() {}\n"
                "};",
@@ -15039,9 +15027,7 @@ TEST_F(FormatTest, PullEmptyFunctionDefinitionsIntoSingleLine) {
 TEST_F(FormatTest, PullInlineFunctionDefinitionsIntoSingleLine) {
   FormatStyle MergeInlineOnly = getLLVMStyle();
   MergeInlineOnly.AllowShortFunctionsOnASingleLine =
-      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                       /*Inline=*/true,
-                                       /*Other=*/false});
+      FormatStyle::ShortFunctionStyle::setEmptyAndInline();
   verifyFormat("class C {\n"
                "  int f() { return 42; }\n"
                "};",
@@ -15146,9 +15132,7 @@ TEST_F(FormatTest, PullInlineFunctionDefinitionsIntoSingleLine) {
 TEST_F(FormatTest, CustomShortFunctionOptions) {
   FormatStyle CustomEmpty = getLLVMStyle();
   CustomEmpty.AllowShortFunctionsOnASingleLine =
-      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                       /*Inline=*/false,
-                                       /*Other=*/false});
+      FormatStyle::ShortFunctionStyle::setEmptyOnly();
 
   // Empty functions should be on a single line
   verifyFormat("int f() {}", CustomEmpty);
@@ -15185,9 +15169,7 @@ TEST_F(FormatTest, CustomShortFunctionOptions) {
   // Test with Inline = true, All = false
   FormatStyle CustomInline = getLLVMStyle();
   CustomInline.AllowShortFunctionsOnASingleLine =
-      FormatStyle::ShortFunctionStyle({/*Empty=*/false,
-                                       /*Inline=*/true,
-                                       /*Other=*/false});
+      FormatStyle::ShortFunctionStyle::setInlineOnly();
 
   verifyFormat("class C {\n"
                "  int f() {}\n"
@@ -15212,9 +15194,7 @@ TEST_F(FormatTest, CustomShortFunctionOptions) {
   // Test with All = true
   FormatStyle CustomAll = getLLVMStyle();
   CustomAll.AllowShortFunctionsOnASingleLine =
-      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                       /*Inline=*/true,
-                                       /*Other=*/true});
+      FormatStyle::ShortFunctionStyle::setAll();
 
   // All functions should be on a single line if they fit
   verifyFormat("int f() { return 42; }", CustomAll);
@@ -15233,9 +15213,7 @@ TEST_F(FormatTest, CustomShortFunctionOptions) {
   // Test various combinations
   FormatStyle CustomMixed = getLLVMStyle();
   CustomMixed.AllowShortFunctionsOnASingleLine =
-      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                       /*Inline=*/true,
-                                       /*Other=*/false});
+      FormatStyle::ShortFunctionStyle::setEmptyAndInline();
 
   // Empty functions should be on a single line
   verifyFormat("int f() {}", CustomMixed);
@@ -15260,9 +15238,7 @@ TEST_F(FormatTest, CustomShortFunctionOptions) {
 TEST_F(FormatTest, PullInlineOnlyFunctionDefinitionsIntoSingleLine) {
   FormatStyle MergeInlineOnly = getLLVMStyle();
   MergeInlineOnly.AllowShortFunctionsOnASingleLine =
-      FormatStyle::ShortFunctionStyle({/*Empty=*/false,
-                                       /*Inline=*/true,
-                                       /*Other=*/false});
+      FormatStyle::ShortFunctionStyle::setInlineOnly();
   verifyFormat("class C {\n"
                "  int f() { return 42; }\n"
                "};",
@@ -15334,9 +15310,7 @@ TEST_F(FormatTest, SplitEmptyFunction) {
                Style);
 
   Style.AllowShortFunctionsOnASingleLine =
-      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                       /*Inline=*/false,
-                                       /*Other=*/false});
+      FormatStyle::ShortFunctionStyle::setEmptyOnly();
   verifyFormat("int f() {}", Style);
   verifyFormat("int aaaaaaaaaaaaaa(int bbbbbbbbbbbbbb)\n"
                "{}",
@@ -15348,9 +15322,7 @@ TEST_F(FormatTest, SplitEmptyFunction) {
                Style);
 
   Style.AllowShortFunctionsOnASingleLine =
-      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                       /*Inline=*/true,
-                                       /*Other=*/false});
+      FormatStyle::ShortFunctionStyle::setEmptyAndInline();
   verifyFormat("class Foo {\n"
                "  int f() {}\n"
                "};",
@@ -15359,6 +15331,10 @@ TEST_F(FormatTest, SplitEmptyFunction) {
                "  int f() { return 0; }\n"
                "};",
                Style);
+  verifyFormat("class Foo {\n"
+               "  int f() { return 0; }\n"
+               "};",
+               Style);
   verifyFormat("class Foo {\n"
                "  int aaaaaaaaaaaaaa(int bbbbbbbbbbbbbb)\n"
                "  {}\n"
@@ -15373,9 +15349,7 @@ TEST_F(FormatTest, SplitEmptyFunction) {
                Style);
 
   Style.AllowShortFunctionsOnASingleLine =
-      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                       /*Inline=*/true,
-                                       /*Other=*/true});
+      FormatStyle::ShortFunctionStyle::setAll();
   verifyFormat("int f() {}", Style);
   verifyFormat("int f() { return 0; }", Style);
   verifyFormat("int aaaaaaaaaaaaaa(int bbbbbbbbbbbbbb)\n"
@@ -15421,9 +15395,7 @@ TEST_F(FormatTest, SplitEmptyFunctionButNotRecord) {
 TEST_F(FormatTest, KeepShortFunctionAfterPPElse) {
   FormatStyle Style = getLLVMStyle();
   Style.AllowShortFunctionsOnASingleLine =
-      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                       /*Inline=*/true,
-                                       /*Other=*/true});
+      FormatStyle::ShortFunctionStyle::setAll();
   verifyFormat("#ifdef A\n"
                "int f() {}\n"
                "#else\n"
@@ -21546,9 +21518,7 @@ TEST_F(FormatTest, WhitesmithsBraceBreaking) {
 
   // Make a few changes to the style for testing purposes
   WhitesmithsBraceStyle.AllowShortFunctionsOnASingleLine =
-      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                       /*Inline=*/false,
-                                       /*Other=*/false});
+      FormatStyle::ShortFunctionStyle::setEmptyOnly();
   WhitesmithsBraceStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_None;
 
   // FIXME: this test case can't decide whether there should be a blank line
@@ -23105,9 +23075,7 @@ TEST_F(FormatTest, BreakConstructorInitializersBeforeComma) {
 
   Style.ColumnLimit = 80;
   Style.AllowShortFunctionsOnASingleLine =
-      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                       /*Inline=*/true,
-                                       /*Other=*/true});
+      FormatStyle::ShortFunctionStyle::setAll();
   Style.ConstructorInitializerIndentWidth = 2;
   verifyFormat("SomeClass::Constructor()\n"
                "  : a(a)\n"
diff --git a/clang/unittests/Format/FormatTestCSharp.cpp b/clang/unittests/Format/FormatTestCSharp.cpp
index 22c757509f5fb..da39620916ba4 100644
--- a/clang/unittests/Format/FormatTestCSharp.cpp
+++ b/clang/unittests/Format/FormatTestCSharp.cpp
@@ -1661,9 +1661,7 @@ TEST_F(FormatTestCSharp, ShortFunctions) {
   FormatStyle Style = getLLVMStyle(FormatStyle::LK_CSharp);
   Style.NamespaceIndentation = FormatStyle::NI_All;
   Style.AllowShortFunctionsOnASingleLine =
-      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                       /*Inline=*/true,
-                                       /*Other=*/false});
+      FormatStyle::ShortFunctionStyle::setEmptyAndInline();
   verifyFormat("interface Interface {\n"
                "  void f() { return; }\n"
                "};",
diff --git a/clang/unittests/Format/FormatTestJS.cpp b/clang/unittests/Format/FormatTestJS.cpp
index 03e55e4498fd4..fe2dc6f404fe0 100644
--- a/clang/unittests/Format/FormatTestJS.cpp
+++ b/clang/unittests/Format/FormatTestJS.cpp
@@ -1016,9 +1016,7 @@ TEST_F(FormatTestJS, TrailingCommaInsertion) {
 TEST_F(FormatTestJS, FunctionLiterals) {
   FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
   Style.AllowShortFunctionsOnASingleLine =
-      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                       /*Inline=*/true,
-                                       /*Other=*/false});
+      FormatStyle::ShortFunctionStyle::setEmptyAndInline();
   verifyFormat("doFoo(function() {});");
   verifyFormat("doFoo(function() { return 1; });", Style);
   verifyFormat("var func = function() {\n"
@@ -1132,9 +1130,7 @@ TEST_F(FormatTestJS, DontWrapEmptyLiterals) {
 TEST_F(FormatTestJS, InliningFunctionLiterals) {
   FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
   Style.AllowShortFunctionsOnASingleLine =
-      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                       /*Inline=*/true,
-                                       /*Other=*/false});
+      FormatStyle::ShortFunctionStyle::setEmptyAndInline();
   verifyFormat("var func = function() {\n"
                "  return 1;\n"
                "};",
@@ -1150,9 +1146,7 @@ TEST_F(FormatTestJS, InliningFunctionLiterals) {
                Style);
 
   Style.AllowShortFunctionsOnASingleLine =
-      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                       /*Inline=*/true,
-                                       /*Other=*/true});
+      FormatStyle::ShortFunctionStyle::setAll();
   verifyFormat("var func = function() { return 1; };", Style);
   verifyFormat("var func = doSomething(function() { return 1; });", Style);
   verifyFormat(
@@ -1186,9 +1180,7 @@ TEST_F(FormatTestJS, InliningFunctionLiterals) {
                Style);
 
   Style.AllowShortFunctionsOnASingleLine =
-      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                       /*Inline=*/false,
-                                       /*Other=*/false});
+      FormatStyle::ShortFunctionStyle::setEmptyOnly();
   verifyFormat("var func = function() {\n"
                "  return 1;\n"
                "};",
@@ -1197,10 +1189,8 @@ TEST_F(FormatTestJS, InliningFunctionLiterals) {
 
 TEST_F(FormatTestJS, InliningFunctionLiteralsNew) {
   FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
-  Style.AllowShortFunctionsOnASingleLine =
-      FormatStyle::ShortFunctionStyle({/*Empty=*/false,
-                                       /*Inline=*/false,
-                                       /*Other=*/true});
+  Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
+  Style.AllowShortFunctionsOnASingleLine.Other = true;
   verifyFormat("var func = function() { return 1; };", Style);
   verifyFormat("var func = doSomething(function() {\n"
                "  return 1;\n"
@@ -1229,9 +1219,7 @@ TEST_F(FormatTestJS, InliningFunctionLiteralsNew) {
 TEST_F(FormatTestJS, MultipleFunctionLiterals) {
   FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
   Style.AllowShortFunctionsOnASingleLine =
-      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                       /*Inline=*/true,
-                                       /*Other=*/true});
+      FormatStyle::ShortFunctionStyle::setAll();
   verifyFormat("promise.then(\n"
                "    function success() {\n"
                "      doFoo();\n"
diff --git a/clang/unittests/Format/FormatTestJava.cpp b/clang/unittests/Format/FormatTestJava.cpp
index 77ca00d0fd132..581661f131a6d 100644
--- a/clang/unittests/Format/FormatTestJava.cpp
+++ b/clang/unittests/Format/FormatTestJava.cpp
@@ -597,9 +597,7 @@ TEST_F(FormatTestJava, RetainsLogicalShifts) {
 TEST_F(FormatTestJava, ShortFunctions) {
   FormatStyle Style = getLLVMStyle(FormatStyle::LK_Java);
   Style.AllowShortFunctionsOnASingleLine =
-      FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                       /*Inline=*/true,
-                                       /*Other=*/false});
+      FormatStyle::ShortFunctionStyle::setEmptyAndInline();
   verifyFormat("enum Enum {\n"
                "  E1,\n"
                "  E2;\n"

>From d7ad2a8e97e51307b553403df6441535998ee478 Mon Sep 17 00:00:00 2001
From: Ivan Rymarchyk <>
Date: Sat, 17 May 2025 14:19:33 -0700
Subject: [PATCH 13/21] added one forgotten change

---
 clang/lib/Format/Format.cpp | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index bd439eca7ace9..77eda64b626d6 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -628,9 +628,7 @@ template <> struct MappingTraits<FormatStyle::ShortFunctionStyle> {
     IO.enumCase(Value, "Empty",
                 FormatStyle::ShortFunctionStyle::setEmptyOnly());
     IO.enumCase(Value, "Inline",
-                FormatStyle::ShortFunctionStyle({/*Empty=*/true,
-                                                 /*Inline=*/true,
-                                                 /*Other=*/false}));
+                FormatStyle::ShortFunctionStyle::setEmptyAndInline());
     IO.enumCase(Value, "InlineOnly",
                 FormatStyle::ShortFunctionStyle::setInlineOnly());
     IO.enumCase(Value, "All", FormatStyle::ShortFunctionStyle::setAll());

>From 8cdab54443a1121b9b5cda47117d09c333bd7e7b Mon Sep 17 00:00:00 2001
From: owenca <owenpiano at gmail.com>
Date: Sat, 14 Mar 2026 20:04:22 -0700
Subject: [PATCH 14/21] Refactor ShortFunctionStyle initialization

---
 clang/lib/Format/Format.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index a5c597d5a0613..adfe4ba982453 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -733,7 +733,7 @@ template <> struct ScalarEnumerationTraits<FormatStyle::ShortBlockStyle> {
 
 template <> struct MappingTraits<FormatStyle::ShortFunctionStyle> {
   static void enumInput(IO &IO, FormatStyle::ShortFunctionStyle &Value) {
-    IO.enumCase(Value, "None", FormatStyle::ShortFunctionStyle({}));
+    IO.enumCase(Value, "None", FormatStyle::ShortFunctionStyle());
     IO.enumCase(Value, "Empty",
                 FormatStyle::ShortFunctionStyle::setEmptyOnly());
     IO.enumCase(Value, "Inline",
@@ -744,7 +744,7 @@ template <> struct MappingTraits<FormatStyle::ShortFunctionStyle> {
 
     // For backward compatibility.
     IO.enumCase(Value, "true", FormatStyle::ShortFunctionStyle::setAll());
-    IO.enumCase(Value, "false", FormatStyle::ShortFunctionStyle({}));
+    IO.enumCase(Value, "false", FormatStyle::ShortFunctionStyle());
   }
 
   static void mapping(IO &IO, FormatStyle::ShortFunctionStyle &Value) {
@@ -2273,7 +2273,7 @@ FormatStyle getMicrosoftStyle(FormatStyle::LanguageKind Language) {
   Style.BraceWrapping.BeforeWhile = false;
   Style.PenaltyReturnTypeOnItsOwnLine = 1000;
   Style.AllowShortEnumsOnASingleLine = false;
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
+  Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle();
   Style.AllowShortCaseLabelsOnASingleLine = false;
   Style.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
   Style.AllowShortLoopsOnASingleLine = false;

>From c68afc2fb4b3ded12f2b759965733c14c4cf89a8 Mon Sep 17 00:00:00 2001
From: owenca <owenpiano at gmail.com>
Date: Sat, 14 Mar 2026 20:07:15 -0700
Subject: [PATCH 15/21] Update fmt.Println message from 'Hello' to 'Goodbye'

---
 .../Format/DefinitionBlockSeparatorTest.cpp   | 2372 +++++++++++++----
 1 file changed, 1795 insertions(+), 577 deletions(-)

diff --git a/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp b/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp
index 895ab0fe73cc9..8cd0dd840acf8 100644
--- a/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp
+++ b/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp
@@ -1,4 +1,4 @@
-//===- DefinitionBlockSeparatorTest.cpp - Formatting unit tests -----------===//
+//===- unittest/Format/ConfigParseTest.cpp - Config parsing unit tests ----===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -6,614 +6,1832 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "FormatTestUtils.h"
 #include "clang/Format/Format.h"
 
-#include "llvm/Support/Debug.h"
+#include "llvm/Support/VirtualFileSystem.h"
 #include "gtest/gtest.h"
 
-#define DEBUG_TYPE "definition-block-separator-test"
-
 namespace clang {
 namespace format {
 namespace {
 
-class DefinitionBlockSeparatorTest : public testing::Test {
-protected:
-  static std::string
-  separateDefinitionBlocks(StringRef Code,
-                           const std::vector<tooling::Range> &Ranges,
-                           const FormatStyle &Style = getLLVMStyle()) {
-    LLVM_DEBUG(llvm::errs() << "---\n");
-    LLVM_DEBUG(llvm::errs() << Code << "\n\n");
-    tooling::Replacements Replaces = reformat(Style, Code, Ranges, "<stdin>");
-    auto Result = applyAllReplacements(Code, Replaces);
-    EXPECT_TRUE(static_cast<bool>(Result));
-    LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
-    return *Result;
-  }
-
-  static std::string
-  separateDefinitionBlocks(StringRef Code,
-                           const FormatStyle &Style = getLLVMStyle()) {
-    return separateDefinitionBlocks(
-        Code,
-        /*Ranges=*/{1, tooling::Range(0, Code.size())}, Style);
-  }
-
-  static void _verifyFormat(const char *File, int Line, StringRef Code,
-                            const FormatStyle &Style = getLLVMStyle(),
-                            StringRef ExpectedCode = "", bool Inverse = true) {
-    testing::ScopedTrace t(File, Line, testing::Message() << Code.str());
-    bool HasOriginalCode = true;
-    if (ExpectedCode == "") {
-      ExpectedCode = Code;
-      HasOriginalCode = false;
-    }
-
-    EXPECT_EQ(ExpectedCode, separateDefinitionBlocks(ExpectedCode, Style))
-        << "Expected code is not stable";
-    if (Inverse) {
-      FormatStyle InverseStyle = Style;
-      if (Style.SeparateDefinitionBlocks == FormatStyle::SDS_Always)
-        InverseStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Never;
-      else
-        InverseStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
-      EXPECT_NE(ExpectedCode,
-                separateDefinitionBlocks(ExpectedCode, InverseStyle))
-          << "Inverse formatting makes no difference";
-    }
-    std::string CodeToFormat =
-        HasOriginalCode ? Code.str() : removeEmptyLines(Code);
-    std::string Result = separateDefinitionBlocks(CodeToFormat, Style);
-    EXPECT_EQ(ExpectedCode, Result) << "Test failed. Formatted:\n" << Result;
-  }
-
-  static std::string removeEmptyLines(StringRef Code) {
-    std::string Result = "";
-    for (auto Char : Code.str()) {
-      if (Result.size()) {
-        auto LastChar = Result.back();
-        if ((Char == '\n' && LastChar == '\n') ||
-            (Char == '\r' && (LastChar == '\r' || LastChar == '\n'))) {
-          continue;
-        }
-      }
-      Result.push_back(Char);
-    }
-    return Result;
-  }
-};
-
-#define verifyFormat(...) _verifyFormat(__FILE__, __LINE__, __VA_ARGS__)
-
-TEST_F(DefinitionBlockSeparatorTest, Basic) {
-  FormatStyle Style = getLLVMStyle();
-  Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
-  verifyFormat("int foo(int i, int j) {\n"
-               "  int r = i + j;\n"
-               "  return r;\n"
-               "}\n"
-               "\n"
-               "int bar(int j, int k) {\n"
-               "  int r = j + k;\n"
-               "  return r;\n"
-               "}",
-               Style);
-
-  verifyFormat("struct foo {\n"
-               "  int i, j;\n"
-               "};\n"
-               "\n"
-               "struct bar {\n"
-               "  int j, k;\n"
-               "};",
-               Style);
-
-  verifyFormat("union foo {\n"
-               "  int i, j;\n"
-               "};\n"
-               "\n"
-               "union bar {\n"
-               "  int j, k;\n"
-               "};",
-               Style);
-
-  verifyFormat("class foo {\n"
-               "  int i, j;\n"
-               "};\n"
-               "\n"
-               "class bar {\n"
-               "  int j, k;\n"
-               "};",
-               Style);
-
-  verifyFormat("namespace foo {\n"
-               "int i, j;\n"
-               "}\n"
-               "\n"
-               "namespace bar {\n"
-               "int j, k;\n"
-               "}",
-               Style);
-
-  verifyFormat("enum Foo { FOO, BAR };\n"
-               "\n"
-               "enum Bar { FOOBAR, BARFOO };",
-               Style);
-
-  FormatStyle BreakAfterReturnTypeStyle = Style;
-  BreakAfterReturnTypeStyle.BreakAfterReturnType = FormatStyle::RTBS_All;
-  // Test uppercased long typename
-  verifyFormat("class Foo {\n"
-               "  void\n"
-               "  Bar(int t, int p) {\n"
-               "    int r = t + p;\n"
-               "    return r;\n"
-               "  }\n"
-               "\n"
-               "  HRESULT\n"
-               "  Foobar(int t, int p) {\n"
-               "    int r = t * p;\n"
-               "    return r;\n"
-               "  }\n"
-               "}",
-               BreakAfterReturnTypeStyle);
+void dropDiagnosticHandler(const llvm::SMDiagnostic &, void *) {}
+FormatStyle getGoogleStyle() { return getGoogleStyle(FormatStyle::LK_Cpp); }
+
+#define EXPECT_ALL_STYLES_EQUAL(Styles)                                        \
+  for (size_t i = 1; i < Styles.size(); ++i)                                   \
+  EXPECT_EQ(Styles[0], Styles[i])                                              \
+      << "Style #" << i << " of " << Styles.size() << " differs from Style #0"
+
+TEST(ConfigParseTest, GetsPredefinedStyleByName) {
+  SmallVector<FormatStyle, 3> Styles;
+  Styles.resize(3);
+
+  Styles[0] = getLLVMStyle();
+  EXPECT_TRUE(getPredefinedStyle("LLVM", FormatStyle::LK_Cpp, &Styles[1]));
+  EXPECT_TRUE(getPredefinedStyle("lLvM", FormatStyle::LK_Cpp, &Styles[2]));
+  EXPECT_ALL_STYLES_EQUAL(Styles);
+
+  Styles[0] = getGoogleStyle();
+  EXPECT_TRUE(getPredefinedStyle("Google", FormatStyle::LK_Cpp, &Styles[1]));
+  EXPECT_TRUE(getPredefinedStyle("gOOgle", FormatStyle::LK_Cpp, &Styles[2]));
+  EXPECT_ALL_STYLES_EQUAL(Styles);
+
+  Styles[0] = getGoogleStyle(FormatStyle::LK_JavaScript);
+  EXPECT_TRUE(
+      getPredefinedStyle("Google", FormatStyle::LK_JavaScript, &Styles[1]));
+  EXPECT_TRUE(
+      getPredefinedStyle("gOOgle", FormatStyle::LK_JavaScript, &Styles[2]));
+  EXPECT_ALL_STYLES_EQUAL(Styles);
+
+  Styles[0] = getChromiumStyle(FormatStyle::LK_Cpp);
+  EXPECT_TRUE(getPredefinedStyle("Chromium", FormatStyle::LK_Cpp, &Styles[1]));
+  EXPECT_TRUE(getPredefinedStyle("cHRoMiUM", FormatStyle::LK_Cpp, &Styles[2]));
+  EXPECT_ALL_STYLES_EQUAL(Styles);
+
+  Styles[0] = getMozillaStyle();
+  EXPECT_TRUE(getPredefinedStyle("Mozilla", FormatStyle::LK_Cpp, &Styles[1]));
+  EXPECT_TRUE(getPredefinedStyle("moZILla", FormatStyle::LK_Cpp, &Styles[2]));
+  EXPECT_ALL_STYLES_EQUAL(Styles);
+
+  Styles[0] = getWebKitStyle();
+  EXPECT_TRUE(getPredefinedStyle("WebKit", FormatStyle::LK_Cpp, &Styles[1]));
+  EXPECT_TRUE(getPredefinedStyle("wEbKit", FormatStyle::LK_Cpp, &Styles[2]));
+  EXPECT_ALL_STYLES_EQUAL(Styles);
+
+  Styles[0] = getGNUStyle();
+  EXPECT_TRUE(getPredefinedStyle("GNU", FormatStyle::LK_Cpp, &Styles[1]));
+  EXPECT_TRUE(getPredefinedStyle("gnU", FormatStyle::LK_Cpp, &Styles[2]));
+  EXPECT_ALL_STYLES_EQUAL(Styles);
+
+  Styles[0] = getClangFormatStyle();
+  EXPECT_TRUE(
+      getPredefinedStyle("clang-format", FormatStyle::LK_Cpp, &Styles[1]));
+  EXPECT_TRUE(
+      getPredefinedStyle("Clang-format", FormatStyle::LK_Cpp, &Styles[2]));
+  EXPECT_ALL_STYLES_EQUAL(Styles);
+
+  EXPECT_FALSE(getPredefinedStyle("qwerty", FormatStyle::LK_Cpp, &Styles[0]));
 }
 
-TEST_F(DefinitionBlockSeparatorTest, FormatConflict) {
-  FormatStyle Style = getLLVMStyle();
-  Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
-  StringRef Code = "class Test {\n"
-                   "public:\n"
-                   "  static void foo() {\n"
-                   "    int t;\n"
-                   "    return 1;\n"
-                   "  }\n"
-                   "};";
-  std::vector<tooling::Range> Ranges = {1, tooling::Range(0, Code.size())};
-  EXPECT_EQ(reformat(Style, Code, Ranges, "<stdin>").size(), 0u);
+TEST(ConfigParseTest, GetsCorrectBasedOnStyle) {
+  SmallVector<FormatStyle, 8> Styles;
+  Styles.resize(2);
+
+  Styles[0] = getGoogleStyle();
+  Styles[1] = getLLVMStyle();
+  EXPECT_EQ(0, parseConfiguration("BasedOnStyle: Google", &Styles[1]).value());
+  EXPECT_ALL_STYLES_EQUAL(Styles);
+
+  Styles.resize(5);
+  Styles[0] = getGoogleStyle(FormatStyle::LK_JavaScript);
+  Styles[1] = getLLVMStyle();
+  Styles[1].Language = FormatStyle::LK_JavaScript;
+  EXPECT_EQ(0, parseConfiguration("BasedOnStyle: Google", &Styles[1]).value());
+
+  Styles[2] = getLLVMStyle();
+  Styles[2].Language = FormatStyle::LK_JavaScript;
+  EXPECT_EQ(0, parseConfiguration("Language: JavaScript\n"
+                                  "BasedOnStyle: Google",
+                                  &Styles[2])
+                   .value());
+
+  Styles[3] = getLLVMStyle();
+  Styles[3].Language = FormatStyle::LK_JavaScript;
+  EXPECT_EQ(0, parseConfiguration("BasedOnStyle: Google\n"
+                                  "Language: JavaScript",
+                                  &Styles[3])
+                   .value());
+
+  Styles[4] = getLLVMStyle();
+  Styles[4].Language = FormatStyle::LK_JavaScript;
+  EXPECT_EQ(0, parseConfiguration("---\n"
+                                  "BasedOnStyle: LLVM\n"
+                                  "IndentWidth: 123\n"
+                                  "---\n"
+                                  "BasedOnStyle: Google\n"
+                                  "Language: JavaScript",
+                                  &Styles[4])
+                   .value());
+  EXPECT_ALL_STYLES_EQUAL(Styles);
 }
 
-TEST_F(DefinitionBlockSeparatorTest, CommentBlock) {
-  FormatStyle Style = getLLVMStyle();
-  Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
-  std::string Prefix = "enum Foo { FOO, BAR };\n"
-                       "\n"
-                       "/*\n"
-                       "test1\n"
-                       "test2\n"
-                       "*/\n"
-                       "int foo(int i, int j) {\n"
-                       "  int r = i + j;\n"
-                       "  return r;\n"
-                       "}\n";
-  std::string Suffix = "enum Bar { FOOBAR, BARFOO };\n"
-                       "\n"
-                       "/* Comment block in one line*/\n"
-                       "int bar3(int j, int k) {\n"
-                       "  // A comment\n"
-                       "  int r = j % k;\n"
-                       "  return r;\n"
-                       "}\n";
-  std::string CommentedCode = "/*\n"
-                              "int bar2(int j, int k) {\n"
-                              "  int r = j / k;\n"
-                              "  return r;\n"
-                              "}\n"
-                              "*/\n";
-  verifyFormat(removeEmptyLines(Prefix) + "\n" + CommentedCode + "\n" +
-                   removeEmptyLines(Suffix),
-               Style, Prefix + "\n" + CommentedCode + "\n" + Suffix);
-  verifyFormat(removeEmptyLines(Prefix) + "\n" + CommentedCode +
-                   removeEmptyLines(Suffix),
-               Style, Prefix + "\n" + CommentedCode + Suffix);
+#define CHECK_PARSE_BOOL_FIELD(FIELD, CONFIG_NAME)                             \
+  Style.FIELD = false;                                                         \
+  EXPECT_EQ(0, parseConfiguration(CONFIG_NAME ": true", &Style).value());      \
+  EXPECT_TRUE(Style.FIELD);                                                    \
+  EXPECT_EQ(0, parseConfiguration(CONFIG_NAME ": false", &Style).value());     \
+  EXPECT_FALSE(Style.FIELD)
+
+#define CHECK_PARSE_BOOL(FIELD) CHECK_PARSE_BOOL_FIELD(FIELD, #FIELD)
+
+#define CHECK_PARSE_NESTED_BOOL_FIELD(STRUCT, FIELD, CONFIG_NAME)              \
+  Style.STRUCT.FIELD = false;                                                  \
+  EXPECT_EQ(0,                                                                 \
+            parseConfiguration(#STRUCT ":\n  " CONFIG_NAME ": true", &Style)   \
+                .value());                                                     \
+  EXPECT_TRUE(Style.STRUCT.FIELD);                                             \
+  EXPECT_EQ(0,                                                                 \
+            parseConfiguration(#STRUCT ":\n  " CONFIG_NAME ": false", &Style)  \
+                .value());                                                     \
+  EXPECT_FALSE(Style.STRUCT.FIELD)
+
+#define CHECK_PARSE_NESTED_BOOL(STRUCT, FIELD)                                 \
+  CHECK_PARSE_NESTED_BOOL_FIELD(STRUCT, FIELD, #FIELD)
+
+#define CHECK_PARSE(TEXT, FIELD, VALUE)                                        \
+  EXPECT_NE(VALUE, Style.FIELD) << "Initial value already the same!";          \
+  EXPECT_EQ(0, parseConfiguration(TEXT, &Style).value());                      \
+  EXPECT_EQ(VALUE, Style.FIELD) << "Unexpected value after parsing!"
+
+#define CHECK_PARSE_INT(FIELD) CHECK_PARSE(#FIELD ": -1234", FIELD, -1234)
+
+#define CHECK_PARSE_UNSIGNED(FIELD) CHECK_PARSE(#FIELD ": 1234", FIELD, 1234u)
+
+#define CHECK_PARSE_LIST(FIELD)                                                \
+  CHECK_PARSE(#FIELD ": [foo]", FIELD, std::vector<std::string>{"foo"})
+
+#define CHECK_PARSE_NESTED_VALUE(TEXT, STRUCT, FIELD, VALUE)                   \
+  EXPECT_NE(VALUE, Style.STRUCT.FIELD) << "Initial value already the same!";   \
+  EXPECT_EQ(0, parseConfiguration(#STRUCT ":\n  " TEXT, &Style).value());      \
+  EXPECT_EQ(VALUE, Style.STRUCT.FIELD) << "Unexpected value after parsing!"
+
+TEST(ConfigParseTest, ParsesConfigurationBools) {
+  FormatStyle Style = {};
+  Style.Language = FormatStyle::LK_Cpp;
+  CHECK_PARSE_BOOL(AllowAllArgumentsOnNextLine);
+  CHECK_PARSE_BOOL(AllowAllParametersOfDeclarationOnNextLine);
+  CHECK_PARSE_BOOL(AllowBreakBeforeQtProperty);
+  CHECK_PARSE_BOOL(AllowShortCaseExpressionOnASingleLine);
+  CHECK_PARSE_BOOL(AllowShortCaseLabelsOnASingleLine);
+  CHECK_PARSE_BOOL(AllowShortCompoundRequirementOnASingleLine);
+  CHECK_PARSE_BOOL(AllowShortEnumsOnASingleLine);
+  CHECK_PARSE_BOOL(AllowShortLoopsOnASingleLine);
+  CHECK_PARSE_BOOL(AllowShortNamespacesOnASingleLine);
+  CHECK_PARSE_BOOL(BinPackArguments);
+  CHECK_PARSE_BOOL(BinPackLongBracedList);
+  CHECK_PARSE_BOOL(BreakAdjacentStringLiterals);
+  CHECK_PARSE_BOOL(BreakAfterJavaFieldAnnotations);
+  CHECK_PARSE_BOOL(BreakAfterOpenBracketBracedList);
+  CHECK_PARSE_BOOL(BreakAfterOpenBracketFunction);
+  CHECK_PARSE_BOOL(BreakAfterOpenBracketIf);
+  CHECK_PARSE_BOOL(BreakAfterOpenBracketLoop);
+  CHECK_PARSE_BOOL(BreakAfterOpenBracketSwitch);
+  CHECK_PARSE_BOOL(BreakBeforeCloseBracketBracedList);
+  CHECK_PARSE_BOOL(BreakBeforeCloseBracketFunction);
+  CHECK_PARSE_BOOL(BreakBeforeCloseBracketIf);
+  CHECK_PARSE_BOOL(BreakBeforeCloseBracketLoop);
+  CHECK_PARSE_BOOL(BreakBeforeCloseBracketSwitch);
+  CHECK_PARSE_BOOL(BreakBeforeTemplateCloser);
+  CHECK_PARSE_BOOL(BreakBeforeTernaryOperators);
+  CHECK_PARSE_BOOL(BreakStringLiterals);
+  CHECK_PARSE_BOOL(CompactNamespaces);
+  CHECK_PARSE_BOOL(DerivePointerAlignment);
+  CHECK_PARSE_BOOL_FIELD(DerivePointerAlignment, "DerivePointerBinding");
+  CHECK_PARSE_BOOL(DisableFormat);
+  CHECK_PARSE_BOOL(IndentAccessModifiers);
+  CHECK_PARSE_BOOL(IndentCaseBlocks);
+  CHECK_PARSE_BOOL(IndentCaseLabels);
+  CHECK_PARSE_BOOL(IndentExportBlock);
+  CHECK_PARSE_BOOL(IndentRequiresClause);
+  CHECK_PARSE_BOOL_FIELD(IndentRequiresClause, "IndentRequires");
+  CHECK_PARSE_BOOL(IndentWrappedFunctionNames);
+  CHECK_PARSE_BOOL(InsertBraces);
+  CHECK_PARSE_BOOL(InsertNewlineAtEOF);
+  CHECK_PARSE_BOOL_FIELD(KeepEmptyLines.AtEndOfFile, "KeepEmptyLinesAtEOF");
+  CHECK_PARSE_BOOL_FIELD(KeepEmptyLines.AtStartOfBlock,
+                         "KeepEmptyLinesAtTheStartOfBlocks");
+  CHECK_PARSE_BOOL(KeepFormFeed);
+  CHECK_PARSE_BOOL(ObjCSpaceAfterMethodDeclarationPrefix);
+  CHECK_PARSE_BOOL(ObjCSpaceAfterProperty);
+  CHECK_PARSE_BOOL(ObjCSpaceBeforeProtocolList);
+  CHECK_PARSE_BOOL(RemoveBracesLLVM);
+  CHECK_PARSE_BOOL(RemoveEmptyLinesInUnwrappedLines);
+  CHECK_PARSE_BOOL(RemoveSemicolon);
+  CHECK_PARSE_BOOL(SkipMacroDefinitionBody);
+  CHECK_PARSE_BOOL(SpacesInSquareBrackets);
+  CHECK_PARSE_BOOL(SpacesInContainerLiterals);
+  CHECK_PARSE_BOOL(SpaceAfterCStyleCast);
+  CHECK_PARSE_BOOL(SpaceAfterTemplateKeyword);
+  CHECK_PARSE_BOOL(SpaceAfterOperatorKeyword);
+  CHECK_PARSE_BOOL(SpaceAfterLogicalNot);
+  CHECK_PARSE_BOOL(SpaceBeforeAssignmentOperators);
+  CHECK_PARSE_BOOL(SpaceBeforeCaseColon);
+  CHECK_PARSE_BOOL(SpaceBeforeCpp11BracedList);
+  CHECK_PARSE_BOOL(SpaceBeforeCtorInitializerColon);
+  CHECK_PARSE_BOOL(SpaceBeforeInheritanceColon);
+  CHECK_PARSE_BOOL(SpaceBeforeJsonColon);
+  CHECK_PARSE_BOOL(SpaceBeforeRangeBasedForLoopColon);
+  CHECK_PARSE_BOOL(SpaceBeforeSquareBrackets);
+  CHECK_PARSE_BOOL(VerilogBreakBetweenInstancePorts);
+
+  CHECK_PARSE_NESTED_BOOL(AlignConsecutiveShortCaseStatements, Enabled);
+  CHECK_PARSE_NESTED_BOOL(AlignConsecutiveShortCaseStatements,
+                          AcrossEmptyLines);
+  CHECK_PARSE_NESTED_BOOL(AlignConsecutiveShortCaseStatements, AcrossComments);
+  CHECK_PARSE_NESTED_BOOL(AlignConsecutiveShortCaseStatements, AlignCaseArrows);
+  CHECK_PARSE_NESTED_BOOL(AlignConsecutiveShortCaseStatements, AlignCaseColons);
+  CHECK_PARSE_NESTED_BOOL(AllowShortFunctionsOnASingleLine, Empty);
+  CHECK_PARSE_NESTED_BOOL(AllowShortFunctionsOnASingleLine, Inline);
+  CHECK_PARSE_NESTED_BOOL(AllowShortFunctionsOnASingleLine, Other);
+  CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterCaseLabel);
+  CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterClass);
+  CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterEnum);
+  CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterFunction);
+  CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterNamespace);
+  CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterObjCDeclaration);
+  CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterStruct);
+  CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterUnion);
+  CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterExternBlock);
+  CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeCatch);
+  CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeElse);
+  CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeLambdaBody);
+  CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeWhile);
+  CHECK_PARSE_NESTED_BOOL(BraceWrapping, IndentBraces);
+  CHECK_PARSE_NESTED_BOOL(BraceWrapping, SplitEmptyFunction);
+  CHECK_PARSE_NESTED_BOOL(BraceWrapping, SplitEmptyRecord);
+  CHECK_PARSE_NESTED_BOOL(BraceWrapping, SplitEmptyNamespace);
+  CHECK_PARSE_NESTED_BOOL(KeepEmptyLines, AtEndOfFile);
+  CHECK_PARSE_NESTED_BOOL(KeepEmptyLines, AtStartOfBlock);
+  CHECK_PARSE_NESTED_BOOL(KeepEmptyLines, AtStartOfFile);
+  CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterControlStatements);
+  CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterForeachMacros);
+  CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions,
+                          AfterFunctionDeclarationName);
+  CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions,
+                          AfterFunctionDefinitionName);
+  CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterIfMacros);
+  CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterNot);
+  CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterOverloadedOperator);
+  CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterPlacementOperator);
+  CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, BeforeNonEmptyParentheses);
+  CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, ExceptDoubleParentheses);
+  CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InCStyleCasts);
+  CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InConditionalStatements);
+  CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InEmptyParentheses);
+  CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, Other);
+  CHECK_PARSE_NESTED_BOOL(SortIncludes, Enabled);
+  CHECK_PARSE_NESTED_BOOL(SortIncludes, IgnoreCase);
+  CHECK_PARSE_NESTED_BOOL(SortIncludes, IgnoreExtension);
 }
 
-TEST_F(DefinitionBlockSeparatorTest, UntouchBlockStartStyle) {
-  // Returns a std::pair of two strings, with the first one for passing into
-  // Always test and the second one be the expected result of the first string.
-  auto MakeUntouchTest = [&](std::string BlockHeader, std::string BlockChanger,
-                             std::string BlockFooter, bool BlockEndNewLine) {
-    std::string CodePart1 = "enum Foo { FOO, BAR };\n"
-                            "\n"
-                            "/*\n"
-                            "test1\n"
-                            "test2\n"
-                            "*/\n"
-                            "int foo(int i, int j) {\n"
-                            "  int r = i + j;\n"
-                            "  return r;\n"
-                            "}\n";
-    std::string CodePart2 = "/* Comment block in one line*/\n"
-                            "enum Bar { FOOBAR, BARFOO };\n"
-                            "\n"
-                            "int bar3(int j, int k) {\n"
-                            "  // A comment\n"
-                            "  int r = j % k;\n"
-                            "  return r;\n"
-                            "}\n";
-    std::string CodePart3 = "int bar2(int j, int k) {\n"
-                            "  int r = j / k;\n"
-                            "  return r;\n"
-                            "}\n";
-    std::string ConcatAll = BlockHeader + CodePart1 + BlockChanger + CodePart2 +
-                            BlockFooter + (BlockEndNewLine ? "\n" : "") +
-                            CodePart3;
-    return std::make_pair(BlockHeader + removeEmptyLines(CodePart1) +
-                              BlockChanger + removeEmptyLines(CodePart2) +
-                              BlockFooter + removeEmptyLines(CodePart3),
-                          ConcatAll);
+#undef CHECK_PARSE_BOOL
+
+TEST(ConfigParseTest, ParsesConfigurationIntegers) {
+  FormatStyle Style = {};
+  Style.Language = FormatStyle::LK_Cpp;
+
+  CHECK_PARSE_INT(AccessModifierOffset);
+  CHECK_PARSE_INT(BracedInitializerIndentWidth);
+  CHECK_PARSE_INT(PPIndentWidth);
+
+  CHECK_PARSE_UNSIGNED(ColumnLimit);
+  CHECK_PARSE_UNSIGNED(ConstructorInitializerIndentWidth);
+  CHECK_PARSE_UNSIGNED(ContinuationIndentWidth);
+  CHECK_PARSE_UNSIGNED(IndentWidth);
+  CHECK_PARSE_UNSIGNED(MaxEmptyLinesToKeep);
+  CHECK_PARSE_UNSIGNED(ObjCBlockIndentWidth);
+  CHECK_PARSE_UNSIGNED(PenaltyBreakAssignment);
+  CHECK_PARSE_UNSIGNED(PenaltyBreakBeforeFirstCallParameter);
+  CHECK_PARSE_UNSIGNED(PenaltyBreakBeforeMemberAccess);
+  CHECK_PARSE_UNSIGNED(PenaltyBreakComment);
+  CHECK_PARSE_UNSIGNED(PenaltyBreakFirstLessLess);
+  CHECK_PARSE_UNSIGNED(PenaltyBreakOpenParenthesis);
+  CHECK_PARSE_UNSIGNED(PenaltyBreakScopeResolution);
+  CHECK_PARSE_UNSIGNED(PenaltyBreakString);
+  CHECK_PARSE_UNSIGNED(PenaltyBreakTemplateDeclaration);
+  CHECK_PARSE_UNSIGNED(PenaltyExcessCharacter);
+  CHECK_PARSE_UNSIGNED(PenaltyIndentedWhitespace);
+  CHECK_PARSE_UNSIGNED(PenaltyReturnTypeOnItsOwnLine);
+  CHECK_PARSE_UNSIGNED(ShortNamespaceLines);
+  CHECK_PARSE_UNSIGNED(SpacesBeforeTrailingComments);
+  CHECK_PARSE_UNSIGNED(TabWidth);
+}
+
+TEST(ConfigParseTest, ParsesConfiguration) {
+  FormatStyle Style = {};
+  Style.Language = FormatStyle::LK_Cpp;
+  CHECK_PARSE("CommentPragmas: '// abc$'", CommentPragmas, "// abc$");
+  CHECK_PARSE("OneLineFormatOffRegex: // ab$", OneLineFormatOffRegex, "// ab$");
+
+  Style.QualifierAlignment = FormatStyle::QAS_Right;
+  CHECK_PARSE("QualifierAlignment: Leave", QualifierAlignment,
+              FormatStyle::QAS_Leave);
+  CHECK_PARSE("QualifierAlignment: Right", QualifierAlignment,
+              FormatStyle::QAS_Right);
+  CHECK_PARSE("QualifierAlignment: Left", QualifierAlignment,
+              FormatStyle::QAS_Left);
+  CHECK_PARSE("QualifierAlignment: Custom", QualifierAlignment,
+              FormatStyle::QAS_Custom);
+
+  Style.QualifierOrder.clear();
+  CHECK_PARSE("QualifierOrder: [ const, volatile, type ]", QualifierOrder,
+              std::vector<std::string>({"const", "volatile", "type"}));
+  Style.QualifierOrder.clear();
+  CHECK_PARSE("QualifierOrder: [const, type]", QualifierOrder,
+              std::vector<std::string>({"const", "type"}));
+  Style.QualifierOrder.clear();
+  CHECK_PARSE("QualifierOrder: [volatile, type]", QualifierOrder,
+              std::vector<std::string>({"volatile", "type"}));
+
+#define CHECK_ALIGN_CONSECUTIVE(FIELD)                                         \
+  do {                                                                         \
+    Style.FIELD.Enabled = true;                                                \
+    CHECK_PARSE(#FIELD ": None", FIELD,                                        \
+                FormatStyle::AlignConsecutiveStyle({}));                       \
+    CHECK_PARSE(                                                               \
+        #FIELD ": Consecutive", FIELD,                                         \
+        FormatStyle::AlignConsecutiveStyle(                                    \
+            {/*Enabled=*/true, /*AcrossEmptyLines=*/false,                     \
+             /*AcrossComments=*/false, /*AlignCompound=*/false,                \
+             /*AlignFunctionDeclarations=*/true,                               \
+             /*AlignFunctionPointers=*/false, /*PadOperators=*/true}));        \
+    CHECK_PARSE(                                                               \
+        #FIELD ": AcrossEmptyLines", FIELD,                                    \
+        FormatStyle::AlignConsecutiveStyle(                                    \
+            {/*Enabled=*/true, /*AcrossEmptyLines=*/true,                      \
+             /*AcrossComments=*/false, /*AlignCompound=*/false,                \
+             /*AlignFunctionDeclarations=*/true,                               \
+             /*AlignFunctionPointers=*/false, /*PadOperators=*/true}));        \
+    CHECK_PARSE(                                                               \
+        #FIELD ": AcrossComments", FIELD,                                      \
+        FormatStyle::AlignConsecutiveStyle(                                    \
+            {/*Enabled=*/true, /*AcrossEmptyLines=*/false,                     \
+             /*AcrossComments=*/true, /*AlignCompound=*/false,                 \
+             /*AlignFunctionDeclarations=*/true,                               \
+             /*AlignFunctionPointers=*/false, /*PadOperators=*/true}));        \
+    CHECK_PARSE(                                                               \
+        #FIELD ": AcrossEmptyLinesAndComments", FIELD,                         \
+        FormatStyle::AlignConsecutiveStyle(                                    \
+            {/*Enabled=*/true, /*AcrossEmptyLines=*/true,                      \
+             /*AcrossComments=*/true, /*AlignCompound=*/false,                 \
+             /*AlignFunctionDeclarations=*/true,                               \
+             /*AlignFunctionPointers=*/false, /*PadOperators=*/true}));        \
+    /* For backwards compability, false / true should still parse */           \
+    CHECK_PARSE(#FIELD ": false", FIELD,                                       \
+                FormatStyle::AlignConsecutiveStyle({}));                       \
+    CHECK_PARSE(                                                               \
+        #FIELD ": true", FIELD,                                                \
+        FormatStyle::AlignConsecutiveStyle(                                    \
+            {/*Enabled=*/true, /*AcrossEmptyLines=*/false,                     \
+             /*AcrossComments=*/false, /*AlignCompound=*/false,                \
+             /*AlignFunctionDeclarations=*/true,                               \
+             /*AlignFunctionPointers=*/false, /*PadOperators=*/true}));        \
+                                                                               \
+    CHECK_PARSE_NESTED_BOOL(FIELD, Enabled);                                   \
+    CHECK_PARSE_NESTED_BOOL(FIELD, AcrossEmptyLines);                          \
+    CHECK_PARSE_NESTED_BOOL(FIELD, AcrossComments);                            \
+    CHECK_PARSE_NESTED_BOOL(FIELD, AlignCompound);                             \
+    CHECK_PARSE_NESTED_BOOL(FIELD, AlignFunctionDeclarations);                 \
+    CHECK_PARSE_NESTED_BOOL(FIELD, AlignFunctionPointers);                     \
+    CHECK_PARSE_NESTED_BOOL(FIELD, PadOperators);                              \
+  } while (false)
+
+  CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveAssignments);
+  CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveBitFields);
+  CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveMacros);
+  CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveDeclarations);
+
+#undef CHECK_ALIGN_CONSECUTIVE
+
+  Style.PointerAlignment = FormatStyle::PAS_Middle;
+  CHECK_PARSE("PointerAlignment: Left", PointerAlignment,
+              FormatStyle::PAS_Left);
+  CHECK_PARSE("PointerAlignment: Right", PointerAlignment,
+              FormatStyle::PAS_Right);
+  CHECK_PARSE("PointerAlignment: Middle", PointerAlignment,
+              FormatStyle::PAS_Middle);
+  Style.ReferenceAlignment = FormatStyle::RAS_Middle;
+  CHECK_PARSE("ReferenceAlignment: Pointer", ReferenceAlignment,
+              FormatStyle::RAS_Pointer);
+  CHECK_PARSE("ReferenceAlignment: Left", ReferenceAlignment,
+              FormatStyle::RAS_Left);
+  CHECK_PARSE("ReferenceAlignment: Right", ReferenceAlignment,
+              FormatStyle::RAS_Right);
+  CHECK_PARSE("ReferenceAlignment: Middle", ReferenceAlignment,
+              FormatStyle::RAS_Middle);
+  // For backward compatibility:
+  CHECK_PARSE("PointerBindsToType: Left", PointerAlignment,
+              FormatStyle::PAS_Left);
+  CHECK_PARSE("PointerBindsToType: Right", PointerAlignment,
+              FormatStyle::PAS_Right);
+  CHECK_PARSE("PointerBindsToType: Middle", PointerAlignment,
+              FormatStyle::PAS_Middle);
+
+  Style.ReflowComments = FormatStyle::RCS_Always;
+  CHECK_PARSE("ReflowComments: Never", ReflowComments, FormatStyle::RCS_Never);
+  CHECK_PARSE("ReflowComments: IndentOnly", ReflowComments,
+              FormatStyle::RCS_IndentOnly);
+  CHECK_PARSE("ReflowComments: Always", ReflowComments,
+              FormatStyle::RCS_Always);
+  // For backward compatibility:
+  CHECK_PARSE("ReflowComments: false", ReflowComments, FormatStyle::RCS_Never);
+  CHECK_PARSE("ReflowComments: true", ReflowComments, FormatStyle::RCS_Always);
+
+  Style.Standard = FormatStyle::LS_Auto;
+  CHECK_PARSE("Standard: c++03", Standard, FormatStyle::LS_Cpp03);
+  CHECK_PARSE("Standard: c++11", Standard, FormatStyle::LS_Cpp11);
+  CHECK_PARSE("Standard: c++14", Standard, FormatStyle::LS_Cpp14);
+  CHECK_PARSE("Standard: c++17", Standard, FormatStyle::LS_Cpp17);
+  CHECK_PARSE("Standard: c++20", Standard, FormatStyle::LS_Cpp20);
+  CHECK_PARSE("Standard: Auto", Standard, FormatStyle::LS_Auto);
+  CHECK_PARSE("Standard: Latest", Standard, FormatStyle::LS_Latest);
+  // Legacy aliases:
+  CHECK_PARSE("Standard: Cpp03", Standard, FormatStyle::LS_Cpp03);
+  CHECK_PARSE("Standard: Cpp11", Standard, FormatStyle::LS_Latest);
+  CHECK_PARSE("Standard: C++03", Standard, FormatStyle::LS_Cpp03);
+  CHECK_PARSE("Standard: C++11", Standard, FormatStyle::LS_Cpp11);
+
+  Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All;
+  CHECK_PARSE("BreakBeforeBinaryOperators: NonAssignment",
+              BreakBeforeBinaryOperators, FormatStyle::BOS_NonAssignment);
+  CHECK_PARSE("BreakBeforeBinaryOperators: None", BreakBeforeBinaryOperators,
+              FormatStyle::BOS_None);
+  CHECK_PARSE("BreakBeforeBinaryOperators: All", BreakBeforeBinaryOperators,
+              FormatStyle::BOS_All);
+  // For backward compatibility:
+  CHECK_PARSE("BreakBeforeBinaryOperators: false", BreakBeforeBinaryOperators,
+              FormatStyle::BOS_None);
+  CHECK_PARSE("BreakBeforeBinaryOperators: true", BreakBeforeBinaryOperators,
+              FormatStyle::BOS_All);
+
+  Style.BreakBinaryOperations.Default = FormatStyle::BBO_Never;
+  CHECK_PARSE("BreakBinaryOperations: OnePerLine", BreakBinaryOperations,
+              FormatStyle::BreakBinaryOperationsOptions(
+                  {FormatStyle::BBO_OnePerLine, {}}));
+  CHECK_PARSE("BreakBinaryOperations: RespectPrecedence", BreakBinaryOperations,
+              FormatStyle::BreakBinaryOperationsOptions(
+                  {FormatStyle::BBO_RespectPrecedence, {}}));
+  CHECK_PARSE(
+      "BreakBinaryOperations: Never", BreakBinaryOperations,
+      FormatStyle::BreakBinaryOperationsOptions({FormatStyle::BBO_Never, {}}));
+
+  // Structured form
+  Style.BreakBinaryOperations.Default = FormatStyle::BBO_Never;
+  CHECK_PARSE("BreakBinaryOperations:\n"
+              "  Default: OnePerLine",
+              BreakBinaryOperations,
+              FormatStyle::BreakBinaryOperationsOptions(
+                  {FormatStyle::BBO_OnePerLine, {}}));
+
+  Style.BreakBinaryOperations.Default = FormatStyle::BBO_Never;
+  EXPECT_EQ(0, parseConfiguration("BreakBinaryOperations:\n"
+                                  "  Default: Never\n"
+                                  "  PerOperator:\n"
+                                  "    - Operators: ['&&', '||']\n"
+                                  "      Style: OnePerLine\n"
+                                  "      MinChainLength: 3",
+                                  &Style)
+                   .value());
+  EXPECT_EQ(Style.BreakBinaryOperations.Default, FormatStyle::BBO_Never);
+  ASSERT_EQ(Style.BreakBinaryOperations.PerOperator.size(), 1u);
+  std::vector<tok::TokenKind> ExpectedOps = {tok::ampamp, tok::pipepipe};
+  EXPECT_EQ(Style.BreakBinaryOperations.PerOperator[0].Operators, ExpectedOps);
+  EXPECT_EQ(Style.BreakBinaryOperations.PerOperator[0].Style,
+            FormatStyle::BBO_OnePerLine);
+  EXPECT_EQ(Style.BreakBinaryOperations.PerOperator[0].MinChainLength, 3u);
+
+  // Parse ">" and ">>" which have edge cases: clang-format splits ">>" into
+  // two ">" tokens, so ">>" maps to tok::greatergreater while ">" maps to
+  // tok::greater.
+  Style.BreakBinaryOperations.Default = FormatStyle::BBO_Never;
+  EXPECT_EQ(0, parseConfiguration("BreakBinaryOperations:\n"
+                                  "  Default: Never\n"
+                                  "  PerOperator:\n"
+                                  "    - Operators: ['>', '>>']\n"
+                                  "      Style: OnePerLine",
+                                  &Style)
+                   .value());
+  ASSERT_EQ(Style.BreakBinaryOperations.PerOperator.size(), 1u);
+  std::vector<tok::TokenKind> ExpectedShiftOps = {tok::greater,
+                                                  tok::greatergreater};
+  EXPECT_EQ(Style.BreakBinaryOperations.PerOperator[0].Operators,
+            ExpectedShiftOps);
+
+  Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon;
+  CHECK_PARSE("BreakConstructorInitializers: BeforeComma",
+              BreakConstructorInitializers, FormatStyle::BCIS_BeforeComma);
+  CHECK_PARSE("BreakConstructorInitializers: AfterColon",
+              BreakConstructorInitializers, FormatStyle::BCIS_AfterColon);
+  CHECK_PARSE("BreakConstructorInitializers: AfterComma",
+              BreakConstructorInitializers, FormatStyle::BCIS_AfterComma);
+  CHECK_PARSE("BreakConstructorInitializers: BeforeColon",
+              BreakConstructorInitializers, FormatStyle::BCIS_BeforeColon);
+  // For backward compatibility:
+  CHECK_PARSE("BreakConstructorInitializersBeforeComma: true",
+              BreakConstructorInitializers, FormatStyle::BCIS_BeforeComma);
+
+  Style.BreakInheritanceList = FormatStyle::BILS_BeforeColon;
+  CHECK_PARSE("BreakInheritanceList: AfterComma", BreakInheritanceList,
+              FormatStyle::BILS_AfterComma);
+  CHECK_PARSE("BreakInheritanceList: BeforeComma", BreakInheritanceList,
+              FormatStyle::BILS_BeforeComma);
+  CHECK_PARSE("BreakInheritanceList: AfterColon", BreakInheritanceList,
+              FormatStyle::BILS_AfterColon);
+  CHECK_PARSE("BreakInheritanceList: BeforeColon", BreakInheritanceList,
+              FormatStyle::BILS_BeforeColon);
+  // For backward compatibility:
+  CHECK_PARSE("BreakBeforeInheritanceComma: true", BreakInheritanceList,
+              FormatStyle::BILS_BeforeComma);
+
+  Style.BinPackParameters = FormatStyle::BPPS_OnePerLine;
+  CHECK_PARSE("BinPackParameters: BinPack", BinPackParameters,
+              FormatStyle::BPPS_BinPack);
+  CHECK_PARSE("BinPackParameters: OnePerLine", BinPackParameters,
+              FormatStyle::BPPS_OnePerLine);
+  CHECK_PARSE("BinPackParameters: AlwaysOnePerLine", BinPackParameters,
+              FormatStyle::BPPS_AlwaysOnePerLine);
+  // For backward compatibility.
+  CHECK_PARSE("BinPackParameters: true", BinPackParameters,
+              FormatStyle::BPPS_BinPack);
+  CHECK_PARSE("BinPackParameters: false", BinPackParameters,
+              FormatStyle::BPPS_OnePerLine);
+
+  Style.PackConstructorInitializers = FormatStyle::PCIS_BinPack;
+  CHECK_PARSE("PackConstructorInitializers: Never", PackConstructorInitializers,
+              FormatStyle::PCIS_Never);
+  CHECK_PARSE("PackConstructorInitializers: BinPack",
+              PackConstructorInitializers, FormatStyle::PCIS_BinPack);
+  CHECK_PARSE("PackConstructorInitializers: CurrentLine",
+              PackConstructorInitializers, FormatStyle::PCIS_CurrentLine);
+  CHECK_PARSE("PackConstructorInitializers: NextLine",
+              PackConstructorInitializers, FormatStyle::PCIS_NextLine);
+  CHECK_PARSE("PackConstructorInitializers: NextLineOnly",
+              PackConstructorInitializers, FormatStyle::PCIS_NextLineOnly);
+  // For backward compatibility:
+  CHECK_PARSE("BasedOnStyle: Google\n"
+              "ConstructorInitializerAllOnOneLineOrOnePerLine: true\n"
+              "AllowAllConstructorInitializersOnNextLine: false",
+              PackConstructorInitializers, FormatStyle::PCIS_CurrentLine);
+  Style.PackConstructorInitializers = FormatStyle::PCIS_NextLine;
+  CHECK_PARSE("BasedOnStyle: Google\n"
+              "ConstructorInitializerAllOnOneLineOrOnePerLine: false",
+              PackConstructorInitializers, FormatStyle::PCIS_BinPack);
+  CHECK_PARSE("ConstructorInitializerAllOnOneLineOrOnePerLine: true\n"
+              "AllowAllConstructorInitializersOnNextLine: true",
+              PackConstructorInitializers, FormatStyle::PCIS_NextLine);
+  Style.PackConstructorInitializers = FormatStyle::PCIS_BinPack;
+  CHECK_PARSE("ConstructorInitializerAllOnOneLineOrOnePerLine: true\n"
+              "AllowAllConstructorInitializersOnNextLine: false",
+              PackConstructorInitializers, FormatStyle::PCIS_CurrentLine);
+
+  Style.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_LogicalBlock;
+  CHECK_PARSE("EmptyLineBeforeAccessModifier: Never",
+              EmptyLineBeforeAccessModifier, FormatStyle::ELBAMS_Never);
+  CHECK_PARSE("EmptyLineBeforeAccessModifier: Leave",
+              EmptyLineBeforeAccessModifier, FormatStyle::ELBAMS_Leave);
+  CHECK_PARSE("EmptyLineBeforeAccessModifier: LogicalBlock",
+              EmptyLineBeforeAccessModifier, FormatStyle::ELBAMS_LogicalBlock);
+  CHECK_PARSE("EmptyLineBeforeAccessModifier: Always",
+              EmptyLineBeforeAccessModifier, FormatStyle::ELBAMS_Always);
+
+  Style.EnumTrailingComma = FormatStyle::ETC_Insert;
+  CHECK_PARSE("EnumTrailingComma: Leave", EnumTrailingComma,
+              FormatStyle::ETC_Leave);
+  CHECK_PARSE("EnumTrailingComma: Insert", EnumTrailingComma,
+              FormatStyle::ETC_Insert);
+  CHECK_PARSE("EnumTrailingComma: Remove", EnumTrailingComma,
+              FormatStyle::ETC_Remove);
+
+  Style.AlignAfterOpenBracket = false;
+  CHECK_PARSE("AlignAfterOpenBracket: Align", AlignAfterOpenBracket, true);
+  CHECK_PARSE("AlignAfterOpenBracket: DontAlign", AlignAfterOpenBracket, false);
+  // For backward compatibility:
+  CHECK_PARSE("AlignAfterOpenBracket: AlwaysBreak", AlignAfterOpenBracket,
+              true);
+  CHECK_PARSE("AlignAfterOpenBracket: AlwaysBreak\n"
+              "BreakAfterOpenBracketIf: false",
+              BreakAfterOpenBracketIf, false);
+  CHECK_PARSE("BreakAfterOpenBracketLoop: true\n"
+              "AlignAfterOpenBracket: AlwaysBreak",
+              BreakAfterOpenBracketLoop, true);
+  CHECK_PARSE("AlignAfterOpenBracket: false", AlignAfterOpenBracket, false);
+  CHECK_PARSE("AlignAfterOpenBracket: BlockIndent", AlignAfterOpenBracket,
+              true);
+  Style.AlignAfterOpenBracket = false;
+  CHECK_PARSE("AlignAfterOpenBracket: true", AlignAfterOpenBracket, true);
+
+  Style.AlignEscapedNewlines = FormatStyle::ENAS_Left;
+  CHECK_PARSE("AlignEscapedNewlines: DontAlign", AlignEscapedNewlines,
+              FormatStyle::ENAS_DontAlign);
+  CHECK_PARSE("AlignEscapedNewlines: Left", AlignEscapedNewlines,
+              FormatStyle::ENAS_Left);
+  CHECK_PARSE("AlignEscapedNewlines: LeftWithLastLine", AlignEscapedNewlines,
+              FormatStyle::ENAS_LeftWithLastLine);
+  CHECK_PARSE("AlignEscapedNewlines: Right", AlignEscapedNewlines,
+              FormatStyle::ENAS_Right);
+  // For backward compatibility:
+  CHECK_PARSE("AlignEscapedNewlinesLeft: true", AlignEscapedNewlines,
+              FormatStyle::ENAS_Left);
+  CHECK_PARSE("AlignEscapedNewlinesLeft: false", AlignEscapedNewlines,
+              FormatStyle::ENAS_Right);
+
+  Style.AlignOperands = FormatStyle::OAS_Align;
+  CHECK_PARSE("AlignOperands: DontAlign", AlignOperands,
+              FormatStyle::OAS_DontAlign);
+  CHECK_PARSE("AlignOperands: Align", AlignOperands, FormatStyle::OAS_Align);
+  CHECK_PARSE("AlignOperands: AlignAfterOperator", AlignOperands,
+              FormatStyle::OAS_AlignAfterOperator);
+  // For backward compatibility:
+  CHECK_PARSE("AlignOperands: false", AlignOperands,
+              FormatStyle::OAS_DontAlign);
+  CHECK_PARSE("AlignOperands: true", AlignOperands, FormatStyle::OAS_Align);
+
+  CHECK_PARSE("AlignTrailingComments: Leave", AlignTrailingComments,
+              FormatStyle::TrailingCommentsAlignmentStyle(
+                  {FormatStyle::TCAS_Leave, 0, true}));
+  CHECK_PARSE("AlignTrailingComments: Always", AlignTrailingComments,
+              FormatStyle::TrailingCommentsAlignmentStyle(
+                  {FormatStyle::TCAS_Always, 0, true}));
+  CHECK_PARSE("AlignTrailingComments: Never", AlignTrailingComments,
+              FormatStyle::TrailingCommentsAlignmentStyle(
+                  {FormatStyle::TCAS_Never, 0, true}));
+  // For backwards compatibility
+  CHECK_PARSE("AlignTrailingComments: true", AlignTrailingComments,
+              FormatStyle::TrailingCommentsAlignmentStyle(
+                  {FormatStyle::TCAS_Always, 0, true}));
+  CHECK_PARSE("AlignTrailingComments: false", AlignTrailingComments,
+              FormatStyle::TrailingCommentsAlignmentStyle(
+                  {FormatStyle::TCAS_Never, 0, true}));
+  CHECK_PARSE_NESTED_VALUE("Kind: Always", AlignTrailingComments, Kind,
+                           FormatStyle::TCAS_Always);
+  CHECK_PARSE_NESTED_VALUE("Kind: Never", AlignTrailingComments, Kind,
+                           FormatStyle::TCAS_Never);
+  CHECK_PARSE_NESTED_VALUE("Kind: Leave", AlignTrailingComments, Kind,
+                           FormatStyle::TCAS_Leave);
+  CHECK_PARSE_NESTED_VALUE("OverEmptyLines: 1234", AlignTrailingComments,
+                           OverEmptyLines, 1234u);
+  CHECK_PARSE_NESTED_BOOL(AlignTrailingComments, AlignPPAndNotPP);
+
+  Style.UseTab = FormatStyle::UT_ForIndentation;
+  CHECK_PARSE("UseTab: Never", UseTab, FormatStyle::UT_Never);
+  CHECK_PARSE("UseTab: ForIndentation", UseTab, FormatStyle::UT_ForIndentation);
+  CHECK_PARSE("UseTab: Always", UseTab, FormatStyle::UT_Always);
+  CHECK_PARSE("UseTab: ForContinuationAndIndentation", UseTab,
+              FormatStyle::UT_ForContinuationAndIndentation);
+  CHECK_PARSE("UseTab: AlignWithSpaces", UseTab,
+              FormatStyle::UT_AlignWithSpaces);
+  // For backward compatibility:
+  CHECK_PARSE("UseTab: false", UseTab, FormatStyle::UT_Never);
+  CHECK_PARSE("UseTab: true", UseTab, FormatStyle::UT_Always);
+
+  Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Empty;
+  CHECK_PARSE("AllowShortBlocksOnASingleLine: Never",
+              AllowShortBlocksOnASingleLine, FormatStyle::SBS_Never);
+  CHECK_PARSE("AllowShortBlocksOnASingleLine: Empty",
+              AllowShortBlocksOnASingleLine, FormatStyle::SBS_Empty);
+  CHECK_PARSE("AllowShortBlocksOnASingleLine: Always",
+              AllowShortBlocksOnASingleLine, FormatStyle::SBS_Always);
+  // For backward compatibility:
+  CHECK_PARSE("AllowShortBlocksOnASingleLine: false",
+              AllowShortBlocksOnASingleLine, FormatStyle::SBS_Never);
+  CHECK_PARSE("AllowShortBlocksOnASingleLine: true",
+              AllowShortBlocksOnASingleLine, FormatStyle::SBS_Always);
+
+  CHECK_PARSE("AllowShortFunctionsOnASingleLine: None",
+              AllowShortFunctionsOnASingleLine,
+              FormatStyle::ShortFunctionStyle());
+  CHECK_PARSE("AllowShortFunctionsOnASingleLine: Inline",
+              AllowShortFunctionsOnASingleLine,
+              FormatStyle::ShortFunctionStyle::setEmptyAndInline());
+  CHECK_PARSE("AllowShortFunctionsOnASingleLine: Empty",
+              AllowShortFunctionsOnASingleLine,
+              FormatStyle::ShortFunctionStyle::setEmptyOnly());
+  CHECK_PARSE("AllowShortFunctionsOnASingleLine: All",
+              AllowShortFunctionsOnASingleLine,
+              FormatStyle::ShortFunctionStyle::setAll());
+  CHECK_PARSE("AllowShortFunctionsOnASingleLine: InlineOnly",
+              AllowShortFunctionsOnASingleLine,
+              FormatStyle::ShortFunctionStyle::setInlineOnly());
+
+  // For backward compatibility:
+  CHECK_PARSE("AllowShortFunctionsOnASingleLine: false",
+              AllowShortFunctionsOnASingleLine,
+              FormatStyle::ShortFunctionStyle());
+  CHECK_PARSE("AllowShortFunctionsOnASingleLine: true",
+              AllowShortFunctionsOnASingleLine,
+              FormatStyle::ShortFunctionStyle::setAll());
+
+  Style.AllowShortLambdasOnASingleLine = FormatStyle::SLS_All;
+  CHECK_PARSE("AllowShortLambdasOnASingleLine: None",
+              AllowShortLambdasOnASingleLine, FormatStyle::SLS_None);
+  CHECK_PARSE("AllowShortLambdasOnASingleLine: Empty",
+              AllowShortLambdasOnASingleLine, FormatStyle::SLS_Empty);
+  CHECK_PARSE("AllowShortLambdasOnASingleLine: Inline",
+              AllowShortLambdasOnASingleLine, FormatStyle::SLS_Inline);
+  CHECK_PARSE("AllowShortLambdasOnASingleLine: All",
+              AllowShortLambdasOnASingleLine, FormatStyle::SLS_All);
+  // For backward compatibility:
+  CHECK_PARSE("AllowShortLambdasOnASingleLine: false",
+              AllowShortLambdasOnASingleLine, FormatStyle::SLS_None);
+  CHECK_PARSE("AllowShortLambdasOnASingleLine: true",
+              AllowShortLambdasOnASingleLine, FormatStyle::SLS_All);
+
+  Style.SpaceAroundPointerQualifiers = FormatStyle::SAPQ_Both;
+  CHECK_PARSE("SpaceAroundPointerQualifiers: Default",
+              SpaceAroundPointerQualifiers, FormatStyle::SAPQ_Default);
+  CHECK_PARSE("SpaceAroundPointerQualifiers: Before",
+              SpaceAroundPointerQualifiers, FormatStyle::SAPQ_Before);
+  CHECK_PARSE("SpaceAroundPointerQualifiers: After",
+              SpaceAroundPointerQualifiers, FormatStyle::SAPQ_After);
+  CHECK_PARSE("SpaceAroundPointerQualifiers: Both",
+              SpaceAroundPointerQualifiers, FormatStyle::SAPQ_Both);
+
+  Style.SpaceBeforeParens = FormatStyle::SBPO_Always;
+  CHECK_PARSE("SpaceBeforeParens: Never", SpaceBeforeParens,
+              FormatStyle::SBPO_Never);
+  CHECK_PARSE("SpaceBeforeParens: Always", SpaceBeforeParens,
+              FormatStyle::SBPO_Always);
+  CHECK_PARSE("SpaceBeforeParens: ControlStatements", SpaceBeforeParens,
+              FormatStyle::SBPO_ControlStatements);
+  CHECK_PARSE("SpaceBeforeParens: ControlStatementsExceptControlMacros",
+              SpaceBeforeParens,
+              FormatStyle::SBPO_ControlStatementsExceptControlMacros);
+  CHECK_PARSE("SpaceBeforeParens: NonEmptyParentheses", SpaceBeforeParens,
+              FormatStyle::SBPO_NonEmptyParentheses);
+  CHECK_PARSE("SpaceBeforeParens: Custom", SpaceBeforeParens,
+              FormatStyle::SBPO_Custom);
+  // For backward compatibility:
+  CHECK_PARSE("SpaceAfterControlStatementKeyword: false", SpaceBeforeParens,
+              FormatStyle::SBPO_Never);
+  CHECK_PARSE("SpaceAfterControlStatementKeyword: true", SpaceBeforeParens,
+              FormatStyle::SBPO_ControlStatements);
+  CHECK_PARSE("SpaceBeforeParens: ControlStatementsExceptForEachMacros",
+              SpaceBeforeParens,
+              FormatStyle::SBPO_ControlStatementsExceptControlMacros);
+
+  Style.SpaceInEmptyBraces = FormatStyle::SIEB_Never;
+  CHECK_PARSE("SpaceInEmptyBraces: Always", SpaceInEmptyBraces,
+              FormatStyle::SIEB_Always);
+  CHECK_PARSE("SpaceInEmptyBraces: Block", SpaceInEmptyBraces,
+              FormatStyle::SIEB_Block);
+  CHECK_PARSE("SpaceInEmptyBraces: Never", SpaceInEmptyBraces,
+              FormatStyle::SIEB_Never);
+  // For backward compatibility:
+  CHECK_PARSE("SpaceInEmptyBlock: true", SpaceInEmptyBraces,
+              FormatStyle::SIEB_Block);
+
+  // For backward compatibility:
+  Style.SpacesInParens = FormatStyle::SIPO_Never;
+  Style.SpacesInParensOptions = {};
+  CHECK_PARSE("SpacesInParentheses: true", SpacesInParens,
+              FormatStyle::SIPO_Custom);
+  Style.SpacesInParens = FormatStyle::SIPO_Never;
+  Style.SpacesInParensOptions = {};
+  CHECK_PARSE(
+      "SpacesInParentheses: true", SpacesInParensOptions,
+      FormatStyle::SpacesInParensCustom(false, true, false, false, true));
+  Style.SpacesInParens = FormatStyle::SIPO_Never;
+  Style.SpacesInParensOptions = {};
+  CHECK_PARSE(
+      "SpacesInConditionalStatement: true", SpacesInParensOptions,
+      FormatStyle::SpacesInParensCustom(false, true, false, false, false));
+  Style.SpacesInParens = FormatStyle::SIPO_Never;
+  Style.SpacesInParensOptions = {};
+  CHECK_PARSE(
+      "SpacesInCStyleCastParentheses: true", SpacesInParensOptions,
+      FormatStyle::SpacesInParensCustom(false, false, true, false, false));
+  Style.SpacesInParens = FormatStyle::SIPO_Never;
+  Style.SpacesInParensOptions = {};
+  CHECK_PARSE(
+      "SpaceInEmptyParentheses: true", SpacesInParensOptions,
+      FormatStyle::SpacesInParensCustom(false, false, false, true, false));
+  Style.SpacesInParens = FormatStyle::SIPO_Never;
+  Style.SpacesInParensOptions = {};
+
+  Style.ColumnLimit = 123;
+  FormatStyle BaseStyle = getLLVMStyle();
+  CHECK_PARSE("BasedOnStyle: LLVM", ColumnLimit, BaseStyle.ColumnLimit);
+  CHECK_PARSE("BasedOnStyle: LLVM\nColumnLimit: 1234", ColumnLimit, 1234u);
+
+  Style.BreakBeforeBraces = FormatStyle::BS_Stroustrup;
+  CHECK_PARSE("BreakBeforeBraces: Attach", BreakBeforeBraces,
+              FormatStyle::BS_Attach);
+  CHECK_PARSE("BreakBeforeBraces: Linux", BreakBeforeBraces,
+              FormatStyle::BS_Linux);
+  CHECK_PARSE("BreakBeforeBraces: Mozilla", BreakBeforeBraces,
+              FormatStyle::BS_Mozilla);
+  CHECK_PARSE("BreakBeforeBraces: Stroustrup", BreakBeforeBraces,
+              FormatStyle::BS_Stroustrup);
+  CHECK_PARSE("BreakBeforeBraces: Allman", BreakBeforeBraces,
+              FormatStyle::BS_Allman);
+  CHECK_PARSE("BreakBeforeBraces: Whitesmiths", BreakBeforeBraces,
+              FormatStyle::BS_Whitesmiths);
+  CHECK_PARSE("BreakBeforeBraces: GNU", BreakBeforeBraces, FormatStyle::BS_GNU);
+  CHECK_PARSE("BreakBeforeBraces: WebKit", BreakBeforeBraces,
+              FormatStyle::BS_WebKit);
+  CHECK_PARSE("BreakBeforeBraces: Custom", BreakBeforeBraces,
+              FormatStyle::BS_Custom);
+
+  Style.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Never;
+  CHECK_PARSE("BraceWrapping:\n"
+              "  AfterControlStatement: MultiLine",
+              BraceWrapping.AfterControlStatement,
+              FormatStyle::BWACS_MultiLine);
+  CHECK_PARSE("BraceWrapping:\n"
+              "  AfterControlStatement: Always",
+              BraceWrapping.AfterControlStatement, FormatStyle::BWACS_Always);
+  CHECK_PARSE("BraceWrapping:\n"
+              "  AfterControlStatement: Never",
+              BraceWrapping.AfterControlStatement, FormatStyle::BWACS_Never);
+  // For backward compatibility:
+  CHECK_PARSE("BraceWrapping:\n"
+              "  AfterControlStatement: true",
+              BraceWrapping.AfterControlStatement, FormatStyle::BWACS_Always);
+  CHECK_PARSE("BraceWrapping:\n"
+              "  AfterControlStatement: false",
+              BraceWrapping.AfterControlStatement, FormatStyle::BWACS_Never);
+
+  Style.BreakAfterReturnType = FormatStyle::RTBS_All;
+  CHECK_PARSE("BreakAfterReturnType: None", BreakAfterReturnType,
+              FormatStyle::RTBS_None);
+  CHECK_PARSE("BreakAfterReturnType: Automatic", BreakAfterReturnType,
+              FormatStyle::RTBS_Automatic);
+  CHECK_PARSE("BreakAfterReturnType: ExceptShortType", BreakAfterReturnType,
+              FormatStyle::RTBS_ExceptShortType);
+  CHECK_PARSE("BreakAfterReturnType: All", BreakAfterReturnType,
+              FormatStyle::RTBS_All);
+  CHECK_PARSE("BreakAfterReturnType: TopLevel", BreakAfterReturnType,
+              FormatStyle::RTBS_TopLevel);
+  CHECK_PARSE("BreakAfterReturnType: AllDefinitions", BreakAfterReturnType,
+              FormatStyle::RTBS_AllDefinitions);
+  CHECK_PARSE("BreakAfterReturnType: TopLevelDefinitions", BreakAfterReturnType,
+              FormatStyle::RTBS_TopLevelDefinitions);
+  // For backward compatibility:
+  CHECK_PARSE("AlwaysBreakAfterReturnType: None", BreakAfterReturnType,
+              FormatStyle::RTBS_None);
+  CHECK_PARSE("AlwaysBreakAfterReturnType: Automatic", BreakAfterReturnType,
+              FormatStyle::RTBS_Automatic);
+  CHECK_PARSE("AlwaysBreakAfterReturnType: ExceptShortType",
+              BreakAfterReturnType, FormatStyle::RTBS_ExceptShortType);
+  CHECK_PARSE("AlwaysBreakAfterReturnType: All", BreakAfterReturnType,
+              FormatStyle::RTBS_All);
+  CHECK_PARSE("AlwaysBreakAfterReturnType: TopLevel", BreakAfterReturnType,
+              FormatStyle::RTBS_TopLevel);
+  CHECK_PARSE("AlwaysBreakAfterReturnType: AllDefinitions",
+              BreakAfterReturnType, FormatStyle::RTBS_AllDefinitions);
+  CHECK_PARSE("AlwaysBreakAfterReturnType: TopLevelDefinitions",
+              BreakAfterReturnType, FormatStyle::RTBS_TopLevelDefinitions);
+
+  Style.BreakTemplateDeclarations = FormatStyle::BTDS_Yes;
+  CHECK_PARSE("BreakTemplateDeclarations: Leave", BreakTemplateDeclarations,
+              FormatStyle::BTDS_Leave);
+  CHECK_PARSE("BreakTemplateDeclarations: No", BreakTemplateDeclarations,
+              FormatStyle::BTDS_No);
+  CHECK_PARSE("BreakTemplateDeclarations: MultiLine", BreakTemplateDeclarations,
+              FormatStyle::BTDS_MultiLine);
+  CHECK_PARSE("BreakTemplateDeclarations: Yes", BreakTemplateDeclarations,
+              FormatStyle::BTDS_Yes);
+  CHECK_PARSE("BreakTemplateDeclarations: false", BreakTemplateDeclarations,
+              FormatStyle::BTDS_MultiLine);
+  CHECK_PARSE("BreakTemplateDeclarations: true", BreakTemplateDeclarations,
+              FormatStyle::BTDS_Yes);
+  // For backward compatibility:
+  CHECK_PARSE("AlwaysBreakTemplateDeclarations: Leave",
+              BreakTemplateDeclarations, FormatStyle::BTDS_Leave);
+  CHECK_PARSE("AlwaysBreakTemplateDeclarations: No", BreakTemplateDeclarations,
+              FormatStyle::BTDS_No);
+  CHECK_PARSE("AlwaysBreakTemplateDeclarations: MultiLine",
+              BreakTemplateDeclarations, FormatStyle::BTDS_MultiLine);
+  CHECK_PARSE("AlwaysBreakTemplateDeclarations: Yes", BreakTemplateDeclarations,
+              FormatStyle::BTDS_Yes);
+  CHECK_PARSE("AlwaysBreakTemplateDeclarations: false",
+              BreakTemplateDeclarations, FormatStyle::BTDS_MultiLine);
+  CHECK_PARSE("AlwaysBreakTemplateDeclarations: true",
+              BreakTemplateDeclarations, FormatStyle::BTDS_Yes);
+
+  Style.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_All;
+  CHECK_PARSE("AlwaysBreakAfterDefinitionReturnType: None",
+              AlwaysBreakAfterDefinitionReturnType, FormatStyle::DRTBS_None);
+  CHECK_PARSE("AlwaysBreakAfterDefinitionReturnType: All",
+              AlwaysBreakAfterDefinitionReturnType, FormatStyle::DRTBS_All);
+  CHECK_PARSE("AlwaysBreakAfterDefinitionReturnType: TopLevel",
+              AlwaysBreakAfterDefinitionReturnType,
+              FormatStyle::DRTBS_TopLevel);
+
+  Style.NamespaceIndentation = FormatStyle::NI_All;
+  CHECK_PARSE("NamespaceIndentation: None", NamespaceIndentation,
+              FormatStyle::NI_None);
+  CHECK_PARSE("NamespaceIndentation: Inner", NamespaceIndentation,
+              FormatStyle::NI_Inner);
+  CHECK_PARSE("NamespaceIndentation: All", NamespaceIndentation,
+              FormatStyle::NI_All);
+
+  Style.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_OnlyFirstIf;
+  CHECK_PARSE("AllowShortIfStatementsOnASingleLine: Never",
+              AllowShortIfStatementsOnASingleLine, FormatStyle::SIS_Never);
+  CHECK_PARSE("AllowShortIfStatementsOnASingleLine: WithoutElse",
+              AllowShortIfStatementsOnASingleLine,
+              FormatStyle::SIS_WithoutElse);
+  CHECK_PARSE("AllowShortIfStatementsOnASingleLine: OnlyFirstIf",
+              AllowShortIfStatementsOnASingleLine,
+              FormatStyle::SIS_OnlyFirstIf);
+  CHECK_PARSE("AllowShortIfStatementsOnASingleLine: AllIfsAndElse",
+              AllowShortIfStatementsOnASingleLine,
+              FormatStyle::SIS_AllIfsAndElse);
+  CHECK_PARSE("AllowShortIfStatementsOnASingleLine: Always",
+              AllowShortIfStatementsOnASingleLine,
+              FormatStyle::SIS_OnlyFirstIf);
+  CHECK_PARSE("AllowShortIfStatementsOnASingleLine: false",
+              AllowShortIfStatementsOnASingleLine, FormatStyle::SIS_Never);
+  CHECK_PARSE("AllowShortIfStatementsOnASingleLine: true",
+              AllowShortIfStatementsOnASingleLine,
+              FormatStyle::SIS_WithoutElse);
+
+  Style.IndentExternBlock = FormatStyle::IEBS_NoIndent;
+  CHECK_PARSE("IndentExternBlock: AfterExternBlock", IndentExternBlock,
+              FormatStyle::IEBS_AfterExternBlock);
+  CHECK_PARSE("IndentExternBlock: Indent", IndentExternBlock,
+              FormatStyle::IEBS_Indent);
+  CHECK_PARSE("IndentExternBlock: NoIndent", IndentExternBlock,
+              FormatStyle::IEBS_NoIndent);
+  CHECK_PARSE("IndentExternBlock: true", IndentExternBlock,
+              FormatStyle::IEBS_Indent);
+  CHECK_PARSE("IndentExternBlock: false", IndentExternBlock,
+              FormatStyle::IEBS_NoIndent);
+
+  Style.IndentGotoLabels = FormatStyle::IGLS_OuterIndent;
+  CHECK_PARSE("IndentGotoLabels: NoIndent", IndentGotoLabels,
+              FormatStyle::IGLS_NoIndent);
+  CHECK_PARSE("IndentGotoLabels: OuterIndent", IndentGotoLabels,
+              FormatStyle::IGLS_OuterIndent);
+  CHECK_PARSE("IndentGotoLabels: InnerIndent", IndentGotoLabels,
+              FormatStyle::IGLS_InnerIndent);
+  CHECK_PARSE("IndentGotoLabels: HalfIndent", IndentGotoLabels,
+              FormatStyle::IGLS_HalfIndent);
+  CHECK_PARSE("IndentGotoLabels: false", IndentGotoLabels,
+              FormatStyle::IGLS_NoIndent);
+  CHECK_PARSE("IndentGotoLabels: true", IndentGotoLabels,
+              FormatStyle::IGLS_OuterIndent);
+
+  Style.BitFieldColonSpacing = FormatStyle::BFCS_None;
+  CHECK_PARSE("BitFieldColonSpacing: Both", BitFieldColonSpacing,
+              FormatStyle::BFCS_Both);
+  CHECK_PARSE("BitFieldColonSpacing: None", BitFieldColonSpacing,
+              FormatStyle::BFCS_None);
+  CHECK_PARSE("BitFieldColonSpacing: Before", BitFieldColonSpacing,
+              FormatStyle::BFCS_Before);
+  CHECK_PARSE("BitFieldColonSpacing: After", BitFieldColonSpacing,
+              FormatStyle::BFCS_After);
+
+  Style.SortJavaStaticImport = FormatStyle::SJSIO_Before;
+  CHECK_PARSE("SortJavaStaticImport: After", SortJavaStaticImport,
+              FormatStyle::SJSIO_After);
+  CHECK_PARSE("SortJavaStaticImport: Before", SortJavaStaticImport,
+              FormatStyle::SJSIO_Before);
+
+  Style.SortUsingDeclarations = FormatStyle::SUD_LexicographicNumeric;
+  CHECK_PARSE("SortUsingDeclarations: Never", SortUsingDeclarations,
+              FormatStyle::SUD_Never);
+  CHECK_PARSE("SortUsingDeclarations: Lexicographic", SortUsingDeclarations,
+              FormatStyle::SUD_Lexicographic);
+  CHECK_PARSE("SortUsingDeclarations: LexicographicNumeric",
+              SortUsingDeclarations, FormatStyle::SUD_LexicographicNumeric);
+  // For backward compatibility:
+  CHECK_PARSE("SortUsingDeclarations: false", SortUsingDeclarations,
+              FormatStyle::SUD_Never);
+  CHECK_PARSE("SortUsingDeclarations: true", SortUsingDeclarations,
+              FormatStyle::SUD_LexicographicNumeric);
+
+  CHECK_PARSE("WrapNamespaceBodyWithEmptyLines: Never",
+              WrapNamespaceBodyWithEmptyLines, FormatStyle::WNBWELS_Never);
+  CHECK_PARSE("WrapNamespaceBodyWithEmptyLines: Always",
+              WrapNamespaceBodyWithEmptyLines, FormatStyle::WNBWELS_Always);
+  CHECK_PARSE("WrapNamespaceBodyWithEmptyLines: Leave",
+              WrapNamespaceBodyWithEmptyLines, FormatStyle::WNBWELS_Leave);
+
+  // FIXME: This is required because parsing a configuration simply overwrites
+  // the first N elements of the list instead of resetting it.
+  Style.ForEachMacros.clear();
+  std::vector<std::string> BoostForeach;
+  BoostForeach.push_back("BOOST_FOREACH");
+  CHECK_PARSE("ForEachMacros: [BOOST_FOREACH]", ForEachMacros, BoostForeach);
+  std::vector<std::string> BoostAndQForeach;
+  BoostAndQForeach.push_back("BOOST_FOREACH");
+  BoostAndQForeach.push_back("Q_FOREACH");
+  CHECK_PARSE("ForEachMacros: [BOOST_FOREACH, Q_FOREACH]", ForEachMacros,
+              BoostAndQForeach);
+
+  Style.IfMacros.clear();
+  std::vector<std::string> CustomIfs;
+  CustomIfs.push_back("MYIF");
+  CHECK_PARSE("IfMacros: [MYIF]", IfMacros, CustomIfs);
+
+  Style.AttributeMacros.clear();
+  CHECK_PARSE("BasedOnStyle: LLVM", AttributeMacros,
+              std::vector<std::string>{"__capability"});
+  CHECK_PARSE(
+      "BasedOnStyle: Google", AttributeMacros,
+      std::vector<std::string>({"__capability", "absl_nonnull", "absl_nullable",
+                                "absl_nullability_unknown"}));
+  Style.AttributeMacros.clear();
+  CHECK_PARSE("AttributeMacros: [attr1, attr2]", AttributeMacros,
+              std::vector<std::string>({"attr1", "attr2"}));
+
+  Style.StatementAttributeLikeMacros.clear();
+  CHECK_PARSE("StatementAttributeLikeMacros: [emit,Q_EMIT]",
+              StatementAttributeLikeMacros,
+              std::vector<std::string>({"emit", "Q_EMIT"}));
+
+  Style.Macros.clear();
+  CHECK_PARSE("{Macros: [foo]}", Macros, std::vector<std::string>({"foo"}));
+  std::vector<std::string> GoogleMacros;
+  GoogleMacros.push_back("ASSIGN_OR_RETURN(a, b)=a = (b)");
+  GoogleMacros.push_back("ASSIGN_OR_RETURN(a, b, c)=a = (b); if (x) return c");
+  CHECK_PARSE("BasedOnStyle: Google", Macros, GoogleMacros);
+
+  Style.StatementMacros.clear();
+  CHECK_PARSE("StatementMacros: [QUNUSED]", StatementMacros,
+              std::vector<std::string>{"QUNUSED"});
+  CHECK_PARSE("StatementMacros: [QUNUSED, QT_REQUIRE_VERSION]", StatementMacros,
+              std::vector<std::string>({"QUNUSED", "QT_REQUIRE_VERSION"}));
+
+  CHECK_PARSE_LIST(JavaImportGroups);
+  CHECK_PARSE_LIST(MacrosSkippedByRemoveParentheses);
+  CHECK_PARSE_LIST(NamespaceMacros);
+  CHECK_PARSE_LIST(ObjCPropertyAttributeOrder);
+  CHECK_PARSE_LIST(TableGenBreakingDAGArgOperators);
+  CHECK_PARSE_LIST(TemplateNames);
+  CHECK_PARSE_LIST(TypeNames);
+  CHECK_PARSE_LIST(TypenameMacros);
+  CHECK_PARSE_LIST(VariableTemplates);
+
+  Style.WhitespaceSensitiveMacros.clear();
+  CHECK_PARSE("WhitespaceSensitiveMacros: [STRINGIZE]",
+              WhitespaceSensitiveMacros, std::vector<std::string>{"STRINGIZE"});
+  CHECK_PARSE("WhitespaceSensitiveMacros: [STRINGIZE, ASSERT]",
+              WhitespaceSensitiveMacros,
+              std::vector<std::string>({"STRINGIZE", "ASSERT"}));
+  Style.WhitespaceSensitiveMacros.clear();
+  CHECK_PARSE("WhitespaceSensitiveMacros: ['STRINGIZE']",
+              WhitespaceSensitiveMacros, std::vector<std::string>{"STRINGIZE"});
+  CHECK_PARSE("WhitespaceSensitiveMacros: ['STRINGIZE', 'ASSERT']",
+              WhitespaceSensitiveMacros,
+              std::vector<std::string>({"STRINGIZE", "ASSERT"}));
+
+  Style.IncludeStyle.IncludeCategories.clear();
+  std::vector<tooling::IncludeStyle::IncludeCategory> ExpectedCategories = {
+      {"abc/.*", 2, 0, false}, {".*", 1, 0, true}};
+  CHECK_PARSE("IncludeCategories:\n"
+              "  - Regex: abc/.*\n"
+              "    Priority: 2\n"
+              "  - Regex: .*\n"
+              "    Priority: 1\n"
+              "    CaseSensitive: true",
+              IncludeStyle.IncludeCategories, ExpectedCategories);
+  CHECK_PARSE("IncludeIsMainRegex: 'abc$'", IncludeStyle.IncludeIsMainRegex,
+              "abc$");
+  CHECK_PARSE("IncludeIsMainSourceRegex: 'abc$'",
+              IncludeStyle.IncludeIsMainSourceRegex, "abc$");
+
+  Style.SortIncludes = {};
+  CHECK_PARSE(
+      "SortIncludes: true", SortIncludes,
+      FormatStyle::SortIncludesOptions(
+          {/*Enabled=*/true, /*IgnoreCase=*/false, /*IgnoreExtension=*/false}));
+  CHECK_PARSE("SortIncludes: false", SortIncludes,
+              FormatStyle::SortIncludesOptions({}));
+  CHECK_PARSE(
+      "SortIncludes: CaseInsensitive", SortIncludes,
+      FormatStyle::SortIncludesOptions(
+          {/*Enabled=*/true, /*IgnoreCase=*/true, /*IgnoreExtension=*/false}));
+  CHECK_PARSE(
+      "SortIncludes: CaseSensitive", SortIncludes,
+      FormatStyle::SortIncludesOptions(
+          {/*Enabled=*/true, /*IgnoreCase=*/false, /*IgnoreExtension=*/false}));
+  CHECK_PARSE("SortIncludes: Never", SortIncludes,
+              FormatStyle::SortIncludesOptions({}));
+
+  Style.RawStringFormats.clear();
+  std::vector<FormatStyle::RawStringFormat> ExpectedRawStringFormats = {
+      {
+          FormatStyle::LK_TextProto,
+          {"pb", "proto"},
+          {"PARSE_TEXT_PROTO"},
+          /*CanonicalDelimiter=*/"",
+          "llvm",
+      },
+      {
+          FormatStyle::LK_Cpp,
+          {"cc", "cpp"},
+          {"C_CODEBLOCK", "CPPEVAL"},
+          /*CanonicalDelimiter=*/"cc",
+          /*BasedOnStyle=*/"",
+      },
   };
 
-  FormatStyle AlwaysStyle = getLLVMStyle();
-  AlwaysStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
-
-  FormatStyle NeverStyle = getLLVMStyle();
-  NeverStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Never;
-
-  auto TestKit = MakeUntouchTest("/* FOOBAR */\n"
-                                 "#ifdef FOO\n\n",
-                                 "\n#elifndef BAR\n\n", "\n#endif\n\n", false);
-  verifyFormat(TestKit.first, AlwaysStyle, TestKit.second);
-  verifyFormat(TestKit.second, NeverStyle, removeEmptyLines(TestKit.second));
-
-  TestKit = MakeUntouchTest("/* FOOBAR */\n"
-                            "#ifdef FOO\n",
-                            "#elifndef BAR\n", "#endif\n", false);
-  verifyFormat(TestKit.first, AlwaysStyle, TestKit.second);
-  verifyFormat(TestKit.second, NeverStyle, removeEmptyLines(TestKit.second));
-
-  TestKit = MakeUntouchTest("namespace Ns {\n\n",
-                            "\n} // namespace Ns\n\n"
-                            "namespace {\n\n",
-                            "\n} // namespace\n", true);
-  verifyFormat(TestKit.first, AlwaysStyle, TestKit.second);
-  verifyFormat(TestKit.second, NeverStyle, removeEmptyLines(TestKit.second));
-
-  TestKit = MakeUntouchTest("namespace Ns {\n",
-                            "} // namespace Ns\n\n"
-                            "namespace {\n",
-                            "} // namespace\n", true);
-  verifyFormat(TestKit.first, AlwaysStyle, TestKit.second);
-  verifyFormat(TestKit.second, NeverStyle, removeEmptyLines(TestKit.second));
+  CHECK_PARSE("RawStringFormats:\n"
+              "  - Language: TextProto\n"
+              "    Delimiters:\n"
+              "      - 'pb'\n"
+              "      - 'proto'\n"
+              "    EnclosingFunctions:\n"
+              "      - 'PARSE_TEXT_PROTO'\n"
+              "    BasedOnStyle: llvm\n"
+              "  - Language: Cpp\n"
+              "    Delimiters:\n"
+              "      - 'cc'\n"
+              "      - 'cpp'\n"
+              "    EnclosingFunctions:\n"
+              "      - 'C_CODEBLOCK'\n"
+              "      - 'CPPEVAL'\n"
+              "    CanonicalDelimiter: 'cc'",
+              RawStringFormats, ExpectedRawStringFormats);
+
+  CHECK_PARSE("SpacesInLineCommentPrefix:\n"
+              "  Minimum: 0\n"
+              "  Maximum: 0",
+              SpacesInLineCommentPrefix.Minimum, 0u);
+  EXPECT_EQ(Style.SpacesInLineCommentPrefix.Maximum, 0u);
+  Style.SpacesInLineCommentPrefix.Minimum = 1;
+  CHECK_PARSE("SpacesInLineCommentPrefix:\n"
+              "  Minimum: 2",
+              SpacesInLineCommentPrefix.Minimum, 0u);
+  CHECK_PARSE("SpacesInLineCommentPrefix:\n"
+              "  Maximum: -1",
+              SpacesInLineCommentPrefix.Maximum, -1u);
+  CHECK_PARSE("SpacesInLineCommentPrefix:\n"
+              "  Minimum: 2",
+              SpacesInLineCommentPrefix.Minimum, 2u);
+  CHECK_PARSE("SpacesInLineCommentPrefix:\n"
+              "  Maximum: 1",
+              SpacesInLineCommentPrefix.Maximum, 1u);
+  EXPECT_EQ(Style.SpacesInLineCommentPrefix.Minimum, 1u);
+
+  Style.SpacesInAngles = FormatStyle::SIAS_Always;
+  CHECK_PARSE("SpacesInAngles: Never", SpacesInAngles, FormatStyle::SIAS_Never);
+  CHECK_PARSE("SpacesInAngles: Always", SpacesInAngles,
+              FormatStyle::SIAS_Always);
+  CHECK_PARSE("SpacesInAngles: Leave", SpacesInAngles, FormatStyle::SIAS_Leave);
+  // For backward compatibility:
+  CHECK_PARSE("SpacesInAngles: false", SpacesInAngles, FormatStyle::SIAS_Never);
+  CHECK_PARSE("SpacesInAngles: true", SpacesInAngles, FormatStyle::SIAS_Always);
+
+  CHECK_PARSE("RequiresClausePosition: WithPreceding", RequiresClausePosition,
+              FormatStyle::RCPS_WithPreceding);
+  CHECK_PARSE("RequiresClausePosition: WithFollowing", RequiresClausePosition,
+              FormatStyle::RCPS_WithFollowing);
+  CHECK_PARSE("RequiresClausePosition: SingleLine", RequiresClausePosition,
+              FormatStyle::RCPS_SingleLine);
+  CHECK_PARSE("RequiresClausePosition: OwnLine", RequiresClausePosition,
+              FormatStyle::RCPS_OwnLine);
+
+  CHECK_PARSE("BreakBeforeConceptDeclarations: Never",
+              BreakBeforeConceptDeclarations, FormatStyle::BBCDS_Never);
+  CHECK_PARSE("BreakBeforeConceptDeclarations: Always",
+              BreakBeforeConceptDeclarations, FormatStyle::BBCDS_Always);
+  CHECK_PARSE("BreakBeforeConceptDeclarations: Allowed",
+              BreakBeforeConceptDeclarations, FormatStyle::BBCDS_Allowed);
+  // For backward compatibility:
+  CHECK_PARSE("BreakBeforeConceptDeclarations: true",
+              BreakBeforeConceptDeclarations, FormatStyle::BBCDS_Always);
+  CHECK_PARSE("BreakBeforeConceptDeclarations: false",
+              BreakBeforeConceptDeclarations, FormatStyle::BBCDS_Allowed);
+
+  CHECK_PARSE("BreakAfterAttributes: Always", BreakAfterAttributes,
+              FormatStyle::ABS_Always);
+  CHECK_PARSE("BreakAfterAttributes: Leave", BreakAfterAttributes,
+              FormatStyle::ABS_Leave);
+  CHECK_PARSE("BreakAfterAttributes: Never", BreakAfterAttributes,
+              FormatStyle::ABS_Never);
+
+  const auto DefaultLineEnding = FormatStyle::LE_DeriveLF;
+  CHECK_PARSE("LineEnding: LF", LineEnding, FormatStyle::LE_LF);
+  CHECK_PARSE("LineEnding: CRLF", LineEnding, FormatStyle::LE_CRLF);
+  CHECK_PARSE("LineEnding: DeriveCRLF", LineEnding, FormatStyle::LE_DeriveCRLF);
+  CHECK_PARSE("LineEnding: DeriveLF", LineEnding, DefaultLineEnding);
+  // For backward compatibility:
+  CHECK_PARSE("DeriveLineEnding: false", LineEnding, FormatStyle::LE_LF);
+  Style.LineEnding = DefaultLineEnding;
+  CHECK_PARSE("DeriveLineEnding: false\n"
+              "UseCRLF: true",
+              LineEnding, FormatStyle::LE_CRLF);
+  Style.LineEnding = DefaultLineEnding;
+  CHECK_PARSE("UseCRLF: true", LineEnding, FormatStyle::LE_DeriveCRLF);
+
+  CHECK_PARSE("RemoveParentheses: MultipleParentheses", RemoveParentheses,
+              FormatStyle::RPS_MultipleParentheses);
+  CHECK_PARSE("RemoveParentheses: ReturnStatement", RemoveParentheses,
+              FormatStyle::RPS_ReturnStatement);
+  CHECK_PARSE("RemoveParentheses: Leave", RemoveParentheses,
+              FormatStyle::RPS_Leave);
+
+  CHECK_PARSE("AllowBreakBeforeNoexceptSpecifier: Always",
+              AllowBreakBeforeNoexceptSpecifier, FormatStyle::BBNSS_Always);
+  CHECK_PARSE("AllowBreakBeforeNoexceptSpecifier: OnlyWithParen",
+              AllowBreakBeforeNoexceptSpecifier,
+              FormatStyle::BBNSS_OnlyWithParen);
+  CHECK_PARSE("AllowBreakBeforeNoexceptSpecifier: Never",
+              AllowBreakBeforeNoexceptSpecifier, FormatStyle::BBNSS_Never);
+
+  Style.SeparateDefinitionBlocks = FormatStyle::SDS_Never;
+  CHECK_PARSE("SeparateDefinitionBlocks: Always", SeparateDefinitionBlocks,
+              FormatStyle::SDS_Always);
+  CHECK_PARSE("SeparateDefinitionBlocks: Leave", SeparateDefinitionBlocks,
+              FormatStyle::SDS_Leave);
+  CHECK_PARSE("SeparateDefinitionBlocks: Never", SeparateDefinitionBlocks,
+              FormatStyle::SDS_Never);
+
+  CHECK_PARSE("Cpp11BracedListStyle: Block", Cpp11BracedListStyle,
+              FormatStyle::BLS_Block);
+  CHECK_PARSE("Cpp11BracedListStyle: FunctionCall", Cpp11BracedListStyle,
+              FormatStyle::BLS_FunctionCall);
+  CHECK_PARSE("Cpp11BracedListStyle: AlignFirstComment", Cpp11BracedListStyle,
+              FormatStyle::BLS_AlignFirstComment);
+  // For backward compatibility:
+  CHECK_PARSE("Cpp11BracedListStyle: false", Cpp11BracedListStyle,
+              FormatStyle::BLS_Block);
+  CHECK_PARSE("Cpp11BracedListStyle: true", Cpp11BracedListStyle,
+              FormatStyle::BLS_AlignFirstComment);
+
+  constexpr FormatStyle::IntegerLiteralSeparatorStyle
+      ExpectedIntegerLiteralSeparatorStyle{/*Binary=*/2,
+                                           /*BinaryMinDigitInsert=*/5,
+                                           /*BinaryMaxDigitRemove=*/2,
+                                           /*Decimal=*/6,
+                                           /*DecimalMinDigitInsert=*/6,
+                                           /*DecimalMaxDigitRemove=*/3,
+                                           /*Hex=*/4,
+                                           /*HexMinDigitInsert=*/2,
+                                           /*HexMaxDigitRemove=*/1};
+  CHECK_PARSE("IntegerLiteralSeparator:\n"
+              "  Binary: 2\n"
+              "  BinaryMinDigitsInsert: 5\n"
+              "  BinaryMaxDigitsRemove: 2\n"
+              "  Decimal: 6\n"
+              "  DecimalMinDigitsInsert: 6\n"
+              "  DecimalMaxDigitsRemove: 3\n"
+              "  Hex: 4\n"
+              "  HexMinDigitsInsert: 2\n"
+              "  HexMaxDigitsRemove: 1",
+              IntegerLiteralSeparator, ExpectedIntegerLiteralSeparatorStyle);
+
+  // Backward compatibility:
+  CHECK_PARSE_NESTED_VALUE("BinaryMinDigits: 6", IntegerLiteralSeparator,
+                           BinaryMinDigitsInsert, 6);
+  CHECK_PARSE_NESTED_VALUE("DecimalMinDigits: 5", IntegerLiteralSeparator,
+                           DecimalMinDigitsInsert, 5);
+  CHECK_PARSE_NESTED_VALUE("HexMinDigits: 5", IntegerLiteralSeparator,
+                           HexMinDigitsInsert, 5);
 }
 
-TEST_F(DefinitionBlockSeparatorTest, Always) {
-  FormatStyle Style = getLLVMStyle();
-  Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
-
-  verifyFormat("// clang-format off\n"
-               "template<class T>\n"
-               "concept C = not A<S<T>>;\n"
-               "// clang-format on\n"
-               "\n"
-               "struct E {};",
-               Style);
-
-  std::string Prefix = "namespace {\n";
-  std::string Infix = "\n"
-                      "// Enum test1\n"
-                      "// Enum test2\n"
-                      "enum Foo { FOO, BAR };\n"
-                      "\n"
-                      "/*\n"
-                      "test1\n"
-                      "test2\n"
-                      "*/\n"
-                      "/*const*/ int foo(int i, int j) {\n"
-                      "  int r = i + j;\n"
-                      "  return r;\n"
-                      "}\n"
-                      "\n"
-                      "// Foobar\n"
-                      "int i, j, k;\n"
-                      "\n"
-                      "// Comment for function\n"
-                      "// Comment line 2\n"
-                      "// Comment line 3\n"
-                      "int bar(int j, int k) {\n"
-                      "  {\n"
-                      "    int r = j * k;\n"
-                      "    return r;\n"
-                      "  }\n"
-                      "}\n"
-                      "\n"
-                      "int bar2(int j, int k) {\n"
-                      "  int r = j / k;\n"
-                      "  return r;\n"
-                      "}\n"
-                      "\n"
-                      "/* Comment block in one line*/\n"
-                      "enum Bar { FOOBAR, BARFOO };\n"
-                      "\n"
-                      "int bar3(int j, int k, const enum Bar b) {\n"
-                      "  // A comment\n"
-                      "  int r = j % k;\n"
-                      "  if (struct S = getS()) {\n"
-                      "    // if condition\n"
-                      "  }\n"
-                      "  return r;\n"
-                      "}\n";
-  std::string Postfix = "\n"
-                        "} // namespace\n"
-                        "\n"
-                        "namespace T {\n"
-                        "int i, j, k;\n"
-                        "} // namespace T";
-  verifyFormat(Prefix + removeEmptyLines(Infix) + removeEmptyLines(Postfix),
-               Style, Prefix + Infix + Postfix);
+TEST(ConfigParseTest, ParsesConfigurationWithLanguages) {
+  FormatStyle Style = {};
+  Style.Language = FormatStyle::LK_Cpp;
+  CHECK_PARSE("Language: Cpp\n"
+              "IndentWidth: 12",
+              IndentWidth, 12u);
+  EXPECT_EQ(parseConfiguration("Language: JavaScript\n"
+                               "IndentWidth: 34",
+                               &Style),
+            ParseError::Unsuitable);
+  FormatStyle BinPackedTCS = {};
+  BinPackedTCS.Language = FormatStyle::LK_JavaScript;
+  EXPECT_EQ(parseConfiguration("BinPackArguments: true\n"
+                               "InsertTrailingCommas: Wrapped",
+                               &BinPackedTCS),
+            ParseError::BinPackTrailingCommaConflict);
+  EXPECT_EQ(12u, Style.IndentWidth);
+  CHECK_PARSE("IndentWidth: 56", IndentWidth, 56u);
+  EXPECT_EQ(FormatStyle::LK_Cpp, Style.Language);
+
+  Style.Language = FormatStyle::LK_JavaScript;
+  CHECK_PARSE("Language: JavaScript\n"
+              "IndentWidth: 12",
+              IndentWidth, 12u);
+  CHECK_PARSE("IndentWidth: 23", IndentWidth, 23u);
+  EXPECT_EQ(parseConfiguration("Language: Cpp\n"
+                               "IndentWidth: 34",
+                               &Style),
+            ParseError::Unsuitable);
+  EXPECT_EQ(23u, Style.IndentWidth);
+  CHECK_PARSE("IndentWidth: 56", IndentWidth, 56u);
+  EXPECT_EQ(FormatStyle::LK_JavaScript, Style.Language);
+
+  CHECK_PARSE("BasedOnStyle: LLVM\n"
+              "IndentWidth: 67",
+              IndentWidth, 67u);
+
+  CHECK_PARSE("---\n"
+              "Language: JavaScript\n"
+              "IndentWidth: 12\n"
+              "---\n"
+              "Language: Cpp\n"
+              "IndentWidth: 34\n"
+              "...\n",
+              IndentWidth, 12u);
+
+  Style.Language = FormatStyle::LK_Cpp;
+  CHECK_PARSE("---\n"
+              "Language: JavaScript\n"
+              "IndentWidth: 12\n"
+              "---\n"
+              "Language: Cpp\n"
+              "IndentWidth: 34\n"
+              "...\n",
+              IndentWidth, 34u);
+  CHECK_PARSE("---\n"
+              "IndentWidth: 78\n"
+              "---\n"
+              "Language: JavaScript\n"
+              "IndentWidth: 56\n"
+              "...\n",
+              IndentWidth, 78u);
+
+  Style.ColumnLimit = 123;
+  Style.IndentWidth = 234;
+  Style.BreakBeforeBraces = FormatStyle::BS_Linux;
+  Style.TabWidth = 345;
+  EXPECT_FALSE(parseConfiguration("---\n"
+                                  "IndentWidth: 456\n"
+                                  "BreakBeforeBraces: Allman\n"
+                                  "---\n"
+                                  "Language: JavaScript\n"
+                                  "IndentWidth: 111\n"
+                                  "TabWidth: 111\n"
+                                  "---\n"
+                                  "Language: Cpp\n"
+                                  "BreakBeforeBraces: Stroustrup\n"
+                                  "TabWidth: 789\n"
+                                  "...\n",
+                                  &Style));
+  EXPECT_EQ(123u, Style.ColumnLimit);
+  EXPECT_EQ(456u, Style.IndentWidth);
+  EXPECT_EQ(FormatStyle::BS_Stroustrup, Style.BreakBeforeBraces);
+  EXPECT_EQ(789u, Style.TabWidth);
+
+  EXPECT_EQ(parseConfiguration("---\n"
+                               "Language: JavaScript\n"
+                               "IndentWidth: 56\n"
+                               "---\n"
+                               "IndentWidth: 78\n"
+                               "...\n",
+                               &Style),
+            ParseError::Error);
+  EXPECT_EQ(parseConfiguration("---\n"
+                               "Language: JavaScript\n"
+                               "IndentWidth: 56\n"
+                               "---\n"
+                               "Language: JavaScript\n"
+                               "IndentWidth: 78\n"
+                               "...\n",
+                               &Style),
+            ParseError::Error);
+
+  EXPECT_EQ(FormatStyle::LK_Cpp, Style.Language);
+
+  Style.Language = FormatStyle::LK_Verilog;
+  CHECK_PARSE("---\n"
+              "Language: Verilog\n"
+              "IndentWidth: 12\n"
+              "---\n"
+              "Language: Cpp\n"
+              "IndentWidth: 34\n"
+              "...\n",
+              IndentWidth, 12u);
+  CHECK_PARSE("---\n"
+              "IndentWidth: 78\n"
+              "---\n"
+              "Language: Verilog\n"
+              "IndentWidth: 56\n"
+              "...\n",
+              IndentWidth, 56u);
 }
 
-TEST_F(DefinitionBlockSeparatorTest, Never) {
-  FormatStyle Style = getLLVMStyle();
-  Style.SeparateDefinitionBlocks = FormatStyle::SDS_Never;
-  std::string Prefix = "namespace {\n";
-  std::string Postfix = "// Enum test1\n"
-                        "// Enum test2\n"
-                        "enum Foo { FOO, BAR };\n"
-                        "\n"
-                        "/*\n"
-                        "test1\n"
-                        "test2\n"
-                        "*/\n"
-                        "/*const*/ int foo(int i, int j) {\n"
-                        "  int r = i + j;\n"
-                        "  return r;\n"
-                        "}\n"
-                        "\n"
-                        "// Foobar\n"
-                        "int i, j, k;\n"
-                        "\n"
-                        "// Comment for function\n"
-                        "// Comment line 2\n"
-                        "// Comment line 3\n"
-                        "int bar(int j, int k) {\n"
-                        "  {\n"
-                        "    int r = j * k;\n"
-                        "    return r;\n"
-                        "  }\n"
-                        "}\n"
-                        "\n"
-                        "int bar2(int j, int k) {\n"
-                        "  int r = j / k;\n"
-                        "  return r;\n"
-                        "}\n"
-                        "\n"
-                        "/* Comment block in one line*/\n"
-                        "enum Bar { FOOBAR, BARFOO };\n"
-                        "\n"
-                        "int bar3(int j, int k, const enum Bar b) {\n"
-                        "  // A comment\n"
-                        "  int r = j % k;\n"
-                        "  if (struct S = getS()) {\n"
-                        "    // if condition\n"
-                        "  }\n"
-                        "  return r;\n"
-                        "}\n"
-                        "} // namespace";
-  verifyFormat(Prefix + "\n\n\n" + Postfix, Style,
-               Prefix + removeEmptyLines(Postfix));
+TEST(ConfigParseTest, AllowCommentOnlyConfigFile) {
+  FormatStyle Style = {};
+  Style.Language = FormatStyle::LK_Cpp;
+  EXPECT_EQ(parseConfiguration("#Language: C", &Style), ParseError::Success);
+  EXPECT_EQ(Style.Language, FormatStyle::LK_Cpp);
 }
 
-TEST_F(DefinitionBlockSeparatorTest, OpeningBracketOwnsLine) {
-  FormatStyle Style = getLLVMStyle();
-  Style.BreakBeforeBraces = FormatStyle::BS_Allman;
-  Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
-  verifyFormat("namespace NS\n"
-               "{\n"
-               "// Enum test1\n"
-               "// Enum test2\n"
-               "enum Foo\n"
-               "{\n"
-               "  FOO,\n"
-               "  BAR\n"
-               "};\n"
-               "\n"
-               "/*\n"
-               "test1\n"
-               "test2\n"
-               "*/\n"
-               "/*const*/ int foo(int i, int j)\n"
-               "{\n"
-               "  int r = i + j;\n"
-               "  return r;\n"
-               "}\n"
-               "\n"
-               "// Foobar\n"
-               "int i, j, k;\n"
-               "\n"
-               "// Comment for function\n"
-               "// Comment line 2\n"
-               "// Comment line 3\n"
-               "int bar(int j, int k)\n"
-               "{\n"
-               "  {\n"
-               "    int r = j * k;\n"
-               "    return r;\n"
-               "  }\n"
-               "}\n"
-               "\n"
-               "int bar2(int j, int k)\n"
-               "{\n"
-               "  int r = j / k;\n"
-               "  return r;\n"
-               "}\n"
-               "\n"
-               "enum Bar\n"
-               "{\n"
-               "  FOOBAR,\n"
-               "  BARFOO\n"
-               "};\n"
-               "\n"
-               "int bar3(int j, int k, const enum Bar b)\n"
-               "{\n"
-               "  // A comment\n"
-               "  int r = j % k;\n"
-               "  if (struct S = getS())\n"
-               "  {\n"
-               "    // if condition\n"
-               "  }\n"
-               "  return r;\n"
-               "}\n"
-               "} // namespace NS",
-               Style);
+TEST(ConfigParseTest, AllowCppForC) {
+  FormatStyle Style = {};
+  Style.Language = FormatStyle::LK_C;
+  EXPECT_EQ(parseConfiguration("Language: Cpp", &Style), ParseError::Success);
+
+  CHECK_PARSE("---\n"
+              "IndentWidth: 4\n"
+              "---\n"
+              "Language: Cpp\n"
+              "IndentWidth: 8\n",
+              IndentWidth, 8u);
+
+  EXPECT_EQ(parseConfiguration("---\n"
+                               "Language: ObjC\n"
+                               "---\n"
+                               "Language: Cpp\n",
+                               &Style),
+            ParseError::Success);
 }
 
-TEST_F(DefinitionBlockSeparatorTest, TryBlocks) {
-  FormatStyle Style = getLLVMStyle();
-  Style.BreakBeforeBraces = FormatStyle::BS_Allman;
-  Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
-  verifyFormat("void FunctionWithInternalTry()\n"
-               "{\n"
-               "  try\n"
-               "  {\n"
-               "    return;\n"
-               "  }\n"
-               "  catch (const std::exception &)\n"
-               "  {\n"
-               "  }\n"
-               "}",
-               Style, "", /*Inverse=*/false);
-  verifyFormat("void FunctionWithTryBlock()\n"
-               "try\n"
-               "{\n"
-               "  return;\n"
-               "}\n"
-               "catch (const std::exception &)\n"
-               "{\n"
-               "}",
-               Style, "", /*Inverse=*/false);
+TEST(ConfigParseTest, HandleDotHFile) {
+  FormatStyle Style = {};
+  Style.Language = FormatStyle::LK_Cpp;
+  EXPECT_EQ(parseConfiguration("Language: C", &Style,
+                               /*AllowUnknownOptions=*/false,
+                               /*IsDotHFile=*/true),
+            ParseError::Success);
+  EXPECT_EQ(Style.Language, FormatStyle::LK_C);
+
+  Style = {};
+  Style.Language = FormatStyle::LK_Cpp;
+  EXPECT_EQ(parseConfiguration("Language: Cpp\n"
+                               "...\n"
+                               "Language: C",
+                               &Style,
+                               /*AllowUnknownOptions=*/false,
+                               /*IsDotHFile=*/true),
+            ParseError::Success);
+  EXPECT_EQ(Style.Language, FormatStyle::LK_Cpp);
 }
 
-TEST_F(DefinitionBlockSeparatorTest, Leave) {
+TEST(ConfigParseTest, UsesLanguageForBasedOnStyle) {
+  FormatStyle Style = {};
+  Style.Language = FormatStyle::LK_JavaScript;
+  Style.BreakBeforeTernaryOperators = true;
+  EXPECT_EQ(0, parseConfiguration("BasedOnStyle: Google", &Style).value());
+  EXPECT_FALSE(Style.BreakBeforeTernaryOperators);
+
+  Style.BreakBeforeTernaryOperators = true;
+  EXPECT_EQ(0, parseConfiguration("---\n"
+                                  "BasedOnStyle: Google\n"
+                                  "---\n"
+                                  "Language: JavaScript\n"
+                                  "IndentWidth: 76\n"
+                                  "...\n",
+                                  &Style)
+                   .value());
+  EXPECT_FALSE(Style.BreakBeforeTernaryOperators);
+  EXPECT_EQ(76u, Style.IndentWidth);
+  EXPECT_EQ(FormatStyle::LK_JavaScript, Style.Language);
+}
+
+TEST(ConfigParseTest, ConfigurationRoundTripTest) {
   FormatStyle Style = getLLVMStyle();
-  Style.SeparateDefinitionBlocks = FormatStyle::SDS_Leave;
-  Style.MaxEmptyLinesToKeep = 3;
-  std::string LeaveAs = "namespace {\n"
-                        "\n"
-                        "// Enum test1\n"
-                        "// Enum test2\n"
-                        "enum Foo { FOO, BAR };\n"
-                        "\n\n\n"
-                        "/*\n"
-                        "test1\n"
-                        "test2\n"
-                        "*/\n"
-                        "/*const*/ int foo(int i, int j) {\n"
-                        "  int r = i + j;\n"
-                        "  return r;\n"
-                        "}\n"
-                        "\n"
-                        "// Foobar\n"
-                        "int i, j, k;\n"
-                        "\n"
-                        "// Comment for function\n"
-                        "// Comment line 2\n"
-                        "// Comment line 3\n"
-                        "int bar(int j, int k) {\n"
-                        "  {\n"
-                        "    int r = j * k;\n"
-                        "    return r;\n"
-                        "  }\n"
-                        "}\n"
-                        "\n"
-                        "int bar2(int j, int k) {\n"
-                        "  int r = j / k;\n"
-                        "  return r;\n"
-                        "}\n"
-                        "\n"
-                        "// Comment for inline enum\n"
-                        "enum Bar { FOOBAR, BARFOO };\n"
-                        "int bar3(int j, int k, const enum Bar b) {\n"
-                        "  // A comment\n"
-                        "  int r = j % k;\n"
-                        "  if (struct S = getS()) {\n"
-                        "    // if condition\n"
-                        "  }\n"
-                        "  return r;\n"
-                        "}\n"
-                        "} // namespace";
-  verifyFormat(LeaveAs, Style, LeaveAs);
+  std::string YAML = configurationAsText(Style);
+  FormatStyle ParsedStyle = {};
+  ParsedStyle.Language = FormatStyle::LK_Cpp;
+  EXPECT_EQ(0, parseConfiguration(YAML, &ParsedStyle).value());
+  EXPECT_EQ(Style, ParsedStyle);
 }
 
-TEST_F(DefinitionBlockSeparatorTest, CSharp) {
-  FormatStyle Style = getLLVMStyle(FormatStyle::LK_CSharp);
-  Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
-  Style.AllowShortEnumsOnASingleLine = false;
-  verifyFormat("namespace {\r\n"
-               "public class SomeTinyClass {\r\n"
-               "  int X;\r\n"
-               "}\r\n"
-               "\r\n"
-               "public class AnotherTinyClass {\r\n"
-               "  int Y;\r\n"
-               "}\r\n"
-               "\r\n"
-               "internal static String toString() {\r\n"
-               "}\r\n"
-               "\r\n"
-               "// Comment for enum\r\n"
-               "public enum var {\r\n"
-               "  none,\r\n"
-               "  @string,\r\n"
-               "  bool,\r\n"
-               "  @enum\r\n"
-               "}\r\n"
-               "\r\n"
-               "// Test\r\n"
-               "[STAThread]\r\n"
-               "static void Main(string[] args) {\r\n"
-               "  Console.WriteLine(\"HelloWorld\");\r\n"
-               "}\r\n"
-               "\r\n"
-               "static decimal Test() {\r\n"
-               "}\r\n"
-               "}\r\n"
-               "\r\n"
-               "public class FoobarClass {\r\n"
-               "  int foobar;\r\n"
-               "}\r\n"
-               "\r\n"
-               "public class LogFactory<TLogger>\r\n"
-               "    where TLogger : class, new() {\r\n"
-               "  int i;\r\n"
-               "}",
-               Style);
+TEST(ConfigParseTest, GetStyleWithEmptyFileName) {
+  llvm::vfs::InMemoryFileSystem FS;
+  auto Style1 = getStyle("file", "", "Google", "", &FS);
+  ASSERT_TRUE((bool)Style1);
+  ASSERT_EQ(*Style1, getGoogleStyle());
 }
 
-TEST_F(DefinitionBlockSeparatorTest, JavaScript) {
-  FormatStyle Style = getLLVMStyle(FormatStyle::LK_JavaScript);
-  Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
-  Style.AllowShortEnumsOnASingleLine = false;
-  verifyFormat("export const enum Foo {\n"
-               "  A = 1,\n"
-               "  B\n"
-               "}\n"
-               "\n"
-               "export function A() {\n"
-               "}\n"
-               "\n"
-               "export default function B() {\n"
-               "}\n"
-               "\n"
-               "export function C() {\n"
-               "}\n"
-               "\n"
-               "var t, p, q;\n"
-               "\n"
-               "export abstract class X {\n"
-               "  y: number;\n"
-               "}\n"
-               "\n"
-               "export const enum Bar {\n"
-               "  D = 1,\n"
-               "  E\n"
-               "}",
-               Style);
+TEST(ConfigParseTest, GetStyleOfFile) {
+  llvm::vfs::InMemoryFileSystem FS;
+  // Test 1: format file in the same directory.
+  ASSERT_TRUE(
+      FS.addFile("/a/.clang-format", 0,
+                 llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: LLVM")));
+  ASSERT_TRUE(
+      FS.addFile("/a/test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int i;")));
+  auto Style1 = getStyle("file", "/a/.clang-format", "Google", "", &FS);
+  ASSERT_TRUE((bool)Style1);
+  ASSERT_EQ(*Style1, getLLVMStyle());
+
+  // Test 2.1: fallback to default.
+  ASSERT_TRUE(
+      FS.addFile("/b/test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int i;")));
+  auto Style2 = getStyle("file", "/b/test.cpp", "Mozilla", "", &FS);
+  ASSERT_TRUE((bool)Style2);
+  ASSERT_EQ(*Style2, getMozillaStyle());
+
+  // Test 2.2: no format on 'none' fallback style.
+  Style2 = getStyle("file", "/b/test.cpp", "none", "", &FS);
+  ASSERT_TRUE((bool)Style2);
+  ASSERT_EQ(*Style2, getNoStyle());
+
+  // Test 2.3: format if config is found with no based style while fallback is
+  // 'none'.
+  ASSERT_TRUE(FS.addFile("/b/.clang-format", 0,
+                         llvm::MemoryBuffer::getMemBuffer("IndentWidth: 2")));
+  Style2 = getStyle("file", "/b/test.cpp", "none", "", &FS);
+  ASSERT_TRUE((bool)Style2);
+  ASSERT_EQ(*Style2, getLLVMStyle());
+
+  // Test 2.4: format if yaml with no based style, while fallback is 'none'.
+  Style2 = getStyle("{}", "a.h", "none", "", &FS);
+  ASSERT_TRUE((bool)Style2);
+  ASSERT_EQ(*Style2, getLLVMStyle());
+
+  // Test 3: format file in parent directory.
+  ASSERT_TRUE(
+      FS.addFile("/c/.clang-format", 0,
+                 llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: Google")));
+  ASSERT_TRUE(FS.addFile("/c/sub/sub/sub/test.cpp", 0,
+                         llvm::MemoryBuffer::getMemBuffer("int i;")));
+  auto Style3 = getStyle("file", "/c/sub/sub/sub/test.cpp", "LLVM", "", &FS);
+  ASSERT_TRUE((bool)Style3);
+  ASSERT_EQ(*Style3, getGoogleStyle());
+
+  // Test 4: error on invalid fallback style
+  auto Style4 = getStyle("file", "a.h", "KungFu", "", &FS);
+  ASSERT_FALSE((bool)Style4);
+  llvm::consumeError(Style4.takeError());
+
+  // Test 5: error on invalid yaml on command line
+  auto Style5 = getStyle("{invalid_key=invalid_value}", "a.h", "LLVM", "", &FS,
+                         /*AllowUnknownOptions=*/false, dropDiagnosticHandler);
+  ASSERT_FALSE((bool)Style5);
+  llvm::consumeError(Style5.takeError());
+
+  // Test 6: error on invalid style
+  auto Style6 = getStyle("KungFu", "a.h", "LLVM", "", &FS);
+  ASSERT_FALSE((bool)Style6);
+  llvm::consumeError(Style6.takeError());
+
+  // Test 7: found config file, error on parsing it
+  ASSERT_TRUE(
+      FS.addFile("/d/.clang-format", 0,
+                 llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: LLVM\n"
+                                                  "InvalidKey: InvalidValue")));
+  ASSERT_TRUE(
+      FS.addFile("/d/test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int i;")));
+  auto Style7a = getStyle("file", "/d/.clang-format", "LLVM", "", &FS,
+                          /*AllowUnknownOptions=*/false, dropDiagnosticHandler);
+  ASSERT_FALSE((bool)Style7a);
+  llvm::consumeError(Style7a.takeError());
+
+  auto Style7b = getStyle("file", "/d/.clang-format", "LLVM", "", &FS,
+                          /*AllowUnknownOptions=*/true, dropDiagnosticHandler);
+  ASSERT_TRUE((bool)Style7b);
+
+  // Test 8: inferred per-language defaults apply.
+  auto StyleTd = getStyle("file", "x.td", "llvm", "", &FS);
+  ASSERT_TRUE((bool)StyleTd);
+  ASSERT_EQ(*StyleTd, getLLVMStyle(FormatStyle::LK_TableGen));
+
+  // Test 9.1.1: overwriting a file style, when no parent file exists with no
+  // fallback style.
+  ASSERT_TRUE(FS.addFile(
+      "/e/sub/.clang-format", 0,
+      llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: InheritParentConfig\n"
+                                       "ColumnLimit: 20")));
+  ASSERT_TRUE(FS.addFile("/e/sub/code.cpp", 0,
+                         llvm::MemoryBuffer::getMemBuffer("int i;")));
+  auto Style9 = getStyle("file", "/e/sub/code.cpp", "none", "", &FS);
+  ASSERT_TRUE(static_cast<bool>(Style9));
+  ASSERT_EQ(*Style9, [] {
+    auto Style = getNoStyle();
+    Style.ColumnLimit = 20;
+    return Style;
+  }());
+
+  // Test 9.1.2: propagate more than one level with no parent file.
+  ASSERT_TRUE(FS.addFile("/e/sub/sub/code.cpp", 0,
+                         llvm::MemoryBuffer::getMemBuffer("int i;")));
+  ASSERT_TRUE(FS.addFile("/e/sub/sub/.clang-format", 0,
+                         llvm::MemoryBuffer::getMemBuffer(
+                             "BasedOnStyle: InheritParentConfig\n"
+                             "WhitespaceSensitiveMacros: ['FOO', 'BAR']")));
+  std::vector<std::string> NonDefaultWhiteSpaceMacros =
+      Style9->WhitespaceSensitiveMacros;
+  NonDefaultWhiteSpaceMacros[0] = "FOO";
+  NonDefaultWhiteSpaceMacros[1] = "BAR";
+
+  ASSERT_NE(Style9->WhitespaceSensitiveMacros, NonDefaultWhiteSpaceMacros);
+  Style9 = getStyle("file", "/e/sub/sub/code.cpp", "none", "", &FS);
+  ASSERT_TRUE(static_cast<bool>(Style9));
+  ASSERT_EQ(*Style9, [&NonDefaultWhiteSpaceMacros] {
+    auto Style = getNoStyle();
+    Style.ColumnLimit = 20;
+    Style.WhitespaceSensitiveMacros = NonDefaultWhiteSpaceMacros;
+    return Style;
+  }());
+
+  // Test 9.2: with LLVM fallback style
+  Style9 = getStyle("file", "/e/sub/code.cpp", "LLVM", "", &FS);
+  ASSERT_TRUE(static_cast<bool>(Style9));
+  ASSERT_EQ(*Style9, [] {
+    auto Style = getLLVMStyle();
+    Style.ColumnLimit = 20;
+    return Style;
+  }());
+
+  // Test 9.3: with a parent file
+  ASSERT_TRUE(
+      FS.addFile("/e/.clang-format", 0,
+                 llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: Google\n"
+                                                  "UseTab: Always")));
+  Style9 = getStyle("file", "/e/sub/code.cpp", "none", "", &FS);
+  ASSERT_TRUE(static_cast<bool>(Style9));
+  ASSERT_EQ(*Style9, [] {
+    auto Style = getGoogleStyle();
+    Style.ColumnLimit = 20;
+    Style.UseTab = FormatStyle::UT_Always;
+    return Style;
+  }());
+
+  // Test 9.4: propagate more than one level with a parent file.
+  const auto SubSubStyle = [&NonDefaultWhiteSpaceMacros] {
+    auto Style = getGoogleStyle();
+    Style.ColumnLimit = 20;
+    Style.UseTab = FormatStyle::UT_Always;
+    Style.WhitespaceSensitiveMacros = NonDefaultWhiteSpaceMacros;
+    return Style;
+  }();
+
+  ASSERT_NE(Style9->WhitespaceSensitiveMacros, NonDefaultWhiteSpaceMacros);
+  Style9 = getStyle("file", "/e/sub/sub/code.cpp", "none", "", &FS);
+  ASSERT_TRUE(static_cast<bool>(Style9));
+  ASSERT_EQ(*Style9, SubSubStyle);
+
+  // Test 9.5: use InheritParentConfig as style name
+  Style9 =
+      getStyle("inheritparentconfig", "/e/sub/sub/code.cpp", "none", "", &FS);
+  ASSERT_TRUE(static_cast<bool>(Style9));
+  ASSERT_EQ(*Style9, SubSubStyle);
+
+  // Test 9.6: use command line style with inheritance
+  Style9 = getStyle("{BasedOnStyle: InheritParentConfig}",
+                    "/e/sub/sub/code.cpp", "none", "", &FS);
+  ASSERT_TRUE(static_cast<bool>(Style9));
+  ASSERT_EQ(*Style9, SubSubStyle);
+
+  // Test 9.7: use command line style with inheritance and own config
+  Style9 = getStyle("{BasedOnStyle: InheritParentConfig, "
+                    "WhitespaceSensitiveMacros: ['FOO', 'BAR']}",
+                    "/e/sub/code.cpp", "none", "", &FS);
+  ASSERT_TRUE(static_cast<bool>(Style9));
+  ASSERT_EQ(*Style9, SubSubStyle);
+
+  // Test 9.8: use inheritance from a file without BasedOnStyle
+  ASSERT_TRUE(FS.addFile(
+      "/e/withoutbase/.clang-format", 0,
+      llvm::MemoryBuffer::getMemBuffer("BracedInitializerIndentWidth: 2\n"
+                                       "ColumnLimit: 123")));
+  ASSERT_TRUE(
+      FS.addFile("/e/withoutbase/sub/.clang-format", 0,
+                 llvm::MemoryBuffer::getMemBuffer(
+                     "BasedOnStyle: InheritParentConfig\nIndentWidth: 7")));
+  // Make sure we do not use the fallback style
+  Style9 = getStyle("file", "/e/withoutbase/code.cpp", "google", "", &FS);
+  ASSERT_TRUE(static_cast<bool>(Style9));
+  ASSERT_EQ(*Style9, [] {
+    auto Style = getLLVMStyle();
+    Style.BracedInitializerIndentWidth = 2;
+    Style.ColumnLimit = 123;
+    return Style;
+  }());
+
+  Style9 = getStyle("file", "/e/withoutbase/sub/code.cpp", "google", "", &FS);
+  ASSERT_TRUE(static_cast<bool>(Style9));
+  ASSERT_EQ(*Style9, [] {
+    auto Style = getLLVMStyle();
+    Style.BracedInitializerIndentWidth = 2;
+    Style.ColumnLimit = 123;
+    Style.IndentWidth = 7;
+    return Style;
+  }());
+
+  // Test 9.9: use inheritance from a specific config file.
+  Style9 = getStyle("file:/e/sub/sub/.clang-format", "/e/sub/sub/code.cpp",
+                    "none", "", &FS);
+  ASSERT_TRUE(static_cast<bool>(Style9));
+  ASSERT_EQ(*Style9, SubSubStyle);
+}
+
+TEST(ConfigParseTest, GetStyleOfSpecificFile) {
+  llvm::vfs::InMemoryFileSystem FS;
+  // Specify absolute path to a format file in a parent directory.
+  ASSERT_TRUE(
+      FS.addFile("/e/.clang-format", 0,
+                 llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: LLVM")));
+  ASSERT_TRUE(
+      FS.addFile("/e/explicit.clang-format", 0,
+                 llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: Google")));
+  ASSERT_TRUE(FS.addFile("/e/sub/sub/sub/test.cpp", 0,
+                         llvm::MemoryBuffer::getMemBuffer("int i;")));
+  auto Style = getStyle("file:/e/explicit.clang-format",
+                        "/e/sub/sub/sub/test.cpp", "LLVM", "", &FS);
+  ASSERT_TRUE(static_cast<bool>(Style));
+  ASSERT_EQ(*Style, getGoogleStyle());
+
+  // Specify relative path to a format file.
+  ASSERT_TRUE(
+      FS.addFile("../../e/explicit.clang-format", 0,
+                 llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: Google")));
+  Style = getStyle("file:../../e/explicit.clang-format",
+                   "/e/sub/sub/sub/test.cpp", "LLVM", "", &FS);
+  ASSERT_TRUE(static_cast<bool>(Style));
+  ASSERT_EQ(*Style, getGoogleStyle());
+
+  // Specify path to a format file that does not exist.
+  Style = getStyle("file:/e/missing.clang-format", "/e/sub/sub/sub/test.cpp",
+                   "LLVM", "", &FS);
+  ASSERT_FALSE(static_cast<bool>(Style));
+  llvm::consumeError(Style.takeError());
+
+  // Specify path to a file on the filesystem.
+  SmallString<128> FormatFilePath;
+  std::error_code ECF = llvm::sys::fs::createTemporaryFile(
+      "FormatFileTest", "tpl", FormatFilePath);
+  EXPECT_FALSE((bool)ECF);
+  llvm::raw_fd_ostream FormatFileTest(FormatFilePath, ECF);
+  EXPECT_FALSE((bool)ECF);
+  FormatFileTest << "BasedOnStyle: Google\n";
+  FormatFileTest.close();
+
+  SmallString<128> TestFilePath;
+  std::error_code ECT =
+      llvm::sys::fs::createTemporaryFile("CodeFileTest", "cc", TestFilePath);
+  EXPECT_FALSE((bool)ECT);
+  llvm::raw_fd_ostream CodeFileTest(TestFilePath, ECT);
+  CodeFileTest << "int i;\n";
+  CodeFileTest.close();
+
+  std::string format_file_arg = std::string("file:") + FormatFilePath.c_str();
+  Style = getStyle(format_file_arg, TestFilePath, "LLVM", "", nullptr);
+
+  llvm::sys::fs::remove(FormatFilePath.c_str());
+  llvm::sys::fs::remove(TestFilePath.c_str());
+  ASSERT_TRUE(static_cast<bool>(Style));
+  ASSERT_EQ(*Style, getGoogleStyle());
+}
+
+TEST(ConfigParseTest, GetStyleOutput) {
+  llvm::vfs::InMemoryFileSystem FS;
+
+  // Don't suppress output.
+  testing::internal::CaptureStderr();
+  auto Style = getStyle("{invalid_key=invalid_value}", "a.h", "LLVM", "", &FS,
+                        /*AllowUnknownOptions=*/true);
+  auto Output = testing::internal::GetCapturedStderr();
+  ASSERT_TRUE((bool)Style);
+  ASSERT_FALSE(Output.empty());
+
+  // Suppress stderr.
+  testing::internal::CaptureStderr();
+  Style = getStyle("{invalid_key=invalid_value}", "a.h", "LLVM", "", &FS,
+                   /*AllowUnknownOptions=*/true, dropDiagnosticHandler);
+  Output = testing::internal::GetCapturedStderr();
+  ASSERT_TRUE((bool)Style);
+  ASSERT_TRUE(Output.empty());
+}
+
+TEST(ConfigParseTest, RedirectInheritance) {
+  llvm::vfs::InMemoryFileSystem FS;
+  constexpr StringRef Config("BasedOnStyle: InheritParentConfig\n"
+                             "ColumnLimit: 20");
+  constexpr StringRef Code("int *f(int i, int j);");
+
+  ASSERT_TRUE(
+      FS.addFile("/a/.clang-format", 0,
+                 llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: GNU")));
+  ASSERT_TRUE(FS.addFile("/a/proj/.clang-format", 0,
+                         llvm::MemoryBuffer::getMemBuffer(
+                             "BasedOnStyle: InheritParentConfig=/a/config")));
+  ASSERT_TRUE(
+      FS.addFile("/a/proj/test.cc", 0, llvm::MemoryBuffer::getMemBuffer(Code)));
+  auto Style = getStyle("file", "/a/proj/test.cc", "none", "", &FS);
+  ASSERT_FALSE(static_cast<bool>(Style));
+  ASSERT_EQ(toString(Style.takeError()),
+            "Failed to inherit configuration directory /a/config");
+
+  ASSERT_TRUE(FS.addFile("/a/config/.clang-format", 0,
+                         llvm::MemoryBuffer::getMemBuffer(Config)));
+  Style = getStyle("file", "/a/proj/test.cc", "none", "", &FS);
+  ASSERT_TRUE(static_cast<bool>(Style));
+  ASSERT_EQ(*Style, [] {
+    auto Style = getGNUStyle();
+    Style.ColumnLimit = 20;
+    return Style;
+  }());
+
+  ASSERT_TRUE(FS.addFile(
+      "/a/proj/src/.clang-format", 0,
+      llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: InheritParentConfig\n"
+                                       "PointerAlignment: Left")));
+  ASSERT_TRUE(FS.addFile("/a/proj/src/test.cc", 0,
+                         llvm::MemoryBuffer::getMemBuffer(Code)));
+  Style = getStyle("file", "/a/proj/src/test.cc", "none", "", &FS);
+  ASSERT_TRUE(static_cast<bool>(Style));
+  ASSERT_EQ(*Style, [] {
+    auto Style = getGNUStyle();
+    Style.ColumnLimit = 20;
+    Style.PointerAlignment = FormatStyle::PAS_Left;
+    return Style;
+  }());
+
+  ASSERT_TRUE(FS.addFile("/a/loop/.clang-format", 0,
+                         llvm::MemoryBuffer::getMemBuffer(
+                             "BasedOnStyle: InheritParentConfig=config/")));
+  ASSERT_TRUE(
+      FS.addFile("/a/loop/test.cc", 0, llvm::MemoryBuffer::getMemBuffer(Code)));
+  ASSERT_TRUE(FS.addFile("/a/loop/config/_clang-format", 0,
+                         llvm::MemoryBuffer::getMemBuffer(Config)));
+  Style = getStyle("file", "/a/loop/test.cc", "none", "", &FS);
+  ASSERT_FALSE(static_cast<bool>(Style));
+  ASSERT_EQ(toString(Style.takeError()),
+            "Loop detected when inheriting configuration file in /a/loop");
 }
+
 } // namespace
 } // namespace format
 } // namespace clang

>From 53e8bb940d8430763e56695a2aedcaee99216cd3 Mon Sep 17 00:00:00 2001
From: owenca <owenpiano at gmail.com>
Date: Sat, 14 Mar 2026 20:09:17 -0700
Subject: [PATCH 16/21] Update print statement from 'Hello' to 'Goodbye'

---
 .../Format/DefinitionBlockSeparatorTest.cpp   | 2372 ++++-------------
 1 file changed, 577 insertions(+), 1795 deletions(-)

diff --git a/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp b/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp
index 8cd0dd840acf8..b1b4b1d047523 100644
--- a/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp
+++ b/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp
@@ -1,4 +1,4 @@
-//===- unittest/Format/ConfigParseTest.cpp - Config parsing unit tests ----===//
+//===- DefinitionBlockSeparatorTest.cpp - Formatting unit tests -----------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -6,1832 +6,614 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "FormatTestUtils.h"
 #include "clang/Format/Format.h"
 
-#include "llvm/Support/VirtualFileSystem.h"
+#include "llvm/Support/Debug.h"
 #include "gtest/gtest.h"
 
+#define DEBUG_TYPE "definition-block-separator-test"
+
 namespace clang {
 namespace format {
 namespace {
 
-void dropDiagnosticHandler(const llvm::SMDiagnostic &, void *) {}
-FormatStyle getGoogleStyle() { return getGoogleStyle(FormatStyle::LK_Cpp); }
-
-#define EXPECT_ALL_STYLES_EQUAL(Styles)                                        \
-  for (size_t i = 1; i < Styles.size(); ++i)                                   \
-  EXPECT_EQ(Styles[0], Styles[i])                                              \
-      << "Style #" << i << " of " << Styles.size() << " differs from Style #0"
-
-TEST(ConfigParseTest, GetsPredefinedStyleByName) {
-  SmallVector<FormatStyle, 3> Styles;
-  Styles.resize(3);
-
-  Styles[0] = getLLVMStyle();
-  EXPECT_TRUE(getPredefinedStyle("LLVM", FormatStyle::LK_Cpp, &Styles[1]));
-  EXPECT_TRUE(getPredefinedStyle("lLvM", FormatStyle::LK_Cpp, &Styles[2]));
-  EXPECT_ALL_STYLES_EQUAL(Styles);
-
-  Styles[0] = getGoogleStyle();
-  EXPECT_TRUE(getPredefinedStyle("Google", FormatStyle::LK_Cpp, &Styles[1]));
-  EXPECT_TRUE(getPredefinedStyle("gOOgle", FormatStyle::LK_Cpp, &Styles[2]));
-  EXPECT_ALL_STYLES_EQUAL(Styles);
-
-  Styles[0] = getGoogleStyle(FormatStyle::LK_JavaScript);
-  EXPECT_TRUE(
-      getPredefinedStyle("Google", FormatStyle::LK_JavaScript, &Styles[1]));
-  EXPECT_TRUE(
-      getPredefinedStyle("gOOgle", FormatStyle::LK_JavaScript, &Styles[2]));
-  EXPECT_ALL_STYLES_EQUAL(Styles);
-
-  Styles[0] = getChromiumStyle(FormatStyle::LK_Cpp);
-  EXPECT_TRUE(getPredefinedStyle("Chromium", FormatStyle::LK_Cpp, &Styles[1]));
-  EXPECT_TRUE(getPredefinedStyle("cHRoMiUM", FormatStyle::LK_Cpp, &Styles[2]));
-  EXPECT_ALL_STYLES_EQUAL(Styles);
-
-  Styles[0] = getMozillaStyle();
-  EXPECT_TRUE(getPredefinedStyle("Mozilla", FormatStyle::LK_Cpp, &Styles[1]));
-  EXPECT_TRUE(getPredefinedStyle("moZILla", FormatStyle::LK_Cpp, &Styles[2]));
-  EXPECT_ALL_STYLES_EQUAL(Styles);
-
-  Styles[0] = getWebKitStyle();
-  EXPECT_TRUE(getPredefinedStyle("WebKit", FormatStyle::LK_Cpp, &Styles[1]));
-  EXPECT_TRUE(getPredefinedStyle("wEbKit", FormatStyle::LK_Cpp, &Styles[2]));
-  EXPECT_ALL_STYLES_EQUAL(Styles);
-
-  Styles[0] = getGNUStyle();
-  EXPECT_TRUE(getPredefinedStyle("GNU", FormatStyle::LK_Cpp, &Styles[1]));
-  EXPECT_TRUE(getPredefinedStyle("gnU", FormatStyle::LK_Cpp, &Styles[2]));
-  EXPECT_ALL_STYLES_EQUAL(Styles);
-
-  Styles[0] = getClangFormatStyle();
-  EXPECT_TRUE(
-      getPredefinedStyle("clang-format", FormatStyle::LK_Cpp, &Styles[1]));
-  EXPECT_TRUE(
-      getPredefinedStyle("Clang-format", FormatStyle::LK_Cpp, &Styles[2]));
-  EXPECT_ALL_STYLES_EQUAL(Styles);
-
-  EXPECT_FALSE(getPredefinedStyle("qwerty", FormatStyle::LK_Cpp, &Styles[0]));
-}
-
-TEST(ConfigParseTest, GetsCorrectBasedOnStyle) {
-  SmallVector<FormatStyle, 8> Styles;
-  Styles.resize(2);
-
-  Styles[0] = getGoogleStyle();
-  Styles[1] = getLLVMStyle();
-  EXPECT_EQ(0, parseConfiguration("BasedOnStyle: Google", &Styles[1]).value());
-  EXPECT_ALL_STYLES_EQUAL(Styles);
-
-  Styles.resize(5);
-  Styles[0] = getGoogleStyle(FormatStyle::LK_JavaScript);
-  Styles[1] = getLLVMStyle();
-  Styles[1].Language = FormatStyle::LK_JavaScript;
-  EXPECT_EQ(0, parseConfiguration("BasedOnStyle: Google", &Styles[1]).value());
-
-  Styles[2] = getLLVMStyle();
-  Styles[2].Language = FormatStyle::LK_JavaScript;
-  EXPECT_EQ(0, parseConfiguration("Language: JavaScript\n"
-                                  "BasedOnStyle: Google",
-                                  &Styles[2])
-                   .value());
-
-  Styles[3] = getLLVMStyle();
-  Styles[3].Language = FormatStyle::LK_JavaScript;
-  EXPECT_EQ(0, parseConfiguration("BasedOnStyle: Google\n"
-                                  "Language: JavaScript",
-                                  &Styles[3])
-                   .value());
-
-  Styles[4] = getLLVMStyle();
-  Styles[4].Language = FormatStyle::LK_JavaScript;
-  EXPECT_EQ(0, parseConfiguration("---\n"
-                                  "BasedOnStyle: LLVM\n"
-                                  "IndentWidth: 123\n"
-                                  "---\n"
-                                  "BasedOnStyle: Google\n"
-                                  "Language: JavaScript",
-                                  &Styles[4])
-                   .value());
-  EXPECT_ALL_STYLES_EQUAL(Styles);
+class DefinitionBlockSeparatorTest : public testing::Test {
+protected:
+  static std::string
+  separateDefinitionBlocks(StringRef Code,
+                           const std::vector<tooling::Range> &Ranges,
+                           const FormatStyle &Style = getLLVMStyle()) {
+    LLVM_DEBUG(llvm::errs() << "---\n");
+    LLVM_DEBUG(llvm::errs() << Code << "\n\n");
+    tooling::Replacements Replaces = reformat(Style, Code, Ranges, "<stdin>");
+    auto Result = applyAllReplacements(Code, Replaces);
+    EXPECT_TRUE(static_cast<bool>(Result));
+    LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
+    return *Result;
+  }
+
+  static std::string
+  separateDefinitionBlocks(StringRef Code,
+                           const FormatStyle &Style = getLLVMStyle()) {
+    return separateDefinitionBlocks(
+        Code,
+        /*Ranges=*/{1, tooling::Range(0, Code.size())}, Style);
+  }
+
+  static void _verifyFormat(const char *File, int Line, StringRef Code,
+                            const FormatStyle &Style = getLLVMStyle(),
+                            StringRef ExpectedCode = "", bool Inverse = true) {
+    testing::ScopedTrace t(File, Line, testing::Message() << Code.str());
+    bool HasOriginalCode = true;
+    if (ExpectedCode == "") {
+      ExpectedCode = Code;
+      HasOriginalCode = false;
+    }
+
+    EXPECT_EQ(ExpectedCode, separateDefinitionBlocks(ExpectedCode, Style))
+        << "Expected code is not stable";
+    if (Inverse) {
+      FormatStyle InverseStyle = Style;
+      if (Style.SeparateDefinitionBlocks == FormatStyle::SDS_Always)
+        InverseStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Never;
+      else
+        InverseStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
+      EXPECT_NE(ExpectedCode,
+                separateDefinitionBlocks(ExpectedCode, InverseStyle))
+          << "Inverse formatting makes no difference";
+    }
+    std::string CodeToFormat =
+        HasOriginalCode ? Code.str() : removeEmptyLines(Code);
+    std::string Result = separateDefinitionBlocks(CodeToFormat, Style);
+    EXPECT_EQ(ExpectedCode, Result) << "Test failed. Formatted:\n" << Result;
+  }
+
+  static std::string removeEmptyLines(StringRef Code) {
+    std::string Result = "";
+    for (auto Char : Code.str()) {
+      if (Result.size()) {
+        auto LastChar = Result.back();
+        if ((Char == '\n' && LastChar == '\n') ||
+            (Char == '\r' && (LastChar == '\r' || LastChar == '\n'))) {
+          continue;
+        }
+      }
+      Result.push_back(Char);
+    }
+    return Result;
+  }
+};
+
+#define verifyFormat(...) _verifyFormat(__FILE__, __LINE__, __VA_ARGS__)
+
+TEST_F(DefinitionBlockSeparatorTest, Basic) {
+  FormatStyle Style = getLLVMStyle();
+  Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
+  verifyFormat("int foo(int i, int j) {\n"
+               "  int r = i + j;\n"
+               "  return r;\n"
+               "}\n"
+               "\n"
+               "int bar(int j, int k) {\n"
+               "  int r = j + k;\n"
+               "  return r;\n"
+               "}",
+               Style);
+
+  verifyFormat("struct foo {\n"
+               "  int i, j;\n"
+               "};\n"
+               "\n"
+               "struct bar {\n"
+               "  int j, k;\n"
+               "};",
+               Style);
+
+  verifyFormat("union foo {\n"
+               "  int i, j;\n"
+               "};\n"
+               "\n"
+               "union bar {\n"
+               "  int j, k;\n"
+               "};",
+               Style);
+
+  verifyFormat("class foo {\n"
+               "  int i, j;\n"
+               "};\n"
+               "\n"
+               "class bar {\n"
+               "  int j, k;\n"
+               "};",
+               Style);
+
+  verifyFormat("namespace foo {\n"
+               "int i, j;\n"
+               "}\n"
+               "\n"
+               "namespace bar {\n"
+               "int j, k;\n"
+               "}",
+               Style);
+
+  verifyFormat("enum Foo { FOO, BAR };\n"
+               "\n"
+               "enum Bar { FOOBAR, BARFOO };",
+               Style);
+
+  FormatStyle BreakAfterReturnTypeStyle = Style;
+  BreakAfterReturnTypeStyle.BreakAfterReturnType = FormatStyle::RTBS_All;
+  // Test uppercased long typename
+  verifyFormat("class Foo {\n"
+               "  void\n"
+               "  Bar(int t, int p) {\n"
+               "    int r = t + p;\n"
+               "    return r;\n"
+               "  }\n"
+               "\n"
+               "  HRESULT\n"
+               "  Foobar(int t, int p) {\n"
+               "    int r = t * p;\n"
+               "    return r;\n"
+               "  }\n"
+               "}",
+               BreakAfterReturnTypeStyle);
 }
 
-#define CHECK_PARSE_BOOL_FIELD(FIELD, CONFIG_NAME)                             \
-  Style.FIELD = false;                                                         \
-  EXPECT_EQ(0, parseConfiguration(CONFIG_NAME ": true", &Style).value());      \
-  EXPECT_TRUE(Style.FIELD);                                                    \
-  EXPECT_EQ(0, parseConfiguration(CONFIG_NAME ": false", &Style).value());     \
-  EXPECT_FALSE(Style.FIELD)
-
-#define CHECK_PARSE_BOOL(FIELD) CHECK_PARSE_BOOL_FIELD(FIELD, #FIELD)
-
-#define CHECK_PARSE_NESTED_BOOL_FIELD(STRUCT, FIELD, CONFIG_NAME)              \
-  Style.STRUCT.FIELD = false;                                                  \
-  EXPECT_EQ(0,                                                                 \
-            parseConfiguration(#STRUCT ":\n  " CONFIG_NAME ": true", &Style)   \
-                .value());                                                     \
-  EXPECT_TRUE(Style.STRUCT.FIELD);                                             \
-  EXPECT_EQ(0,                                                                 \
-            parseConfiguration(#STRUCT ":\n  " CONFIG_NAME ": false", &Style)  \
-                .value());                                                     \
-  EXPECT_FALSE(Style.STRUCT.FIELD)
-
-#define CHECK_PARSE_NESTED_BOOL(STRUCT, FIELD)                                 \
-  CHECK_PARSE_NESTED_BOOL_FIELD(STRUCT, FIELD, #FIELD)
-
-#define CHECK_PARSE(TEXT, FIELD, VALUE)                                        \
-  EXPECT_NE(VALUE, Style.FIELD) << "Initial value already the same!";          \
-  EXPECT_EQ(0, parseConfiguration(TEXT, &Style).value());                      \
-  EXPECT_EQ(VALUE, Style.FIELD) << "Unexpected value after parsing!"
-
-#define CHECK_PARSE_INT(FIELD) CHECK_PARSE(#FIELD ": -1234", FIELD, -1234)
-
-#define CHECK_PARSE_UNSIGNED(FIELD) CHECK_PARSE(#FIELD ": 1234", FIELD, 1234u)
-
-#define CHECK_PARSE_LIST(FIELD)                                                \
-  CHECK_PARSE(#FIELD ": [foo]", FIELD, std::vector<std::string>{"foo"})
-
-#define CHECK_PARSE_NESTED_VALUE(TEXT, STRUCT, FIELD, VALUE)                   \
-  EXPECT_NE(VALUE, Style.STRUCT.FIELD) << "Initial value already the same!";   \
-  EXPECT_EQ(0, parseConfiguration(#STRUCT ":\n  " TEXT, &Style).value());      \
-  EXPECT_EQ(VALUE, Style.STRUCT.FIELD) << "Unexpected value after parsing!"
-
-TEST(ConfigParseTest, ParsesConfigurationBools) {
-  FormatStyle Style = {};
-  Style.Language = FormatStyle::LK_Cpp;
-  CHECK_PARSE_BOOL(AllowAllArgumentsOnNextLine);
-  CHECK_PARSE_BOOL(AllowAllParametersOfDeclarationOnNextLine);
-  CHECK_PARSE_BOOL(AllowBreakBeforeQtProperty);
-  CHECK_PARSE_BOOL(AllowShortCaseExpressionOnASingleLine);
-  CHECK_PARSE_BOOL(AllowShortCaseLabelsOnASingleLine);
-  CHECK_PARSE_BOOL(AllowShortCompoundRequirementOnASingleLine);
-  CHECK_PARSE_BOOL(AllowShortEnumsOnASingleLine);
-  CHECK_PARSE_BOOL(AllowShortLoopsOnASingleLine);
-  CHECK_PARSE_BOOL(AllowShortNamespacesOnASingleLine);
-  CHECK_PARSE_BOOL(BinPackArguments);
-  CHECK_PARSE_BOOL(BinPackLongBracedList);
-  CHECK_PARSE_BOOL(BreakAdjacentStringLiterals);
-  CHECK_PARSE_BOOL(BreakAfterJavaFieldAnnotations);
-  CHECK_PARSE_BOOL(BreakAfterOpenBracketBracedList);
-  CHECK_PARSE_BOOL(BreakAfterOpenBracketFunction);
-  CHECK_PARSE_BOOL(BreakAfterOpenBracketIf);
-  CHECK_PARSE_BOOL(BreakAfterOpenBracketLoop);
-  CHECK_PARSE_BOOL(BreakAfterOpenBracketSwitch);
-  CHECK_PARSE_BOOL(BreakBeforeCloseBracketBracedList);
-  CHECK_PARSE_BOOL(BreakBeforeCloseBracketFunction);
-  CHECK_PARSE_BOOL(BreakBeforeCloseBracketIf);
-  CHECK_PARSE_BOOL(BreakBeforeCloseBracketLoop);
-  CHECK_PARSE_BOOL(BreakBeforeCloseBracketSwitch);
-  CHECK_PARSE_BOOL(BreakBeforeTemplateCloser);
-  CHECK_PARSE_BOOL(BreakBeforeTernaryOperators);
-  CHECK_PARSE_BOOL(BreakStringLiterals);
-  CHECK_PARSE_BOOL(CompactNamespaces);
-  CHECK_PARSE_BOOL(DerivePointerAlignment);
-  CHECK_PARSE_BOOL_FIELD(DerivePointerAlignment, "DerivePointerBinding");
-  CHECK_PARSE_BOOL(DisableFormat);
-  CHECK_PARSE_BOOL(IndentAccessModifiers);
-  CHECK_PARSE_BOOL(IndentCaseBlocks);
-  CHECK_PARSE_BOOL(IndentCaseLabels);
-  CHECK_PARSE_BOOL(IndentExportBlock);
-  CHECK_PARSE_BOOL(IndentRequiresClause);
-  CHECK_PARSE_BOOL_FIELD(IndentRequiresClause, "IndentRequires");
-  CHECK_PARSE_BOOL(IndentWrappedFunctionNames);
-  CHECK_PARSE_BOOL(InsertBraces);
-  CHECK_PARSE_BOOL(InsertNewlineAtEOF);
-  CHECK_PARSE_BOOL_FIELD(KeepEmptyLines.AtEndOfFile, "KeepEmptyLinesAtEOF");
-  CHECK_PARSE_BOOL_FIELD(KeepEmptyLines.AtStartOfBlock,
-                         "KeepEmptyLinesAtTheStartOfBlocks");
-  CHECK_PARSE_BOOL(KeepFormFeed);
-  CHECK_PARSE_BOOL(ObjCSpaceAfterMethodDeclarationPrefix);
-  CHECK_PARSE_BOOL(ObjCSpaceAfterProperty);
-  CHECK_PARSE_BOOL(ObjCSpaceBeforeProtocolList);
-  CHECK_PARSE_BOOL(RemoveBracesLLVM);
-  CHECK_PARSE_BOOL(RemoveEmptyLinesInUnwrappedLines);
-  CHECK_PARSE_BOOL(RemoveSemicolon);
-  CHECK_PARSE_BOOL(SkipMacroDefinitionBody);
-  CHECK_PARSE_BOOL(SpacesInSquareBrackets);
-  CHECK_PARSE_BOOL(SpacesInContainerLiterals);
-  CHECK_PARSE_BOOL(SpaceAfterCStyleCast);
-  CHECK_PARSE_BOOL(SpaceAfterTemplateKeyword);
-  CHECK_PARSE_BOOL(SpaceAfterOperatorKeyword);
-  CHECK_PARSE_BOOL(SpaceAfterLogicalNot);
-  CHECK_PARSE_BOOL(SpaceBeforeAssignmentOperators);
-  CHECK_PARSE_BOOL(SpaceBeforeCaseColon);
-  CHECK_PARSE_BOOL(SpaceBeforeCpp11BracedList);
-  CHECK_PARSE_BOOL(SpaceBeforeCtorInitializerColon);
-  CHECK_PARSE_BOOL(SpaceBeforeInheritanceColon);
-  CHECK_PARSE_BOOL(SpaceBeforeJsonColon);
-  CHECK_PARSE_BOOL(SpaceBeforeRangeBasedForLoopColon);
-  CHECK_PARSE_BOOL(SpaceBeforeSquareBrackets);
-  CHECK_PARSE_BOOL(VerilogBreakBetweenInstancePorts);
-
-  CHECK_PARSE_NESTED_BOOL(AlignConsecutiveShortCaseStatements, Enabled);
-  CHECK_PARSE_NESTED_BOOL(AlignConsecutiveShortCaseStatements,
-                          AcrossEmptyLines);
-  CHECK_PARSE_NESTED_BOOL(AlignConsecutiveShortCaseStatements, AcrossComments);
-  CHECK_PARSE_NESTED_BOOL(AlignConsecutiveShortCaseStatements, AlignCaseArrows);
-  CHECK_PARSE_NESTED_BOOL(AlignConsecutiveShortCaseStatements, AlignCaseColons);
-  CHECK_PARSE_NESTED_BOOL(AllowShortFunctionsOnASingleLine, Empty);
-  CHECK_PARSE_NESTED_BOOL(AllowShortFunctionsOnASingleLine, Inline);
-  CHECK_PARSE_NESTED_BOOL(AllowShortFunctionsOnASingleLine, Other);
-  CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterCaseLabel);
-  CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterClass);
-  CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterEnum);
-  CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterFunction);
-  CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterNamespace);
-  CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterObjCDeclaration);
-  CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterStruct);
-  CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterUnion);
-  CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterExternBlock);
-  CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeCatch);
-  CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeElse);
-  CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeLambdaBody);
-  CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeWhile);
-  CHECK_PARSE_NESTED_BOOL(BraceWrapping, IndentBraces);
-  CHECK_PARSE_NESTED_BOOL(BraceWrapping, SplitEmptyFunction);
-  CHECK_PARSE_NESTED_BOOL(BraceWrapping, SplitEmptyRecord);
-  CHECK_PARSE_NESTED_BOOL(BraceWrapping, SplitEmptyNamespace);
-  CHECK_PARSE_NESTED_BOOL(KeepEmptyLines, AtEndOfFile);
-  CHECK_PARSE_NESTED_BOOL(KeepEmptyLines, AtStartOfBlock);
-  CHECK_PARSE_NESTED_BOOL(KeepEmptyLines, AtStartOfFile);
-  CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterControlStatements);
-  CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterForeachMacros);
-  CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions,
-                          AfterFunctionDeclarationName);
-  CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions,
-                          AfterFunctionDefinitionName);
-  CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterIfMacros);
-  CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterNot);
-  CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterOverloadedOperator);
-  CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterPlacementOperator);
-  CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, BeforeNonEmptyParentheses);
-  CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, ExceptDoubleParentheses);
-  CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InCStyleCasts);
-  CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InConditionalStatements);
-  CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InEmptyParentheses);
-  CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, Other);
-  CHECK_PARSE_NESTED_BOOL(SortIncludes, Enabled);
-  CHECK_PARSE_NESTED_BOOL(SortIncludes, IgnoreCase);
-  CHECK_PARSE_NESTED_BOOL(SortIncludes, IgnoreExtension);
+TEST_F(DefinitionBlockSeparatorTest, FormatConflict) {
+  FormatStyle Style = getLLVMStyle();
+  Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
+  StringRef Code = "class Test {\n"
+                   "public:\n"
+                   "  static void foo() {\n"
+                   "    int t;\n"
+                   "    return 1;\n"
+                   "  }\n"
+                   "};";
+  std::vector<tooling::Range> Ranges = {1, tooling::Range(0, Code.size())};
+  EXPECT_EQ(reformat(Style, Code, Ranges, "<stdin>").size(), 0u);
 }
 
-#undef CHECK_PARSE_BOOL
-
-TEST(ConfigParseTest, ParsesConfigurationIntegers) {
-  FormatStyle Style = {};
-  Style.Language = FormatStyle::LK_Cpp;
-
-  CHECK_PARSE_INT(AccessModifierOffset);
-  CHECK_PARSE_INT(BracedInitializerIndentWidth);
-  CHECK_PARSE_INT(PPIndentWidth);
-
-  CHECK_PARSE_UNSIGNED(ColumnLimit);
-  CHECK_PARSE_UNSIGNED(ConstructorInitializerIndentWidth);
-  CHECK_PARSE_UNSIGNED(ContinuationIndentWidth);
-  CHECK_PARSE_UNSIGNED(IndentWidth);
-  CHECK_PARSE_UNSIGNED(MaxEmptyLinesToKeep);
-  CHECK_PARSE_UNSIGNED(ObjCBlockIndentWidth);
-  CHECK_PARSE_UNSIGNED(PenaltyBreakAssignment);
-  CHECK_PARSE_UNSIGNED(PenaltyBreakBeforeFirstCallParameter);
-  CHECK_PARSE_UNSIGNED(PenaltyBreakBeforeMemberAccess);
-  CHECK_PARSE_UNSIGNED(PenaltyBreakComment);
-  CHECK_PARSE_UNSIGNED(PenaltyBreakFirstLessLess);
-  CHECK_PARSE_UNSIGNED(PenaltyBreakOpenParenthesis);
-  CHECK_PARSE_UNSIGNED(PenaltyBreakScopeResolution);
-  CHECK_PARSE_UNSIGNED(PenaltyBreakString);
-  CHECK_PARSE_UNSIGNED(PenaltyBreakTemplateDeclaration);
-  CHECK_PARSE_UNSIGNED(PenaltyExcessCharacter);
-  CHECK_PARSE_UNSIGNED(PenaltyIndentedWhitespace);
-  CHECK_PARSE_UNSIGNED(PenaltyReturnTypeOnItsOwnLine);
-  CHECK_PARSE_UNSIGNED(ShortNamespaceLines);
-  CHECK_PARSE_UNSIGNED(SpacesBeforeTrailingComments);
-  CHECK_PARSE_UNSIGNED(TabWidth);
+TEST_F(DefinitionBlockSeparatorTest, CommentBlock) {
+  FormatStyle Style = getLLVMStyle();
+  Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
+  std::string Prefix = "enum Foo { FOO, BAR };\n"
+                       "\n"
+                       "/*\n"
+                       "test1\n"
+                       "test2\n"
+                       "*/\n"
+                       "int foo(int i, int j) {\n"
+                       "  int r = i + j;\n"
+                       "  return r;\n"
+                       "}\n";
+  std::string Suffix = "enum Bar { FOOBAR, BARFOO };\n"
+                       "\n"
+                       "/* Comment block in one line*/\n"
+                       "int bar3(int j, int k) {\n"
+                       "  // A comment\n"
+                       "  int r = j % k;\n"
+                       "  return r;\n"
+                       "}\n";
+  std::string CommentedCode = "/*\n"
+                              "int bar2(int j, int k) {\n"
+                              "  int r = j / k;\n"
+                              "  return r;\n"
+                              "}\n"
+                              "*/\n";
+  verifyFormat(removeEmptyLines(Prefix) + "\n" + CommentedCode + "\n" +
+                   removeEmptyLines(Suffix),
+               Style, Prefix + "\n" + CommentedCode + "\n" + Suffix);
+  verifyFormat(removeEmptyLines(Prefix) + "\n" + CommentedCode +
+                   removeEmptyLines(Suffix),
+               Style, Prefix + "\n" + CommentedCode + Suffix);
 }
 
-TEST(ConfigParseTest, ParsesConfiguration) {
-  FormatStyle Style = {};
-  Style.Language = FormatStyle::LK_Cpp;
-  CHECK_PARSE("CommentPragmas: '// abc$'", CommentPragmas, "// abc$");
-  CHECK_PARSE("OneLineFormatOffRegex: // ab$", OneLineFormatOffRegex, "// ab$");
-
-  Style.QualifierAlignment = FormatStyle::QAS_Right;
-  CHECK_PARSE("QualifierAlignment: Leave", QualifierAlignment,
-              FormatStyle::QAS_Leave);
-  CHECK_PARSE("QualifierAlignment: Right", QualifierAlignment,
-              FormatStyle::QAS_Right);
-  CHECK_PARSE("QualifierAlignment: Left", QualifierAlignment,
-              FormatStyle::QAS_Left);
-  CHECK_PARSE("QualifierAlignment: Custom", QualifierAlignment,
-              FormatStyle::QAS_Custom);
-
-  Style.QualifierOrder.clear();
-  CHECK_PARSE("QualifierOrder: [ const, volatile, type ]", QualifierOrder,
-              std::vector<std::string>({"const", "volatile", "type"}));
-  Style.QualifierOrder.clear();
-  CHECK_PARSE("QualifierOrder: [const, type]", QualifierOrder,
-              std::vector<std::string>({"const", "type"}));
-  Style.QualifierOrder.clear();
-  CHECK_PARSE("QualifierOrder: [volatile, type]", QualifierOrder,
-              std::vector<std::string>({"volatile", "type"}));
-
-#define CHECK_ALIGN_CONSECUTIVE(FIELD)                                         \
-  do {                                                                         \
-    Style.FIELD.Enabled = true;                                                \
-    CHECK_PARSE(#FIELD ": None", FIELD,                                        \
-                FormatStyle::AlignConsecutiveStyle({}));                       \
-    CHECK_PARSE(                                                               \
-        #FIELD ": Consecutive", FIELD,                                         \
-        FormatStyle::AlignConsecutiveStyle(                                    \
-            {/*Enabled=*/true, /*AcrossEmptyLines=*/false,                     \
-             /*AcrossComments=*/false, /*AlignCompound=*/false,                \
-             /*AlignFunctionDeclarations=*/true,                               \
-             /*AlignFunctionPointers=*/false, /*PadOperators=*/true}));        \
-    CHECK_PARSE(                                                               \
-        #FIELD ": AcrossEmptyLines", FIELD,                                    \
-        FormatStyle::AlignConsecutiveStyle(                                    \
-            {/*Enabled=*/true, /*AcrossEmptyLines=*/true,                      \
-             /*AcrossComments=*/false, /*AlignCompound=*/false,                \
-             /*AlignFunctionDeclarations=*/true,                               \
-             /*AlignFunctionPointers=*/false, /*PadOperators=*/true}));        \
-    CHECK_PARSE(                                                               \
-        #FIELD ": AcrossComments", FIELD,                                      \
-        FormatStyle::AlignConsecutiveStyle(                                    \
-            {/*Enabled=*/true, /*AcrossEmptyLines=*/false,                     \
-             /*AcrossComments=*/true, /*AlignCompound=*/false,                 \
-             /*AlignFunctionDeclarations=*/true,                               \
-             /*AlignFunctionPointers=*/false, /*PadOperators=*/true}));        \
-    CHECK_PARSE(                                                               \
-        #FIELD ": AcrossEmptyLinesAndComments", FIELD,                         \
-        FormatStyle::AlignConsecutiveStyle(                                    \
-            {/*Enabled=*/true, /*AcrossEmptyLines=*/true,                      \
-             /*AcrossComments=*/true, /*AlignCompound=*/false,                 \
-             /*AlignFunctionDeclarations=*/true,                               \
-             /*AlignFunctionPointers=*/false, /*PadOperators=*/true}));        \
-    /* For backwards compability, false / true should still parse */           \
-    CHECK_PARSE(#FIELD ": false", FIELD,                                       \
-                FormatStyle::AlignConsecutiveStyle({}));                       \
-    CHECK_PARSE(                                                               \
-        #FIELD ": true", FIELD,                                                \
-        FormatStyle::AlignConsecutiveStyle(                                    \
-            {/*Enabled=*/true, /*AcrossEmptyLines=*/false,                     \
-             /*AcrossComments=*/false, /*AlignCompound=*/false,                \
-             /*AlignFunctionDeclarations=*/true,                               \
-             /*AlignFunctionPointers=*/false, /*PadOperators=*/true}));        \
-                                                                               \
-    CHECK_PARSE_NESTED_BOOL(FIELD, Enabled);                                   \
-    CHECK_PARSE_NESTED_BOOL(FIELD, AcrossEmptyLines);                          \
-    CHECK_PARSE_NESTED_BOOL(FIELD, AcrossComments);                            \
-    CHECK_PARSE_NESTED_BOOL(FIELD, AlignCompound);                             \
-    CHECK_PARSE_NESTED_BOOL(FIELD, AlignFunctionDeclarations);                 \
-    CHECK_PARSE_NESTED_BOOL(FIELD, AlignFunctionPointers);                     \
-    CHECK_PARSE_NESTED_BOOL(FIELD, PadOperators);                              \
-  } while (false)
-
-  CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveAssignments);
-  CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveBitFields);
-  CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveMacros);
-  CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveDeclarations);
-
-#undef CHECK_ALIGN_CONSECUTIVE
-
-  Style.PointerAlignment = FormatStyle::PAS_Middle;
-  CHECK_PARSE("PointerAlignment: Left", PointerAlignment,
-              FormatStyle::PAS_Left);
-  CHECK_PARSE("PointerAlignment: Right", PointerAlignment,
-              FormatStyle::PAS_Right);
-  CHECK_PARSE("PointerAlignment: Middle", PointerAlignment,
-              FormatStyle::PAS_Middle);
-  Style.ReferenceAlignment = FormatStyle::RAS_Middle;
-  CHECK_PARSE("ReferenceAlignment: Pointer", ReferenceAlignment,
-              FormatStyle::RAS_Pointer);
-  CHECK_PARSE("ReferenceAlignment: Left", ReferenceAlignment,
-              FormatStyle::RAS_Left);
-  CHECK_PARSE("ReferenceAlignment: Right", ReferenceAlignment,
-              FormatStyle::RAS_Right);
-  CHECK_PARSE("ReferenceAlignment: Middle", ReferenceAlignment,
-              FormatStyle::RAS_Middle);
-  // For backward compatibility:
-  CHECK_PARSE("PointerBindsToType: Left", PointerAlignment,
-              FormatStyle::PAS_Left);
-  CHECK_PARSE("PointerBindsToType: Right", PointerAlignment,
-              FormatStyle::PAS_Right);
-  CHECK_PARSE("PointerBindsToType: Middle", PointerAlignment,
-              FormatStyle::PAS_Middle);
-
-  Style.ReflowComments = FormatStyle::RCS_Always;
-  CHECK_PARSE("ReflowComments: Never", ReflowComments, FormatStyle::RCS_Never);
-  CHECK_PARSE("ReflowComments: IndentOnly", ReflowComments,
-              FormatStyle::RCS_IndentOnly);
-  CHECK_PARSE("ReflowComments: Always", ReflowComments,
-              FormatStyle::RCS_Always);
-  // For backward compatibility:
-  CHECK_PARSE("ReflowComments: false", ReflowComments, FormatStyle::RCS_Never);
-  CHECK_PARSE("ReflowComments: true", ReflowComments, FormatStyle::RCS_Always);
-
-  Style.Standard = FormatStyle::LS_Auto;
-  CHECK_PARSE("Standard: c++03", Standard, FormatStyle::LS_Cpp03);
-  CHECK_PARSE("Standard: c++11", Standard, FormatStyle::LS_Cpp11);
-  CHECK_PARSE("Standard: c++14", Standard, FormatStyle::LS_Cpp14);
-  CHECK_PARSE("Standard: c++17", Standard, FormatStyle::LS_Cpp17);
-  CHECK_PARSE("Standard: c++20", Standard, FormatStyle::LS_Cpp20);
-  CHECK_PARSE("Standard: Auto", Standard, FormatStyle::LS_Auto);
-  CHECK_PARSE("Standard: Latest", Standard, FormatStyle::LS_Latest);
-  // Legacy aliases:
-  CHECK_PARSE("Standard: Cpp03", Standard, FormatStyle::LS_Cpp03);
-  CHECK_PARSE("Standard: Cpp11", Standard, FormatStyle::LS_Latest);
-  CHECK_PARSE("Standard: C++03", Standard, FormatStyle::LS_Cpp03);
-  CHECK_PARSE("Standard: C++11", Standard, FormatStyle::LS_Cpp11);
-
-  Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All;
-  CHECK_PARSE("BreakBeforeBinaryOperators: NonAssignment",
-              BreakBeforeBinaryOperators, FormatStyle::BOS_NonAssignment);
-  CHECK_PARSE("BreakBeforeBinaryOperators: None", BreakBeforeBinaryOperators,
-              FormatStyle::BOS_None);
-  CHECK_PARSE("BreakBeforeBinaryOperators: All", BreakBeforeBinaryOperators,
-              FormatStyle::BOS_All);
-  // For backward compatibility:
-  CHECK_PARSE("BreakBeforeBinaryOperators: false", BreakBeforeBinaryOperators,
-              FormatStyle::BOS_None);
-  CHECK_PARSE("BreakBeforeBinaryOperators: true", BreakBeforeBinaryOperators,
-              FormatStyle::BOS_All);
-
-  Style.BreakBinaryOperations.Default = FormatStyle::BBO_Never;
-  CHECK_PARSE("BreakBinaryOperations: OnePerLine", BreakBinaryOperations,
-              FormatStyle::BreakBinaryOperationsOptions(
-                  {FormatStyle::BBO_OnePerLine, {}}));
-  CHECK_PARSE("BreakBinaryOperations: RespectPrecedence", BreakBinaryOperations,
-              FormatStyle::BreakBinaryOperationsOptions(
-                  {FormatStyle::BBO_RespectPrecedence, {}}));
-  CHECK_PARSE(
-      "BreakBinaryOperations: Never", BreakBinaryOperations,
-      FormatStyle::BreakBinaryOperationsOptions({FormatStyle::BBO_Never, {}}));
-
-  // Structured form
-  Style.BreakBinaryOperations.Default = FormatStyle::BBO_Never;
-  CHECK_PARSE("BreakBinaryOperations:\n"
-              "  Default: OnePerLine",
-              BreakBinaryOperations,
-              FormatStyle::BreakBinaryOperationsOptions(
-                  {FormatStyle::BBO_OnePerLine, {}}));
-
-  Style.BreakBinaryOperations.Default = FormatStyle::BBO_Never;
-  EXPECT_EQ(0, parseConfiguration("BreakBinaryOperations:\n"
-                                  "  Default: Never\n"
-                                  "  PerOperator:\n"
-                                  "    - Operators: ['&&', '||']\n"
-                                  "      Style: OnePerLine\n"
-                                  "      MinChainLength: 3",
-                                  &Style)
-                   .value());
-  EXPECT_EQ(Style.BreakBinaryOperations.Default, FormatStyle::BBO_Never);
-  ASSERT_EQ(Style.BreakBinaryOperations.PerOperator.size(), 1u);
-  std::vector<tok::TokenKind> ExpectedOps = {tok::ampamp, tok::pipepipe};
-  EXPECT_EQ(Style.BreakBinaryOperations.PerOperator[0].Operators, ExpectedOps);
-  EXPECT_EQ(Style.BreakBinaryOperations.PerOperator[0].Style,
-            FormatStyle::BBO_OnePerLine);
-  EXPECT_EQ(Style.BreakBinaryOperations.PerOperator[0].MinChainLength, 3u);
-
-  // Parse ">" and ">>" which have edge cases: clang-format splits ">>" into
-  // two ">" tokens, so ">>" maps to tok::greatergreater while ">" maps to
-  // tok::greater.
-  Style.BreakBinaryOperations.Default = FormatStyle::BBO_Never;
-  EXPECT_EQ(0, parseConfiguration("BreakBinaryOperations:\n"
-                                  "  Default: Never\n"
-                                  "  PerOperator:\n"
-                                  "    - Operators: ['>', '>>']\n"
-                                  "      Style: OnePerLine",
-                                  &Style)
-                   .value());
-  ASSERT_EQ(Style.BreakBinaryOperations.PerOperator.size(), 1u);
-  std::vector<tok::TokenKind> ExpectedShiftOps = {tok::greater,
-                                                  tok::greatergreater};
-  EXPECT_EQ(Style.BreakBinaryOperations.PerOperator[0].Operators,
-            ExpectedShiftOps);
-
-  Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon;
-  CHECK_PARSE("BreakConstructorInitializers: BeforeComma",
-              BreakConstructorInitializers, FormatStyle::BCIS_BeforeComma);
-  CHECK_PARSE("BreakConstructorInitializers: AfterColon",
-              BreakConstructorInitializers, FormatStyle::BCIS_AfterColon);
-  CHECK_PARSE("BreakConstructorInitializers: AfterComma",
-              BreakConstructorInitializers, FormatStyle::BCIS_AfterComma);
-  CHECK_PARSE("BreakConstructorInitializers: BeforeColon",
-              BreakConstructorInitializers, FormatStyle::BCIS_BeforeColon);
-  // For backward compatibility:
-  CHECK_PARSE("BreakConstructorInitializersBeforeComma: true",
-              BreakConstructorInitializers, FormatStyle::BCIS_BeforeComma);
-
-  Style.BreakInheritanceList = FormatStyle::BILS_BeforeColon;
-  CHECK_PARSE("BreakInheritanceList: AfterComma", BreakInheritanceList,
-              FormatStyle::BILS_AfterComma);
-  CHECK_PARSE("BreakInheritanceList: BeforeComma", BreakInheritanceList,
-              FormatStyle::BILS_BeforeComma);
-  CHECK_PARSE("BreakInheritanceList: AfterColon", BreakInheritanceList,
-              FormatStyle::BILS_AfterColon);
-  CHECK_PARSE("BreakInheritanceList: BeforeColon", BreakInheritanceList,
-              FormatStyle::BILS_BeforeColon);
-  // For backward compatibility:
-  CHECK_PARSE("BreakBeforeInheritanceComma: true", BreakInheritanceList,
-              FormatStyle::BILS_BeforeComma);
-
-  Style.BinPackParameters = FormatStyle::BPPS_OnePerLine;
-  CHECK_PARSE("BinPackParameters: BinPack", BinPackParameters,
-              FormatStyle::BPPS_BinPack);
-  CHECK_PARSE("BinPackParameters: OnePerLine", BinPackParameters,
-              FormatStyle::BPPS_OnePerLine);
-  CHECK_PARSE("BinPackParameters: AlwaysOnePerLine", BinPackParameters,
-              FormatStyle::BPPS_AlwaysOnePerLine);
-  // For backward compatibility.
-  CHECK_PARSE("BinPackParameters: true", BinPackParameters,
-              FormatStyle::BPPS_BinPack);
-  CHECK_PARSE("BinPackParameters: false", BinPackParameters,
-              FormatStyle::BPPS_OnePerLine);
-
-  Style.PackConstructorInitializers = FormatStyle::PCIS_BinPack;
-  CHECK_PARSE("PackConstructorInitializers: Never", PackConstructorInitializers,
-              FormatStyle::PCIS_Never);
-  CHECK_PARSE("PackConstructorInitializers: BinPack",
-              PackConstructorInitializers, FormatStyle::PCIS_BinPack);
-  CHECK_PARSE("PackConstructorInitializers: CurrentLine",
-              PackConstructorInitializers, FormatStyle::PCIS_CurrentLine);
-  CHECK_PARSE("PackConstructorInitializers: NextLine",
-              PackConstructorInitializers, FormatStyle::PCIS_NextLine);
-  CHECK_PARSE("PackConstructorInitializers: NextLineOnly",
-              PackConstructorInitializers, FormatStyle::PCIS_NextLineOnly);
-  // For backward compatibility:
-  CHECK_PARSE("BasedOnStyle: Google\n"
-              "ConstructorInitializerAllOnOneLineOrOnePerLine: true\n"
-              "AllowAllConstructorInitializersOnNextLine: false",
-              PackConstructorInitializers, FormatStyle::PCIS_CurrentLine);
-  Style.PackConstructorInitializers = FormatStyle::PCIS_NextLine;
-  CHECK_PARSE("BasedOnStyle: Google\n"
-              "ConstructorInitializerAllOnOneLineOrOnePerLine: false",
-              PackConstructorInitializers, FormatStyle::PCIS_BinPack);
-  CHECK_PARSE("ConstructorInitializerAllOnOneLineOrOnePerLine: true\n"
-              "AllowAllConstructorInitializersOnNextLine: true",
-              PackConstructorInitializers, FormatStyle::PCIS_NextLine);
-  Style.PackConstructorInitializers = FormatStyle::PCIS_BinPack;
-  CHECK_PARSE("ConstructorInitializerAllOnOneLineOrOnePerLine: true\n"
-              "AllowAllConstructorInitializersOnNextLine: false",
-              PackConstructorInitializers, FormatStyle::PCIS_CurrentLine);
-
-  Style.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_LogicalBlock;
-  CHECK_PARSE("EmptyLineBeforeAccessModifier: Never",
-              EmptyLineBeforeAccessModifier, FormatStyle::ELBAMS_Never);
-  CHECK_PARSE("EmptyLineBeforeAccessModifier: Leave",
-              EmptyLineBeforeAccessModifier, FormatStyle::ELBAMS_Leave);
-  CHECK_PARSE("EmptyLineBeforeAccessModifier: LogicalBlock",
-              EmptyLineBeforeAccessModifier, FormatStyle::ELBAMS_LogicalBlock);
-  CHECK_PARSE("EmptyLineBeforeAccessModifier: Always",
-              EmptyLineBeforeAccessModifier, FormatStyle::ELBAMS_Always);
-
-  Style.EnumTrailingComma = FormatStyle::ETC_Insert;
-  CHECK_PARSE("EnumTrailingComma: Leave", EnumTrailingComma,
-              FormatStyle::ETC_Leave);
-  CHECK_PARSE("EnumTrailingComma: Insert", EnumTrailingComma,
-              FormatStyle::ETC_Insert);
-  CHECK_PARSE("EnumTrailingComma: Remove", EnumTrailingComma,
-              FormatStyle::ETC_Remove);
-
-  Style.AlignAfterOpenBracket = false;
-  CHECK_PARSE("AlignAfterOpenBracket: Align", AlignAfterOpenBracket, true);
-  CHECK_PARSE("AlignAfterOpenBracket: DontAlign", AlignAfterOpenBracket, false);
-  // For backward compatibility:
-  CHECK_PARSE("AlignAfterOpenBracket: AlwaysBreak", AlignAfterOpenBracket,
-              true);
-  CHECK_PARSE("AlignAfterOpenBracket: AlwaysBreak\n"
-              "BreakAfterOpenBracketIf: false",
-              BreakAfterOpenBracketIf, false);
-  CHECK_PARSE("BreakAfterOpenBracketLoop: true\n"
-              "AlignAfterOpenBracket: AlwaysBreak",
-              BreakAfterOpenBracketLoop, true);
-  CHECK_PARSE("AlignAfterOpenBracket: false", AlignAfterOpenBracket, false);
-  CHECK_PARSE("AlignAfterOpenBracket: BlockIndent", AlignAfterOpenBracket,
-              true);
-  Style.AlignAfterOpenBracket = false;
-  CHECK_PARSE("AlignAfterOpenBracket: true", AlignAfterOpenBracket, true);
-
-  Style.AlignEscapedNewlines = FormatStyle::ENAS_Left;
-  CHECK_PARSE("AlignEscapedNewlines: DontAlign", AlignEscapedNewlines,
-              FormatStyle::ENAS_DontAlign);
-  CHECK_PARSE("AlignEscapedNewlines: Left", AlignEscapedNewlines,
-              FormatStyle::ENAS_Left);
-  CHECK_PARSE("AlignEscapedNewlines: LeftWithLastLine", AlignEscapedNewlines,
-              FormatStyle::ENAS_LeftWithLastLine);
-  CHECK_PARSE("AlignEscapedNewlines: Right", AlignEscapedNewlines,
-              FormatStyle::ENAS_Right);
-  // For backward compatibility:
-  CHECK_PARSE("AlignEscapedNewlinesLeft: true", AlignEscapedNewlines,
-              FormatStyle::ENAS_Left);
-  CHECK_PARSE("AlignEscapedNewlinesLeft: false", AlignEscapedNewlines,
-              FormatStyle::ENAS_Right);
-
-  Style.AlignOperands = FormatStyle::OAS_Align;
-  CHECK_PARSE("AlignOperands: DontAlign", AlignOperands,
-              FormatStyle::OAS_DontAlign);
-  CHECK_PARSE("AlignOperands: Align", AlignOperands, FormatStyle::OAS_Align);
-  CHECK_PARSE("AlignOperands: AlignAfterOperator", AlignOperands,
-              FormatStyle::OAS_AlignAfterOperator);
-  // For backward compatibility:
-  CHECK_PARSE("AlignOperands: false", AlignOperands,
-              FormatStyle::OAS_DontAlign);
-  CHECK_PARSE("AlignOperands: true", AlignOperands, FormatStyle::OAS_Align);
-
-  CHECK_PARSE("AlignTrailingComments: Leave", AlignTrailingComments,
-              FormatStyle::TrailingCommentsAlignmentStyle(
-                  {FormatStyle::TCAS_Leave, 0, true}));
-  CHECK_PARSE("AlignTrailingComments: Always", AlignTrailingComments,
-              FormatStyle::TrailingCommentsAlignmentStyle(
-                  {FormatStyle::TCAS_Always, 0, true}));
-  CHECK_PARSE("AlignTrailingComments: Never", AlignTrailingComments,
-              FormatStyle::TrailingCommentsAlignmentStyle(
-                  {FormatStyle::TCAS_Never, 0, true}));
-  // For backwards compatibility
-  CHECK_PARSE("AlignTrailingComments: true", AlignTrailingComments,
-              FormatStyle::TrailingCommentsAlignmentStyle(
-                  {FormatStyle::TCAS_Always, 0, true}));
-  CHECK_PARSE("AlignTrailingComments: false", AlignTrailingComments,
-              FormatStyle::TrailingCommentsAlignmentStyle(
-                  {FormatStyle::TCAS_Never, 0, true}));
-  CHECK_PARSE_NESTED_VALUE("Kind: Always", AlignTrailingComments, Kind,
-                           FormatStyle::TCAS_Always);
-  CHECK_PARSE_NESTED_VALUE("Kind: Never", AlignTrailingComments, Kind,
-                           FormatStyle::TCAS_Never);
-  CHECK_PARSE_NESTED_VALUE("Kind: Leave", AlignTrailingComments, Kind,
-                           FormatStyle::TCAS_Leave);
-  CHECK_PARSE_NESTED_VALUE("OverEmptyLines: 1234", AlignTrailingComments,
-                           OverEmptyLines, 1234u);
-  CHECK_PARSE_NESTED_BOOL(AlignTrailingComments, AlignPPAndNotPP);
-
-  Style.UseTab = FormatStyle::UT_ForIndentation;
-  CHECK_PARSE("UseTab: Never", UseTab, FormatStyle::UT_Never);
-  CHECK_PARSE("UseTab: ForIndentation", UseTab, FormatStyle::UT_ForIndentation);
-  CHECK_PARSE("UseTab: Always", UseTab, FormatStyle::UT_Always);
-  CHECK_PARSE("UseTab: ForContinuationAndIndentation", UseTab,
-              FormatStyle::UT_ForContinuationAndIndentation);
-  CHECK_PARSE("UseTab: AlignWithSpaces", UseTab,
-              FormatStyle::UT_AlignWithSpaces);
-  // For backward compatibility:
-  CHECK_PARSE("UseTab: false", UseTab, FormatStyle::UT_Never);
-  CHECK_PARSE("UseTab: true", UseTab, FormatStyle::UT_Always);
-
-  Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Empty;
-  CHECK_PARSE("AllowShortBlocksOnASingleLine: Never",
-              AllowShortBlocksOnASingleLine, FormatStyle::SBS_Never);
-  CHECK_PARSE("AllowShortBlocksOnASingleLine: Empty",
-              AllowShortBlocksOnASingleLine, FormatStyle::SBS_Empty);
-  CHECK_PARSE("AllowShortBlocksOnASingleLine: Always",
-              AllowShortBlocksOnASingleLine, FormatStyle::SBS_Always);
-  // For backward compatibility:
-  CHECK_PARSE("AllowShortBlocksOnASingleLine: false",
-              AllowShortBlocksOnASingleLine, FormatStyle::SBS_Never);
-  CHECK_PARSE("AllowShortBlocksOnASingleLine: true",
-              AllowShortBlocksOnASingleLine, FormatStyle::SBS_Always);
-
-  CHECK_PARSE("AllowShortFunctionsOnASingleLine: None",
-              AllowShortFunctionsOnASingleLine,
-              FormatStyle::ShortFunctionStyle());
-  CHECK_PARSE("AllowShortFunctionsOnASingleLine: Inline",
-              AllowShortFunctionsOnASingleLine,
-              FormatStyle::ShortFunctionStyle::setEmptyAndInline());
-  CHECK_PARSE("AllowShortFunctionsOnASingleLine: Empty",
-              AllowShortFunctionsOnASingleLine,
-              FormatStyle::ShortFunctionStyle::setEmptyOnly());
-  CHECK_PARSE("AllowShortFunctionsOnASingleLine: All",
-              AllowShortFunctionsOnASingleLine,
-              FormatStyle::ShortFunctionStyle::setAll());
-  CHECK_PARSE("AllowShortFunctionsOnASingleLine: InlineOnly",
-              AllowShortFunctionsOnASingleLine,
-              FormatStyle::ShortFunctionStyle::setInlineOnly());
-
-  // For backward compatibility:
-  CHECK_PARSE("AllowShortFunctionsOnASingleLine: false",
-              AllowShortFunctionsOnASingleLine,
-              FormatStyle::ShortFunctionStyle());
-  CHECK_PARSE("AllowShortFunctionsOnASingleLine: true",
-              AllowShortFunctionsOnASingleLine,
-              FormatStyle::ShortFunctionStyle::setAll());
-
-  Style.AllowShortLambdasOnASingleLine = FormatStyle::SLS_All;
-  CHECK_PARSE("AllowShortLambdasOnASingleLine: None",
-              AllowShortLambdasOnASingleLine, FormatStyle::SLS_None);
-  CHECK_PARSE("AllowShortLambdasOnASingleLine: Empty",
-              AllowShortLambdasOnASingleLine, FormatStyle::SLS_Empty);
-  CHECK_PARSE("AllowShortLambdasOnASingleLine: Inline",
-              AllowShortLambdasOnASingleLine, FormatStyle::SLS_Inline);
-  CHECK_PARSE("AllowShortLambdasOnASingleLine: All",
-              AllowShortLambdasOnASingleLine, FormatStyle::SLS_All);
-  // For backward compatibility:
-  CHECK_PARSE("AllowShortLambdasOnASingleLine: false",
-              AllowShortLambdasOnASingleLine, FormatStyle::SLS_None);
-  CHECK_PARSE("AllowShortLambdasOnASingleLine: true",
-              AllowShortLambdasOnASingleLine, FormatStyle::SLS_All);
-
-  Style.SpaceAroundPointerQualifiers = FormatStyle::SAPQ_Both;
-  CHECK_PARSE("SpaceAroundPointerQualifiers: Default",
-              SpaceAroundPointerQualifiers, FormatStyle::SAPQ_Default);
-  CHECK_PARSE("SpaceAroundPointerQualifiers: Before",
-              SpaceAroundPointerQualifiers, FormatStyle::SAPQ_Before);
-  CHECK_PARSE("SpaceAroundPointerQualifiers: After",
-              SpaceAroundPointerQualifiers, FormatStyle::SAPQ_After);
-  CHECK_PARSE("SpaceAroundPointerQualifiers: Both",
-              SpaceAroundPointerQualifiers, FormatStyle::SAPQ_Both);
-
-  Style.SpaceBeforeParens = FormatStyle::SBPO_Always;
-  CHECK_PARSE("SpaceBeforeParens: Never", SpaceBeforeParens,
-              FormatStyle::SBPO_Never);
-  CHECK_PARSE("SpaceBeforeParens: Always", SpaceBeforeParens,
-              FormatStyle::SBPO_Always);
-  CHECK_PARSE("SpaceBeforeParens: ControlStatements", SpaceBeforeParens,
-              FormatStyle::SBPO_ControlStatements);
-  CHECK_PARSE("SpaceBeforeParens: ControlStatementsExceptControlMacros",
-              SpaceBeforeParens,
-              FormatStyle::SBPO_ControlStatementsExceptControlMacros);
-  CHECK_PARSE("SpaceBeforeParens: NonEmptyParentheses", SpaceBeforeParens,
-              FormatStyle::SBPO_NonEmptyParentheses);
-  CHECK_PARSE("SpaceBeforeParens: Custom", SpaceBeforeParens,
-              FormatStyle::SBPO_Custom);
-  // For backward compatibility:
-  CHECK_PARSE("SpaceAfterControlStatementKeyword: false", SpaceBeforeParens,
-              FormatStyle::SBPO_Never);
-  CHECK_PARSE("SpaceAfterControlStatementKeyword: true", SpaceBeforeParens,
-              FormatStyle::SBPO_ControlStatements);
-  CHECK_PARSE("SpaceBeforeParens: ControlStatementsExceptForEachMacros",
-              SpaceBeforeParens,
-              FormatStyle::SBPO_ControlStatementsExceptControlMacros);
-
-  Style.SpaceInEmptyBraces = FormatStyle::SIEB_Never;
-  CHECK_PARSE("SpaceInEmptyBraces: Always", SpaceInEmptyBraces,
-              FormatStyle::SIEB_Always);
-  CHECK_PARSE("SpaceInEmptyBraces: Block", SpaceInEmptyBraces,
-              FormatStyle::SIEB_Block);
-  CHECK_PARSE("SpaceInEmptyBraces: Never", SpaceInEmptyBraces,
-              FormatStyle::SIEB_Never);
-  // For backward compatibility:
-  CHECK_PARSE("SpaceInEmptyBlock: true", SpaceInEmptyBraces,
-              FormatStyle::SIEB_Block);
-
-  // For backward compatibility:
-  Style.SpacesInParens = FormatStyle::SIPO_Never;
-  Style.SpacesInParensOptions = {};
-  CHECK_PARSE("SpacesInParentheses: true", SpacesInParens,
-              FormatStyle::SIPO_Custom);
-  Style.SpacesInParens = FormatStyle::SIPO_Never;
-  Style.SpacesInParensOptions = {};
-  CHECK_PARSE(
-      "SpacesInParentheses: true", SpacesInParensOptions,
-      FormatStyle::SpacesInParensCustom(false, true, false, false, true));
-  Style.SpacesInParens = FormatStyle::SIPO_Never;
-  Style.SpacesInParensOptions = {};
-  CHECK_PARSE(
-      "SpacesInConditionalStatement: true", SpacesInParensOptions,
-      FormatStyle::SpacesInParensCustom(false, true, false, false, false));
-  Style.SpacesInParens = FormatStyle::SIPO_Never;
-  Style.SpacesInParensOptions = {};
-  CHECK_PARSE(
-      "SpacesInCStyleCastParentheses: true", SpacesInParensOptions,
-      FormatStyle::SpacesInParensCustom(false, false, true, false, false));
-  Style.SpacesInParens = FormatStyle::SIPO_Never;
-  Style.SpacesInParensOptions = {};
-  CHECK_PARSE(
-      "SpaceInEmptyParentheses: true", SpacesInParensOptions,
-      FormatStyle::SpacesInParensCustom(false, false, false, true, false));
-  Style.SpacesInParens = FormatStyle::SIPO_Never;
-  Style.SpacesInParensOptions = {};
-
-  Style.ColumnLimit = 123;
-  FormatStyle BaseStyle = getLLVMStyle();
-  CHECK_PARSE("BasedOnStyle: LLVM", ColumnLimit, BaseStyle.ColumnLimit);
-  CHECK_PARSE("BasedOnStyle: LLVM\nColumnLimit: 1234", ColumnLimit, 1234u);
-
-  Style.BreakBeforeBraces = FormatStyle::BS_Stroustrup;
-  CHECK_PARSE("BreakBeforeBraces: Attach", BreakBeforeBraces,
-              FormatStyle::BS_Attach);
-  CHECK_PARSE("BreakBeforeBraces: Linux", BreakBeforeBraces,
-              FormatStyle::BS_Linux);
-  CHECK_PARSE("BreakBeforeBraces: Mozilla", BreakBeforeBraces,
-              FormatStyle::BS_Mozilla);
-  CHECK_PARSE("BreakBeforeBraces: Stroustrup", BreakBeforeBraces,
-              FormatStyle::BS_Stroustrup);
-  CHECK_PARSE("BreakBeforeBraces: Allman", BreakBeforeBraces,
-              FormatStyle::BS_Allman);
-  CHECK_PARSE("BreakBeforeBraces: Whitesmiths", BreakBeforeBraces,
-              FormatStyle::BS_Whitesmiths);
-  CHECK_PARSE("BreakBeforeBraces: GNU", BreakBeforeBraces, FormatStyle::BS_GNU);
-  CHECK_PARSE("BreakBeforeBraces: WebKit", BreakBeforeBraces,
-              FormatStyle::BS_WebKit);
-  CHECK_PARSE("BreakBeforeBraces: Custom", BreakBeforeBraces,
-              FormatStyle::BS_Custom);
-
-  Style.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Never;
-  CHECK_PARSE("BraceWrapping:\n"
-              "  AfterControlStatement: MultiLine",
-              BraceWrapping.AfterControlStatement,
-              FormatStyle::BWACS_MultiLine);
-  CHECK_PARSE("BraceWrapping:\n"
-              "  AfterControlStatement: Always",
-              BraceWrapping.AfterControlStatement, FormatStyle::BWACS_Always);
-  CHECK_PARSE("BraceWrapping:\n"
-              "  AfterControlStatement: Never",
-              BraceWrapping.AfterControlStatement, FormatStyle::BWACS_Never);
-  // For backward compatibility:
-  CHECK_PARSE("BraceWrapping:\n"
-              "  AfterControlStatement: true",
-              BraceWrapping.AfterControlStatement, FormatStyle::BWACS_Always);
-  CHECK_PARSE("BraceWrapping:\n"
-              "  AfterControlStatement: false",
-              BraceWrapping.AfterControlStatement, FormatStyle::BWACS_Never);
-
-  Style.BreakAfterReturnType = FormatStyle::RTBS_All;
-  CHECK_PARSE("BreakAfterReturnType: None", BreakAfterReturnType,
-              FormatStyle::RTBS_None);
-  CHECK_PARSE("BreakAfterReturnType: Automatic", BreakAfterReturnType,
-              FormatStyle::RTBS_Automatic);
-  CHECK_PARSE("BreakAfterReturnType: ExceptShortType", BreakAfterReturnType,
-              FormatStyle::RTBS_ExceptShortType);
-  CHECK_PARSE("BreakAfterReturnType: All", BreakAfterReturnType,
-              FormatStyle::RTBS_All);
-  CHECK_PARSE("BreakAfterReturnType: TopLevel", BreakAfterReturnType,
-              FormatStyle::RTBS_TopLevel);
-  CHECK_PARSE("BreakAfterReturnType: AllDefinitions", BreakAfterReturnType,
-              FormatStyle::RTBS_AllDefinitions);
-  CHECK_PARSE("BreakAfterReturnType: TopLevelDefinitions", BreakAfterReturnType,
-              FormatStyle::RTBS_TopLevelDefinitions);
-  // For backward compatibility:
-  CHECK_PARSE("AlwaysBreakAfterReturnType: None", BreakAfterReturnType,
-              FormatStyle::RTBS_None);
-  CHECK_PARSE("AlwaysBreakAfterReturnType: Automatic", BreakAfterReturnType,
-              FormatStyle::RTBS_Automatic);
-  CHECK_PARSE("AlwaysBreakAfterReturnType: ExceptShortType",
-              BreakAfterReturnType, FormatStyle::RTBS_ExceptShortType);
-  CHECK_PARSE("AlwaysBreakAfterReturnType: All", BreakAfterReturnType,
-              FormatStyle::RTBS_All);
-  CHECK_PARSE("AlwaysBreakAfterReturnType: TopLevel", BreakAfterReturnType,
-              FormatStyle::RTBS_TopLevel);
-  CHECK_PARSE("AlwaysBreakAfterReturnType: AllDefinitions",
-              BreakAfterReturnType, FormatStyle::RTBS_AllDefinitions);
-  CHECK_PARSE("AlwaysBreakAfterReturnType: TopLevelDefinitions",
-              BreakAfterReturnType, FormatStyle::RTBS_TopLevelDefinitions);
-
-  Style.BreakTemplateDeclarations = FormatStyle::BTDS_Yes;
-  CHECK_PARSE("BreakTemplateDeclarations: Leave", BreakTemplateDeclarations,
-              FormatStyle::BTDS_Leave);
-  CHECK_PARSE("BreakTemplateDeclarations: No", BreakTemplateDeclarations,
-              FormatStyle::BTDS_No);
-  CHECK_PARSE("BreakTemplateDeclarations: MultiLine", BreakTemplateDeclarations,
-              FormatStyle::BTDS_MultiLine);
-  CHECK_PARSE("BreakTemplateDeclarations: Yes", BreakTemplateDeclarations,
-              FormatStyle::BTDS_Yes);
-  CHECK_PARSE("BreakTemplateDeclarations: false", BreakTemplateDeclarations,
-              FormatStyle::BTDS_MultiLine);
-  CHECK_PARSE("BreakTemplateDeclarations: true", BreakTemplateDeclarations,
-              FormatStyle::BTDS_Yes);
-  // For backward compatibility:
-  CHECK_PARSE("AlwaysBreakTemplateDeclarations: Leave",
-              BreakTemplateDeclarations, FormatStyle::BTDS_Leave);
-  CHECK_PARSE("AlwaysBreakTemplateDeclarations: No", BreakTemplateDeclarations,
-              FormatStyle::BTDS_No);
-  CHECK_PARSE("AlwaysBreakTemplateDeclarations: MultiLine",
-              BreakTemplateDeclarations, FormatStyle::BTDS_MultiLine);
-  CHECK_PARSE("AlwaysBreakTemplateDeclarations: Yes", BreakTemplateDeclarations,
-              FormatStyle::BTDS_Yes);
-  CHECK_PARSE("AlwaysBreakTemplateDeclarations: false",
-              BreakTemplateDeclarations, FormatStyle::BTDS_MultiLine);
-  CHECK_PARSE("AlwaysBreakTemplateDeclarations: true",
-              BreakTemplateDeclarations, FormatStyle::BTDS_Yes);
-
-  Style.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_All;
-  CHECK_PARSE("AlwaysBreakAfterDefinitionReturnType: None",
-              AlwaysBreakAfterDefinitionReturnType, FormatStyle::DRTBS_None);
-  CHECK_PARSE("AlwaysBreakAfterDefinitionReturnType: All",
-              AlwaysBreakAfterDefinitionReturnType, FormatStyle::DRTBS_All);
-  CHECK_PARSE("AlwaysBreakAfterDefinitionReturnType: TopLevel",
-              AlwaysBreakAfterDefinitionReturnType,
-              FormatStyle::DRTBS_TopLevel);
-
-  Style.NamespaceIndentation = FormatStyle::NI_All;
-  CHECK_PARSE("NamespaceIndentation: None", NamespaceIndentation,
-              FormatStyle::NI_None);
-  CHECK_PARSE("NamespaceIndentation: Inner", NamespaceIndentation,
-              FormatStyle::NI_Inner);
-  CHECK_PARSE("NamespaceIndentation: All", NamespaceIndentation,
-              FormatStyle::NI_All);
-
-  Style.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_OnlyFirstIf;
-  CHECK_PARSE("AllowShortIfStatementsOnASingleLine: Never",
-              AllowShortIfStatementsOnASingleLine, FormatStyle::SIS_Never);
-  CHECK_PARSE("AllowShortIfStatementsOnASingleLine: WithoutElse",
-              AllowShortIfStatementsOnASingleLine,
-              FormatStyle::SIS_WithoutElse);
-  CHECK_PARSE("AllowShortIfStatementsOnASingleLine: OnlyFirstIf",
-              AllowShortIfStatementsOnASingleLine,
-              FormatStyle::SIS_OnlyFirstIf);
-  CHECK_PARSE("AllowShortIfStatementsOnASingleLine: AllIfsAndElse",
-              AllowShortIfStatementsOnASingleLine,
-              FormatStyle::SIS_AllIfsAndElse);
-  CHECK_PARSE("AllowShortIfStatementsOnASingleLine: Always",
-              AllowShortIfStatementsOnASingleLine,
-              FormatStyle::SIS_OnlyFirstIf);
-  CHECK_PARSE("AllowShortIfStatementsOnASingleLine: false",
-              AllowShortIfStatementsOnASingleLine, FormatStyle::SIS_Never);
-  CHECK_PARSE("AllowShortIfStatementsOnASingleLine: true",
-              AllowShortIfStatementsOnASingleLine,
-              FormatStyle::SIS_WithoutElse);
-
-  Style.IndentExternBlock = FormatStyle::IEBS_NoIndent;
-  CHECK_PARSE("IndentExternBlock: AfterExternBlock", IndentExternBlock,
-              FormatStyle::IEBS_AfterExternBlock);
-  CHECK_PARSE("IndentExternBlock: Indent", IndentExternBlock,
-              FormatStyle::IEBS_Indent);
-  CHECK_PARSE("IndentExternBlock: NoIndent", IndentExternBlock,
-              FormatStyle::IEBS_NoIndent);
-  CHECK_PARSE("IndentExternBlock: true", IndentExternBlock,
-              FormatStyle::IEBS_Indent);
-  CHECK_PARSE("IndentExternBlock: false", IndentExternBlock,
-              FormatStyle::IEBS_NoIndent);
-
-  Style.IndentGotoLabels = FormatStyle::IGLS_OuterIndent;
-  CHECK_PARSE("IndentGotoLabels: NoIndent", IndentGotoLabels,
-              FormatStyle::IGLS_NoIndent);
-  CHECK_PARSE("IndentGotoLabels: OuterIndent", IndentGotoLabels,
-              FormatStyle::IGLS_OuterIndent);
-  CHECK_PARSE("IndentGotoLabels: InnerIndent", IndentGotoLabels,
-              FormatStyle::IGLS_InnerIndent);
-  CHECK_PARSE("IndentGotoLabels: HalfIndent", IndentGotoLabels,
-              FormatStyle::IGLS_HalfIndent);
-  CHECK_PARSE("IndentGotoLabels: false", IndentGotoLabels,
-              FormatStyle::IGLS_NoIndent);
-  CHECK_PARSE("IndentGotoLabels: true", IndentGotoLabels,
-              FormatStyle::IGLS_OuterIndent);
-
-  Style.BitFieldColonSpacing = FormatStyle::BFCS_None;
-  CHECK_PARSE("BitFieldColonSpacing: Both", BitFieldColonSpacing,
-              FormatStyle::BFCS_Both);
-  CHECK_PARSE("BitFieldColonSpacing: None", BitFieldColonSpacing,
-              FormatStyle::BFCS_None);
-  CHECK_PARSE("BitFieldColonSpacing: Before", BitFieldColonSpacing,
-              FormatStyle::BFCS_Before);
-  CHECK_PARSE("BitFieldColonSpacing: After", BitFieldColonSpacing,
-              FormatStyle::BFCS_After);
-
-  Style.SortJavaStaticImport = FormatStyle::SJSIO_Before;
-  CHECK_PARSE("SortJavaStaticImport: After", SortJavaStaticImport,
-              FormatStyle::SJSIO_After);
-  CHECK_PARSE("SortJavaStaticImport: Before", SortJavaStaticImport,
-              FormatStyle::SJSIO_Before);
-
-  Style.SortUsingDeclarations = FormatStyle::SUD_LexicographicNumeric;
-  CHECK_PARSE("SortUsingDeclarations: Never", SortUsingDeclarations,
-              FormatStyle::SUD_Never);
-  CHECK_PARSE("SortUsingDeclarations: Lexicographic", SortUsingDeclarations,
-              FormatStyle::SUD_Lexicographic);
-  CHECK_PARSE("SortUsingDeclarations: LexicographicNumeric",
-              SortUsingDeclarations, FormatStyle::SUD_LexicographicNumeric);
-  // For backward compatibility:
-  CHECK_PARSE("SortUsingDeclarations: false", SortUsingDeclarations,
-              FormatStyle::SUD_Never);
-  CHECK_PARSE("SortUsingDeclarations: true", SortUsingDeclarations,
-              FormatStyle::SUD_LexicographicNumeric);
-
-  CHECK_PARSE("WrapNamespaceBodyWithEmptyLines: Never",
-              WrapNamespaceBodyWithEmptyLines, FormatStyle::WNBWELS_Never);
-  CHECK_PARSE("WrapNamespaceBodyWithEmptyLines: Always",
-              WrapNamespaceBodyWithEmptyLines, FormatStyle::WNBWELS_Always);
-  CHECK_PARSE("WrapNamespaceBodyWithEmptyLines: Leave",
-              WrapNamespaceBodyWithEmptyLines, FormatStyle::WNBWELS_Leave);
-
-  // FIXME: This is required because parsing a configuration simply overwrites
-  // the first N elements of the list instead of resetting it.
-  Style.ForEachMacros.clear();
-  std::vector<std::string> BoostForeach;
-  BoostForeach.push_back("BOOST_FOREACH");
-  CHECK_PARSE("ForEachMacros: [BOOST_FOREACH]", ForEachMacros, BoostForeach);
-  std::vector<std::string> BoostAndQForeach;
-  BoostAndQForeach.push_back("BOOST_FOREACH");
-  BoostAndQForeach.push_back("Q_FOREACH");
-  CHECK_PARSE("ForEachMacros: [BOOST_FOREACH, Q_FOREACH]", ForEachMacros,
-              BoostAndQForeach);
-
-  Style.IfMacros.clear();
-  std::vector<std::string> CustomIfs;
-  CustomIfs.push_back("MYIF");
-  CHECK_PARSE("IfMacros: [MYIF]", IfMacros, CustomIfs);
-
-  Style.AttributeMacros.clear();
-  CHECK_PARSE("BasedOnStyle: LLVM", AttributeMacros,
-              std::vector<std::string>{"__capability"});
-  CHECK_PARSE(
-      "BasedOnStyle: Google", AttributeMacros,
-      std::vector<std::string>({"__capability", "absl_nonnull", "absl_nullable",
-                                "absl_nullability_unknown"}));
-  Style.AttributeMacros.clear();
-  CHECK_PARSE("AttributeMacros: [attr1, attr2]", AttributeMacros,
-              std::vector<std::string>({"attr1", "attr2"}));
-
-  Style.StatementAttributeLikeMacros.clear();
-  CHECK_PARSE("StatementAttributeLikeMacros: [emit,Q_EMIT]",
-              StatementAttributeLikeMacros,
-              std::vector<std::string>({"emit", "Q_EMIT"}));
-
-  Style.Macros.clear();
-  CHECK_PARSE("{Macros: [foo]}", Macros, std::vector<std::string>({"foo"}));
-  std::vector<std::string> GoogleMacros;
-  GoogleMacros.push_back("ASSIGN_OR_RETURN(a, b)=a = (b)");
-  GoogleMacros.push_back("ASSIGN_OR_RETURN(a, b, c)=a = (b); if (x) return c");
-  CHECK_PARSE("BasedOnStyle: Google", Macros, GoogleMacros);
-
-  Style.StatementMacros.clear();
-  CHECK_PARSE("StatementMacros: [QUNUSED]", StatementMacros,
-              std::vector<std::string>{"QUNUSED"});
-  CHECK_PARSE("StatementMacros: [QUNUSED, QT_REQUIRE_VERSION]", StatementMacros,
-              std::vector<std::string>({"QUNUSED", "QT_REQUIRE_VERSION"}));
-
-  CHECK_PARSE_LIST(JavaImportGroups);
-  CHECK_PARSE_LIST(MacrosSkippedByRemoveParentheses);
-  CHECK_PARSE_LIST(NamespaceMacros);
-  CHECK_PARSE_LIST(ObjCPropertyAttributeOrder);
-  CHECK_PARSE_LIST(TableGenBreakingDAGArgOperators);
-  CHECK_PARSE_LIST(TemplateNames);
-  CHECK_PARSE_LIST(TypeNames);
-  CHECK_PARSE_LIST(TypenameMacros);
-  CHECK_PARSE_LIST(VariableTemplates);
-
-  Style.WhitespaceSensitiveMacros.clear();
-  CHECK_PARSE("WhitespaceSensitiveMacros: [STRINGIZE]",
-              WhitespaceSensitiveMacros, std::vector<std::string>{"STRINGIZE"});
-  CHECK_PARSE("WhitespaceSensitiveMacros: [STRINGIZE, ASSERT]",
-              WhitespaceSensitiveMacros,
-              std::vector<std::string>({"STRINGIZE", "ASSERT"}));
-  Style.WhitespaceSensitiveMacros.clear();
-  CHECK_PARSE("WhitespaceSensitiveMacros: ['STRINGIZE']",
-              WhitespaceSensitiveMacros, std::vector<std::string>{"STRINGIZE"});
-  CHECK_PARSE("WhitespaceSensitiveMacros: ['STRINGIZE', 'ASSERT']",
-              WhitespaceSensitiveMacros,
-              std::vector<std::string>({"STRINGIZE", "ASSERT"}));
-
-  Style.IncludeStyle.IncludeCategories.clear();
-  std::vector<tooling::IncludeStyle::IncludeCategory> ExpectedCategories = {
-      {"abc/.*", 2, 0, false}, {".*", 1, 0, true}};
-  CHECK_PARSE("IncludeCategories:\n"
-              "  - Regex: abc/.*\n"
-              "    Priority: 2\n"
-              "  - Regex: .*\n"
-              "    Priority: 1\n"
-              "    CaseSensitive: true",
-              IncludeStyle.IncludeCategories, ExpectedCategories);
-  CHECK_PARSE("IncludeIsMainRegex: 'abc$'", IncludeStyle.IncludeIsMainRegex,
-              "abc$");
-  CHECK_PARSE("IncludeIsMainSourceRegex: 'abc$'",
-              IncludeStyle.IncludeIsMainSourceRegex, "abc$");
-
-  Style.SortIncludes = {};
-  CHECK_PARSE(
-      "SortIncludes: true", SortIncludes,
-      FormatStyle::SortIncludesOptions(
-          {/*Enabled=*/true, /*IgnoreCase=*/false, /*IgnoreExtension=*/false}));
-  CHECK_PARSE("SortIncludes: false", SortIncludes,
-              FormatStyle::SortIncludesOptions({}));
-  CHECK_PARSE(
-      "SortIncludes: CaseInsensitive", SortIncludes,
-      FormatStyle::SortIncludesOptions(
-          {/*Enabled=*/true, /*IgnoreCase=*/true, /*IgnoreExtension=*/false}));
-  CHECK_PARSE(
-      "SortIncludes: CaseSensitive", SortIncludes,
-      FormatStyle::SortIncludesOptions(
-          {/*Enabled=*/true, /*IgnoreCase=*/false, /*IgnoreExtension=*/false}));
-  CHECK_PARSE("SortIncludes: Never", SortIncludes,
-              FormatStyle::SortIncludesOptions({}));
-
-  Style.RawStringFormats.clear();
-  std::vector<FormatStyle::RawStringFormat> ExpectedRawStringFormats = {
-      {
-          FormatStyle::LK_TextProto,
-          {"pb", "proto"},
-          {"PARSE_TEXT_PROTO"},
-          /*CanonicalDelimiter=*/"",
-          "llvm",
-      },
-      {
-          FormatStyle::LK_Cpp,
-          {"cc", "cpp"},
-          {"C_CODEBLOCK", "CPPEVAL"},
-          /*CanonicalDelimiter=*/"cc",
-          /*BasedOnStyle=*/"",
-      },
+TEST_F(DefinitionBlockSeparatorTest, UntouchBlockStartStyle) {
+  // Returns a std::pair of two strings, with the first one for passing into
+  // Always test and the second one be the expected result of the first string.
+  auto MakeUntouchTest = [&](std::string BlockHeader, std::string BlockChanger,
+                             std::string BlockFooter, bool BlockEndNewLine) {
+    std::string CodePart1 = "enum Foo { FOO, BAR };\n"
+                            "\n"
+                            "/*\n"
+                            "test1\n"
+                            "test2\n"
+                            "*/\n"
+                            "int foo(int i, int j) {\n"
+                            "  int r = i + j;\n"
+                            "  return r;\n"
+                            "}\n";
+    std::string CodePart2 = "/* Comment block in one line*/\n"
+                            "enum Bar { FOOBAR, BARFOO };\n"
+                            "\n"
+                            "int bar3(int j, int k) {\n"
+                            "  // A comment\n"
+                            "  int r = j % k;\n"
+                            "  return r;\n"
+                            "}\n";
+    std::string CodePart3 = "int bar2(int j, int k) {\n"
+                            "  int r = j / k;\n"
+                            "  return r;\n"
+                            "}\n";
+    std::string ConcatAll = BlockHeader + CodePart1 + BlockChanger + CodePart2 +
+                            BlockFooter + (BlockEndNewLine ? "\n" : "") +
+                            CodePart3;
+    return std::make_pair(BlockHeader + removeEmptyLines(CodePart1) +
+                              BlockChanger + removeEmptyLines(CodePart2) +
+                              BlockFooter + removeEmptyLines(CodePart3),
+                          ConcatAll);
   };
 
-  CHECK_PARSE("RawStringFormats:\n"
-              "  - Language: TextProto\n"
-              "    Delimiters:\n"
-              "      - 'pb'\n"
-              "      - 'proto'\n"
-              "    EnclosingFunctions:\n"
-              "      - 'PARSE_TEXT_PROTO'\n"
-              "    BasedOnStyle: llvm\n"
-              "  - Language: Cpp\n"
-              "    Delimiters:\n"
-              "      - 'cc'\n"
-              "      - 'cpp'\n"
-              "    EnclosingFunctions:\n"
-              "      - 'C_CODEBLOCK'\n"
-              "      - 'CPPEVAL'\n"
-              "    CanonicalDelimiter: 'cc'",
-              RawStringFormats, ExpectedRawStringFormats);
-
-  CHECK_PARSE("SpacesInLineCommentPrefix:\n"
-              "  Minimum: 0\n"
-              "  Maximum: 0",
-              SpacesInLineCommentPrefix.Minimum, 0u);
-  EXPECT_EQ(Style.SpacesInLineCommentPrefix.Maximum, 0u);
-  Style.SpacesInLineCommentPrefix.Minimum = 1;
-  CHECK_PARSE("SpacesInLineCommentPrefix:\n"
-              "  Minimum: 2",
-              SpacesInLineCommentPrefix.Minimum, 0u);
-  CHECK_PARSE("SpacesInLineCommentPrefix:\n"
-              "  Maximum: -1",
-              SpacesInLineCommentPrefix.Maximum, -1u);
-  CHECK_PARSE("SpacesInLineCommentPrefix:\n"
-              "  Minimum: 2",
-              SpacesInLineCommentPrefix.Minimum, 2u);
-  CHECK_PARSE("SpacesInLineCommentPrefix:\n"
-              "  Maximum: 1",
-              SpacesInLineCommentPrefix.Maximum, 1u);
-  EXPECT_EQ(Style.SpacesInLineCommentPrefix.Minimum, 1u);
-
-  Style.SpacesInAngles = FormatStyle::SIAS_Always;
-  CHECK_PARSE("SpacesInAngles: Never", SpacesInAngles, FormatStyle::SIAS_Never);
-  CHECK_PARSE("SpacesInAngles: Always", SpacesInAngles,
-              FormatStyle::SIAS_Always);
-  CHECK_PARSE("SpacesInAngles: Leave", SpacesInAngles, FormatStyle::SIAS_Leave);
-  // For backward compatibility:
-  CHECK_PARSE("SpacesInAngles: false", SpacesInAngles, FormatStyle::SIAS_Never);
-  CHECK_PARSE("SpacesInAngles: true", SpacesInAngles, FormatStyle::SIAS_Always);
-
-  CHECK_PARSE("RequiresClausePosition: WithPreceding", RequiresClausePosition,
-              FormatStyle::RCPS_WithPreceding);
-  CHECK_PARSE("RequiresClausePosition: WithFollowing", RequiresClausePosition,
-              FormatStyle::RCPS_WithFollowing);
-  CHECK_PARSE("RequiresClausePosition: SingleLine", RequiresClausePosition,
-              FormatStyle::RCPS_SingleLine);
-  CHECK_PARSE("RequiresClausePosition: OwnLine", RequiresClausePosition,
-              FormatStyle::RCPS_OwnLine);
-
-  CHECK_PARSE("BreakBeforeConceptDeclarations: Never",
-              BreakBeforeConceptDeclarations, FormatStyle::BBCDS_Never);
-  CHECK_PARSE("BreakBeforeConceptDeclarations: Always",
-              BreakBeforeConceptDeclarations, FormatStyle::BBCDS_Always);
-  CHECK_PARSE("BreakBeforeConceptDeclarations: Allowed",
-              BreakBeforeConceptDeclarations, FormatStyle::BBCDS_Allowed);
-  // For backward compatibility:
-  CHECK_PARSE("BreakBeforeConceptDeclarations: true",
-              BreakBeforeConceptDeclarations, FormatStyle::BBCDS_Always);
-  CHECK_PARSE("BreakBeforeConceptDeclarations: false",
-              BreakBeforeConceptDeclarations, FormatStyle::BBCDS_Allowed);
-
-  CHECK_PARSE("BreakAfterAttributes: Always", BreakAfterAttributes,
-              FormatStyle::ABS_Always);
-  CHECK_PARSE("BreakAfterAttributes: Leave", BreakAfterAttributes,
-              FormatStyle::ABS_Leave);
-  CHECK_PARSE("BreakAfterAttributes: Never", BreakAfterAttributes,
-              FormatStyle::ABS_Never);
-
-  const auto DefaultLineEnding = FormatStyle::LE_DeriveLF;
-  CHECK_PARSE("LineEnding: LF", LineEnding, FormatStyle::LE_LF);
-  CHECK_PARSE("LineEnding: CRLF", LineEnding, FormatStyle::LE_CRLF);
-  CHECK_PARSE("LineEnding: DeriveCRLF", LineEnding, FormatStyle::LE_DeriveCRLF);
-  CHECK_PARSE("LineEnding: DeriveLF", LineEnding, DefaultLineEnding);
-  // For backward compatibility:
-  CHECK_PARSE("DeriveLineEnding: false", LineEnding, FormatStyle::LE_LF);
-  Style.LineEnding = DefaultLineEnding;
-  CHECK_PARSE("DeriveLineEnding: false\n"
-              "UseCRLF: true",
-              LineEnding, FormatStyle::LE_CRLF);
-  Style.LineEnding = DefaultLineEnding;
-  CHECK_PARSE("UseCRLF: true", LineEnding, FormatStyle::LE_DeriveCRLF);
-
-  CHECK_PARSE("RemoveParentheses: MultipleParentheses", RemoveParentheses,
-              FormatStyle::RPS_MultipleParentheses);
-  CHECK_PARSE("RemoveParentheses: ReturnStatement", RemoveParentheses,
-              FormatStyle::RPS_ReturnStatement);
-  CHECK_PARSE("RemoveParentheses: Leave", RemoveParentheses,
-              FormatStyle::RPS_Leave);
-
-  CHECK_PARSE("AllowBreakBeforeNoexceptSpecifier: Always",
-              AllowBreakBeforeNoexceptSpecifier, FormatStyle::BBNSS_Always);
-  CHECK_PARSE("AllowBreakBeforeNoexceptSpecifier: OnlyWithParen",
-              AllowBreakBeforeNoexceptSpecifier,
-              FormatStyle::BBNSS_OnlyWithParen);
-  CHECK_PARSE("AllowBreakBeforeNoexceptSpecifier: Never",
-              AllowBreakBeforeNoexceptSpecifier, FormatStyle::BBNSS_Never);
-
-  Style.SeparateDefinitionBlocks = FormatStyle::SDS_Never;
-  CHECK_PARSE("SeparateDefinitionBlocks: Always", SeparateDefinitionBlocks,
-              FormatStyle::SDS_Always);
-  CHECK_PARSE("SeparateDefinitionBlocks: Leave", SeparateDefinitionBlocks,
-              FormatStyle::SDS_Leave);
-  CHECK_PARSE("SeparateDefinitionBlocks: Never", SeparateDefinitionBlocks,
-              FormatStyle::SDS_Never);
-
-  CHECK_PARSE("Cpp11BracedListStyle: Block", Cpp11BracedListStyle,
-              FormatStyle::BLS_Block);
-  CHECK_PARSE("Cpp11BracedListStyle: FunctionCall", Cpp11BracedListStyle,
-              FormatStyle::BLS_FunctionCall);
-  CHECK_PARSE("Cpp11BracedListStyle: AlignFirstComment", Cpp11BracedListStyle,
-              FormatStyle::BLS_AlignFirstComment);
-  // For backward compatibility:
-  CHECK_PARSE("Cpp11BracedListStyle: false", Cpp11BracedListStyle,
-              FormatStyle::BLS_Block);
-  CHECK_PARSE("Cpp11BracedListStyle: true", Cpp11BracedListStyle,
-              FormatStyle::BLS_AlignFirstComment);
-
-  constexpr FormatStyle::IntegerLiteralSeparatorStyle
-      ExpectedIntegerLiteralSeparatorStyle{/*Binary=*/2,
-                                           /*BinaryMinDigitInsert=*/5,
-                                           /*BinaryMaxDigitRemove=*/2,
-                                           /*Decimal=*/6,
-                                           /*DecimalMinDigitInsert=*/6,
-                                           /*DecimalMaxDigitRemove=*/3,
-                                           /*Hex=*/4,
-                                           /*HexMinDigitInsert=*/2,
-                                           /*HexMaxDigitRemove=*/1};
-  CHECK_PARSE("IntegerLiteralSeparator:\n"
-              "  Binary: 2\n"
-              "  BinaryMinDigitsInsert: 5\n"
-              "  BinaryMaxDigitsRemove: 2\n"
-              "  Decimal: 6\n"
-              "  DecimalMinDigitsInsert: 6\n"
-              "  DecimalMaxDigitsRemove: 3\n"
-              "  Hex: 4\n"
-              "  HexMinDigitsInsert: 2\n"
-              "  HexMaxDigitsRemove: 1",
-              IntegerLiteralSeparator, ExpectedIntegerLiteralSeparatorStyle);
-
-  // Backward compatibility:
-  CHECK_PARSE_NESTED_VALUE("BinaryMinDigits: 6", IntegerLiteralSeparator,
-                           BinaryMinDigitsInsert, 6);
-  CHECK_PARSE_NESTED_VALUE("DecimalMinDigits: 5", IntegerLiteralSeparator,
-                           DecimalMinDigitsInsert, 5);
-  CHECK_PARSE_NESTED_VALUE("HexMinDigits: 5", IntegerLiteralSeparator,
-                           HexMinDigitsInsert, 5);
+  FormatStyle AlwaysStyle = getLLVMStyle();
+  AlwaysStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
+
+  FormatStyle NeverStyle = getLLVMStyle();
+  NeverStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Never;
+
+  auto TestKit = MakeUntouchTest("/* FOOBAR */\n"
+                                 "#ifdef FOO\n\n",
+                                 "\n#elifndef BAR\n\n", "\n#endif\n\n", false);
+  verifyFormat(TestKit.first, AlwaysStyle, TestKit.second);
+  verifyFormat(TestKit.second, NeverStyle, removeEmptyLines(TestKit.second));
+
+  TestKit = MakeUntouchTest("/* FOOBAR */\n"
+                            "#ifdef FOO\n",
+                            "#elifndef BAR\n", "#endif\n", false);
+  verifyFormat(TestKit.first, AlwaysStyle, TestKit.second);
+  verifyFormat(TestKit.second, NeverStyle, removeEmptyLines(TestKit.second));
+
+  TestKit = MakeUntouchTest("namespace Ns {\n\n",
+                            "\n} // namespace Ns\n\n"
+                            "namespace {\n\n",
+                            "\n} // namespace\n", true);
+  verifyFormat(TestKit.first, AlwaysStyle, TestKit.second);
+  verifyFormat(TestKit.second, NeverStyle, removeEmptyLines(TestKit.second));
+
+  TestKit = MakeUntouchTest("namespace Ns {\n",
+                            "} // namespace Ns\n\n"
+                            "namespace {\n",
+                            "} // namespace\n", true);
+  verifyFormat(TestKit.first, AlwaysStyle, TestKit.second);
+  verifyFormat(TestKit.second, NeverStyle, removeEmptyLines(TestKit.second));
 }
 
-TEST(ConfigParseTest, ParsesConfigurationWithLanguages) {
-  FormatStyle Style = {};
-  Style.Language = FormatStyle::LK_Cpp;
-  CHECK_PARSE("Language: Cpp\n"
-              "IndentWidth: 12",
-              IndentWidth, 12u);
-  EXPECT_EQ(parseConfiguration("Language: JavaScript\n"
-                               "IndentWidth: 34",
-                               &Style),
-            ParseError::Unsuitable);
-  FormatStyle BinPackedTCS = {};
-  BinPackedTCS.Language = FormatStyle::LK_JavaScript;
-  EXPECT_EQ(parseConfiguration("BinPackArguments: true\n"
-                               "InsertTrailingCommas: Wrapped",
-                               &BinPackedTCS),
-            ParseError::BinPackTrailingCommaConflict);
-  EXPECT_EQ(12u, Style.IndentWidth);
-  CHECK_PARSE("IndentWidth: 56", IndentWidth, 56u);
-  EXPECT_EQ(FormatStyle::LK_Cpp, Style.Language);
-
-  Style.Language = FormatStyle::LK_JavaScript;
-  CHECK_PARSE("Language: JavaScript\n"
-              "IndentWidth: 12",
-              IndentWidth, 12u);
-  CHECK_PARSE("IndentWidth: 23", IndentWidth, 23u);
-  EXPECT_EQ(parseConfiguration("Language: Cpp\n"
-                               "IndentWidth: 34",
-                               &Style),
-            ParseError::Unsuitable);
-  EXPECT_EQ(23u, Style.IndentWidth);
-  CHECK_PARSE("IndentWidth: 56", IndentWidth, 56u);
-  EXPECT_EQ(FormatStyle::LK_JavaScript, Style.Language);
-
-  CHECK_PARSE("BasedOnStyle: LLVM\n"
-              "IndentWidth: 67",
-              IndentWidth, 67u);
-
-  CHECK_PARSE("---\n"
-              "Language: JavaScript\n"
-              "IndentWidth: 12\n"
-              "---\n"
-              "Language: Cpp\n"
-              "IndentWidth: 34\n"
-              "...\n",
-              IndentWidth, 12u);
-
-  Style.Language = FormatStyle::LK_Cpp;
-  CHECK_PARSE("---\n"
-              "Language: JavaScript\n"
-              "IndentWidth: 12\n"
-              "---\n"
-              "Language: Cpp\n"
-              "IndentWidth: 34\n"
-              "...\n",
-              IndentWidth, 34u);
-  CHECK_PARSE("---\n"
-              "IndentWidth: 78\n"
-              "---\n"
-              "Language: JavaScript\n"
-              "IndentWidth: 56\n"
-              "...\n",
-              IndentWidth, 78u);
-
-  Style.ColumnLimit = 123;
-  Style.IndentWidth = 234;
-  Style.BreakBeforeBraces = FormatStyle::BS_Linux;
-  Style.TabWidth = 345;
-  EXPECT_FALSE(parseConfiguration("---\n"
-                                  "IndentWidth: 456\n"
-                                  "BreakBeforeBraces: Allman\n"
-                                  "---\n"
-                                  "Language: JavaScript\n"
-                                  "IndentWidth: 111\n"
-                                  "TabWidth: 111\n"
-                                  "---\n"
-                                  "Language: Cpp\n"
-                                  "BreakBeforeBraces: Stroustrup\n"
-                                  "TabWidth: 789\n"
-                                  "...\n",
-                                  &Style));
-  EXPECT_EQ(123u, Style.ColumnLimit);
-  EXPECT_EQ(456u, Style.IndentWidth);
-  EXPECT_EQ(FormatStyle::BS_Stroustrup, Style.BreakBeforeBraces);
-  EXPECT_EQ(789u, Style.TabWidth);
-
-  EXPECT_EQ(parseConfiguration("---\n"
-                               "Language: JavaScript\n"
-                               "IndentWidth: 56\n"
-                               "---\n"
-                               "IndentWidth: 78\n"
-                               "...\n",
-                               &Style),
-            ParseError::Error);
-  EXPECT_EQ(parseConfiguration("---\n"
-                               "Language: JavaScript\n"
-                               "IndentWidth: 56\n"
-                               "---\n"
-                               "Language: JavaScript\n"
-                               "IndentWidth: 78\n"
-                               "...\n",
-                               &Style),
-            ParseError::Error);
-
-  EXPECT_EQ(FormatStyle::LK_Cpp, Style.Language);
-
-  Style.Language = FormatStyle::LK_Verilog;
-  CHECK_PARSE("---\n"
-              "Language: Verilog\n"
-              "IndentWidth: 12\n"
-              "---\n"
-              "Language: Cpp\n"
-              "IndentWidth: 34\n"
-              "...\n",
-              IndentWidth, 12u);
-  CHECK_PARSE("---\n"
-              "IndentWidth: 78\n"
-              "---\n"
-              "Language: Verilog\n"
-              "IndentWidth: 56\n"
-              "...\n",
-              IndentWidth, 56u);
-}
-
-TEST(ConfigParseTest, AllowCommentOnlyConfigFile) {
-  FormatStyle Style = {};
-  Style.Language = FormatStyle::LK_Cpp;
-  EXPECT_EQ(parseConfiguration("#Language: C", &Style), ParseError::Success);
-  EXPECT_EQ(Style.Language, FormatStyle::LK_Cpp);
-}
-
-TEST(ConfigParseTest, AllowCppForC) {
-  FormatStyle Style = {};
-  Style.Language = FormatStyle::LK_C;
-  EXPECT_EQ(parseConfiguration("Language: Cpp", &Style), ParseError::Success);
-
-  CHECK_PARSE("---\n"
-              "IndentWidth: 4\n"
-              "---\n"
-              "Language: Cpp\n"
-              "IndentWidth: 8\n",
-              IndentWidth, 8u);
-
-  EXPECT_EQ(parseConfiguration("---\n"
-                               "Language: ObjC\n"
-                               "---\n"
-                               "Language: Cpp\n",
-                               &Style),
-            ParseError::Success);
-}
-
-TEST(ConfigParseTest, HandleDotHFile) {
-  FormatStyle Style = {};
-  Style.Language = FormatStyle::LK_Cpp;
-  EXPECT_EQ(parseConfiguration("Language: C", &Style,
-                               /*AllowUnknownOptions=*/false,
-                               /*IsDotHFile=*/true),
-            ParseError::Success);
-  EXPECT_EQ(Style.Language, FormatStyle::LK_C);
-
-  Style = {};
-  Style.Language = FormatStyle::LK_Cpp;
-  EXPECT_EQ(parseConfiguration("Language: Cpp\n"
-                               "...\n"
-                               "Language: C",
-                               &Style,
-                               /*AllowUnknownOptions=*/false,
-                               /*IsDotHFile=*/true),
-            ParseError::Success);
-  EXPECT_EQ(Style.Language, FormatStyle::LK_Cpp);
-}
-
-TEST(ConfigParseTest, UsesLanguageForBasedOnStyle) {
-  FormatStyle Style = {};
-  Style.Language = FormatStyle::LK_JavaScript;
-  Style.BreakBeforeTernaryOperators = true;
-  EXPECT_EQ(0, parseConfiguration("BasedOnStyle: Google", &Style).value());
-  EXPECT_FALSE(Style.BreakBeforeTernaryOperators);
-
-  Style.BreakBeforeTernaryOperators = true;
-  EXPECT_EQ(0, parseConfiguration("---\n"
-                                  "BasedOnStyle: Google\n"
-                                  "---\n"
-                                  "Language: JavaScript\n"
-                                  "IndentWidth: 76\n"
-                                  "...\n",
-                                  &Style)
-                   .value());
-  EXPECT_FALSE(Style.BreakBeforeTernaryOperators);
-  EXPECT_EQ(76u, Style.IndentWidth);
-  EXPECT_EQ(FormatStyle::LK_JavaScript, Style.Language);
+TEST_F(DefinitionBlockSeparatorTest, Always) {
+  FormatStyle Style = getLLVMStyle();
+  Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
+
+  verifyFormat("// clang-format off\n"
+               "template<class T>\n"
+               "concept C = not A<S<T>>;\n"
+               "// clang-format on\n"
+               "\n"
+               "struct E {};",
+               Style);
+
+  std::string Prefix = "namespace {\n";
+  std::string Infix = "\n"
+                      "// Enum test1\n"
+                      "// Enum test2\n"
+                      "enum Foo { FOO, BAR };\n"
+                      "\n"
+                      "/*\n"
+                      "test1\n"
+                      "test2\n"
+                      "*/\n"
+                      "/*const*/ int foo(int i, int j) {\n"
+                      "  int r = i + j;\n"
+                      "  return r;\n"
+                      "}\n"
+                      "\n"
+                      "// Foobar\n"
+                      "int i, j, k;\n"
+                      "\n"
+                      "// Comment for function\n"
+                      "// Comment line 2\n"
+                      "// Comment line 3\n"
+                      "int bar(int j, int k) {\n"
+                      "  {\n"
+                      "    int r = j * k;\n"
+                      "    return r;\n"
+                      "  }\n"
+                      "}\n"
+                      "\n"
+                      "int bar2(int j, int k) {\n"
+                      "  int r = j / k;\n"
+                      "  return r;\n"
+                      "}\n"
+                      "\n"
+                      "/* Comment block in one line*/\n"
+                      "enum Bar { FOOBAR, BARFOO };\n"
+                      "\n"
+                      "int bar3(int j, int k, const enum Bar b) {\n"
+                      "  // A comment\n"
+                      "  int r = j % k;\n"
+                      "  if (struct S = getS()) {\n"
+                      "    // if condition\n"
+                      "  }\n"
+                      "  return r;\n"
+                      "}\n";
+  std::string Postfix = "\n"
+                        "} // namespace\n"
+                        "\n"
+                        "namespace T {\n"
+                        "int i, j, k;\n"
+                        "} // namespace T";
+  verifyFormat(Prefix + removeEmptyLines(Infix) + removeEmptyLines(Postfix),
+               Style, Prefix + Infix + Postfix);
 }
 
-TEST(ConfigParseTest, ConfigurationRoundTripTest) {
+TEST_F(DefinitionBlockSeparatorTest, Never) {
   FormatStyle Style = getLLVMStyle();
-  std::string YAML = configurationAsText(Style);
-  FormatStyle ParsedStyle = {};
-  ParsedStyle.Language = FormatStyle::LK_Cpp;
-  EXPECT_EQ(0, parseConfiguration(YAML, &ParsedStyle).value());
-  EXPECT_EQ(Style, ParsedStyle);
+  Style.SeparateDefinitionBlocks = FormatStyle::SDS_Never;
+  std::string Prefix = "namespace {\n";
+  std::string Postfix = "// Enum test1\n"
+                        "// Enum test2\n"
+                        "enum Foo { FOO, BAR };\n"
+                        "\n"
+                        "/*\n"
+                        "test1\n"
+                        "test2\n"
+                        "*/\n"
+                        "/*const*/ int foo(int i, int j) {\n"
+                        "  int r = i + j;\n"
+                        "  return r;\n"
+                        "}\n"
+                        "\n"
+                        "// Foobar\n"
+                        "int i, j, k;\n"
+                        "\n"
+                        "// Comment for function\n"
+                        "// Comment line 2\n"
+                        "// Comment line 3\n"
+                        "int bar(int j, int k) {\n"
+                        "  {\n"
+                        "    int r = j * k;\n"
+                        "    return r;\n"
+                        "  }\n"
+                        "}\n"
+                        "\n"
+                        "int bar2(int j, int k) {\n"
+                        "  int r = j / k;\n"
+                        "  return r;\n"
+                        "}\n"
+                        "\n"
+                        "/* Comment block in one line*/\n"
+                        "enum Bar { FOOBAR, BARFOO };\n"
+                        "\n"
+                        "int bar3(int j, int k, const enum Bar b) {\n"
+                        "  // A comment\n"
+                        "  int r = j % k;\n"
+                        "  if (struct S = getS()) {\n"
+                        "    // if condition\n"
+                        "  }\n"
+                        "  return r;\n"
+                        "}\n"
+                        "} // namespace";
+  verifyFormat(Prefix + "\n\n\n" + Postfix, Style,
+               Prefix + removeEmptyLines(Postfix));
 }
 
-TEST(ConfigParseTest, GetStyleWithEmptyFileName) {
-  llvm::vfs::InMemoryFileSystem FS;
-  auto Style1 = getStyle("file", "", "Google", "", &FS);
-  ASSERT_TRUE((bool)Style1);
-  ASSERT_EQ(*Style1, getGoogleStyle());
+TEST_F(DefinitionBlockSeparatorTest, OpeningBracketOwnsLine) {
+  FormatStyle Style = getLLVMStyle();
+  Style.BreakBeforeBraces = FormatStyle::BS_Allman;
+  Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
+  verifyFormat("namespace NS\n"
+               "{\n"
+               "// Enum test1\n"
+               "// Enum test2\n"
+               "enum Foo\n"
+               "{\n"
+               "  FOO,\n"
+               "  BAR\n"
+               "};\n"
+               "\n"
+               "/*\n"
+               "test1\n"
+               "test2\n"
+               "*/\n"
+               "/*const*/ int foo(int i, int j)\n"
+               "{\n"
+               "  int r = i + j;\n"
+               "  return r;\n"
+               "}\n"
+               "\n"
+               "// Foobar\n"
+               "int i, j, k;\n"
+               "\n"
+               "// Comment for function\n"
+               "// Comment line 2\n"
+               "// Comment line 3\n"
+               "int bar(int j, int k)\n"
+               "{\n"
+               "  {\n"
+               "    int r = j * k;\n"
+               "    return r;\n"
+               "  }\n"
+               "}\n"
+               "\n"
+               "int bar2(int j, int k)\n"
+               "{\n"
+               "  int r = j / k;\n"
+               "  return r;\n"
+               "}\n"
+               "\n"
+               "enum Bar\n"
+               "{\n"
+               "  FOOBAR,\n"
+               "  BARFOO\n"
+               "};\n"
+               "\n"
+               "int bar3(int j, int k, const enum Bar b)\n"
+               "{\n"
+               "  // A comment\n"
+               "  int r = j % k;\n"
+               "  if (struct S = getS())\n"
+               "  {\n"
+               "    // if condition\n"
+               "  }\n"
+               "  return r;\n"
+               "}\n"
+               "} // namespace NS",
+               Style);
 }
 
-TEST(ConfigParseTest, GetStyleOfFile) {
-  llvm::vfs::InMemoryFileSystem FS;
-  // Test 1: format file in the same directory.
-  ASSERT_TRUE(
-      FS.addFile("/a/.clang-format", 0,
-                 llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: LLVM")));
-  ASSERT_TRUE(
-      FS.addFile("/a/test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int i;")));
-  auto Style1 = getStyle("file", "/a/.clang-format", "Google", "", &FS);
-  ASSERT_TRUE((bool)Style1);
-  ASSERT_EQ(*Style1, getLLVMStyle());
-
-  // Test 2.1: fallback to default.
-  ASSERT_TRUE(
-      FS.addFile("/b/test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int i;")));
-  auto Style2 = getStyle("file", "/b/test.cpp", "Mozilla", "", &FS);
-  ASSERT_TRUE((bool)Style2);
-  ASSERT_EQ(*Style2, getMozillaStyle());
-
-  // Test 2.2: no format on 'none' fallback style.
-  Style2 = getStyle("file", "/b/test.cpp", "none", "", &FS);
-  ASSERT_TRUE((bool)Style2);
-  ASSERT_EQ(*Style2, getNoStyle());
-
-  // Test 2.3: format if config is found with no based style while fallback is
-  // 'none'.
-  ASSERT_TRUE(FS.addFile("/b/.clang-format", 0,
-                         llvm::MemoryBuffer::getMemBuffer("IndentWidth: 2")));
-  Style2 = getStyle("file", "/b/test.cpp", "none", "", &FS);
-  ASSERT_TRUE((bool)Style2);
-  ASSERT_EQ(*Style2, getLLVMStyle());
-
-  // Test 2.4: format if yaml with no based style, while fallback is 'none'.
-  Style2 = getStyle("{}", "a.h", "none", "", &FS);
-  ASSERT_TRUE((bool)Style2);
-  ASSERT_EQ(*Style2, getLLVMStyle());
-
-  // Test 3: format file in parent directory.
-  ASSERT_TRUE(
-      FS.addFile("/c/.clang-format", 0,
-                 llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: Google")));
-  ASSERT_TRUE(FS.addFile("/c/sub/sub/sub/test.cpp", 0,
-                         llvm::MemoryBuffer::getMemBuffer("int i;")));
-  auto Style3 = getStyle("file", "/c/sub/sub/sub/test.cpp", "LLVM", "", &FS);
-  ASSERT_TRUE((bool)Style3);
-  ASSERT_EQ(*Style3, getGoogleStyle());
-
-  // Test 4: error on invalid fallback style
-  auto Style4 = getStyle("file", "a.h", "KungFu", "", &FS);
-  ASSERT_FALSE((bool)Style4);
-  llvm::consumeError(Style4.takeError());
-
-  // Test 5: error on invalid yaml on command line
-  auto Style5 = getStyle("{invalid_key=invalid_value}", "a.h", "LLVM", "", &FS,
-                         /*AllowUnknownOptions=*/false, dropDiagnosticHandler);
-  ASSERT_FALSE((bool)Style5);
-  llvm::consumeError(Style5.takeError());
-
-  // Test 6: error on invalid style
-  auto Style6 = getStyle("KungFu", "a.h", "LLVM", "", &FS);
-  ASSERT_FALSE((bool)Style6);
-  llvm::consumeError(Style6.takeError());
-
-  // Test 7: found config file, error on parsing it
-  ASSERT_TRUE(
-      FS.addFile("/d/.clang-format", 0,
-                 llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: LLVM\n"
-                                                  "InvalidKey: InvalidValue")));
-  ASSERT_TRUE(
-      FS.addFile("/d/test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int i;")));
-  auto Style7a = getStyle("file", "/d/.clang-format", "LLVM", "", &FS,
-                          /*AllowUnknownOptions=*/false, dropDiagnosticHandler);
-  ASSERT_FALSE((bool)Style7a);
-  llvm::consumeError(Style7a.takeError());
-
-  auto Style7b = getStyle("file", "/d/.clang-format", "LLVM", "", &FS,
-                          /*AllowUnknownOptions=*/true, dropDiagnosticHandler);
-  ASSERT_TRUE((bool)Style7b);
-
-  // Test 8: inferred per-language defaults apply.
-  auto StyleTd = getStyle("file", "x.td", "llvm", "", &FS);
-  ASSERT_TRUE((bool)StyleTd);
-  ASSERT_EQ(*StyleTd, getLLVMStyle(FormatStyle::LK_TableGen));
-
-  // Test 9.1.1: overwriting a file style, when no parent file exists with no
-  // fallback style.
-  ASSERT_TRUE(FS.addFile(
-      "/e/sub/.clang-format", 0,
-      llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: InheritParentConfig\n"
-                                       "ColumnLimit: 20")));
-  ASSERT_TRUE(FS.addFile("/e/sub/code.cpp", 0,
-                         llvm::MemoryBuffer::getMemBuffer("int i;")));
-  auto Style9 = getStyle("file", "/e/sub/code.cpp", "none", "", &FS);
-  ASSERT_TRUE(static_cast<bool>(Style9));
-  ASSERT_EQ(*Style9, [] {
-    auto Style = getNoStyle();
-    Style.ColumnLimit = 20;
-    return Style;
-  }());
-
-  // Test 9.1.2: propagate more than one level with no parent file.
-  ASSERT_TRUE(FS.addFile("/e/sub/sub/code.cpp", 0,
-                         llvm::MemoryBuffer::getMemBuffer("int i;")));
-  ASSERT_TRUE(FS.addFile("/e/sub/sub/.clang-format", 0,
-                         llvm::MemoryBuffer::getMemBuffer(
-                             "BasedOnStyle: InheritParentConfig\n"
-                             "WhitespaceSensitiveMacros: ['FOO', 'BAR']")));
-  std::vector<std::string> NonDefaultWhiteSpaceMacros =
-      Style9->WhitespaceSensitiveMacros;
-  NonDefaultWhiteSpaceMacros[0] = "FOO";
-  NonDefaultWhiteSpaceMacros[1] = "BAR";
-
-  ASSERT_NE(Style9->WhitespaceSensitiveMacros, NonDefaultWhiteSpaceMacros);
-  Style9 = getStyle("file", "/e/sub/sub/code.cpp", "none", "", &FS);
-  ASSERT_TRUE(static_cast<bool>(Style9));
-  ASSERT_EQ(*Style9, [&NonDefaultWhiteSpaceMacros] {
-    auto Style = getNoStyle();
-    Style.ColumnLimit = 20;
-    Style.WhitespaceSensitiveMacros = NonDefaultWhiteSpaceMacros;
-    return Style;
-  }());
-
-  // Test 9.2: with LLVM fallback style
-  Style9 = getStyle("file", "/e/sub/code.cpp", "LLVM", "", &FS);
-  ASSERT_TRUE(static_cast<bool>(Style9));
-  ASSERT_EQ(*Style9, [] {
-    auto Style = getLLVMStyle();
-    Style.ColumnLimit = 20;
-    return Style;
-  }());
-
-  // Test 9.3: with a parent file
-  ASSERT_TRUE(
-      FS.addFile("/e/.clang-format", 0,
-                 llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: Google\n"
-                                                  "UseTab: Always")));
-  Style9 = getStyle("file", "/e/sub/code.cpp", "none", "", &FS);
-  ASSERT_TRUE(static_cast<bool>(Style9));
-  ASSERT_EQ(*Style9, [] {
-    auto Style = getGoogleStyle();
-    Style.ColumnLimit = 20;
-    Style.UseTab = FormatStyle::UT_Always;
-    return Style;
-  }());
-
-  // Test 9.4: propagate more than one level with a parent file.
-  const auto SubSubStyle = [&NonDefaultWhiteSpaceMacros] {
-    auto Style = getGoogleStyle();
-    Style.ColumnLimit = 20;
-    Style.UseTab = FormatStyle::UT_Always;
-    Style.WhitespaceSensitiveMacros = NonDefaultWhiteSpaceMacros;
-    return Style;
-  }();
-
-  ASSERT_NE(Style9->WhitespaceSensitiveMacros, NonDefaultWhiteSpaceMacros);
-  Style9 = getStyle("file", "/e/sub/sub/code.cpp", "none", "", &FS);
-  ASSERT_TRUE(static_cast<bool>(Style9));
-  ASSERT_EQ(*Style9, SubSubStyle);
-
-  // Test 9.5: use InheritParentConfig as style name
-  Style9 =
-      getStyle("inheritparentconfig", "/e/sub/sub/code.cpp", "none", "", &FS);
-  ASSERT_TRUE(static_cast<bool>(Style9));
-  ASSERT_EQ(*Style9, SubSubStyle);
-
-  // Test 9.6: use command line style with inheritance
-  Style9 = getStyle("{BasedOnStyle: InheritParentConfig}",
-                    "/e/sub/sub/code.cpp", "none", "", &FS);
-  ASSERT_TRUE(static_cast<bool>(Style9));
-  ASSERT_EQ(*Style9, SubSubStyle);
-
-  // Test 9.7: use command line style with inheritance and own config
-  Style9 = getStyle("{BasedOnStyle: InheritParentConfig, "
-                    "WhitespaceSensitiveMacros: ['FOO', 'BAR']}",
-                    "/e/sub/code.cpp", "none", "", &FS);
-  ASSERT_TRUE(static_cast<bool>(Style9));
-  ASSERT_EQ(*Style9, SubSubStyle);
-
-  // Test 9.8: use inheritance from a file without BasedOnStyle
-  ASSERT_TRUE(FS.addFile(
-      "/e/withoutbase/.clang-format", 0,
-      llvm::MemoryBuffer::getMemBuffer("BracedInitializerIndentWidth: 2\n"
-                                       "ColumnLimit: 123")));
-  ASSERT_TRUE(
-      FS.addFile("/e/withoutbase/sub/.clang-format", 0,
-                 llvm::MemoryBuffer::getMemBuffer(
-                     "BasedOnStyle: InheritParentConfig\nIndentWidth: 7")));
-  // Make sure we do not use the fallback style
-  Style9 = getStyle("file", "/e/withoutbase/code.cpp", "google", "", &FS);
-  ASSERT_TRUE(static_cast<bool>(Style9));
-  ASSERT_EQ(*Style9, [] {
-    auto Style = getLLVMStyle();
-    Style.BracedInitializerIndentWidth = 2;
-    Style.ColumnLimit = 123;
-    return Style;
-  }());
-
-  Style9 = getStyle("file", "/e/withoutbase/sub/code.cpp", "google", "", &FS);
-  ASSERT_TRUE(static_cast<bool>(Style9));
-  ASSERT_EQ(*Style9, [] {
-    auto Style = getLLVMStyle();
-    Style.BracedInitializerIndentWidth = 2;
-    Style.ColumnLimit = 123;
-    Style.IndentWidth = 7;
-    return Style;
-  }());
-
-  // Test 9.9: use inheritance from a specific config file.
-  Style9 = getStyle("file:/e/sub/sub/.clang-format", "/e/sub/sub/code.cpp",
-                    "none", "", &FS);
-  ASSERT_TRUE(static_cast<bool>(Style9));
-  ASSERT_EQ(*Style9, SubSubStyle);
+TEST_F(DefinitionBlockSeparatorTest, TryBlocks) {
+  FormatStyle Style = getLLVMStyle();
+  Style.BreakBeforeBraces = FormatStyle::BS_Allman;
+  Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
+  verifyFormat("void FunctionWithInternalTry()\n"
+               "{\n"
+               "  try\n"
+               "  {\n"
+               "    return;\n"
+               "  }\n"
+               "  catch (const std::exception &)\n"
+               "  {\n"
+               "  }\n"
+               "}",
+               Style, "", /*Inverse=*/false);
+  verifyFormat("void FunctionWithTryBlock()\n"
+               "try\n"
+               "{\n"
+               "  return;\n"
+               "}\n"
+               "catch (const std::exception &)\n"
+               "{\n"
+               "}",
+               Style, "", /*Inverse=*/false);
 }
 
-TEST(ConfigParseTest, GetStyleOfSpecificFile) {
-  llvm::vfs::InMemoryFileSystem FS;
-  // Specify absolute path to a format file in a parent directory.
-  ASSERT_TRUE(
-      FS.addFile("/e/.clang-format", 0,
-                 llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: LLVM")));
-  ASSERT_TRUE(
-      FS.addFile("/e/explicit.clang-format", 0,
-                 llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: Google")));
-  ASSERT_TRUE(FS.addFile("/e/sub/sub/sub/test.cpp", 0,
-                         llvm::MemoryBuffer::getMemBuffer("int i;")));
-  auto Style = getStyle("file:/e/explicit.clang-format",
-                        "/e/sub/sub/sub/test.cpp", "LLVM", "", &FS);
-  ASSERT_TRUE(static_cast<bool>(Style));
-  ASSERT_EQ(*Style, getGoogleStyle());
-
-  // Specify relative path to a format file.
-  ASSERT_TRUE(
-      FS.addFile("../../e/explicit.clang-format", 0,
-                 llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: Google")));
-  Style = getStyle("file:../../e/explicit.clang-format",
-                   "/e/sub/sub/sub/test.cpp", "LLVM", "", &FS);
-  ASSERT_TRUE(static_cast<bool>(Style));
-  ASSERT_EQ(*Style, getGoogleStyle());
-
-  // Specify path to a format file that does not exist.
-  Style = getStyle("file:/e/missing.clang-format", "/e/sub/sub/sub/test.cpp",
-                   "LLVM", "", &FS);
-  ASSERT_FALSE(static_cast<bool>(Style));
-  llvm::consumeError(Style.takeError());
-
-  // Specify path to a file on the filesystem.
-  SmallString<128> FormatFilePath;
-  std::error_code ECF = llvm::sys::fs::createTemporaryFile(
-      "FormatFileTest", "tpl", FormatFilePath);
-  EXPECT_FALSE((bool)ECF);
-  llvm::raw_fd_ostream FormatFileTest(FormatFilePath, ECF);
-  EXPECT_FALSE((bool)ECF);
-  FormatFileTest << "BasedOnStyle: Google\n";
-  FormatFileTest.close();
-
-  SmallString<128> TestFilePath;
-  std::error_code ECT =
-      llvm::sys::fs::createTemporaryFile("CodeFileTest", "cc", TestFilePath);
-  EXPECT_FALSE((bool)ECT);
-  llvm::raw_fd_ostream CodeFileTest(TestFilePath, ECT);
-  CodeFileTest << "int i;\n";
-  CodeFileTest.close();
-
-  std::string format_file_arg = std::string("file:") + FormatFilePath.c_str();
-  Style = getStyle(format_file_arg, TestFilePath, "LLVM", "", nullptr);
-
-  llvm::sys::fs::remove(FormatFilePath.c_str());
-  llvm::sys::fs::remove(TestFilePath.c_str());
-  ASSERT_TRUE(static_cast<bool>(Style));
-  ASSERT_EQ(*Style, getGoogleStyle());
+TEST_F(DefinitionBlockSeparatorTest, Leave) {
+  FormatStyle Style = getLLVMStyle();
+  Style.SeparateDefinitionBlocks = FormatStyle::SDS_Leave;
+  Style.MaxEmptyLinesToKeep = 3;
+  std::string LeaveAs = "namespace {\n"
+                        "\n"
+                        "// Enum test1\n"
+                        "// Enum test2\n"
+                        "enum Foo { FOO, BAR };\n"
+                        "\n\n\n"
+                        "/*\n"
+                        "test1\n"
+                        "test2\n"
+                        "*/\n"
+                        "/*const*/ int foo(int i, int j) {\n"
+                        "  int r = i + j;\n"
+                        "  return r;\n"
+                        "}\n"
+                        "\n"
+                        "// Foobar\n"
+                        "int i, j, k;\n"
+                        "\n"
+                        "// Comment for function\n"
+                        "// Comment line 2\n"
+                        "// Comment line 3\n"
+                        "int bar(int j, int k) {\n"
+                        "  {\n"
+                        "    int r = j * k;\n"
+                        "    return r;\n"
+                        "  }\n"
+                        "}\n"
+                        "\n"
+                        "int bar2(int j, int k) {\n"
+                        "  int r = j / k;\n"
+                        "  return r;\n"
+                        "}\n"
+                        "\n"
+                        "// Comment for inline enum\n"
+                        "enum Bar { FOOBAR, BARFOO };\n"
+                        "int bar3(int j, int k, const enum Bar b) {\n"
+                        "  // A comment\n"
+                        "  int r = j % k;\n"
+                        "  if (struct S = getS()) {\n"
+                        "    // if condition\n"
+                        "  }\n"
+                        "  return r;\n"
+                        "}\n"
+                        "} // namespace";
+  verifyFormat(LeaveAs, Style, LeaveAs);
 }
 
-TEST(ConfigParseTest, GetStyleOutput) {
-  llvm::vfs::InMemoryFileSystem FS;
-
-  // Don't suppress output.
-  testing::internal::CaptureStderr();
-  auto Style = getStyle("{invalid_key=invalid_value}", "a.h", "LLVM", "", &FS,
-                        /*AllowUnknownOptions=*/true);
-  auto Output = testing::internal::GetCapturedStderr();
-  ASSERT_TRUE((bool)Style);
-  ASSERT_FALSE(Output.empty());
-
-  // Suppress stderr.
-  testing::internal::CaptureStderr();
-  Style = getStyle("{invalid_key=invalid_value}", "a.h", "LLVM", "", &FS,
-                   /*AllowUnknownOptions=*/true, dropDiagnosticHandler);
-  Output = testing::internal::GetCapturedStderr();
-  ASSERT_TRUE((bool)Style);
-  ASSERT_TRUE(Output.empty());
+TEST_F(DefinitionBlockSeparatorTest, CSharp) {
+  FormatStyle Style = getLLVMStyle(FormatStyle::LK_CSharp);
+  Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
+  Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle();
+  Style.AllowShortEnumsOnASingleLine = false;
+  verifyFormat("namespace {\r\n"
+               "public class SomeTinyClass {\r\n"
+               "  int X;\r\n"
+               "}\r\n"
+               "\r\n"
+               "public class AnotherTinyClass {\r\n"
+               "  int Y;\r\n"
+               "}\r\n"
+               "\r\n"
+               "internal static String toString() {\r\n"
+               "}\r\n"
+               "\r\n"
+               "// Comment for enum\r\n"
+               "public enum var {\r\n"
+               "  none,\r\n"
+               "  @string,\r\n"
+               "  bool,\r\n"
+               "  @enum\r\n"
+               "}\r\n"
+               "\r\n"
+               "// Test\r\n"
+               "[STAThread]\r\n"
+               "static void Main(string[] args) {\r\n"
+               "  Console.WriteLine(\"HelloWorld\");\r\n"
+               "}\r\n"
+               "\r\n"
+               "static decimal Test() {\r\n"
+               "}\r\n"
+               "}\r\n"
+               "\r\n"
+               "public class FoobarClass {\r\n"
+               "  int foobar;\r\n"
+               "}\r\n"
+               "\r\n"
+               "public class LogFactory<TLogger>\r\n"
+               "    where TLogger : class, new() {\r\n"
+               "  int i;\r\n"
+               "}",
+               Style);
 }
 
-TEST(ConfigParseTest, RedirectInheritance) {
-  llvm::vfs::InMemoryFileSystem FS;
-  constexpr StringRef Config("BasedOnStyle: InheritParentConfig\n"
-                             "ColumnLimit: 20");
-  constexpr StringRef Code("int *f(int i, int j);");
-
-  ASSERT_TRUE(
-      FS.addFile("/a/.clang-format", 0,
-                 llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: GNU")));
-  ASSERT_TRUE(FS.addFile("/a/proj/.clang-format", 0,
-                         llvm::MemoryBuffer::getMemBuffer(
-                             "BasedOnStyle: InheritParentConfig=/a/config")));
-  ASSERT_TRUE(
-      FS.addFile("/a/proj/test.cc", 0, llvm::MemoryBuffer::getMemBuffer(Code)));
-  auto Style = getStyle("file", "/a/proj/test.cc", "none", "", &FS);
-  ASSERT_FALSE(static_cast<bool>(Style));
-  ASSERT_EQ(toString(Style.takeError()),
-            "Failed to inherit configuration directory /a/config");
-
-  ASSERT_TRUE(FS.addFile("/a/config/.clang-format", 0,
-                         llvm::MemoryBuffer::getMemBuffer(Config)));
-  Style = getStyle("file", "/a/proj/test.cc", "none", "", &FS);
-  ASSERT_TRUE(static_cast<bool>(Style));
-  ASSERT_EQ(*Style, [] {
-    auto Style = getGNUStyle();
-    Style.ColumnLimit = 20;
-    return Style;
-  }());
-
-  ASSERT_TRUE(FS.addFile(
-      "/a/proj/src/.clang-format", 0,
-      llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: InheritParentConfig\n"
-                                       "PointerAlignment: Left")));
-  ASSERT_TRUE(FS.addFile("/a/proj/src/test.cc", 0,
-                         llvm::MemoryBuffer::getMemBuffer(Code)));
-  Style = getStyle("file", "/a/proj/src/test.cc", "none", "", &FS);
-  ASSERT_TRUE(static_cast<bool>(Style));
-  ASSERT_EQ(*Style, [] {
-    auto Style = getGNUStyle();
-    Style.ColumnLimit = 20;
-    Style.PointerAlignment = FormatStyle::PAS_Left;
-    return Style;
-  }());
-
-  ASSERT_TRUE(FS.addFile("/a/loop/.clang-format", 0,
-                         llvm::MemoryBuffer::getMemBuffer(
-                             "BasedOnStyle: InheritParentConfig=config/")));
-  ASSERT_TRUE(
-      FS.addFile("/a/loop/test.cc", 0, llvm::MemoryBuffer::getMemBuffer(Code)));
-  ASSERT_TRUE(FS.addFile("/a/loop/config/_clang-format", 0,
-                         llvm::MemoryBuffer::getMemBuffer(Config)));
-  Style = getStyle("file", "/a/loop/test.cc", "none", "", &FS);
-  ASSERT_FALSE(static_cast<bool>(Style));
-  ASSERT_EQ(toString(Style.takeError()),
-            "Loop detected when inheriting configuration file in /a/loop");
+TEST_F(DefinitionBlockSeparatorTest, JavaScript) {
+  FormatStyle Style = getLLVMStyle(FormatStyle::LK_JavaScript);
+  Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
+  Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle();
+  Style.AllowShortEnumsOnASingleLine = false;
+  verifyFormat("export const enum Foo {\n"
+               "  A = 1,\n"
+               "  B\n"
+               "}\n"
+               "\n"
+               "export function A() {\n"
+               "}\n"
+               "\n"
+               "export default function B() {\n"
+               "}\n"
+               "\n"
+               "export function C() {\n"
+               "}\n"
+               "\n"
+               "var t, p, q;\n"
+               "\n"
+               "export abstract class X {\n"
+               "  y: number;\n"
+               "}\n"
+               "\n"
+               "export const enum Bar {\n"
+               "  D = 1,\n"
+               "  E\n"
+               "}",
+               Style);
 }
-
 } // namespace
 } // namespace format
 } // namespace clang

>From 04516b171fec8003840297bc542662a719379cd4 Mon Sep 17 00:00:00 2001
From: owenca <owenpiano at gmail.com>
Date: Sat, 14 Mar 2026 20:10:13 -0700
Subject: [PATCH 17/21] Refactor AllowShortFunctionsOnASingleLine style usage

---
 clang/unittests/Format/FormatTest.cpp | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index a1788a7a2b483..8d52e1a3b963f 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -3522,7 +3522,7 @@ TEST_F(FormatTest, MultiLineControlStatements) {
   verifyFormat("struct T shortfunction() { return bar(); }", Style);
   verifyFormat("struct T {};", Style);
 
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
+  Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle();
   verifyFormat("void shortfunction()\n"
                "{\n"
                "  bar();\n"
@@ -3546,7 +3546,7 @@ TEST_F(FormatTest, MultiLineControlStatements) {
                "};",
                Style);
 
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
+  Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle();
   verifyFormat("void shortfunction() {\n"
                "  bar();\n"
                "}",
@@ -8513,7 +8513,7 @@ TEST_F(FormatTest, BreakConstructorInitializersAfterColon) {
                "};",
                Style);
 
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
+  Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle();
   verifyNoChange("SomeClass::Constructor() :\n"
                  "    a(a), b(b), c(c) {\n"
                  "}",
@@ -12619,7 +12619,7 @@ TEST_F(FormatTest, UnderstandsAttributes) {
 
   // Check that these are not parsed as function declarations:
   CustomAttrs.AllowShortFunctionsOnASingleLine =
-      FormatStyle::ShortFunctionStyle({});
+      FormatStyle::ShortFunctionStyle();
   CustomAttrs.BreakBeforeBraces = FormatStyle::BS_Allman;
   verifyFormat("SomeType s(InitValue);", CustomAttrs);
   verifyFormat("SomeType s{InitValue};", CustomAttrs);
@@ -12728,7 +12728,7 @@ TEST_F(FormatTest, UnderstandsSquareAttributes) {
   // Make sure we do not parse attributes as lambda introducers.
   FormatStyle MultiLineFunctions = getLLVMStyle();
   MultiLineFunctions.AllowShortFunctionsOnASingleLine =
-      FormatStyle::ShortFunctionStyle({});
+      FormatStyle::ShortFunctionStyle();
   verifyFormat("[[unused]] int b() {\n"
                "  return 42;\n"
                "}",
@@ -14833,7 +14833,7 @@ TEST_F(FormatTest, FormatsBracedListsInColumnLayout) {
 TEST_F(FormatTest, PullTrivialFunctionDefinitionsIntoSingleLine) {
   FormatStyle DoNotMerge = getLLVMStyle();
   DoNotMerge.AllowShortFunctionsOnASingleLine =
-      FormatStyle::ShortFunctionStyle({});
+      FormatStyle::ShortFunctionStyle();
 
   verifyFormat("void f() { return 42; }");
   verifyFormat("void f() {\n"
@@ -14904,7 +14904,7 @@ TEST_F(FormatTest, PullTrivialFunctionDefinitionsIntoSingleLine) {
 
   FormatStyle DoNotMergeNoColumnLimit = NoColumnLimit;
   DoNotMergeNoColumnLimit.AllowShortFunctionsOnASingleLine =
-      FormatStyle::ShortFunctionStyle({});
+      FormatStyle::ShortFunctionStyle();
   verifyFormat("A() : b(0) {\n"
                "}",
                DoNotMergeNoColumnLimit);
@@ -15253,7 +15253,7 @@ TEST_F(FormatTest, PullInlineOnlyFunctionDefinitionsIntoSingleLine) {
 
 TEST_F(FormatTest, SplitEmptyFunction) {
   FormatStyle Style = getLLVMStyleWithColumns(40);
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
+  Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle();
   Style.BreakBeforeBraces = FormatStyle::BS_Custom;
   Style.BraceWrapping.AfterFunction = true;
   Style.BraceWrapping.SplitEmptyFunction = false;
@@ -15327,7 +15327,7 @@ TEST_F(FormatTest, SplitEmptyFunction) {
 
 TEST_F(FormatTest, SplitEmptyFunctionButNotRecord) {
   FormatStyle Style = getLLVMStyleWithColumns(40);
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
+  Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle();
   Style.BreakBeforeBraces = FormatStyle::BS_Custom;
   Style.BraceWrapping.AfterFunction = true;
   Style.BraceWrapping.SplitEmptyFunction = true;
@@ -15357,7 +15357,7 @@ TEST_F(FormatTest, SplitEmptyFunctionButNotRecord) {
 
 TEST_F(FormatTest, MergeShortFunctionBody) {
   auto Style = getLLVMStyle();
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
+  Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle();
   Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Always;
   Style.BreakBeforeBraces = FormatStyle::BS_Custom;
   Style.BraceWrapping.AfterFunction = true;
@@ -23346,7 +23346,7 @@ TEST_F(FormatTest, BreakConstructorInitializersBeforeComma) {
                "}",
                Style);
 
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
+  Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle();
   verifyFormat("SomeClass::Constructor()\n"
                "    : a(a)\n"
                "    , b(b)\n"
@@ -27719,7 +27719,7 @@ TEST_F(FormatTest, FormatDecayCopy) {
 TEST_F(FormatTest, Cpp20ModulesSupport) {
   FormatStyle Style = getLLVMStyle();
   Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Never;
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
+  Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle();
 
   verifyFormat("export import foo;", Style);
   verifyFormat("export import foo:bar;", Style);

>From 752c0424da05247703cf2c57892d3cb4fdc797a4 Mon Sep 17 00:00:00 2001
From: owenca <owenpiano at gmail.com>
Date: Sat, 14 Mar 2026 20:11:27 -0700
Subject: [PATCH 18/21] Update print statement from 'Hello' to 'Goodbye'

---
 clang/unittests/Format/FormatTestCSharp.cpp | 1730 +++++++++++++++++++
 1 file changed, 1730 insertions(+)

diff --git a/clang/unittests/Format/FormatTestCSharp.cpp b/clang/unittests/Format/FormatTestCSharp.cpp
index 805fe6f9bd3c2..9dd04c08454d1 100644
--- a/clang/unittests/Format/FormatTestCSharp.cpp
+++ b/clang/unittests/Format/FormatTestCSharp.cpp
@@ -1728,3 +1728,1733 @@ TEST_F(FormatTestCSharp, GotoCaseLabel) {
 } // namespace test
 } // namespace format
 } // namespace clang
+//===- unittest/Format/FormatTestCSharp.cpp - Formatting tests for CSharp -===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "FormatTestBase.h"
+
+#define DEBUG_TYPE "format-test"
+
+namespace clang {
+namespace format {
+namespace test {
+namespace {
+
+class FormatTestCSharp : public test::FormatTestBase {
+protected:
+  FormatStyle getDefaultStyle() const override {
+    return getMicrosoftStyle(FormatStyle::LK_CSharp);
+  }
+
+  static std::string format(StringRef Code, unsigned Offset, unsigned Length,
+                            const FormatStyle &Style) {
+    LLVM_DEBUG(llvm::errs() << "---\n");
+    LLVM_DEBUG(llvm::errs() << Code << "\n\n");
+    std::vector<tooling::Range> Ranges(1, tooling::Range(Offset, Length));
+    tooling::Replacements Replaces = reformat(Style, Code, Ranges);
+    auto Result = applyAllReplacements(Code, Replaces);
+    EXPECT_TRUE(static_cast<bool>(Result));
+    LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
+    return *Result;
+  }
+
+  static std::string
+  format(StringRef Code,
+         const FormatStyle &Style = getMicrosoftStyle(FormatStyle::LK_CSharp)) {
+    return format(Code, 0, Code.size(), Style);
+  }
+
+  static FormatStyle getStyleWithColumns(unsigned ColumnLimit) {
+    FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp);
+    Style.ColumnLimit = ColumnLimit;
+    return Style;
+  }
+};
+
+TEST_F(FormatTestCSharp, CSharpClass) {
+  verifyFormat("public class SomeClass\n"
+               "{\n"
+               "    void f()\n"
+               "    {\n"
+               "    }\n"
+               "    int g()\n"
+               "    {\n"
+               "        return 0;\n"
+               "    }\n"
+               "    void h()\n"
+               "    {\n"
+               "        while (true)\n"
+               "            f();\n"
+               "        for (;;)\n"
+               "            f();\n"
+               "        if (true)\n"
+               "            f();\n"
+               "    }\n"
+               "}");
+
+  // Ensure that small and empty classes are handled correctly with condensed
+  // (Google C++-like) brace-breaking style.
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
+  Style.BreakBeforeBraces = FormatStyle::BS_Attach;
+
+  verifyFormat("public class SomeEmptyClass {}", Style);
+
+  verifyFormat("public class SomeTinyClass {\n"
+               "  int X;\n"
+               "}",
+               Style);
+  verifyFormat("private class SomeTinyClass {\n"
+               "  int X;\n"
+               "}",
+               Style);
+  verifyFormat("protected class SomeTinyClass {\n"
+               "  int X;\n"
+               "}",
+               Style);
+  verifyFormat("internal class SomeTinyClass {\n"
+               "  int X;\n"
+               "}",
+               Style);
+}
+
+TEST_F(FormatTestCSharp, AccessModifiers) {
+  verifyFormat("public String toString()\n"
+               "{\n"
+               "}");
+  verifyFormat("private String toString()\n"
+               "{\n"
+               "}");
+  verifyFormat("protected String toString()\n"
+               "{\n"
+               "}");
+  verifyFormat("internal String toString()\n"
+               "{\n"
+               "}");
+
+  verifyFormat("public override String toString()\n"
+               "{\n"
+               "}");
+  verifyFormat("private override String toString()\n"
+               "{\n"
+               "}");
+  verifyFormat("protected override String toString()\n"
+               "{\n"
+               "}");
+  verifyFormat("internal override String toString()\n"
+               "{\n"
+               "}");
+
+  verifyFormat("internal static String toString()\n"
+               "{\n"
+               "}");
+}
+
+TEST_F(FormatTestCSharp, NoStringLiteralBreaks) {
+  // Breaking of interpolated strings is not implemented.
+  auto Style = getDefaultStyle();
+  Style.ColumnLimit = 40;
+  Style.BreakStringLiterals = true;
+  verifyFormat("foo("
+               "$\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+               "aaaaaaa\");",
+               Style);
+}
+
+TEST_F(FormatTestCSharp, StringLiteralBreaks) {
+  // The line is 75 characters long.  The default limit for the Microsoft style
+  // is 120.
+  auto Style = getDefaultStyle();
+  Style.BreakStringLiterals = true;
+  verifyFormat("foo("
+               "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+               "aaaaaa\");",
+               Style);
+  // When the column limit is smaller, the string should get broken.
+  Style.ColumnLimit = 40;
+  verifyFormat(R"(foo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +
+    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +
+    "aaa");)",
+               "foo("
+               "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+               "aaaaaa\");",
+               Style);
+  // The new quotes should be the same as the original.
+  verifyFormat(R"(foo(@"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +
+    @"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +
+    @"aaaaa");)",
+               "foo("
+               "@\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+               "aaaaaaa\");",
+               Style);
+  // The operators can be on either line.
+  Style.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment;
+  verifyFormat(R"(foo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    + "a");)",
+               "foo("
+               "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+               "aaaaaa\");",
+               Style);
+  Style.AlignOperands = FormatStyle::OAS_AlignAfterOperator;
+  verifyFormat(R"(foo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    + "a");)",
+               "foo("
+               "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+               "aaaaaa\");",
+               Style);
+  verifyFormat(R"(x = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+  + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";)",
+               "x = "
+               "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+               "aaaaaa\";",
+               Style);
+}
+
+TEST_F(FormatTestCSharp, CSharpVerbatiumStringLiterals) {
+  verifyFormat("foo(@\"aaaaaaaa\\abc\\aaaa\");");
+  // @"ABC\" + ToString("B") - handle embedded \ in literal string at
+  // the end
+  //
+  /*
+   * After removal of Lexer change we are currently not able
+   * To handle these cases
+   verifyFormat("string s = @\"ABC\\\" + ToString(\"B\");");
+   verifyFormat("string s = @\"ABC\"\"DEF\"\"GHI\"");
+   verifyFormat("string s = @\"ABC\"\"DEF\"\"\"");
+   verifyFormat("string s = @\"ABC\"\"DEF\"\"\" + abc");
+  */
+}
+
+TEST_F(FormatTestCSharp, CSharpInterpolatedStringLiterals) {
+  verifyFormat("foo($\"aaaaaaaa{aaa}aaaa\");");
+  verifyFormat("foo($\"aaaa{A}\");");
+  verifyFormat(
+      "foo($\"aaaa{A}"
+      "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\");");
+  verifyFormat("Name = $\"{firstName} {lastName}\";");
+
+  // $"ABC\" + ToString("B") - handle embedded \ in literal string at
+  // the end
+  verifyFormat("string s = $\"A{abc}BC\" + ToString(\"B\");");
+  verifyFormat("$\"{domain}\\\\{user}\"");
+  verifyFormat(
+      "var verbatimInterpolated = $@\"C:\\Users\\{userName}\\Documents\\\";");
+}
+
+TEST_F(FormatTestCSharp, CSharpFatArrows) {
+  verifyIncompleteFormat("Task serverTask = Task.Run(async() => {");
+  verifyFormat("public override string ToString() => \"{Name}\\{Age}\";");
+}
+
+TEST_F(FormatTestCSharp, CSharpConditionalExpressions) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
+  // conditional expression is not seen as a NullConditional.
+  verifyFormat("var y = A < B ? -1 : 1;", Style);
+}
+
+TEST_F(FormatTestCSharp, CSharpNullConditional) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
+  Style.SpaceBeforeParens = FormatStyle::SBPO_Always;
+
+  verifyFormat(
+      "public Person(string firstName, string lastName, int? age = null)");
+
+  verifyFormat("foo () {\n"
+               "  switch (args?.Length) {}\n"
+               "}",
+               Style);
+
+  verifyFormat("switch (args?.Length) {}", Style);
+
+  verifyFormat("public static void Main(string[] args)\n"
+               "{\n"
+               "    string dirPath = args?[0];\n"
+               "}");
+
+  Style.SpaceBeforeParens = FormatStyle::SBPO_Never;
+
+  verifyFormat("switch(args?.Length) {}", Style);
+}
+
+TEST_F(FormatTestCSharp, Attributes) {
+  verifyFormat("[STAThread]\n"
+               "static void Main(string[] args)\n"
+               "{\n"
+               "}");
+
+  verifyFormat("[TestMethod]\n"
+               "private class Test\n"
+               "{\n"
+               "}");
+
+  verifyFormat("[TestMethod]\n"
+               "protected class Test\n"
+               "{\n"
+               "}");
+
+  verifyFormat("[TestMethod]\n"
+               "internal class Test\n"
+               "{\n"
+               "}");
+
+  verifyFormat("[TestMethod]\n"
+               "class Test\n"
+               "{\n"
+               "}");
+
+  verifyFormat("[TestMethod]\n"
+               "[DeploymentItem(\"Test.txt\")]\n"
+               "public class Test\n"
+               "{\n"
+               "}");
+
+  verifyFormat("[System.AttributeUsage(System.AttributeTargets.Method)]\n"
+               "[System.Runtime.InteropServices.ComVisible(true)]\n"
+               "public sealed class STAThreadAttribute : Attribute\n"
+               "{\n"
+               "}");
+
+  verifyFormat("[Verb(\"start\", HelpText = \"Starts the server listening on "
+               "provided port\")]\n"
+               "class Test\n"
+               "{\n"
+               "}");
+
+  verifyFormat("[TestMethod]\n"
+               "public string Host { set; get; }");
+
+  // Adjacent properties should not cause line wrapping issues
+  verifyFormat("[JsonProperty(\"foo\")]\n"
+               "public string Foo { set; get; }\n"
+               "[JsonProperty(\"bar\")]\n"
+               "public string Bar { set; get; }\n"
+               "[JsonProperty(\"bar\")]\n"
+               "protected string Bar { set; get; }\n"
+               "[JsonProperty(\"bar\")]\n"
+               "internal string Bar { set; get; }");
+
+  // Multiple attributes should always be split (not just the first ones)
+  verifyFormat("[XmlIgnore]\n"
+               "[JsonProperty(\"foo\")]\n"
+               "public string Foo { set; get; }");
+
+  verifyFormat("[XmlIgnore]\n"
+               "[JsonProperty(\"foo\")]\n"
+               "public string Foo { set; get; }\n"
+               "[XmlIgnore]\n"
+               "[JsonProperty(\"bar\")]\n"
+               "public string Bar { set; get; }");
+
+  verifyFormat("[XmlIgnore]\n"
+               "[ScriptIgnore]\n"
+               "[JsonProperty(\"foo\")]\n"
+               "public string Foo { set; get; }\n"
+               "[XmlIgnore]\n"
+               "[ScriptIgnore]\n"
+               "[JsonProperty(\"bar\")]\n"
+               "public string Bar { set; get; }");
+
+  verifyFormat("[TestMethod(\"start\", HelpText = \"Starts the server "
+               "listening on provided host\")]\n"
+               "public string Host { set; get; }");
+
+  verifyIncompleteFormat(
+      "[DllImport(\"Hello\", EntryPoint = \"hello_world\")]\n"
+      "// The const char* returned by hello_world must not be deleted.\n"
+      "private static extern IntPtr HelloFromCpp();)");
+
+  // Class attributes go on their own line and do not affect layout of
+  // interfaces. Line wrapping decisions previously caused each interface to be
+  // on its own line.
+  verifyFormat("[SomeAttribute]\n"
+               "[SomeOtherAttribute]\n"
+               "public class A : IShape, IAnimal, IVehicle\n"
+               "{\n"
+               "    int X;\n"
+               "}");
+
+  // Attributes in a method declaration do not cause line wrapping.
+  verifyFormat("void MethodA([In][Out] ref double x)\n"
+               "{\n"
+               "}");
+
+  verifyFormat("void MethodA([In, Out] ref double x)\n"
+               "{\n"
+               "}");
+
+  verifyFormat("void MethodA([In, Out] double[] x)\n"
+               "{\n"
+               "}");
+
+  verifyFormat("void MethodA([In] double[] x)\n"
+               "{\n"
+               "}");
+
+  verifyFormat("void MethodA(int[] x)\n"
+               "{\n"
+               "}");
+  verifyFormat("void MethodA(int[][] x)\n"
+               "{\n"
+               "}");
+  verifyFormat("void MethodA([] x)\n"
+               "{\n"
+               "}");
+
+  verifyFormat("public void Log([CallerLineNumber] int line = -1, "
+               "[CallerFilePath] string path = null,\n"
+               "                [CallerMemberName] string name = null)\n"
+               "{\n"
+               "}");
+
+  // [] in an attribute do not cause premature line wrapping or indenting.
+  verifyFormat(R"(//
+public class A
+{
+    [SomeAttribute(new[] { RED, GREEN, BLUE }, -1.0f, 1.0f)]
+    [DoNotSerialize]
+    public Data MemberVariable;
+})");
+
+  //  Unwrappable lines go on a line of their own.
+  // 'target:' is not treated as a label.
+  // Modify Style to enforce a column limit.
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
+  Style.ColumnLimit = 10;
+  verifyFormat(R"([assembly:InternalsVisibleTo(
+    "SomeAssembly, PublicKey=SomePublicKeyThatExceedsTheColumnLimit")])",
+               Style);
+}
+
+TEST_F(FormatTestCSharp, CSharpUsing) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
+  Style.SpaceBeforeParens = FormatStyle::SBPO_Always;
+  verifyFormat("public void foo () {\n"
+               "  using (StreamWriter sw = new StreamWriter (filenameA)) {}\n"
+               "  using () {}\n"
+               "}",
+               Style);
+
+  // Ensure clang-format affects top-level snippets correctly.
+  verifyFormat("using (StreamWriter sw = new StreamWriter (filenameB)) {}",
+               Style);
+
+  Style.SpaceBeforeParens = FormatStyle::SBPO_Never;
+  verifyFormat("public void foo() {\n"
+               "  using(StreamWriter sw = new StreamWriter(filenameB)) {}\n"
+               "  using() {}\n"
+               "}",
+               Style);
+
+  // Ensure clang-format affects top-level snippets correctly.
+  verifyFormat("using(StreamWriter sw = new StreamWriter(filenameB)) {}",
+               Style);
+
+  Style.SpaceBeforeParens = FormatStyle::SBPO_ControlStatements;
+  verifyFormat("public void foo() {\n"
+               "  using (StreamWriter sw = new StreamWriter(filenameA)) {}\n"
+               "  using () {}\n"
+               "}",
+               Style);
+
+  // Ensure clang-format affects top-level snippets correctly.
+  verifyFormat("using (StreamWriter sw = new StreamWriter(filenameB)) {}",
+               Style);
+
+  Style.SpaceBeforeParens = FormatStyle::SBPO_NonEmptyParentheses;
+  verifyFormat("public void foo() {\n"
+               "  using (StreamWriter sw = new StreamWriter (filenameA)) {}\n"
+               "  using() {}\n"
+               "}",
+               Style);
+
+  // Ensure clang-format affects top-level snippets correctly.
+  verifyFormat("using (StreamWriter sw = new StreamWriter (filenameB)) {}",
+               Style);
+}
+
+TEST_F(FormatTestCSharp, CSharpRegions) {
+  verifyFormat("#region aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaa "
+               "aaaaaaaaaaaaaaa long region");
+}
+
+TEST_F(FormatTestCSharp, CSharpKeyWordEscaping) {
+  // AfterEnum is true by default.
+  verifyFormat("public enum var\n"
+               "{\n"
+               "    none,\n"
+               "    @string,\n"
+               "    bool,\n"
+               "    @enum\n"
+               "}");
+}
+
+TEST_F(FormatTestCSharp, CSharpNullCoalescing) {
+  verifyFormat("var test = ABC ?? DEF");
+  verifyFormat("string myname = name ?? \"ABC\";");
+  verifyFormat("return _name ?? \"DEF\";");
+}
+
+TEST_F(FormatTestCSharp, CSharpNullCoalescingAssignment) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
+  Style.SpaceBeforeAssignmentOperators = true;
+
+  verifyFormat(R"(test ??= ABC;)", Style);
+  verifyFormat(R"(test ??= true;)", Style);
+
+  Style.SpaceBeforeAssignmentOperators = false;
+
+  verifyFormat(R"(test??= ABC;)", Style);
+  verifyFormat(R"(test??= true;)", Style);
+}
+
+TEST_F(FormatTestCSharp, CSharpNullForgiving) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
+
+  verifyFormat("var test = null!;", Style);
+  verifyFormat("string test = someFunctionCall()! + \"ABC\"!", Style);
+  verifyFormat("int test = (1! + 2 + bar! + foo())!", Style);
+  verifyFormat(R"(test ??= !foo!;)", Style);
+  verifyFormat("test = !bar! ?? !foo!;", Style);
+  verifyFormat("bool test = !(!true && !true! || !null && !null! || !false && "
+               "!false! && !bar()! + (!foo()))!",
+               Style);
+
+  // Check that line break keeps identifier with the bang.
+  Style.ColumnLimit = 14;
+
+  verifyFormat("var test =\n"
+               "    foo!;",
+               Style);
+}
+
+TEST_F(FormatTestCSharp, AttributesIndentation) {
+  FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp);
+  Style.BreakAfterReturnType = FormatStyle::RTBS_None;
+
+  verifyFormat("[STAThread]\n"
+               "static void Main(string[] args)\n"
+               "{\n"
+               "}",
+               Style);
+
+  verifyFormat("[STAThread]\n"
+               "void "
+               "veryLooooooooooooooongFunctionName(string[] args)\n"
+               "{\n"
+               "}",
+               Style);
+
+  verifyFormat("[STAThread]\n"
+               "veryLoooooooooooooooooooongReturnType "
+               "veryLooooooooooooooongFunctionName(string[] args)\n"
+               "{\n"
+               "}",
+               Style);
+
+  verifyFormat("[SuppressMessage(\"A\", \"B\", Justification = \"C\")]\n"
+               "public override X Y()\n"
+               "{\n"
+               "}",
+               Style);
+
+  verifyFormat("[SuppressMessage]\n"
+               "public X Y()\n"
+               "{\n"
+               "}",
+               Style);
+
+  verifyFormat("[SuppressMessage]\n"
+               "public override X Y()\n"
+               "{\n"
+               "}",
+               Style);
+
+  verifyFormat("public A(B b) : base(b)\n"
+               "{\n"
+               "    [SuppressMessage]\n"
+               "    public override X Y()\n"
+               "    {\n"
+               "    }\n"
+               "}",
+               Style);
+
+  verifyFormat("public A : Base\n"
+               "{\n"
+               "}\n"
+               "[Test]\n"
+               "public Foo()\n"
+               "{\n"
+               "}",
+               Style);
+
+  verifyFormat("namespace\n"
+               "{\n"
+               "public A : Base\n"
+               "{\n"
+               "}\n"
+               "[Test]\n"
+               "public Foo()\n"
+               "{\n"
+               "}\n"
+               "}",
+               Style);
+}
+
+TEST_F(FormatTestCSharp, CSharpSpaceBefore) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
+  Style.SpaceBeforeParens = FormatStyle::SBPO_Always;
+
+  verifyFormat("List<string> list;", Style);
+  verifyFormat("Dictionary<string, string> dict;", Style);
+
+  verifyFormat("for (int i = 0; i < size (); i++) {\n"
+               "}",
+               Style);
+  verifyFormat("foreach (var x in y) {\n"
+               "}",
+               Style);
+  verifyFormat("switch (x) {}", Style);
+  verifyFormat("do {\n"
+               "} while (x);",
+               Style);
+
+  Style.SpaceBeforeParens = FormatStyle::SBPO_Never;
+
+  verifyFormat("List<string> list;", Style);
+  verifyFormat("Dictionary<string, string> dict;", Style);
+
+  verifyFormat("for(int i = 0; i < size(); i++) {\n"
+               "}",
+               Style);
+  verifyFormat("foreach(var x in y) {\n"
+               "}",
+               Style);
+  verifyFormat("switch(x) {}", Style);
+  verifyFormat("do {\n"
+               "} while(x);",
+               Style);
+}
+
+TEST_F(FormatTestCSharp, CSharpSpaceAfterCStyleCast) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
+
+  verifyFormat("(int)x / y;", Style);
+
+  Style.SpaceAfterCStyleCast = true;
+  verifyFormat("(int) x / y;", Style);
+}
+
+TEST_F(FormatTestCSharp, CSharpEscapedQuotesInVerbatimStrings) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
+
+  verifyFormat(R"(string str = @"""";)", Style);
+  verifyFormat(R"(string str = @"""Hello world""";)", Style);
+  verifyFormat(R"(string str = $@"""Hello {friend}""";)", Style);
+  verifyFormat(R"(return $@"Foo ""/foo?f={Request.Query["f"]}""";)", Style);
+  verifyFormat(R"(return @$"Foo ""/foo?f={Request.Query["f"]}""";)", Style);
+  verifyFormat(R"(return @$"path\to\{specifiedFile}")", Style);
+}
+
+TEST_F(FormatTestCSharp, CSharpQuotesInInterpolatedStrings) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
+
+  verifyFormat(R"(string str1 = $"{null ?? "null"}";)", Style);
+  verifyFormat(R"(string str2 = $"{{{braceCount} braces";)", Style);
+  verifyFormat(R"(string str3 = $"{braceCount}}} braces";)", Style);
+}
+
+TEST_F(FormatTestCSharp, CSharpNewlinesInVerbatimStrings) {
+  // Use MS style as Google Style inserts a line break before multiline strings.
+
+  // verifyFormat does not understand multiline C# string-literals
+  // so check the format explicitly.
+
+  FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp);
+
+  std::string Code = R"(string s1 = $@"some code:
+  class {className} {{
+    {className}() {{}}
+  }}";)";
+
+  EXPECT_EQ(Code, format(Code, Style));
+
+  // Multiline string in the middle of a function call.
+  Code = R"(
+var x = foo(className, $@"some code:
+  class {className} {{
+    {className}() {{}}
+  }}",
+            y);)"; // y aligned with `className` arg.
+
+  EXPECT_EQ(Code, format(Code, Style));
+
+  // Interpolated string with embedded multiline string.
+  Code = R"(Console.WriteLine($"{string.Join(@",
+		", values)}");)";
+
+  EXPECT_EQ(Code, format(Code, Style));
+}
+
+TEST_F(FormatTestCSharp, CSharpNewOperator) {
+  FormatStyle Style = getLLVMStyle(FormatStyle::LK_CSharp);
+
+  verifyFormat("public void F() {\n"
+               "  var v = new C(() => { var t = 5; });\n"
+               "}",
+               Style);
+  verifyFormat("public void F() {\n"
+               "  var v = new C(() => {\n"
+               "    try {\n"
+               "    } catch {\n"
+               "      var t = 5;\n"
+               "    }\n"
+               "  });\n"
+               "}",
+               Style);
+}
+
+TEST_F(FormatTestCSharp, NewModifier) {
+  verifyFormat("public new class NestedC {\n"
+               "  public int x = 100;\n"
+               "}",
+               getLLVMStyle(FormatStyle::LK_CSharp));
+}
+
+TEST_F(FormatTestCSharp, CSharpLambdas) {
+  FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_CSharp);
+  FormatStyle MicrosoftStyle = getMicrosoftStyle(FormatStyle::LK_CSharp);
+
+  verifyFormat(R"(//
+class MyClass {
+  Action<string> greet = name => {
+    string greeting = $"Hello {name}!";
+    Console.WriteLine(greeting);
+  };
+})",
+               GoogleStyle);
+
+  // Microsoft Style:
+  // https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/statements-expressions-operators/lambda-expressions#statement-lambdas
+  verifyFormat(R"(//
+class MyClass
+{
+    Action<string> greet = name =>
+    {
+        string greeting = $"Hello {name}!";
+        Console.WriteLine(greeting);
+    };
+})",
+               MicrosoftStyle);
+
+  verifyFormat("void bar()\n"
+               "{\n"
+               "    Function(Val, (Action)(() =>\n"
+               "                           {\n"
+               "                               lock (mylock)\n"
+               "                               {\n"
+               "                                   if (true)\n"
+               "                                   {\n"
+               "                                       A.Remove(item);\n"
+               "                                   }\n"
+               "                               }\n"
+               "                           }));\n"
+               "}",
+               MicrosoftStyle);
+
+  verifyFormat("void baz()\n"
+               "{\n"
+               "    Function(Val, (Action)(() =>\n"
+               "                           {\n"
+               "                               using (var a = new Lock())\n"
+               "                               {\n"
+               "                                   if (true)\n"
+               "                                   {\n"
+               "                                       A.Remove(item);\n"
+               "                                   }\n"
+               "                               }\n"
+               "                           }));\n"
+               "}",
+               MicrosoftStyle);
+
+  verifyFormat("void baz()\n"
+               "{\n"
+               "    Function(Val, (Action)(() =>\n"
+               "                           {\n"
+               "                               if (true)\n"
+               "                               {\n"
+               "                                   A.Remove(item);\n"
+               "                               }\n"
+               "                           }));\n"
+               "}",
+               MicrosoftStyle);
+
+  verifyFormat("void baz()\n"
+               "{\n"
+               "    Function(Val, (Action)(() =>\n"
+               "                           {\n"
+               "                               do\n"
+               "                               {\n"
+               "                                   A.Remove(item);\n"
+               "                               } while (true)\n"
+               "                           }));\n"
+               "}",
+               MicrosoftStyle);
+
+  verifyFormat("void baz()\n"
+               "{\n"
+               "    Function(Val, (Action)(() =>\n"
+               "                           { A.Remove(item); }));\n"
+               "}",
+               MicrosoftStyle);
+
+  verifyFormat("void bar()\n"
+               "{\n"
+               "    Function(Val, (() =>\n"
+               "                   {\n"
+               "                       lock (mylock)\n"
+               "                       {\n"
+               "                           if (true)\n"
+               "                           {\n"
+               "                               A.Remove(item);\n"
+               "                           }\n"
+               "                       }\n"
+               "                   }));\n"
+               "}",
+               MicrosoftStyle);
+  verifyFormat("void bar()\n"
+               "{\n"
+               "    Function((() =>\n"
+               "              {\n"
+               "                  lock (mylock)\n"
+               "                  {\n"
+               "                      if (true)\n"
+               "                      {\n"
+               "                          A.Remove(item);\n"
+               "                      }\n"
+               "                  }\n"
+               "              }));\n"
+               "}",
+               MicrosoftStyle);
+
+  MicrosoftStyle.IndentWidth = 2;
+  verifyFormat("void bar()\n"
+               "{\n"
+               "  Function((() =>\n"
+               "            {\n"
+               "              lock (mylock)\n"
+               "              {\n"
+               "                if (true)\n"
+               "                {\n"
+               "                  A.Remove(item);\n"
+               "                }\n"
+               "              }\n"
+               "            }));\n"
+               "}",
+               MicrosoftStyle);
+  verifyFormat("void bar() {\n"
+               "  Function((() => {\n"
+               "    lock (mylock) {\n"
+               "      if (true) {\n"
+               "        A.Remove(item);\n"
+               "      }\n"
+               "    }\n"
+               "  }));\n"
+               "}",
+               GoogleStyle);
+}
+
+TEST_F(FormatTestCSharp, CSharpLambdasDontBreakFollowingCodeAlignment) {
+  FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_CSharp);
+  FormatStyle MicrosoftStyle = getMicrosoftStyle(FormatStyle::LK_CSharp);
+
+  verifyFormat(R"(//
+public class Sample
+{
+    public void Test()
+    {
+        while (true)
+        {
+            preBindEnumerators.RemoveAll(enumerator => !enumerator.MoveNext());
+            CodeThatFollowsLambda();
+            IsWellAligned();
+        }
+    }
+})",
+               MicrosoftStyle);
+
+  verifyFormat(R"(//
+public class Sample {
+  public void Test() {
+    while (true) {
+      preBindEnumerators.RemoveAll(enumerator => !enumerator.MoveNext());
+      CodeThatFollowsLambda();
+      IsWellAligned();
+    }
+  }
+})",
+               GoogleStyle);
+}
+
+TEST_F(FormatTestCSharp, CSharpLambdasComplexLambdasDontBreakAlignment) {
+  FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_CSharp);
+  FormatStyle MicrosoftStyle = getMicrosoftStyle(FormatStyle::LK_CSharp);
+
+  verifyFormat(R"(//
+public class Test
+{
+    private static void ComplexLambda(BuildReport protoReport)
+    {
+        allSelectedScenes =
+            veryVeryLongCollectionNameThatPutsTheLineLengthAboveTheThresholds.Where(scene => scene.enabled)
+                .Select(scene => scene.path)
+                .ToArray();
+        if (allSelectedScenes.Count == 0)
+        {
+            return;
+        }
+        Functions();
+        AreWell();
+        Aligned();
+        AfterLambdaBlock();
+    }
+})",
+               MicrosoftStyle);
+
+  verifyFormat(R"(//
+public class Test {
+  private static void ComplexLambda(BuildReport protoReport) {
+    allSelectedScenes = veryVeryLongCollectionNameThatPutsTheLineLengthAboveTheThresholds
+                            .Where(scene => scene.enabled)
+                            .Select(scene => scene.path)
+                            .ToArray();
+    if (allSelectedScenes.Count == 0) {
+      return;
+    }
+    Functions();
+    AreWell();
+    Aligned();
+    AfterLambdaBlock();
+  }
+})",
+               GoogleStyle);
+}
+
+TEST_F(FormatTestCSharp, CSharpLambdasMulipleLambdasDontBreakAlignment) {
+  FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_CSharp);
+  FormatStyle MicrosoftStyle = getMicrosoftStyle(FormatStyle::LK_CSharp);
+
+  verifyFormat(R"(//
+public class Test
+{
+    private static void MultipleLambdas(BuildReport protoReport)
+    {
+        allSelectedScenes =
+            veryVeryLongCollectionNameThatPutsTheLineLengthAboveTheThresholds.Where(scene => scene.enabled)
+                .Select(scene => scene.path)
+                .ToArray();
+        preBindEnumerators.RemoveAll(enumerator => !enumerator.MoveNext());
+        if (allSelectedScenes.Count == 0)
+        {
+            return;
+        }
+        Functions();
+        AreWell();
+        Aligned();
+        AfterLambdaBlock();
+    }
+})",
+               MicrosoftStyle);
+
+  verifyFormat(R"(//
+public class Test {
+  private static void MultipleLambdas(BuildReport protoReport) {
+    allSelectedScenes = veryVeryLongCollectionNameThatPutsTheLineLengthAboveTheThresholds
+                            .Where(scene => scene.enabled)
+                            .Select(scene => scene.path)
+                            .ToArray();
+    preBindEnumerators.RemoveAll(enumerator => !enumerator.MoveNext());
+    if (allSelectedScenes.Count == 0) {
+      return;
+    }
+    Functions();
+    AreWell();
+    Aligned();
+    AfterLambdaBlock();
+  }
+})",
+               GoogleStyle);
+}
+
+TEST_F(FormatTestCSharp, CSharpObjectInitializers) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
+
+  // Start code fragments with a comment line so that C++ raw string literals
+  // as seen are identical to expected formatted code.
+
+  verifyFormat(R"(//
+Shape[] shapes = new[] {
+  new Circle {
+    Radius = 2.7281,
+    Colour = Colours.Red,
+  },
+  new Square {
+    Side = 101.1,
+    Colour = Colours.Yellow,
+  },
+};)",
+               Style);
+
+  // Omitted final `,`s will change the formatting.
+  verifyFormat(R"(//
+Shape[] shapes = new[] { new Circle { Radius = 2.7281, Colour = Colours.Red },
+                         new Square { Side = 101.1, Colour = Colours.Yellow } };)",
+               Style);
+
+  // Lambdas can be supplied as initialiser arguments.
+  verifyFormat(R"(//
+private Transformer _transformer = new X.Y {
+  Filler = (Shape shape) => { return new Transform.Fill(shape, RED); },
+  Scaler = (Shape shape) => { return new Transform.Resize(shape, 0.1); },
+};)",
+               Style);
+
+  // Dictionary initialisation.
+  verifyFormat(R"(//
+var myDict = new Dictionary<string, string> {
+  ["name"] = _donald,
+  ["age"] = Convert.ToString(DateTime.Today.Year - 1934),
+  ["type"] = _duck,
+};)",
+               Style);
+}
+
+TEST_F(FormatTestCSharp, CSharpArrayInitializers) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
+
+  verifyFormat(R"(//
+private MySet<Node>[] setPoints = {
+  new Point<Node>(),
+  new Point<Node>(),
+};)",
+               Style);
+}
+
+TEST_F(FormatTestCSharp, CSharpNamedArguments) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
+
+  verifyFormat(R"(//
+PrintOrderDetails(orderNum: 31, productName: "Red Mug", sellerName: "Gift Shop");)",
+               Style);
+
+  // Ensure that trailing comments do not cause problems.
+  verifyFormat(R"(//
+PrintOrderDetails(orderNum: 31, productName: "Red Mug",  // comment
+                  sellerName: "Gift Shop");)",
+               Style);
+
+  verifyFormat(R"(foreach (var tickCount in task.Begin(seed: 0)) {)", Style);
+}
+
+TEST_F(FormatTestCSharp, CSharpPropertyAccessors) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
+
+  verifyFormat("int Value { get }", Style);
+  verifyFormat("int Value { get; }", Style);
+  verifyFormat("int Value { internal get; }", Style);
+  verifyFormat("int Value { get; } = 0", Style);
+  verifyFormat("int Value { set }", Style);
+  verifyFormat("int Value { set; }", Style);
+  verifyFormat("int Value { init; }", Style);
+  verifyFormat("int Value { internal set; }", Style);
+  verifyFormat("int Value { set; } = 0", Style);
+  verifyFormat("int Value { get; set }", Style);
+  verifyFormat("int Value { get; init; }", Style);
+  verifyFormat("int Value { set; get }", Style);
+  verifyFormat("int Value { get; private set; }", Style);
+  verifyFormat("int Value { get; set; }", Style);
+  verifyFormat("int Value { get; set; } = 0", Style);
+  verifyFormat("int Value { internal get; internal set; }", Style);
+
+  // Do not wrap expression body definitions.
+  verifyFormat(R"(//
+public string Name {
+  get => _name;
+  set => _name = value;
+})",
+               Style);
+  verifyFormat(R"(//
+public string Name {
+  init => _name = value;
+  get => _name;
+})",
+               Style);
+  verifyFormat(R"(//
+public string Name {
+  set => _name = value;
+  get => _name;
+})",
+               Style);
+
+  // Examples taken from
+  // https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties
+  verifyFormat(R"(
+// Expression body definitions
+public class SaleItem {
+  public decimal Price {
+    get => _cost;
+    set => _cost = value;
+  }
+})",
+               Style);
+
+  verifyFormat(R"(
+// Properties with backing fields
+class TimePeriod {
+  public double Hours {
+    get { return _seconds / 3600; }
+    set {
+      if (value < 0 || value > 24)
+        throw new ArgumentOutOfRangeException($"{nameof(value)} must be between 0 and 24.");
+      _seconds = value * 3600;
+    }
+  }
+})",
+               Style);
+
+  verifyFormat(R"(
+// Auto-implemented properties
+public class SaleItem {
+  public decimal Price { get; set; }
+})",
+               Style);
+
+  // Add column limit to wrap long lines.
+  Style.ColumnLimit = 100;
+
+  // Examples with assignment to default value.
+  verifyFormat(R"(
+// Long assignment to default value
+class MyClass {
+  public override VeryLongNamedTypeIndeed VeryLongNamedValue { get; set } =
+      VeryLongNamedTypeIndeed.Create(DefaultFirstArgument, DefaultSecondArgument,
+                                     DefaultThirdArgument);
+})",
+               Style);
+
+  verifyFormat(R"(
+// Long assignment to default value with expression body
+class MyClass {
+  public override VeryLongNamedTypeIndeed VeryLongNamedValue {
+    get => veryLongNamedField;
+    set => veryLongNamedField = value;
+  } = VeryLongNamedTypeIndeed.Create(DefaultFirstArgument, DefaultSecondArgument,
+                                     DefaultThirdArgument);
+})",
+               Style);
+
+  // Brace wrapping and single-lining of accessor can be controlled by config.
+  Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Never;
+  Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+  Style.BraceWrapping.AfterFunction = true;
+
+  verifyFormat(R"(//
+class TimePeriod {
+  public double Hours
+  {
+    get {
+      return _seconds / 3600;
+    }
+    set {
+      _seconds = value * 3600;
+    }
+  }
+})",
+               Style);
+
+  // Microsoft style trivial property accessors have no line break before the
+  // opening brace.
+  auto MicrosoftStyle = getMicrosoftStyle(FormatStyle::LK_CSharp);
+  verifyFormat(R"(//
+public class SaleItem
+{
+    public decimal Price { get; set; }
+})",
+               MicrosoftStyle);
+
+  verifyFormat("internal class Program\n"
+               "{\n"
+               "    bool AutoAllowKnownApps\n"
+               "    {\n"
+               "        get;\n"
+               "        [Simple]\n"
+               "        set;\n"
+               "    }\n"
+               "}",
+               MicrosoftStyle);
+}
+
+TEST_F(FormatTestCSharp, DefaultLiteral) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
+
+  verifyFormat(
+      "T[] InitializeArray<T>(int length, T initialValue = default) {}", Style);
+  verifyFormat("System.Numerics.Complex fillValue = default;", Style);
+  verifyFormat("int Value { get } = default;", Style);
+  verifyFormat("int Value { get } = default!;", Style);
+  verifyFormat(R"(//
+public record Person {
+  public string GetInit { get; init; } = default!;
+};)",
+               Style);
+  verifyFormat(R"(//
+public record Person {
+  public string GetSet { get; set; } = default!;
+};)",
+               Style);
+}
+
+TEST_F(FormatTestCSharp, CSharpSpaces) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
+  Style.SpaceBeforeSquareBrackets = false;
+  Style.SpacesInSquareBrackets = false;
+  Style.SpaceBeforeCpp11BracedList = true;
+  Style.Cpp11BracedListStyle = FormatStyle::BLS_Block;
+  Style.SpacesInContainerLiterals = false;
+  Style.SpaceAfterCStyleCast = false;
+
+  verifyFormat(R"(new Car { "Door", 0.1 })", Style);
+  verifyFormat(R"(new Car { 0.1, "Door" })", Style);
+  verifyFormat(R"(new string[] { "A" })", Style);
+  verifyFormat(R"(new string[] {})", Style);
+  verifyFormat(R"(new Car { someVariableName })", Style);
+  verifyFormat(R"(new Car { someVariableName })", Style);
+  verifyFormat(R"(new Dictionary<string, string> { ["Key"] = "Value" };)",
+               Style);
+  verifyFormat(R"(Apply(x => x.Name, x => () => x.ID);)", Style);
+  verifyFormat(R"(bool[] xs = { true, true };)", Style);
+  verifyIncompleteFormat(
+      R"(taskContext.Factory.Run(async () => doThing(args);)", Style);
+  verifyFormat(R"(catch (TestException) when (innerFinallyExecuted))", Style);
+  verifyFormat(R"(private float[,] Values;)", Style);
+  verifyFormat(R"(Result this[Index x] => Foo(x);)", Style);
+
+  verifyFormat(R"(char[,,] rawCharArray = MakeCharacterGrid();)", Style);
+  verifyFormat(R"(var (key, value))", Style);
+
+  // `&&` is not seen as a reference.
+  verifyFormat(R"(A == typeof(X) && someBool)", Style);
+
+  // Not seen as a C-style cast.
+  verifyFormat(R"(//
+foreach ((A a, B b) in someList) {
+})",
+               Style);
+
+  // space after lock in `lock (processes)`.
+  verifyFormat("lock (process)", Style);
+
+  Style.SpacesInSquareBrackets = true;
+  verifyFormat(R"(private float[ , ] Values;)", Style);
+  verifyFormat(R"(string dirPath = args?[ 0 ];)", Style);
+  verifyFormat(R"(char[ ,, ] rawCharArray = MakeCharacterGrid();)", Style);
+
+  // Method returning tuple
+  verifyFormat(R"(public (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(private (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(protected (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(virtual (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(extern (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(static (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(internal (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(abstract (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(sealed (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(override (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(async (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(unsafe (string name, int age) methodTuple() {})", Style);
+
+  Style.SpacesInSquareBrackets = false;
+  Style.SpaceBeforeSquareBrackets = true;
+  verifyFormat("return a is [1, 2, 3];", Style);
+  verifyFormat("return a is [..];", Style);
+  Style.SpaceBeforeSquareBrackets = false;
+  verifyFormat("return a is [1, 2, 3];", Style);
+  verifyFormat("return a is [..];", Style);
+}
+
+TEST_F(FormatTestCSharp, CSharpNullableTypes) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
+  Style.SpacesInSquareBrackets = false;
+
+  verifyFormat(R"(//
+public class A {
+  void foo() {
+    int? value = some.bar();
+  }
+})",
+               Style); // int? is nullable not a conditional expression.
+
+  verifyFormat(R"(void foo(int? x, int? y, int? z) {})",
+               Style); // Nullables in function definitions.
+
+  verifyFormat(R"(public float? Value;)", Style); // no space before `?`.
+
+  verifyFormat(R"(int?[] arr = new int?[10];)",
+               Style); // An array of a nullable type.
+
+  verifyFormat(R"(var x = (int?)y;)", Style); // Cast to a nullable type.
+
+  verifyFormat(R"(var x = new MyContainer<int?>();)", Style); // Generics.
+
+  verifyFormat(R"(//
+public interface I {
+  int? Function();
+})",
+               Style); // Interface methods.
+
+  Style.ColumnLimit = 10;
+  verifyFormat(R"(//
+public VeryLongType? Function(
+    int arg1,
+    int arg2) {
+  //
+})",
+               Style); // ? sticks with identifier.
+}
+
+TEST_F(FormatTestCSharp, CSharpArraySubscripts) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
+
+  // Do not format array subscript operators as attributes.
+  verifyFormat(R"(//
+if (someThings[index].Contains(myThing)) {
+})",
+               Style);
+
+  verifyFormat(R"(//
+if (someThings[i][j][k].Contains(myThing)) {
+})",
+               Style);
+}
+
+TEST_F(FormatTestCSharp, CSharpGenericTypeConstraints) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
+
+  EXPECT_TRUE(Style.BraceWrapping.SplitEmptyRecord);
+
+  verifyFormat("class ItemFactory<T>\n"
+               "    where T : new() {\n"
+               "}",
+               Style);
+
+  verifyFormat("namespace A {\n"
+               "  delegate T MyDelegate<T>()\n"
+               "      where T : new();\n"
+               "}",
+               Style);
+
+  // When the "where" line is not to be formatted, following lines should not
+  // take on its indentation.
+  verifyFormat("class ItemFactory<T>\n"
+               "    where T : new() {\n"
+               "  int f() {}\n"
+               "}",
+               "class ItemFactory<T>\n"
+               "    where T : new() {\n"
+               "  int f() {}\n"
+               "}",
+               Style, {tooling::Range(43, 13)});
+
+  verifyFormat("class Dictionary<TKey, TVal>\n"
+               "    where TKey : IComparable<TKey>\n"
+               "    where TVal : IMyInterface {\n"
+               "  public void MyMethod<T>(T t)\n"
+               "      where T : IMyInterface {\n"
+               "    doThing();\n"
+               "  }\n"
+               "}",
+               Style);
+
+  verifyFormat("class ItemFactory<T>\n"
+               "    where T : new(), IAnInterface<T>, IAnotherInterface<T>, "
+               "IAnotherInterfaceStill<T> {\n"
+               "}",
+               Style);
+
+  Style.ColumnLimit = 50; // Force lines to be wrapped.
+  verifyFormat(R"(//
+class ItemFactory<T, U>
+    where T : new(),
+              IAnInterface<T>,
+              IAnotherInterface<T, U>,
+              IAnotherInterfaceStill<T, U> {
+})",
+               Style);
+
+  // In other languages `where` can be used as a normal identifier.
+  // This example is in C++!
+  verifyFormat(R"(//
+class A {
+  int f(int where) {}
+};)",
+               getGoogleStyle(FormatStyle::LK_Cpp));
+}
+
+TEST_F(FormatTestCSharp, CSharpAfterEnum) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
+  Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+  Style.BraceWrapping.AfterEnum = false;
+  Style.AllowShortEnumsOnASingleLine = false;
+
+  verifyFormat("enum MyEnum {\n"
+               "  Foo,\n"
+               "  Bar,\n"
+               "}",
+               Style);
+  verifyFormat("internal enum MyEnum {\n"
+               "  Foo,\n"
+               "  Bar,\n"
+               "}",
+               Style);
+  verifyFormat("public enum MyEnum {\n"
+               "  Foo,\n"
+               "  Bar,\n"
+               "}",
+               Style);
+  verifyFormat("protected enum MyEnum {\n"
+               "  Foo,\n"
+               "  Bar,\n"
+               "}",
+               Style);
+  verifyFormat("private enum MyEnum {\n"
+               "  Foo,\n"
+               "  Bar,\n"
+               "}",
+               Style);
+
+  Style.BraceWrapping.AfterEnum = true;
+  Style.AllowShortEnumsOnASingleLine = false;
+
+  verifyFormat("enum MyEnum\n"
+               "{\n"
+               "  Foo,\n"
+               "  Bar,\n"
+               "}",
+               Style);
+  verifyFormat("internal enum MyEnum\n"
+               "{\n"
+               "  Foo,\n"
+               "  Bar,\n"
+               "}",
+               Style);
+  verifyFormat("public enum MyEnum\n"
+               "{\n"
+               "  Foo,\n"
+               "  Bar,\n"
+               "}",
+               Style);
+  verifyFormat("protected enum MyEnum\n"
+               "{\n"
+               "  Foo,\n"
+               "  Bar,\n"
+               "}",
+               Style);
+  verifyFormat("private enum MyEnum\n"
+               "{\n"
+               "  Foo,\n"
+               "  Bar,\n"
+               "}",
+               Style);
+  verifyFormat("/* Foo */ private enum MyEnum\n"
+               "{\n"
+               "  Foo,\n"
+               "  Bar,\n"
+               "}",
+               Style);
+  verifyFormat("/* Foo */ /* Bar */ private enum MyEnum\n"
+               "{\n"
+               "  Foo,\n"
+               "  Bar,\n"
+               "}",
+               Style);
+}
+
+TEST_F(FormatTestCSharp, CSharpAfterClass) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
+  Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+  Style.BraceWrapping.AfterClass = false;
+
+  verifyFormat("class MyClass {\n"
+               "  int a;\n"
+               "  int b;\n"
+               "}",
+               Style);
+  verifyFormat("internal class MyClass {\n"
+               "  int a;\n"
+               "  int b;\n"
+               "}",
+               Style);
+  verifyFormat("public class MyClass {\n"
+               "  int a;\n"
+               "  int b;\n"
+               "}",
+               Style);
+  verifyFormat("protected class MyClass {\n"
+               "  int a;\n"
+               "  int b;\n"
+               "}",
+               Style);
+  verifyFormat("private class MyClass {\n"
+               "  int a;\n"
+               "  int b;\n"
+               "}",
+               Style);
+
+  verifyFormat("interface Interface {\n"
+               "  int a;\n"
+               "  int b;\n"
+               "}",
+               Style);
+  verifyFormat("internal interface Interface {\n"
+               "  int a;\n"
+               "  int b;\n"
+               "}",
+               Style);
+  verifyFormat("public interface Interface {\n"
+               "  int a;\n"
+               "  int b;\n"
+               "}",
+               Style);
+  verifyFormat("protected interface Interface {\n"
+               "  int a;\n"
+               "  int b;\n"
+               "}",
+               Style);
+  verifyFormat("private interface Interface {\n"
+               "  int a;\n"
+               "  int b;\n"
+               "}",
+               Style);
+
+  Style.BraceWrapping.AfterClass = true;
+
+  verifyFormat("class MyClass\n"
+               "{\n"
+               "  int a;\n"
+               "  int b;\n"
+               "}",
+               Style);
+  verifyFormat("internal class MyClass\n"
+               "{\n"
+               "  int a;\n"
+               "  int b;\n"
+               "}",
+               Style);
+  verifyFormat("public class MyClass\n"
+               "{\n"
+               "  int a;\n"
+               "  int b;\n"
+               "}",
+               Style);
+  verifyFormat("protected class MyClass\n"
+               "{\n"
+               "  int a;\n"
+               "  int b;\n"
+               "}",
+               Style);
+  verifyFormat("private class MyClass\n"
+               "{\n"
+               "  int a;\n"
+               "  int b;\n"
+               "}",
+               Style);
+
+  verifyFormat("interface MyInterface\n"
+               "{\n"
+               "  int a;\n"
+               "  int b;\n"
+               "}",
+               Style);
+  verifyFormat("internal interface MyInterface\n"
+               "{\n"
+               "  int a;\n"
+               "  int b;\n"
+               "}",
+               Style);
+  verifyFormat("public interface MyInterface\n"
+               "{\n"
+               "  int a;\n"
+               "  int b;\n"
+               "}",
+               Style);
+  verifyFormat("protected interface MyInterface\n"
+               "{\n"
+               "  int a;\n"
+               "  int b;\n"
+               "}",
+               Style);
+  verifyFormat("private interface MyInterface\n"
+               "{\n"
+               "  int a;\n"
+               "  int b;\n"
+               "}",
+               Style);
+  verifyFormat("/* Foo */ private interface MyInterface\n"
+               "{\n"
+               "  int a;\n"
+               "  int b;\n"
+               "}",
+               Style);
+  verifyFormat("/* Foo */ /* Bar */ private interface MyInterface\n"
+               "{\n"
+               "  int a;\n"
+               "  int b;\n"
+               "}",
+               Style);
+}
+
+TEST_F(FormatTestCSharp, NamespaceIndentation) {
+  FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp);
+  Style.NamespaceIndentation = FormatStyle::NI_None;
+
+  verifyFormat("namespace A\n"
+               "{\n"
+               "public interface Name1\n"
+               "{\n"
+               "}\n"
+               "}",
+               Style);
+
+  verifyFormat("namespace A.B\n"
+               "{\n"
+               "public interface Name1\n"
+               "{\n"
+               "}\n"
+               "}",
+               Style);
+
+  Style.NamespaceIndentation = FormatStyle::NI_Inner;
+
+  verifyFormat("namespace A\n"
+               "{\n"
+               "namespace B\n"
+               "{\n"
+               "    public interface Name1\n"
+               "    {\n"
+               "    }\n"
+               "}\n"
+               "}",
+               Style);
+
+  Style.NamespaceIndentation = FormatStyle::NI_All;
+
+  verifyFormat("namespace A.B\n"
+               "{\n"
+               "    public interface Name1\n"
+               "    {\n"
+               "    }\n"
+               "}",
+               Style);
+
+  verifyFormat("namespace A\n"
+               "{\n"
+               "    namespace B\n"
+               "    {\n"
+               "        public interface Name1\n"
+               "        {\n"
+               "        }\n"
+               "    }\n"
+               "}",
+               Style);
+}
+
+TEST_F(FormatTestCSharp, SwitchExpression) {
+  FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp);
+  verifyFormat("int x = a switch {\n"
+               "    1 => (0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0),\n"
+               "    2 => 1,\n"
+               "    _ => 2\n"
+               "};",
+               Style);
+}
+
+TEST_F(FormatTestCSharp, EmptyShortBlock) {
+  auto Style = getLLVMStyle();
+  Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Empty;
+
+  verifyFormat("try {\n"
+               "  doA();\n"
+               "} catch (Exception e) {\n"
+               "  e.printStackTrace();\n"
+               "}",
+               Style);
+
+  verifyFormat("try {\n"
+               "  doA();\n"
+               "} catch (Exception e) {}",
+               Style);
+}
+
+TEST_F(FormatTestCSharp, ShortFunctions) {
+  FormatStyle Style = getLLVMStyle(FormatStyle::LK_CSharp);
+  Style.NamespaceIndentation = FormatStyle::NI_All;
+  Style.AllowShortFunctionsOnASingleLine =
+      FormatStyle::ShortFunctionStyle::setEmptyAndInline();
+  verifyFormat("interface Interface {\n"
+               "  void f() { return; }\n"
+               "};",
+               Style);
+  verifyFormat("public interface Interface {\n"
+               "  void f() { return; }\n"
+               "};",
+               Style);
+  verifyFormat("namespace {\n"
+               "  void f() {\n"
+               "    return;\n"
+               "  }\n"
+               "};",
+               Style);
+  // "union" is not a keyword in C#.
+  verifyFormat("namespace union {\n"
+               "  void f() {\n"
+               "    return;\n"
+               "  }\n"
+               "};",
+               Style);
+}
+
+TEST_F(FormatTestCSharp, BrokenBrackets) {
+  EXPECT_NE("", format("int where b <")); // reduced from crasher
+}
+
+TEST_F(FormatTestCSharp, GotoCaseLabel) {
+  verifyFormat("switch (i)\n"
+               "{\n"
+               "case 0:\n"
+               "    goto case 1;\n"
+               "case 1:\n"
+               "    j = 0;\n"
+               "    {\n"
+               "        break;\n"
+               "    }\n"
+               "}",
+               "switch (i) {\n"
+               "case 0:\n"
+               "  goto case 1;\n"
+               "case 1:\n"
+               "  j = 0;\n"
+               "  {\n"
+               "    break;\n"
+               "  }\n"
+               "}");
+}
+
+} // namespace
+} // namespace test
+} // namespace format
+} // namespace clang

>From 54245cfe0a31cea34bdd939f38b6ab2beb41c4d7 Mon Sep 17 00:00:00 2001
From: owenca <owenpiano at gmail.com>
Date: Sat, 14 Mar 2026 20:12:48 -0700
Subject: [PATCH 19/21] Refactor FormatTestJS by cleaning up function styles

Removed redundant initialization of AllowShortFunctionsOnASingleLine and deleted InliningFunctionLiteralsNew test case.
---
 clang/unittests/Format/FormatTestJS.cpp | 31 +------------------------
 1 file changed, 1 insertion(+), 30 deletions(-)

diff --git a/clang/unittests/Format/FormatTestJS.cpp b/clang/unittests/Format/FormatTestJS.cpp
index de1e9882d0f77..b405a73bce086 100644
--- a/clang/unittests/Format/FormatTestJS.cpp
+++ b/clang/unittests/Format/FormatTestJS.cpp
@@ -1161,7 +1161,7 @@ TEST_F(FormatTestJS, InliningFunctionLiterals) {
                "}",
                Style);
 
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
+  Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle();
   verifyFormat("var func = function() {\n"
                "  return 1;\n"
                "};",
@@ -1191,35 +1191,6 @@ TEST_F(FormatTestJS, InliningFunctionLiterals) {
                Style);
 }
 
-TEST_F(FormatTestJS, InliningFunctionLiteralsNew) {
-  FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
-  Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
-  Style.AllowShortFunctionsOnASingleLine.Other = true;
-  verifyFormat("var func = function() { return 1; };", Style);
-  verifyFormat("var func = doSomething(function() {\n"
-               "  return 1;\n"
-               "});",
-               Style);
-  verifyFormat("var outer = function() {\n"
-               "  var inner = function() {\n"
-               "    return 1;\n"
-               "  }\n"
-               "};",
-               Style);
-  verifyFormat("function outer1(a, b) {\n"
-               "  function inner1(a, b) {\n"
-               "    return a;\n"
-               "  }\n"
-               "}",
-               Style);
-
-  verifyFormat("function outer1(a, b) {\n"
-               "  function inner1_empty(a, b) {\n"
-               "  }\n"
-               "}",
-               Style);
-}
-
 TEST_F(FormatTestJS, MultipleFunctionLiterals) {
   FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
   Style.AllowShortFunctionsOnASingleLine =

>From 28f214770371f0410ffd8665955d7d9a33c77dd3 Mon Sep 17 00:00:00 2001
From: owenca <owenpiano at gmail.com>
Date: Sat, 14 Mar 2026 20:27:47 -0700
Subject: [PATCH 20/21] Update print statement from 'Hello' to 'Goodbye'

---
 clang/unittests/Format/FormatTestCSharp.cpp | 1730 -------------------
 1 file changed, 1730 deletions(-)

diff --git a/clang/unittests/Format/FormatTestCSharp.cpp b/clang/unittests/Format/FormatTestCSharp.cpp
index 9dd04c08454d1..805fe6f9bd3c2 100644
--- a/clang/unittests/Format/FormatTestCSharp.cpp
+++ b/clang/unittests/Format/FormatTestCSharp.cpp
@@ -1728,1733 +1728,3 @@ TEST_F(FormatTestCSharp, GotoCaseLabel) {
 } // namespace test
 } // namespace format
 } // namespace clang
-//===- unittest/Format/FormatTestCSharp.cpp - Formatting tests for CSharp -===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "FormatTestBase.h"
-
-#define DEBUG_TYPE "format-test"
-
-namespace clang {
-namespace format {
-namespace test {
-namespace {
-
-class FormatTestCSharp : public test::FormatTestBase {
-protected:
-  FormatStyle getDefaultStyle() const override {
-    return getMicrosoftStyle(FormatStyle::LK_CSharp);
-  }
-
-  static std::string format(StringRef Code, unsigned Offset, unsigned Length,
-                            const FormatStyle &Style) {
-    LLVM_DEBUG(llvm::errs() << "---\n");
-    LLVM_DEBUG(llvm::errs() << Code << "\n\n");
-    std::vector<tooling::Range> Ranges(1, tooling::Range(Offset, Length));
-    tooling::Replacements Replaces = reformat(Style, Code, Ranges);
-    auto Result = applyAllReplacements(Code, Replaces);
-    EXPECT_TRUE(static_cast<bool>(Result));
-    LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
-    return *Result;
-  }
-
-  static std::string
-  format(StringRef Code,
-         const FormatStyle &Style = getMicrosoftStyle(FormatStyle::LK_CSharp)) {
-    return format(Code, 0, Code.size(), Style);
-  }
-
-  static FormatStyle getStyleWithColumns(unsigned ColumnLimit) {
-    FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp);
-    Style.ColumnLimit = ColumnLimit;
-    return Style;
-  }
-};
-
-TEST_F(FormatTestCSharp, CSharpClass) {
-  verifyFormat("public class SomeClass\n"
-               "{\n"
-               "    void f()\n"
-               "    {\n"
-               "    }\n"
-               "    int g()\n"
-               "    {\n"
-               "        return 0;\n"
-               "    }\n"
-               "    void h()\n"
-               "    {\n"
-               "        while (true)\n"
-               "            f();\n"
-               "        for (;;)\n"
-               "            f();\n"
-               "        if (true)\n"
-               "            f();\n"
-               "    }\n"
-               "}");
-
-  // Ensure that small and empty classes are handled correctly with condensed
-  // (Google C++-like) brace-breaking style.
-  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
-  Style.BreakBeforeBraces = FormatStyle::BS_Attach;
-
-  verifyFormat("public class SomeEmptyClass {}", Style);
-
-  verifyFormat("public class SomeTinyClass {\n"
-               "  int X;\n"
-               "}",
-               Style);
-  verifyFormat("private class SomeTinyClass {\n"
-               "  int X;\n"
-               "}",
-               Style);
-  verifyFormat("protected class SomeTinyClass {\n"
-               "  int X;\n"
-               "}",
-               Style);
-  verifyFormat("internal class SomeTinyClass {\n"
-               "  int X;\n"
-               "}",
-               Style);
-}
-
-TEST_F(FormatTestCSharp, AccessModifiers) {
-  verifyFormat("public String toString()\n"
-               "{\n"
-               "}");
-  verifyFormat("private String toString()\n"
-               "{\n"
-               "}");
-  verifyFormat("protected String toString()\n"
-               "{\n"
-               "}");
-  verifyFormat("internal String toString()\n"
-               "{\n"
-               "}");
-
-  verifyFormat("public override String toString()\n"
-               "{\n"
-               "}");
-  verifyFormat("private override String toString()\n"
-               "{\n"
-               "}");
-  verifyFormat("protected override String toString()\n"
-               "{\n"
-               "}");
-  verifyFormat("internal override String toString()\n"
-               "{\n"
-               "}");
-
-  verifyFormat("internal static String toString()\n"
-               "{\n"
-               "}");
-}
-
-TEST_F(FormatTestCSharp, NoStringLiteralBreaks) {
-  // Breaking of interpolated strings is not implemented.
-  auto Style = getDefaultStyle();
-  Style.ColumnLimit = 40;
-  Style.BreakStringLiterals = true;
-  verifyFormat("foo("
-               "$\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-               "aaaaaaa\");",
-               Style);
-}
-
-TEST_F(FormatTestCSharp, StringLiteralBreaks) {
-  // The line is 75 characters long.  The default limit for the Microsoft style
-  // is 120.
-  auto Style = getDefaultStyle();
-  Style.BreakStringLiterals = true;
-  verifyFormat("foo("
-               "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-               "aaaaaa\");",
-               Style);
-  // When the column limit is smaller, the string should get broken.
-  Style.ColumnLimit = 40;
-  verifyFormat(R"(foo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +
-    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +
-    "aaa");)",
-               "foo("
-               "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-               "aaaaaa\");",
-               Style);
-  // The new quotes should be the same as the original.
-  verifyFormat(R"(foo(@"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +
-    @"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +
-    @"aaaaa");)",
-               "foo("
-               "@\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-               "aaaaaaa\");",
-               Style);
-  // The operators can be on either line.
-  Style.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment;
-  verifyFormat(R"(foo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-    + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-    + "a");)",
-               "foo("
-               "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-               "aaaaaa\");",
-               Style);
-  Style.AlignOperands = FormatStyle::OAS_AlignAfterOperator;
-  verifyFormat(R"(foo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-    + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-    + "a");)",
-               "foo("
-               "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-               "aaaaaa\");",
-               Style);
-  verifyFormat(R"(x = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-  + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";)",
-               "x = "
-               "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-               "aaaaaa\";",
-               Style);
-}
-
-TEST_F(FormatTestCSharp, CSharpVerbatiumStringLiterals) {
-  verifyFormat("foo(@\"aaaaaaaa\\abc\\aaaa\");");
-  // @"ABC\" + ToString("B") - handle embedded \ in literal string at
-  // the end
-  //
-  /*
-   * After removal of Lexer change we are currently not able
-   * To handle these cases
-   verifyFormat("string s = @\"ABC\\\" + ToString(\"B\");");
-   verifyFormat("string s = @\"ABC\"\"DEF\"\"GHI\"");
-   verifyFormat("string s = @\"ABC\"\"DEF\"\"\"");
-   verifyFormat("string s = @\"ABC\"\"DEF\"\"\" + abc");
-  */
-}
-
-TEST_F(FormatTestCSharp, CSharpInterpolatedStringLiterals) {
-  verifyFormat("foo($\"aaaaaaaa{aaa}aaaa\");");
-  verifyFormat("foo($\"aaaa{A}\");");
-  verifyFormat(
-      "foo($\"aaaa{A}"
-      "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\");");
-  verifyFormat("Name = $\"{firstName} {lastName}\";");
-
-  // $"ABC\" + ToString("B") - handle embedded \ in literal string at
-  // the end
-  verifyFormat("string s = $\"A{abc}BC\" + ToString(\"B\");");
-  verifyFormat("$\"{domain}\\\\{user}\"");
-  verifyFormat(
-      "var verbatimInterpolated = $@\"C:\\Users\\{userName}\\Documents\\\";");
-}
-
-TEST_F(FormatTestCSharp, CSharpFatArrows) {
-  verifyIncompleteFormat("Task serverTask = Task.Run(async() => {");
-  verifyFormat("public override string ToString() => \"{Name}\\{Age}\";");
-}
-
-TEST_F(FormatTestCSharp, CSharpConditionalExpressions) {
-  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
-  // conditional expression is not seen as a NullConditional.
-  verifyFormat("var y = A < B ? -1 : 1;", Style);
-}
-
-TEST_F(FormatTestCSharp, CSharpNullConditional) {
-  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
-  Style.SpaceBeforeParens = FormatStyle::SBPO_Always;
-
-  verifyFormat(
-      "public Person(string firstName, string lastName, int? age = null)");
-
-  verifyFormat("foo () {\n"
-               "  switch (args?.Length) {}\n"
-               "}",
-               Style);
-
-  verifyFormat("switch (args?.Length) {}", Style);
-
-  verifyFormat("public static void Main(string[] args)\n"
-               "{\n"
-               "    string dirPath = args?[0];\n"
-               "}");
-
-  Style.SpaceBeforeParens = FormatStyle::SBPO_Never;
-
-  verifyFormat("switch(args?.Length) {}", Style);
-}
-
-TEST_F(FormatTestCSharp, Attributes) {
-  verifyFormat("[STAThread]\n"
-               "static void Main(string[] args)\n"
-               "{\n"
-               "}");
-
-  verifyFormat("[TestMethod]\n"
-               "private class Test\n"
-               "{\n"
-               "}");
-
-  verifyFormat("[TestMethod]\n"
-               "protected class Test\n"
-               "{\n"
-               "}");
-
-  verifyFormat("[TestMethod]\n"
-               "internal class Test\n"
-               "{\n"
-               "}");
-
-  verifyFormat("[TestMethod]\n"
-               "class Test\n"
-               "{\n"
-               "}");
-
-  verifyFormat("[TestMethod]\n"
-               "[DeploymentItem(\"Test.txt\")]\n"
-               "public class Test\n"
-               "{\n"
-               "}");
-
-  verifyFormat("[System.AttributeUsage(System.AttributeTargets.Method)]\n"
-               "[System.Runtime.InteropServices.ComVisible(true)]\n"
-               "public sealed class STAThreadAttribute : Attribute\n"
-               "{\n"
-               "}");
-
-  verifyFormat("[Verb(\"start\", HelpText = \"Starts the server listening on "
-               "provided port\")]\n"
-               "class Test\n"
-               "{\n"
-               "}");
-
-  verifyFormat("[TestMethod]\n"
-               "public string Host { set; get; }");
-
-  // Adjacent properties should not cause line wrapping issues
-  verifyFormat("[JsonProperty(\"foo\")]\n"
-               "public string Foo { set; get; }\n"
-               "[JsonProperty(\"bar\")]\n"
-               "public string Bar { set; get; }\n"
-               "[JsonProperty(\"bar\")]\n"
-               "protected string Bar { set; get; }\n"
-               "[JsonProperty(\"bar\")]\n"
-               "internal string Bar { set; get; }");
-
-  // Multiple attributes should always be split (not just the first ones)
-  verifyFormat("[XmlIgnore]\n"
-               "[JsonProperty(\"foo\")]\n"
-               "public string Foo { set; get; }");
-
-  verifyFormat("[XmlIgnore]\n"
-               "[JsonProperty(\"foo\")]\n"
-               "public string Foo { set; get; }\n"
-               "[XmlIgnore]\n"
-               "[JsonProperty(\"bar\")]\n"
-               "public string Bar { set; get; }");
-
-  verifyFormat("[XmlIgnore]\n"
-               "[ScriptIgnore]\n"
-               "[JsonProperty(\"foo\")]\n"
-               "public string Foo { set; get; }\n"
-               "[XmlIgnore]\n"
-               "[ScriptIgnore]\n"
-               "[JsonProperty(\"bar\")]\n"
-               "public string Bar { set; get; }");
-
-  verifyFormat("[TestMethod(\"start\", HelpText = \"Starts the server "
-               "listening on provided host\")]\n"
-               "public string Host { set; get; }");
-
-  verifyIncompleteFormat(
-      "[DllImport(\"Hello\", EntryPoint = \"hello_world\")]\n"
-      "// The const char* returned by hello_world must not be deleted.\n"
-      "private static extern IntPtr HelloFromCpp();)");
-
-  // Class attributes go on their own line and do not affect layout of
-  // interfaces. Line wrapping decisions previously caused each interface to be
-  // on its own line.
-  verifyFormat("[SomeAttribute]\n"
-               "[SomeOtherAttribute]\n"
-               "public class A : IShape, IAnimal, IVehicle\n"
-               "{\n"
-               "    int X;\n"
-               "}");
-
-  // Attributes in a method declaration do not cause line wrapping.
-  verifyFormat("void MethodA([In][Out] ref double x)\n"
-               "{\n"
-               "}");
-
-  verifyFormat("void MethodA([In, Out] ref double x)\n"
-               "{\n"
-               "}");
-
-  verifyFormat("void MethodA([In, Out] double[] x)\n"
-               "{\n"
-               "}");
-
-  verifyFormat("void MethodA([In] double[] x)\n"
-               "{\n"
-               "}");
-
-  verifyFormat("void MethodA(int[] x)\n"
-               "{\n"
-               "}");
-  verifyFormat("void MethodA(int[][] x)\n"
-               "{\n"
-               "}");
-  verifyFormat("void MethodA([] x)\n"
-               "{\n"
-               "}");
-
-  verifyFormat("public void Log([CallerLineNumber] int line = -1, "
-               "[CallerFilePath] string path = null,\n"
-               "                [CallerMemberName] string name = null)\n"
-               "{\n"
-               "}");
-
-  // [] in an attribute do not cause premature line wrapping or indenting.
-  verifyFormat(R"(//
-public class A
-{
-    [SomeAttribute(new[] { RED, GREEN, BLUE }, -1.0f, 1.0f)]
-    [DoNotSerialize]
-    public Data MemberVariable;
-})");
-
-  //  Unwrappable lines go on a line of their own.
-  // 'target:' is not treated as a label.
-  // Modify Style to enforce a column limit.
-  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
-  Style.ColumnLimit = 10;
-  verifyFormat(R"([assembly:InternalsVisibleTo(
-    "SomeAssembly, PublicKey=SomePublicKeyThatExceedsTheColumnLimit")])",
-               Style);
-}
-
-TEST_F(FormatTestCSharp, CSharpUsing) {
-  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
-  Style.SpaceBeforeParens = FormatStyle::SBPO_Always;
-  verifyFormat("public void foo () {\n"
-               "  using (StreamWriter sw = new StreamWriter (filenameA)) {}\n"
-               "  using () {}\n"
-               "}",
-               Style);
-
-  // Ensure clang-format affects top-level snippets correctly.
-  verifyFormat("using (StreamWriter sw = new StreamWriter (filenameB)) {}",
-               Style);
-
-  Style.SpaceBeforeParens = FormatStyle::SBPO_Never;
-  verifyFormat("public void foo() {\n"
-               "  using(StreamWriter sw = new StreamWriter(filenameB)) {}\n"
-               "  using() {}\n"
-               "}",
-               Style);
-
-  // Ensure clang-format affects top-level snippets correctly.
-  verifyFormat("using(StreamWriter sw = new StreamWriter(filenameB)) {}",
-               Style);
-
-  Style.SpaceBeforeParens = FormatStyle::SBPO_ControlStatements;
-  verifyFormat("public void foo() {\n"
-               "  using (StreamWriter sw = new StreamWriter(filenameA)) {}\n"
-               "  using () {}\n"
-               "}",
-               Style);
-
-  // Ensure clang-format affects top-level snippets correctly.
-  verifyFormat("using (StreamWriter sw = new StreamWriter(filenameB)) {}",
-               Style);
-
-  Style.SpaceBeforeParens = FormatStyle::SBPO_NonEmptyParentheses;
-  verifyFormat("public void foo() {\n"
-               "  using (StreamWriter sw = new StreamWriter (filenameA)) {}\n"
-               "  using() {}\n"
-               "}",
-               Style);
-
-  // Ensure clang-format affects top-level snippets correctly.
-  verifyFormat("using (StreamWriter sw = new StreamWriter (filenameB)) {}",
-               Style);
-}
-
-TEST_F(FormatTestCSharp, CSharpRegions) {
-  verifyFormat("#region aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaa "
-               "aaaaaaaaaaaaaaa long region");
-}
-
-TEST_F(FormatTestCSharp, CSharpKeyWordEscaping) {
-  // AfterEnum is true by default.
-  verifyFormat("public enum var\n"
-               "{\n"
-               "    none,\n"
-               "    @string,\n"
-               "    bool,\n"
-               "    @enum\n"
-               "}");
-}
-
-TEST_F(FormatTestCSharp, CSharpNullCoalescing) {
-  verifyFormat("var test = ABC ?? DEF");
-  verifyFormat("string myname = name ?? \"ABC\";");
-  verifyFormat("return _name ?? \"DEF\";");
-}
-
-TEST_F(FormatTestCSharp, CSharpNullCoalescingAssignment) {
-  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
-  Style.SpaceBeforeAssignmentOperators = true;
-
-  verifyFormat(R"(test ??= ABC;)", Style);
-  verifyFormat(R"(test ??= true;)", Style);
-
-  Style.SpaceBeforeAssignmentOperators = false;
-
-  verifyFormat(R"(test??= ABC;)", Style);
-  verifyFormat(R"(test??= true;)", Style);
-}
-
-TEST_F(FormatTestCSharp, CSharpNullForgiving) {
-  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
-
-  verifyFormat("var test = null!;", Style);
-  verifyFormat("string test = someFunctionCall()! + \"ABC\"!", Style);
-  verifyFormat("int test = (1! + 2 + bar! + foo())!", Style);
-  verifyFormat(R"(test ??= !foo!;)", Style);
-  verifyFormat("test = !bar! ?? !foo!;", Style);
-  verifyFormat("bool test = !(!true && !true! || !null && !null! || !false && "
-               "!false! && !bar()! + (!foo()))!",
-               Style);
-
-  // Check that line break keeps identifier with the bang.
-  Style.ColumnLimit = 14;
-
-  verifyFormat("var test =\n"
-               "    foo!;",
-               Style);
-}
-
-TEST_F(FormatTestCSharp, AttributesIndentation) {
-  FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp);
-  Style.BreakAfterReturnType = FormatStyle::RTBS_None;
-
-  verifyFormat("[STAThread]\n"
-               "static void Main(string[] args)\n"
-               "{\n"
-               "}",
-               Style);
-
-  verifyFormat("[STAThread]\n"
-               "void "
-               "veryLooooooooooooooongFunctionName(string[] args)\n"
-               "{\n"
-               "}",
-               Style);
-
-  verifyFormat("[STAThread]\n"
-               "veryLoooooooooooooooooooongReturnType "
-               "veryLooooooooooooooongFunctionName(string[] args)\n"
-               "{\n"
-               "}",
-               Style);
-
-  verifyFormat("[SuppressMessage(\"A\", \"B\", Justification = \"C\")]\n"
-               "public override X Y()\n"
-               "{\n"
-               "}",
-               Style);
-
-  verifyFormat("[SuppressMessage]\n"
-               "public X Y()\n"
-               "{\n"
-               "}",
-               Style);
-
-  verifyFormat("[SuppressMessage]\n"
-               "public override X Y()\n"
-               "{\n"
-               "}",
-               Style);
-
-  verifyFormat("public A(B b) : base(b)\n"
-               "{\n"
-               "    [SuppressMessage]\n"
-               "    public override X Y()\n"
-               "    {\n"
-               "    }\n"
-               "}",
-               Style);
-
-  verifyFormat("public A : Base\n"
-               "{\n"
-               "}\n"
-               "[Test]\n"
-               "public Foo()\n"
-               "{\n"
-               "}",
-               Style);
-
-  verifyFormat("namespace\n"
-               "{\n"
-               "public A : Base\n"
-               "{\n"
-               "}\n"
-               "[Test]\n"
-               "public Foo()\n"
-               "{\n"
-               "}\n"
-               "}",
-               Style);
-}
-
-TEST_F(FormatTestCSharp, CSharpSpaceBefore) {
-  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
-  Style.SpaceBeforeParens = FormatStyle::SBPO_Always;
-
-  verifyFormat("List<string> list;", Style);
-  verifyFormat("Dictionary<string, string> dict;", Style);
-
-  verifyFormat("for (int i = 0; i < size (); i++) {\n"
-               "}",
-               Style);
-  verifyFormat("foreach (var x in y) {\n"
-               "}",
-               Style);
-  verifyFormat("switch (x) {}", Style);
-  verifyFormat("do {\n"
-               "} while (x);",
-               Style);
-
-  Style.SpaceBeforeParens = FormatStyle::SBPO_Never;
-
-  verifyFormat("List<string> list;", Style);
-  verifyFormat("Dictionary<string, string> dict;", Style);
-
-  verifyFormat("for(int i = 0; i < size(); i++) {\n"
-               "}",
-               Style);
-  verifyFormat("foreach(var x in y) {\n"
-               "}",
-               Style);
-  verifyFormat("switch(x) {}", Style);
-  verifyFormat("do {\n"
-               "} while(x);",
-               Style);
-}
-
-TEST_F(FormatTestCSharp, CSharpSpaceAfterCStyleCast) {
-  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
-
-  verifyFormat("(int)x / y;", Style);
-
-  Style.SpaceAfterCStyleCast = true;
-  verifyFormat("(int) x / y;", Style);
-}
-
-TEST_F(FormatTestCSharp, CSharpEscapedQuotesInVerbatimStrings) {
-  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
-
-  verifyFormat(R"(string str = @"""";)", Style);
-  verifyFormat(R"(string str = @"""Hello world""";)", Style);
-  verifyFormat(R"(string str = $@"""Hello {friend}""";)", Style);
-  verifyFormat(R"(return $@"Foo ""/foo?f={Request.Query["f"]}""";)", Style);
-  verifyFormat(R"(return @$"Foo ""/foo?f={Request.Query["f"]}""";)", Style);
-  verifyFormat(R"(return @$"path\to\{specifiedFile}")", Style);
-}
-
-TEST_F(FormatTestCSharp, CSharpQuotesInInterpolatedStrings) {
-  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
-
-  verifyFormat(R"(string str1 = $"{null ?? "null"}";)", Style);
-  verifyFormat(R"(string str2 = $"{{{braceCount} braces";)", Style);
-  verifyFormat(R"(string str3 = $"{braceCount}}} braces";)", Style);
-}
-
-TEST_F(FormatTestCSharp, CSharpNewlinesInVerbatimStrings) {
-  // Use MS style as Google Style inserts a line break before multiline strings.
-
-  // verifyFormat does not understand multiline C# string-literals
-  // so check the format explicitly.
-
-  FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp);
-
-  std::string Code = R"(string s1 = $@"some code:
-  class {className} {{
-    {className}() {{}}
-  }}";)";
-
-  EXPECT_EQ(Code, format(Code, Style));
-
-  // Multiline string in the middle of a function call.
-  Code = R"(
-var x = foo(className, $@"some code:
-  class {className} {{
-    {className}() {{}}
-  }}",
-            y);)"; // y aligned with `className` arg.
-
-  EXPECT_EQ(Code, format(Code, Style));
-
-  // Interpolated string with embedded multiline string.
-  Code = R"(Console.WriteLine($"{string.Join(@",
-		", values)}");)";
-
-  EXPECT_EQ(Code, format(Code, Style));
-}
-
-TEST_F(FormatTestCSharp, CSharpNewOperator) {
-  FormatStyle Style = getLLVMStyle(FormatStyle::LK_CSharp);
-
-  verifyFormat("public void F() {\n"
-               "  var v = new C(() => { var t = 5; });\n"
-               "}",
-               Style);
-  verifyFormat("public void F() {\n"
-               "  var v = new C(() => {\n"
-               "    try {\n"
-               "    } catch {\n"
-               "      var t = 5;\n"
-               "    }\n"
-               "  });\n"
-               "}",
-               Style);
-}
-
-TEST_F(FormatTestCSharp, NewModifier) {
-  verifyFormat("public new class NestedC {\n"
-               "  public int x = 100;\n"
-               "}",
-               getLLVMStyle(FormatStyle::LK_CSharp));
-}
-
-TEST_F(FormatTestCSharp, CSharpLambdas) {
-  FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_CSharp);
-  FormatStyle MicrosoftStyle = getMicrosoftStyle(FormatStyle::LK_CSharp);
-
-  verifyFormat(R"(//
-class MyClass {
-  Action<string> greet = name => {
-    string greeting = $"Hello {name}!";
-    Console.WriteLine(greeting);
-  };
-})",
-               GoogleStyle);
-
-  // Microsoft Style:
-  // https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/statements-expressions-operators/lambda-expressions#statement-lambdas
-  verifyFormat(R"(//
-class MyClass
-{
-    Action<string> greet = name =>
-    {
-        string greeting = $"Hello {name}!";
-        Console.WriteLine(greeting);
-    };
-})",
-               MicrosoftStyle);
-
-  verifyFormat("void bar()\n"
-               "{\n"
-               "    Function(Val, (Action)(() =>\n"
-               "                           {\n"
-               "                               lock (mylock)\n"
-               "                               {\n"
-               "                                   if (true)\n"
-               "                                   {\n"
-               "                                       A.Remove(item);\n"
-               "                                   }\n"
-               "                               }\n"
-               "                           }));\n"
-               "}",
-               MicrosoftStyle);
-
-  verifyFormat("void baz()\n"
-               "{\n"
-               "    Function(Val, (Action)(() =>\n"
-               "                           {\n"
-               "                               using (var a = new Lock())\n"
-               "                               {\n"
-               "                                   if (true)\n"
-               "                                   {\n"
-               "                                       A.Remove(item);\n"
-               "                                   }\n"
-               "                               }\n"
-               "                           }));\n"
-               "}",
-               MicrosoftStyle);
-
-  verifyFormat("void baz()\n"
-               "{\n"
-               "    Function(Val, (Action)(() =>\n"
-               "                           {\n"
-               "                               if (true)\n"
-               "                               {\n"
-               "                                   A.Remove(item);\n"
-               "                               }\n"
-               "                           }));\n"
-               "}",
-               MicrosoftStyle);
-
-  verifyFormat("void baz()\n"
-               "{\n"
-               "    Function(Val, (Action)(() =>\n"
-               "                           {\n"
-               "                               do\n"
-               "                               {\n"
-               "                                   A.Remove(item);\n"
-               "                               } while (true)\n"
-               "                           }));\n"
-               "}",
-               MicrosoftStyle);
-
-  verifyFormat("void baz()\n"
-               "{\n"
-               "    Function(Val, (Action)(() =>\n"
-               "                           { A.Remove(item); }));\n"
-               "}",
-               MicrosoftStyle);
-
-  verifyFormat("void bar()\n"
-               "{\n"
-               "    Function(Val, (() =>\n"
-               "                   {\n"
-               "                       lock (mylock)\n"
-               "                       {\n"
-               "                           if (true)\n"
-               "                           {\n"
-               "                               A.Remove(item);\n"
-               "                           }\n"
-               "                       }\n"
-               "                   }));\n"
-               "}",
-               MicrosoftStyle);
-  verifyFormat("void bar()\n"
-               "{\n"
-               "    Function((() =>\n"
-               "              {\n"
-               "                  lock (mylock)\n"
-               "                  {\n"
-               "                      if (true)\n"
-               "                      {\n"
-               "                          A.Remove(item);\n"
-               "                      }\n"
-               "                  }\n"
-               "              }));\n"
-               "}",
-               MicrosoftStyle);
-
-  MicrosoftStyle.IndentWidth = 2;
-  verifyFormat("void bar()\n"
-               "{\n"
-               "  Function((() =>\n"
-               "            {\n"
-               "              lock (mylock)\n"
-               "              {\n"
-               "                if (true)\n"
-               "                {\n"
-               "                  A.Remove(item);\n"
-               "                }\n"
-               "              }\n"
-               "            }));\n"
-               "}",
-               MicrosoftStyle);
-  verifyFormat("void bar() {\n"
-               "  Function((() => {\n"
-               "    lock (mylock) {\n"
-               "      if (true) {\n"
-               "        A.Remove(item);\n"
-               "      }\n"
-               "    }\n"
-               "  }));\n"
-               "}",
-               GoogleStyle);
-}
-
-TEST_F(FormatTestCSharp, CSharpLambdasDontBreakFollowingCodeAlignment) {
-  FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_CSharp);
-  FormatStyle MicrosoftStyle = getMicrosoftStyle(FormatStyle::LK_CSharp);
-
-  verifyFormat(R"(//
-public class Sample
-{
-    public void Test()
-    {
-        while (true)
-        {
-            preBindEnumerators.RemoveAll(enumerator => !enumerator.MoveNext());
-            CodeThatFollowsLambda();
-            IsWellAligned();
-        }
-    }
-})",
-               MicrosoftStyle);
-
-  verifyFormat(R"(//
-public class Sample {
-  public void Test() {
-    while (true) {
-      preBindEnumerators.RemoveAll(enumerator => !enumerator.MoveNext());
-      CodeThatFollowsLambda();
-      IsWellAligned();
-    }
-  }
-})",
-               GoogleStyle);
-}
-
-TEST_F(FormatTestCSharp, CSharpLambdasComplexLambdasDontBreakAlignment) {
-  FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_CSharp);
-  FormatStyle MicrosoftStyle = getMicrosoftStyle(FormatStyle::LK_CSharp);
-
-  verifyFormat(R"(//
-public class Test
-{
-    private static void ComplexLambda(BuildReport protoReport)
-    {
-        allSelectedScenes =
-            veryVeryLongCollectionNameThatPutsTheLineLengthAboveTheThresholds.Where(scene => scene.enabled)
-                .Select(scene => scene.path)
-                .ToArray();
-        if (allSelectedScenes.Count == 0)
-        {
-            return;
-        }
-        Functions();
-        AreWell();
-        Aligned();
-        AfterLambdaBlock();
-    }
-})",
-               MicrosoftStyle);
-
-  verifyFormat(R"(//
-public class Test {
-  private static void ComplexLambda(BuildReport protoReport) {
-    allSelectedScenes = veryVeryLongCollectionNameThatPutsTheLineLengthAboveTheThresholds
-                            .Where(scene => scene.enabled)
-                            .Select(scene => scene.path)
-                            .ToArray();
-    if (allSelectedScenes.Count == 0) {
-      return;
-    }
-    Functions();
-    AreWell();
-    Aligned();
-    AfterLambdaBlock();
-  }
-})",
-               GoogleStyle);
-}
-
-TEST_F(FormatTestCSharp, CSharpLambdasMulipleLambdasDontBreakAlignment) {
-  FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_CSharp);
-  FormatStyle MicrosoftStyle = getMicrosoftStyle(FormatStyle::LK_CSharp);
-
-  verifyFormat(R"(//
-public class Test
-{
-    private static void MultipleLambdas(BuildReport protoReport)
-    {
-        allSelectedScenes =
-            veryVeryLongCollectionNameThatPutsTheLineLengthAboveTheThresholds.Where(scene => scene.enabled)
-                .Select(scene => scene.path)
-                .ToArray();
-        preBindEnumerators.RemoveAll(enumerator => !enumerator.MoveNext());
-        if (allSelectedScenes.Count == 0)
-        {
-            return;
-        }
-        Functions();
-        AreWell();
-        Aligned();
-        AfterLambdaBlock();
-    }
-})",
-               MicrosoftStyle);
-
-  verifyFormat(R"(//
-public class Test {
-  private static void MultipleLambdas(BuildReport protoReport) {
-    allSelectedScenes = veryVeryLongCollectionNameThatPutsTheLineLengthAboveTheThresholds
-                            .Where(scene => scene.enabled)
-                            .Select(scene => scene.path)
-                            .ToArray();
-    preBindEnumerators.RemoveAll(enumerator => !enumerator.MoveNext());
-    if (allSelectedScenes.Count == 0) {
-      return;
-    }
-    Functions();
-    AreWell();
-    Aligned();
-    AfterLambdaBlock();
-  }
-})",
-               GoogleStyle);
-}
-
-TEST_F(FormatTestCSharp, CSharpObjectInitializers) {
-  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
-
-  // Start code fragments with a comment line so that C++ raw string literals
-  // as seen are identical to expected formatted code.
-
-  verifyFormat(R"(//
-Shape[] shapes = new[] {
-  new Circle {
-    Radius = 2.7281,
-    Colour = Colours.Red,
-  },
-  new Square {
-    Side = 101.1,
-    Colour = Colours.Yellow,
-  },
-};)",
-               Style);
-
-  // Omitted final `,`s will change the formatting.
-  verifyFormat(R"(//
-Shape[] shapes = new[] { new Circle { Radius = 2.7281, Colour = Colours.Red },
-                         new Square { Side = 101.1, Colour = Colours.Yellow } };)",
-               Style);
-
-  // Lambdas can be supplied as initialiser arguments.
-  verifyFormat(R"(//
-private Transformer _transformer = new X.Y {
-  Filler = (Shape shape) => { return new Transform.Fill(shape, RED); },
-  Scaler = (Shape shape) => { return new Transform.Resize(shape, 0.1); },
-};)",
-               Style);
-
-  // Dictionary initialisation.
-  verifyFormat(R"(//
-var myDict = new Dictionary<string, string> {
-  ["name"] = _donald,
-  ["age"] = Convert.ToString(DateTime.Today.Year - 1934),
-  ["type"] = _duck,
-};)",
-               Style);
-}
-
-TEST_F(FormatTestCSharp, CSharpArrayInitializers) {
-  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
-
-  verifyFormat(R"(//
-private MySet<Node>[] setPoints = {
-  new Point<Node>(),
-  new Point<Node>(),
-};)",
-               Style);
-}
-
-TEST_F(FormatTestCSharp, CSharpNamedArguments) {
-  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
-
-  verifyFormat(R"(//
-PrintOrderDetails(orderNum: 31, productName: "Red Mug", sellerName: "Gift Shop");)",
-               Style);
-
-  // Ensure that trailing comments do not cause problems.
-  verifyFormat(R"(//
-PrintOrderDetails(orderNum: 31, productName: "Red Mug",  // comment
-                  sellerName: "Gift Shop");)",
-               Style);
-
-  verifyFormat(R"(foreach (var tickCount in task.Begin(seed: 0)) {)", Style);
-}
-
-TEST_F(FormatTestCSharp, CSharpPropertyAccessors) {
-  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
-
-  verifyFormat("int Value { get }", Style);
-  verifyFormat("int Value { get; }", Style);
-  verifyFormat("int Value { internal get; }", Style);
-  verifyFormat("int Value { get; } = 0", Style);
-  verifyFormat("int Value { set }", Style);
-  verifyFormat("int Value { set; }", Style);
-  verifyFormat("int Value { init; }", Style);
-  verifyFormat("int Value { internal set; }", Style);
-  verifyFormat("int Value { set; } = 0", Style);
-  verifyFormat("int Value { get; set }", Style);
-  verifyFormat("int Value { get; init; }", Style);
-  verifyFormat("int Value { set; get }", Style);
-  verifyFormat("int Value { get; private set; }", Style);
-  verifyFormat("int Value { get; set; }", Style);
-  verifyFormat("int Value { get; set; } = 0", Style);
-  verifyFormat("int Value { internal get; internal set; }", Style);
-
-  // Do not wrap expression body definitions.
-  verifyFormat(R"(//
-public string Name {
-  get => _name;
-  set => _name = value;
-})",
-               Style);
-  verifyFormat(R"(//
-public string Name {
-  init => _name = value;
-  get => _name;
-})",
-               Style);
-  verifyFormat(R"(//
-public string Name {
-  set => _name = value;
-  get => _name;
-})",
-               Style);
-
-  // Examples taken from
-  // https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties
-  verifyFormat(R"(
-// Expression body definitions
-public class SaleItem {
-  public decimal Price {
-    get => _cost;
-    set => _cost = value;
-  }
-})",
-               Style);
-
-  verifyFormat(R"(
-// Properties with backing fields
-class TimePeriod {
-  public double Hours {
-    get { return _seconds / 3600; }
-    set {
-      if (value < 0 || value > 24)
-        throw new ArgumentOutOfRangeException($"{nameof(value)} must be between 0 and 24.");
-      _seconds = value * 3600;
-    }
-  }
-})",
-               Style);
-
-  verifyFormat(R"(
-// Auto-implemented properties
-public class SaleItem {
-  public decimal Price { get; set; }
-})",
-               Style);
-
-  // Add column limit to wrap long lines.
-  Style.ColumnLimit = 100;
-
-  // Examples with assignment to default value.
-  verifyFormat(R"(
-// Long assignment to default value
-class MyClass {
-  public override VeryLongNamedTypeIndeed VeryLongNamedValue { get; set } =
-      VeryLongNamedTypeIndeed.Create(DefaultFirstArgument, DefaultSecondArgument,
-                                     DefaultThirdArgument);
-})",
-               Style);
-
-  verifyFormat(R"(
-// Long assignment to default value with expression body
-class MyClass {
-  public override VeryLongNamedTypeIndeed VeryLongNamedValue {
-    get => veryLongNamedField;
-    set => veryLongNamedField = value;
-  } = VeryLongNamedTypeIndeed.Create(DefaultFirstArgument, DefaultSecondArgument,
-                                     DefaultThirdArgument);
-})",
-               Style);
-
-  // Brace wrapping and single-lining of accessor can be controlled by config.
-  Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Never;
-  Style.BreakBeforeBraces = FormatStyle::BS_Custom;
-  Style.BraceWrapping.AfterFunction = true;
-
-  verifyFormat(R"(//
-class TimePeriod {
-  public double Hours
-  {
-    get {
-      return _seconds / 3600;
-    }
-    set {
-      _seconds = value * 3600;
-    }
-  }
-})",
-               Style);
-
-  // Microsoft style trivial property accessors have no line break before the
-  // opening brace.
-  auto MicrosoftStyle = getMicrosoftStyle(FormatStyle::LK_CSharp);
-  verifyFormat(R"(//
-public class SaleItem
-{
-    public decimal Price { get; set; }
-})",
-               MicrosoftStyle);
-
-  verifyFormat("internal class Program\n"
-               "{\n"
-               "    bool AutoAllowKnownApps\n"
-               "    {\n"
-               "        get;\n"
-               "        [Simple]\n"
-               "        set;\n"
-               "    }\n"
-               "}",
-               MicrosoftStyle);
-}
-
-TEST_F(FormatTestCSharp, DefaultLiteral) {
-  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
-
-  verifyFormat(
-      "T[] InitializeArray<T>(int length, T initialValue = default) {}", Style);
-  verifyFormat("System.Numerics.Complex fillValue = default;", Style);
-  verifyFormat("int Value { get } = default;", Style);
-  verifyFormat("int Value { get } = default!;", Style);
-  verifyFormat(R"(//
-public record Person {
-  public string GetInit { get; init; } = default!;
-};)",
-               Style);
-  verifyFormat(R"(//
-public record Person {
-  public string GetSet { get; set; } = default!;
-};)",
-               Style);
-}
-
-TEST_F(FormatTestCSharp, CSharpSpaces) {
-  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
-  Style.SpaceBeforeSquareBrackets = false;
-  Style.SpacesInSquareBrackets = false;
-  Style.SpaceBeforeCpp11BracedList = true;
-  Style.Cpp11BracedListStyle = FormatStyle::BLS_Block;
-  Style.SpacesInContainerLiterals = false;
-  Style.SpaceAfterCStyleCast = false;
-
-  verifyFormat(R"(new Car { "Door", 0.1 })", Style);
-  verifyFormat(R"(new Car { 0.1, "Door" })", Style);
-  verifyFormat(R"(new string[] { "A" })", Style);
-  verifyFormat(R"(new string[] {})", Style);
-  verifyFormat(R"(new Car { someVariableName })", Style);
-  verifyFormat(R"(new Car { someVariableName })", Style);
-  verifyFormat(R"(new Dictionary<string, string> { ["Key"] = "Value" };)",
-               Style);
-  verifyFormat(R"(Apply(x => x.Name, x => () => x.ID);)", Style);
-  verifyFormat(R"(bool[] xs = { true, true };)", Style);
-  verifyIncompleteFormat(
-      R"(taskContext.Factory.Run(async () => doThing(args);)", Style);
-  verifyFormat(R"(catch (TestException) when (innerFinallyExecuted))", Style);
-  verifyFormat(R"(private float[,] Values;)", Style);
-  verifyFormat(R"(Result this[Index x] => Foo(x);)", Style);
-
-  verifyFormat(R"(char[,,] rawCharArray = MakeCharacterGrid();)", Style);
-  verifyFormat(R"(var (key, value))", Style);
-
-  // `&&` is not seen as a reference.
-  verifyFormat(R"(A == typeof(X) && someBool)", Style);
-
-  // Not seen as a C-style cast.
-  verifyFormat(R"(//
-foreach ((A a, B b) in someList) {
-})",
-               Style);
-
-  // space after lock in `lock (processes)`.
-  verifyFormat("lock (process)", Style);
-
-  Style.SpacesInSquareBrackets = true;
-  verifyFormat(R"(private float[ , ] Values;)", Style);
-  verifyFormat(R"(string dirPath = args?[ 0 ];)", Style);
-  verifyFormat(R"(char[ ,, ] rawCharArray = MakeCharacterGrid();)", Style);
-
-  // Method returning tuple
-  verifyFormat(R"(public (string name, int age) methodTuple() {})", Style);
-  verifyFormat(R"(private (string name, int age) methodTuple() {})", Style);
-  verifyFormat(R"(protected (string name, int age) methodTuple() {})", Style);
-  verifyFormat(R"(virtual (string name, int age) methodTuple() {})", Style);
-  verifyFormat(R"(extern (string name, int age) methodTuple() {})", Style);
-  verifyFormat(R"(static (string name, int age) methodTuple() {})", Style);
-  verifyFormat(R"(internal (string name, int age) methodTuple() {})", Style);
-  verifyFormat(R"(abstract (string name, int age) methodTuple() {})", Style);
-  verifyFormat(R"(sealed (string name, int age) methodTuple() {})", Style);
-  verifyFormat(R"(override (string name, int age) methodTuple() {})", Style);
-  verifyFormat(R"(async (string name, int age) methodTuple() {})", Style);
-  verifyFormat(R"(unsafe (string name, int age) methodTuple() {})", Style);
-
-  Style.SpacesInSquareBrackets = false;
-  Style.SpaceBeforeSquareBrackets = true;
-  verifyFormat("return a is [1, 2, 3];", Style);
-  verifyFormat("return a is [..];", Style);
-  Style.SpaceBeforeSquareBrackets = false;
-  verifyFormat("return a is [1, 2, 3];", Style);
-  verifyFormat("return a is [..];", Style);
-}
-
-TEST_F(FormatTestCSharp, CSharpNullableTypes) {
-  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
-  Style.SpacesInSquareBrackets = false;
-
-  verifyFormat(R"(//
-public class A {
-  void foo() {
-    int? value = some.bar();
-  }
-})",
-               Style); // int? is nullable not a conditional expression.
-
-  verifyFormat(R"(void foo(int? x, int? y, int? z) {})",
-               Style); // Nullables in function definitions.
-
-  verifyFormat(R"(public float? Value;)", Style); // no space before `?`.
-
-  verifyFormat(R"(int?[] arr = new int?[10];)",
-               Style); // An array of a nullable type.
-
-  verifyFormat(R"(var x = (int?)y;)", Style); // Cast to a nullable type.
-
-  verifyFormat(R"(var x = new MyContainer<int?>();)", Style); // Generics.
-
-  verifyFormat(R"(//
-public interface I {
-  int? Function();
-})",
-               Style); // Interface methods.
-
-  Style.ColumnLimit = 10;
-  verifyFormat(R"(//
-public VeryLongType? Function(
-    int arg1,
-    int arg2) {
-  //
-})",
-               Style); // ? sticks with identifier.
-}
-
-TEST_F(FormatTestCSharp, CSharpArraySubscripts) {
-  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
-
-  // Do not format array subscript operators as attributes.
-  verifyFormat(R"(//
-if (someThings[index].Contains(myThing)) {
-})",
-               Style);
-
-  verifyFormat(R"(//
-if (someThings[i][j][k].Contains(myThing)) {
-})",
-               Style);
-}
-
-TEST_F(FormatTestCSharp, CSharpGenericTypeConstraints) {
-  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
-
-  EXPECT_TRUE(Style.BraceWrapping.SplitEmptyRecord);
-
-  verifyFormat("class ItemFactory<T>\n"
-               "    where T : new() {\n"
-               "}",
-               Style);
-
-  verifyFormat("namespace A {\n"
-               "  delegate T MyDelegate<T>()\n"
-               "      where T : new();\n"
-               "}",
-               Style);
-
-  // When the "where" line is not to be formatted, following lines should not
-  // take on its indentation.
-  verifyFormat("class ItemFactory<T>\n"
-               "    where T : new() {\n"
-               "  int f() {}\n"
-               "}",
-               "class ItemFactory<T>\n"
-               "    where T : new() {\n"
-               "  int f() {}\n"
-               "}",
-               Style, {tooling::Range(43, 13)});
-
-  verifyFormat("class Dictionary<TKey, TVal>\n"
-               "    where TKey : IComparable<TKey>\n"
-               "    where TVal : IMyInterface {\n"
-               "  public void MyMethod<T>(T t)\n"
-               "      where T : IMyInterface {\n"
-               "    doThing();\n"
-               "  }\n"
-               "}",
-               Style);
-
-  verifyFormat("class ItemFactory<T>\n"
-               "    where T : new(), IAnInterface<T>, IAnotherInterface<T>, "
-               "IAnotherInterfaceStill<T> {\n"
-               "}",
-               Style);
-
-  Style.ColumnLimit = 50; // Force lines to be wrapped.
-  verifyFormat(R"(//
-class ItemFactory<T, U>
-    where T : new(),
-              IAnInterface<T>,
-              IAnotherInterface<T, U>,
-              IAnotherInterfaceStill<T, U> {
-})",
-               Style);
-
-  // In other languages `where` can be used as a normal identifier.
-  // This example is in C++!
-  verifyFormat(R"(//
-class A {
-  int f(int where) {}
-};)",
-               getGoogleStyle(FormatStyle::LK_Cpp));
-}
-
-TEST_F(FormatTestCSharp, CSharpAfterEnum) {
-  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
-  Style.BreakBeforeBraces = FormatStyle::BS_Custom;
-  Style.BraceWrapping.AfterEnum = false;
-  Style.AllowShortEnumsOnASingleLine = false;
-
-  verifyFormat("enum MyEnum {\n"
-               "  Foo,\n"
-               "  Bar,\n"
-               "}",
-               Style);
-  verifyFormat("internal enum MyEnum {\n"
-               "  Foo,\n"
-               "  Bar,\n"
-               "}",
-               Style);
-  verifyFormat("public enum MyEnum {\n"
-               "  Foo,\n"
-               "  Bar,\n"
-               "}",
-               Style);
-  verifyFormat("protected enum MyEnum {\n"
-               "  Foo,\n"
-               "  Bar,\n"
-               "}",
-               Style);
-  verifyFormat("private enum MyEnum {\n"
-               "  Foo,\n"
-               "  Bar,\n"
-               "}",
-               Style);
-
-  Style.BraceWrapping.AfterEnum = true;
-  Style.AllowShortEnumsOnASingleLine = false;
-
-  verifyFormat("enum MyEnum\n"
-               "{\n"
-               "  Foo,\n"
-               "  Bar,\n"
-               "}",
-               Style);
-  verifyFormat("internal enum MyEnum\n"
-               "{\n"
-               "  Foo,\n"
-               "  Bar,\n"
-               "}",
-               Style);
-  verifyFormat("public enum MyEnum\n"
-               "{\n"
-               "  Foo,\n"
-               "  Bar,\n"
-               "}",
-               Style);
-  verifyFormat("protected enum MyEnum\n"
-               "{\n"
-               "  Foo,\n"
-               "  Bar,\n"
-               "}",
-               Style);
-  verifyFormat("private enum MyEnum\n"
-               "{\n"
-               "  Foo,\n"
-               "  Bar,\n"
-               "}",
-               Style);
-  verifyFormat("/* Foo */ private enum MyEnum\n"
-               "{\n"
-               "  Foo,\n"
-               "  Bar,\n"
-               "}",
-               Style);
-  verifyFormat("/* Foo */ /* Bar */ private enum MyEnum\n"
-               "{\n"
-               "  Foo,\n"
-               "  Bar,\n"
-               "}",
-               Style);
-}
-
-TEST_F(FormatTestCSharp, CSharpAfterClass) {
-  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
-  Style.BreakBeforeBraces = FormatStyle::BS_Custom;
-  Style.BraceWrapping.AfterClass = false;
-
-  verifyFormat("class MyClass {\n"
-               "  int a;\n"
-               "  int b;\n"
-               "}",
-               Style);
-  verifyFormat("internal class MyClass {\n"
-               "  int a;\n"
-               "  int b;\n"
-               "}",
-               Style);
-  verifyFormat("public class MyClass {\n"
-               "  int a;\n"
-               "  int b;\n"
-               "}",
-               Style);
-  verifyFormat("protected class MyClass {\n"
-               "  int a;\n"
-               "  int b;\n"
-               "}",
-               Style);
-  verifyFormat("private class MyClass {\n"
-               "  int a;\n"
-               "  int b;\n"
-               "}",
-               Style);
-
-  verifyFormat("interface Interface {\n"
-               "  int a;\n"
-               "  int b;\n"
-               "}",
-               Style);
-  verifyFormat("internal interface Interface {\n"
-               "  int a;\n"
-               "  int b;\n"
-               "}",
-               Style);
-  verifyFormat("public interface Interface {\n"
-               "  int a;\n"
-               "  int b;\n"
-               "}",
-               Style);
-  verifyFormat("protected interface Interface {\n"
-               "  int a;\n"
-               "  int b;\n"
-               "}",
-               Style);
-  verifyFormat("private interface Interface {\n"
-               "  int a;\n"
-               "  int b;\n"
-               "}",
-               Style);
-
-  Style.BraceWrapping.AfterClass = true;
-
-  verifyFormat("class MyClass\n"
-               "{\n"
-               "  int a;\n"
-               "  int b;\n"
-               "}",
-               Style);
-  verifyFormat("internal class MyClass\n"
-               "{\n"
-               "  int a;\n"
-               "  int b;\n"
-               "}",
-               Style);
-  verifyFormat("public class MyClass\n"
-               "{\n"
-               "  int a;\n"
-               "  int b;\n"
-               "}",
-               Style);
-  verifyFormat("protected class MyClass\n"
-               "{\n"
-               "  int a;\n"
-               "  int b;\n"
-               "}",
-               Style);
-  verifyFormat("private class MyClass\n"
-               "{\n"
-               "  int a;\n"
-               "  int b;\n"
-               "}",
-               Style);
-
-  verifyFormat("interface MyInterface\n"
-               "{\n"
-               "  int a;\n"
-               "  int b;\n"
-               "}",
-               Style);
-  verifyFormat("internal interface MyInterface\n"
-               "{\n"
-               "  int a;\n"
-               "  int b;\n"
-               "}",
-               Style);
-  verifyFormat("public interface MyInterface\n"
-               "{\n"
-               "  int a;\n"
-               "  int b;\n"
-               "}",
-               Style);
-  verifyFormat("protected interface MyInterface\n"
-               "{\n"
-               "  int a;\n"
-               "  int b;\n"
-               "}",
-               Style);
-  verifyFormat("private interface MyInterface\n"
-               "{\n"
-               "  int a;\n"
-               "  int b;\n"
-               "}",
-               Style);
-  verifyFormat("/* Foo */ private interface MyInterface\n"
-               "{\n"
-               "  int a;\n"
-               "  int b;\n"
-               "}",
-               Style);
-  verifyFormat("/* Foo */ /* Bar */ private interface MyInterface\n"
-               "{\n"
-               "  int a;\n"
-               "  int b;\n"
-               "}",
-               Style);
-}
-
-TEST_F(FormatTestCSharp, NamespaceIndentation) {
-  FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp);
-  Style.NamespaceIndentation = FormatStyle::NI_None;
-
-  verifyFormat("namespace A\n"
-               "{\n"
-               "public interface Name1\n"
-               "{\n"
-               "}\n"
-               "}",
-               Style);
-
-  verifyFormat("namespace A.B\n"
-               "{\n"
-               "public interface Name1\n"
-               "{\n"
-               "}\n"
-               "}",
-               Style);
-
-  Style.NamespaceIndentation = FormatStyle::NI_Inner;
-
-  verifyFormat("namespace A\n"
-               "{\n"
-               "namespace B\n"
-               "{\n"
-               "    public interface Name1\n"
-               "    {\n"
-               "    }\n"
-               "}\n"
-               "}",
-               Style);
-
-  Style.NamespaceIndentation = FormatStyle::NI_All;
-
-  verifyFormat("namespace A.B\n"
-               "{\n"
-               "    public interface Name1\n"
-               "    {\n"
-               "    }\n"
-               "}",
-               Style);
-
-  verifyFormat("namespace A\n"
-               "{\n"
-               "    namespace B\n"
-               "    {\n"
-               "        public interface Name1\n"
-               "        {\n"
-               "        }\n"
-               "    }\n"
-               "}",
-               Style);
-}
-
-TEST_F(FormatTestCSharp, SwitchExpression) {
-  FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp);
-  verifyFormat("int x = a switch {\n"
-               "    1 => (0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0),\n"
-               "    2 => 1,\n"
-               "    _ => 2\n"
-               "};",
-               Style);
-}
-
-TEST_F(FormatTestCSharp, EmptyShortBlock) {
-  auto Style = getLLVMStyle();
-  Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Empty;
-
-  verifyFormat("try {\n"
-               "  doA();\n"
-               "} catch (Exception e) {\n"
-               "  e.printStackTrace();\n"
-               "}",
-               Style);
-
-  verifyFormat("try {\n"
-               "  doA();\n"
-               "} catch (Exception e) {}",
-               Style);
-}
-
-TEST_F(FormatTestCSharp, ShortFunctions) {
-  FormatStyle Style = getLLVMStyle(FormatStyle::LK_CSharp);
-  Style.NamespaceIndentation = FormatStyle::NI_All;
-  Style.AllowShortFunctionsOnASingleLine =
-      FormatStyle::ShortFunctionStyle::setEmptyAndInline();
-  verifyFormat("interface Interface {\n"
-               "  void f() { return; }\n"
-               "};",
-               Style);
-  verifyFormat("public interface Interface {\n"
-               "  void f() { return; }\n"
-               "};",
-               Style);
-  verifyFormat("namespace {\n"
-               "  void f() {\n"
-               "    return;\n"
-               "  }\n"
-               "};",
-               Style);
-  // "union" is not a keyword in C#.
-  verifyFormat("namespace union {\n"
-               "  void f() {\n"
-               "    return;\n"
-               "  }\n"
-               "};",
-               Style);
-}
-
-TEST_F(FormatTestCSharp, BrokenBrackets) {
-  EXPECT_NE("", format("int where b <")); // reduced from crasher
-}
-
-TEST_F(FormatTestCSharp, GotoCaseLabel) {
-  verifyFormat("switch (i)\n"
-               "{\n"
-               "case 0:\n"
-               "    goto case 1;\n"
-               "case 1:\n"
-               "    j = 0;\n"
-               "    {\n"
-               "        break;\n"
-               "    }\n"
-               "}",
-               "switch (i) {\n"
-               "case 0:\n"
-               "  goto case 1;\n"
-               "case 1:\n"
-               "  j = 0;\n"
-               "  {\n"
-               "    break;\n"
-               "  }\n"
-               "}");
-}
-
-} // namespace
-} // namespace test
-} // namespace format
-} // namespace clang

>From 6afd907fa3cf18b0c34cc3d6d298cfefb5e2aecf Mon Sep 17 00:00:00 2001
From: owenca <owenpiano at gmail.com>
Date: Sat, 14 Mar 2026 20:37:57 -0700
Subject: [PATCH 21/21] Add tests for AllowShortFunctionsOnASingleLine

---
 clang/unittests/Format/ConfigParseTest.cpp | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index ec27951afcbc6..8cd0dd840acf8 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -231,6 +231,9 @@ TEST(ConfigParseTest, ParsesConfigurationBools) {
   CHECK_PARSE_NESTED_BOOL(AlignConsecutiveShortCaseStatements, AcrossComments);
   CHECK_PARSE_NESTED_BOOL(AlignConsecutiveShortCaseStatements, AlignCaseArrows);
   CHECK_PARSE_NESTED_BOOL(AlignConsecutiveShortCaseStatements, AlignCaseColons);
+  CHECK_PARSE_NESTED_BOOL(AllowShortFunctionsOnASingleLine, Empty);
+  CHECK_PARSE_NESTED_BOOL(AllowShortFunctionsOnASingleLine, Inline);
+  CHECK_PARSE_NESTED_BOOL(AllowShortFunctionsOnASingleLine, Other);
   CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterCaseLabel);
   CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterClass);
   CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterEnum);
@@ -687,7 +690,7 @@ TEST(ConfigParseTest, ParsesConfiguration) {
 
   CHECK_PARSE("AllowShortFunctionsOnASingleLine: None",
               AllowShortFunctionsOnASingleLine,
-              FormatStyle::ShortFunctionStyle({}));
+              FormatStyle::ShortFunctionStyle());
   CHECK_PARSE("AllowShortFunctionsOnASingleLine: Inline",
               AllowShortFunctionsOnASingleLine,
               FormatStyle::ShortFunctionStyle::setEmptyAndInline());
@@ -704,7 +707,7 @@ TEST(ConfigParseTest, ParsesConfiguration) {
   // For backward compatibility:
   CHECK_PARSE("AllowShortFunctionsOnASingleLine: false",
               AllowShortFunctionsOnASingleLine,
-              FormatStyle::ShortFunctionStyle({}));
+              FormatStyle::ShortFunctionStyle());
   CHECK_PARSE("AllowShortFunctionsOnASingleLine: true",
               AllowShortFunctionsOnASingleLine,
               FormatStyle::ShortFunctionStyle::setAll());



More information about the cfe-commits mailing list