Index: clang/include/clang/Format/Format.h =================================================================== --- clang/include/clang/Format/Format.h +++ clang/include/clang/Format/Format.h @@ -55,6 +55,18 @@ /// The extra indent or outdent of access modifiers, e.g. ``public:``. int AccessModifierOffset; + /// If true, the empty line is inserted before access modifiers + /// \code + /// true: false: + /// struct foo { vs. struct foo { + /// int i; int i; + /// private: + /// private: int j; + /// int j; } + /// } + /// \endcode + bool InsertEmptyLineBeforeAccessModifier; + /// Different styles for aligning after open brackets. enum BracketAlignmentStyle { /// Align parameters on the open bracket, e.g.: @@ -2355,6 +2367,8 @@ IndentExternBlock == R.IndentExternBlock && IndentWidth == R.IndentWidth && Language == R.Language && IndentWrappedFunctionNames == R.IndentWrappedFunctionNames && + InsertEmptyLineBeforeAccessModifier == + R.InsertEmptyLineBeforeAccessModifier && JavaImportGroups == R.JavaImportGroups && JavaScriptQuotes == R.JavaScriptQuotes && JavaScriptWrapImports == R.JavaScriptWrapImports && Index: clang/lib/Format/Format.cpp =================================================================== --- clang/lib/Format/Format.cpp +++ clang/lib/Format/Format.cpp @@ -411,6 +411,8 @@ } IO.mapOptional("AccessModifierOffset", Style.AccessModifierOffset); + IO.mapOptional("InsertEmptyLineBeforeAccessModifier", + Style.InsertEmptyLineBeforeAccessModifier); IO.mapOptional("AlignAfterOpenBracket", Style.AlignAfterOpenBracket); IO.mapOptional("AlignConsecutiveMacros", Style.AlignConsecutiveMacros); IO.mapOptional("AlignConsecutiveAssignments", @@ -884,6 +886,7 @@ LLVMStyle.IndentPPDirectives = FormatStyle::PPDIS_None; LLVMStyle.IndentWrappedFunctionNames = false; LLVMStyle.IndentWidth = 2; + LLVMStyle.InsertEmptyLineBeforeAccessModifier = true; LLVMStyle.InsertTrailingCommas = FormatStyle::TCS_None; LLVMStyle.JavaScriptQuotes = FormatStyle::JSQS_Leave; LLVMStyle.JavaScriptWrapImports = true; Index: clang/lib/Format/UnwrappedLineFormatter.cpp =================================================================== --- clang/lib/Format/UnwrappedLineFormatter.cpp +++ clang/lib/Format/UnwrappedLineFormatter.cpp @@ -1216,10 +1216,17 @@ Newlines = 1; // Insert extra new line before access specifiers. - if (PreviousLine && PreviousLine->Last->isOneOf(tok::semi, tok::r_brace) && + if (Style.InsertEmptyLineBeforeAccessModifier && PreviousLine && + PreviousLine->Last->isOneOf(tok::semi, tok::r_brace) && RootToken.isAccessSpecifier() && RootToken.NewlinesBefore == 1) ++Newlines; + // Remove empty lines before access specifiers. + if (!Style.InsertEmptyLineBeforeAccessModifier && PreviousLine && + PreviousLine->Last->isOneOf(tok::semi, tok::r_brace, tok::l_brace) && + RootToken.isAccessSpecifier() && RootToken.NewlinesBefore > 1) + Newlines = 1; + // Remove empty lines after access specifiers. if (PreviousLine && PreviousLine->First->isAccessSpecifier() && (!PreviousLine->InPPDirective || !RootToken.HasUnescapedNewline)) Index: clang/test/Format/access-modifiers.cpp =================================================================== --- /dev/null +++ clang/test/Format/access-modifiers.cpp @@ -0,0 +1,63 @@ +// RUN: grep -Ev "// *[A-Z-]+:" %s \ +// RUN: | clang-format -style="{BasedOnStyle: LLVM, InsertEmptyLineBeforeAccessModifier: true}" -lines=1:10 \ +// RUN: | clang-format -style="{BasedOnStyle: LLVM, InsertEmptyLineBeforeAccessModifier: false}" -lines=11:32 \ +// 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 i +// CHECK-NEXT: {{^private:$}} +// CHECK: } +struct foo3 { + int i; + +private: + int j; +} + +// CHECK: struct bar3 +// CHECK-NEXT: {{^private:$}} +// CHECK: } +struct bar3 { + +private: + int i; + int j; +}