**DisableFormat** (``bool``)
Disables formatting completely.
+**EmptyLineBeforeAccessModifier** (``EmptyLineBeforeAccessModifierStyle``)
+ Defines in which cases to put empty line before access modifiers.
+
+ Possible values:
+
+ * ``ELBAMS_Never`` (in configuration: ``Never``)
+ Remove all empty lines before access modifiers.
+
+ .. code-block:: c++
+
+ struct foo {
+ private:
+ int i;
+ protected:
+ int j;
+ /* comment */
+ public:
+ foo() {}
+ private:
+ protected:
+ };
+
+ * ``ELBAMS_Leave`` (in configuration: ``Leave``)
+ Keep existing empty lines before access modifiers.
+
+ * ``ELBAMS_LogicalBlock`` (in configuration: ``LogicalBlock``)
+ Add empty line only when access modifier starts a new logical block.
+ Logical block is a group of one or more member fields or functions.
+
+ .. code-block:: c++
+
+ struct foo {
+ private:
+ int i;
+
+ protected:
+ int j;
+ /* comment */
+ public:
+ foo() {}
+
+ private:
+ protected:
+ };
+
+ * ``ELBAMS_Always`` (in configuration: ``Always``)
+ Always add empty line before access modifiers unless access modifier
+ is at the start of struct or class definition.
+
+ .. code-block:: c++
+
+ struct foo {
+ private:
+ int i;
+
+ protected:
+ int j;
+ /* comment */
+
+ public:
+ foo() {}
+
+ private:
+
+ protected:
+ };
+
+
+
**ExperimentalAutoDetectBinPacking** (``bool``)
If ``true``, clang-format detects whether function calls and
definitions are formatted with one parameter per line.
/// Disables formatting completely.
bool DisableFormat;
+ /// Different styles for empty line before access modifiers.
+ enum EmptyLineBeforeAccessModifierStyle : unsigned char {
+ /// Remove all empty lines before access modifiers.
+ /// \code
+ /// struct foo {
+ /// private:
+ /// int i;
+ /// protected:
+ /// int j;
+ /// /* comment */
+ /// public:
+ /// foo() {}
+ /// private:
+ /// protected:
+ /// };
+ /// \endcode
+ ELBAMS_Never,
+ /// Keep existing empty lines before access modifiers.
+ ELBAMS_Leave,
+ /// Add empty line only when access modifier starts a new logical block.
+ /// Logical block is a group of one or more member fields or functions.
+ /// \code
+ /// struct foo {
+ /// private:
+ /// int i;
+ ///
+ /// protected:
+ /// int j;
+ /// /* comment */
+ /// public:
+ /// foo() {}
+ ///
+ /// private:
+ /// protected:
+ /// };
+ /// \endcode
+ ELBAMS_LogicalBlock,
+ /// Always add empty line before access modifiers unless access modifier
+ /// is at the start of struct or class definition.
+ /// \code
+ /// struct foo {
+ /// private:
+ /// int i;
+ ///
+ /// protected:
+ /// int j;
+ /// /* comment */
+ ///
+ /// public:
+ /// foo() {}
+ ///
+ /// private:
+ ///
+ /// protected:
+ /// };
+ /// \endcode
+ ELBAMS_Always,
+ };
+
+ /// Defines in which cases to put empty line before access modifiers.
+ EmptyLineBeforeAccessModifierStyle EmptyLineBeforeAccessModifier;
+
/// If ``true``, clang-format detects whether function calls and
/// definitions are formatted with one parameter per line.
///
DeriveLineEnding == R.DeriveLineEnding &&
DerivePointerAlignment == R.DerivePointerAlignment &&
DisableFormat == R.DisableFormat &&
+ EmptyLineBeforeAccessModifier == R.EmptyLineBeforeAccessModifier &&
ExperimentalAutoDetectBinPacking ==
R.ExperimentalAutoDetectBinPacking &&
FixNamespaceComments == R.FixNamespaceComments &&
};
template <>
+struct ScalarEnumerationTraits<
+ FormatStyle::EmptyLineBeforeAccessModifierStyle> {
+ static void
+ enumeration(IO &IO, FormatStyle::EmptyLineBeforeAccessModifierStyle &Value) {
+ IO.enumCase(Value, "Never", FormatStyle::ELBAMS_Never);
+ IO.enumCase(Value, "Leave", FormatStyle::ELBAMS_Leave);
+ IO.enumCase(Value, "LogicalBlock", FormatStyle::ELBAMS_LogicalBlock);
+ IO.enumCase(Value, "Always", FormatStyle::ELBAMS_Always);
+ }
+};
+
+template <>
struct ScalarEnumerationTraits<FormatStyle::PPDirectiveIndentStyle> {
static void enumeration(IO &IO, FormatStyle::PPDirectiveIndentStyle &Value) {
IO.enumCase(Value, "None", FormatStyle::PPDIS_None);
IO.mapOptional("DeriveLineEnding", Style.DeriveLineEnding);
IO.mapOptional("DerivePointerAlignment", Style.DerivePointerAlignment);
IO.mapOptional("DisableFormat", Style.DisableFormat);
+ IO.mapOptional("EmptyLineBeforeAccessModifier",
+ Style.EmptyLineBeforeAccessModifier);
IO.mapOptional("ExperimentalAutoDetectBinPacking",
Style.ExperimentalAutoDetectBinPacking);
IO.mapOptional("FixNamespaceComments", Style.FixNamespaceComments);
LLVMStyle.Cpp11BracedListStyle = true;
LLVMStyle.DeriveLineEnding = true;
LLVMStyle.DerivePointerAlignment = false;
+ LLVMStyle.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_LogicalBlock;
LLVMStyle.ExperimentalAutoDetectBinPacking = false;
LLVMStyle.FixNamespaceComments = true;
LLVMStyle.ForEachMacros.push_back("foreach");
!startsExternCBlock(*PreviousLine))
Newlines = 1;
- // Insert extra new line before access specifiers.
- if (PreviousLine && PreviousLine->Last->isOneOf(tok::semi, tok::r_brace) &&
- RootToken.isAccessSpecifier() && RootToken.NewlinesBefore == 1)
- ++Newlines;
+ // Insert or remove empty line before access specifiers.
+ if (PreviousLine && RootToken.isAccessSpecifier()) {
+ switch (Style.EmptyLineBeforeAccessModifier) {
+ case FormatStyle::ELBAMS_Never:
+ if (RootToken.NewlinesBefore > 1)
+ Newlines = 1;
+ break;
+ case FormatStyle::ELBAMS_Leave:
+ Newlines = std::max(RootToken.NewlinesBefore, 1u);
+ break;
+ case FormatStyle::ELBAMS_LogicalBlock:
+ if (PreviousLine->Last->isOneOf(tok::semi, tok::r_brace) &&
+ RootToken.NewlinesBefore <= 1)
+ Newlines = 2;
+ break;
+ case FormatStyle::ELBAMS_Always: {
+ const FormatToken *previousToken;
+ if (PreviousLine->Last->is(tok::comment))
+ previousToken = PreviousLine->Last->getPreviousNonComment();
+ else
+ previousToken = PreviousLine->Last;
+ if ((!previousToken || !previousToken->is(tok::l_brace)) &&
+ RootToken.NewlinesBefore <= 1)
+ Newlines = 2;
+ } break;
+ }
+ }
// Remove empty lines after access specifiers.
if (PreviousLine && PreviousLine->First->isAccessSpecifier() &&
--- /dev/null
+// RUN: grep -Ev "// *[A-Z-]+:" %s \
+// RUN: | clang-format -style="{BasedOnStyle: LLVM, EmptyLineBeforeAccessModifier: LogicalBlock}" -lines=1:14 \
+// RUN: | clang-format -style="{BasedOnStyle: LLVM, EmptyLineBeforeAccessModifier: Never}" -lines=14:40 \
+// RUN: | FileCheck -strict-whitespace %s
+
+// CHECK: int i
+// CHECK-NEXT: {{^$}}
+// CHECK-NEXT: {{^private:$}}
+// CHECK: }
+struct foo1 {
+ int i;
+
+private:
+ int j;
+};
+
+// CHECK: struct bar1
+// CHECK-NEXT: {{^private:$}}
+// CHECK: }
+struct bar1 {
+private:
+ int i;
+ int j;
+};
+
+// CHECK: int i
+// CHECK-NEXT: {{^private:$}}
+// CHECK: }
+struct foo2 {
+ int i;
+
+private:
+ int j;
+};
+
+// CHECK: struct bar2
+// CHECK-NEXT: {{^private:$}}
+// CHECK: }
+struct bar2 {
+private:
+ int i;
+ int j;
+};
+
+// CHECK: int j
+// CHECK-NEXT: {{^private:$}}
+// CHECK: }
+struct foo3 {
+ int i;
+ int j;
+
+private:
+};
+
+// CHECK: struct bar3
+// CHECK-NEXT: {{^private:$}}
+// CHECK: }
+struct bar3 {
+
+private:
+ int i;
+ int j;
+};
getLLVMStyle());
}
+TEST_F(FormatTest, FormatsAccessModifiers) {
+ FormatStyle Style = getLLVMStyle();
+ EXPECT_EQ(Style.EmptyLineBeforeAccessModifier,
+ FormatStyle::ELBAMS_LogicalBlock);
+ verifyFormat("struct foo {\n"
+ "private:\n"
+ " void f() {}\n"
+ "\n"
+ "private:\n"
+ " int i;\n"
+ "\n"
+ "protected:\n"
+ " int j;\n"
+ "};\n",
+ Style);
+ verifyFormat("struct foo {\n"
+ "private:\n"
+ " void f() {}\n"
+ "\n"
+ "private:\n"
+ " int i;\n"
+ "\n"
+ "protected:\n"
+ " int j;\n"
+ "};\n",
+ "struct foo {\n"
+ "private:\n"
+ " void f() {}\n"
+ "private:\n"
+ " int i;\n"
+ "protected:\n"
+ " int j;\n"
+ "};\n",
+ Style);
+ verifyFormat("struct foo { /* comment */\n"
+ "private:\n"
+ " int i;\n"
+ " // comment\n"
+ "private:\n"
+ " int j;\n"
+ "};\n",
+ Style);
+ verifyFormat("struct foo {\n"
+ "#ifdef FOO\n"
+ "#endif\n"
+ "private:\n"
+ " int i;\n"
+ "#ifdef FOO\n"
+ "private:\n"
+ "#endif\n"
+ " int j;\n"
+ "};\n",
+ Style);
+ Style.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_Never;
+ verifyFormat("struct foo {\n"
+ "private:\n"
+ " void f() {}\n"
+ "private:\n"
+ " int i;\n"
+ "protected:\n"
+ " int j;\n"
+ "};\n",
+ Style);
+ verifyFormat("struct foo {\n"
+ "private:\n"
+ " void f() {}\n"
+ "private:\n"
+ " int i;\n"
+ "protected:\n"
+ " int j;\n"
+ "};\n",
+ "struct foo {\n"
+ "\n"
+ "private:\n"
+ " void f() {}\n"
+ "\n"
+ "private:\n"
+ " int i;\n"
+ "\n"
+ "protected:\n"
+ " int j;\n"
+ "};\n",
+ Style);
+ verifyFormat("struct foo { /* comment */\n"
+ "private:\n"
+ " int i;\n"
+ " // comment\n"
+ "private:\n"
+ " int j;\n"
+ "};\n",
+ "struct foo { /* comment */\n"
+ "\n"
+ "private:\n"
+ " int i;\n"
+ " // comment\n"
+ "\n"
+ "private:\n"
+ " int j;\n"
+ "};\n",
+ Style);
+ verifyFormat("struct foo {\n"
+ "#ifdef FOO\n"
+ "#endif\n"
+ "private:\n"
+ " int i;\n"
+ "#ifdef FOO\n"
+ "private:\n"
+ "#endif\n"
+ " int j;\n"
+ "};\n",
+ "struct foo {\n"
+ "#ifdef FOO\n"
+ "#endif\n"
+ "\n"
+ "private:\n"
+ " int i;\n"
+ "#ifdef FOO\n"
+ "\n"
+ "private:\n"
+ "#endif\n"
+ " int j;\n"
+ "};\n",
+ Style);
+ Style.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_Always;
+ verifyFormat("struct foo {\n"
+ "private:\n"
+ " void f() {}\n"
+ "\n"
+ "private:\n"
+ " int i;\n"
+ "\n"
+ "protected:\n"
+ " int j;\n"
+ "};\n",
+ Style);
+ verifyFormat("struct foo {\n"
+ "private:\n"
+ " void f() {}\n"
+ "\n"
+ "private:\n"
+ " int i;\n"
+ "\n"
+ "protected:\n"
+ " int j;\n"
+ "};\n",
+ "struct foo {\n"
+ "private:\n"
+ " void f() {}\n"
+ "private:\n"
+ " int i;\n"
+ "protected:\n"
+ " int j;\n"
+ "};\n",
+ Style);
+ verifyFormat("struct foo { /* comment */\n"
+ "private:\n"
+ " int i;\n"
+ " // comment\n"
+ "\n"
+ "private:\n"
+ " int j;\n"
+ "};\n",
+ "struct foo { /* comment */\n"
+ "private:\n"
+ " int i;\n"
+ " // comment\n"
+ "\n"
+ "private:\n"
+ " int j;\n"
+ "};\n",
+ Style);
+ verifyFormat("struct foo {\n"
+ "#ifdef FOO\n"
+ "#endif\n"
+ "\n"
+ "private:\n"
+ " int i;\n"
+ "#ifdef FOO\n"
+ "\n"
+ "private:\n"
+ "#endif\n"
+ " int j;\n"
+ "};\n",
+ "struct foo {\n"
+ "#ifdef FOO\n"
+ "#endif\n"
+ "private:\n"
+ " int i;\n"
+ "#ifdef FOO\n"
+ "private:\n"
+ "#endif\n"
+ " int j;\n"
+ "};\n",
+ Style);
+ Style.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_Leave;
+ EXPECT_EQ("struct foo {\n"
+ "\n"
+ "private:\n"
+ " void f() {}\n"
+ "\n"
+ "private:\n"
+ " int i;\n"
+ "\n"
+ "protected:\n"
+ " int j;\n"
+ "};\n",
+ format("struct foo {\n"
+ "\n"
+ "private:\n"
+ " void f() {}\n"
+ "\n"
+ "private:\n"
+ " int i;\n"
+ "\n"
+ "protected:\n"
+ " int j;\n"
+ "};\n",
+ Style));
+ verifyFormat("struct foo {\n"
+ "private:\n"
+ " void f() {}\n"
+ "private:\n"
+ " int i;\n"
+ "protected:\n"
+ " int j;\n"
+ "};\n",
+ Style);
+ EXPECT_EQ("struct foo { /* comment */\n"
+ "\n"
+ "private:\n"
+ " int i;\n"
+ " // comment\n"
+ "\n"
+ "private:\n"
+ " int j;\n"
+ "};\n",
+ format("struct foo { /* comment */\n"
+ "\n"
+ "private:\n"
+ " int i;\n"
+ " // comment\n"
+ "\n"
+ "private:\n"
+ " int j;\n"
+ "};\n",
+ Style));
+ verifyFormat("struct foo { /* comment */\n"
+ "private:\n"
+ " int i;\n"
+ " // comment\n"
+ "private:\n"
+ " int j;\n"
+ "};\n",
+ Style);
+ EXPECT_EQ("struct foo {\n"
+ "#ifdef FOO\n"
+ "#endif\n"
+ "\n"
+ "private:\n"
+ " int i;\n"
+ "#ifdef FOO\n"
+ "\n"
+ "private:\n"
+ "#endif\n"
+ " int j;\n"
+ "};\n",
+ format("struct foo {\n"
+ "#ifdef FOO\n"
+ "#endif\n"
+ "\n"
+ "private:\n"
+ " int i;\n"
+ "#ifdef FOO\n"
+ "\n"
+ "private:\n"
+ "#endif\n"
+ " int j;\n"
+ "};\n",
+ Style));
+ verifyFormat("struct foo {\n"
+ "#ifdef FOO\n"
+ "#endif\n"
+ "private:\n"
+ " int i;\n"
+ "#ifdef FOO\n"
+ "private:\n"
+ "#endif\n"
+ " int j;\n"
+ "};\n",
+ Style);
+}
+
TEST_F(FormatTest, FormatsArrays) {
verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaa[aaaaaaaaaaaaaaaaaaaaaaaaa]\n"
" [bbbbbbbbbbbbbbbbbbbbbbbbb] = c;");
CHECK_PARSE("BreakBeforeInheritanceComma: true", BreakInheritanceList,
FormatStyle::BILS_BeforeComma);
+ 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.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak;
CHECK_PARSE("AlignAfterOpenBracket: Align", AlignAfterOpenBracket,
FormatStyle::BAS_Align);