Skip to content

Commit

Permalink
Fixes bug 20587 - Add K&R break before braces style
Browse files Browse the repository at this point in the history
Summary:
http://llvm.org/bugs/show_bug.cgi?id=20587

Added K&R style. It could be enabled by the following option:

```
BreakBeforeBraces: KernighanRitchie
```

This style is like `Attach`, but break *only* before function
declarations.

As I can see, no additional logic required to support this style, any
style different from other styles automagically satisfies K&R.

Reviewers: djasper

Reviewed By: djasper

Subscribers: cfe-commits, klimek

Differential Revision: http://reviews.llvm.org/D4837

llvm-svn: 215354
  • Loading branch information
roman-kashitsyn committed Aug 11, 2014
1 parent 5082ce0 commit a043ced
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 42 deletions.
24 changes: 18 additions & 6 deletions clang/lib/Format/UnwrappedLineParser.cpp
Expand Up @@ -434,6 +434,19 @@ static bool IsGoogScope(const UnwrappedLine &Line) {
return I->Tok->is(tok::l_paren);
}

static bool ShouldBreakBeforeBrace(const FormatStyle &Style,
const FormatToken &InitialToken) {
switch (Style.BreakBeforeBraces) {
case FormatStyle::BS_Linux:
return InitialToken.isOneOf(tok::kw_namespace, tok::kw_class);
case FormatStyle::BS_Allman:
case FormatStyle::BS_GNU:
return true;
default:
return false;
}
}

void UnwrappedLineParser::parseChildBlock() {
FormatTok->BlockKind = BK_Block;
nextToken();
Expand Down Expand Up @@ -1167,13 +1180,13 @@ void UnwrappedLineParser::parseTryCatch() {

void UnwrappedLineParser::parseNamespace() {
assert(FormatTok->Tok.is(tok::kw_namespace) && "'namespace' expected");

const FormatToken &InitialToken = *FormatTok;
nextToken();
if (FormatTok->Tok.is(tok::identifier))
nextToken();
if (FormatTok->Tok.is(tok::l_brace)) {
if (Style.BreakBeforeBraces == FormatStyle::BS_Linux ||
Style.BreakBeforeBraces == FormatStyle::BS_Allman ||
Style.BreakBeforeBraces == FormatStyle::BS_GNU)
if (ShouldBreakBeforeBrace(Style, InitialToken))
addUnwrappedLine();

bool AddLevel = Style.NamespaceIndentation == FormatStyle::NI_All ||
Expand Down Expand Up @@ -1327,6 +1340,7 @@ void UnwrappedLineParser::parseEnum() {
}

void UnwrappedLineParser::parseRecord() {
const FormatToken &InitialToken = *FormatTok;
nextToken();
if (FormatTok->isOneOf(tok::identifier, tok::coloncolon, tok::kw___attribute,
tok::kw___declspec, tok::kw_alignas)) {
Expand Down Expand Up @@ -1361,9 +1375,7 @@ void UnwrappedLineParser::parseRecord() {
}
}
if (FormatTok->Tok.is(tok::l_brace)) {
if (Style.BreakBeforeBraces == FormatStyle::BS_Linux ||
Style.BreakBeforeBraces == FormatStyle::BS_Allman ||
Style.BreakBeforeBraces == FormatStyle::BS_GNU)
if (ShouldBreakBeforeBrace(Style, InitialToken))
addUnwrappedLine();

parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/true,
Expand Down
98 changes: 62 additions & 36 deletions clang/unittests/Format/FormatTest.cpp
Expand Up @@ -7671,8 +7671,8 @@ TEST_F(FormatTest, ConfigurableSpaceBeforeAssignmentOperators) {
}

TEST_F(FormatTest, LinuxBraceBreaking) {
FormatStyle BreakBeforeBrace = getLLVMStyle();
BreakBeforeBrace.BreakBeforeBraces = FormatStyle::BS_Linux;
FormatStyle LinuxBraceStyle = getLLVMStyle();
LinuxBraceStyle.BreakBeforeBraces = FormatStyle::BS_Linux;
verifyFormat("namespace a\n"
"{\n"
"class A\n"
Expand All @@ -7685,14 +7685,33 @@ TEST_F(FormatTest, LinuxBraceBreaking) {
" }\n"
" }\n"
" void g() { return; }\n"
"}\n"
"}",
BreakBeforeBrace);
"};\n"
"struct B {\n"
" int x;\n"
"};\n"
"}\n",
LinuxBraceStyle);
verifyFormat("enum X {\n"
" Y = 0,\n"
"}\n",
LinuxBraceStyle);
verifyFormat("struct S {\n"
" int Type;\n"
" union {\n"
" int x;\n"
" double y;\n"
" } Value;\n"
" class C\n"
" {\n"
" MyFavoriteType Value;\n"
" } Class;\n"
"}\n",
LinuxBraceStyle);
}

TEST_F(FormatTest, StroustrupBraceBreaking) {
FormatStyle BreakBeforeBrace = getLLVMStyle();
BreakBeforeBrace.BreakBeforeBraces = FormatStyle::BS_Stroustrup;
FormatStyle StroustrupBraceStyle = getLLVMStyle();
StroustrupBraceStyle.BreakBeforeBraces = FormatStyle::BS_Stroustrup;
verifyFormat("namespace a {\n"
"class A {\n"
" void f()\n"
Expand All @@ -7703,9 +7722,12 @@ TEST_F(FormatTest, StroustrupBraceBreaking) {
" }\n"
" }\n"
" void g() { return; }\n"
"}\n"
"}",
BreakBeforeBrace);
"};\n"
"struct B {\n"
" int x;\n"
"};\n"
"}\n",
StroustrupBraceStyle);

verifyFormat("void foo()\n"
"{\n"
Expand All @@ -7716,7 +7738,7 @@ TEST_F(FormatTest, StroustrupBraceBreaking) {
" b();\n"
" }\n"
"}\n",
BreakBeforeBrace);
StroustrupBraceStyle);

verifyFormat("#ifdef _DEBUG\n"
"int foo(int i = 0)\n"
Expand All @@ -7726,7 +7748,7 @@ TEST_F(FormatTest, StroustrupBraceBreaking) {
"{\n"
" return i;\n"
"}",
BreakBeforeBrace);
StroustrupBraceStyle);

verifyFormat("void foo() {}\n"
"void bar()\n"
Expand All @@ -7738,20 +7760,20 @@ TEST_F(FormatTest, StroustrupBraceBreaking) {
"{\n"
"}\n"
"#endif",
BreakBeforeBrace);
StroustrupBraceStyle);

verifyFormat("void foobar() { int i = 5; }\n"
"#ifdef _DEBUG\n"
"void bar() {}\n"
"#else\n"
"void bar() { foobar(); }\n"
"#endif",
BreakBeforeBrace);
StroustrupBraceStyle);
}

TEST_F(FormatTest, AllmanBraceBreaking) {
FormatStyle BreakBeforeBrace = getLLVMStyle();
BreakBeforeBrace.BreakBeforeBraces = FormatStyle::BS_Allman;
FormatStyle AllmanBraceStyle = getLLVMStyle();
AllmanBraceStyle.BreakBeforeBraces = FormatStyle::BS_Allman;
verifyFormat("namespace a\n"
"{\n"
"class A\n"
Expand All @@ -7765,9 +7787,13 @@ TEST_F(FormatTest, AllmanBraceBreaking) {
" }\n"
" }\n"
" void g() { return; }\n"
"}\n"
"};\n"
"struct B\n"
"{\n"
" int x;\n"
"};\n"
"}",
BreakBeforeBrace);
AllmanBraceStyle);

verifyFormat("void f()\n"
"{\n"
Expand All @@ -7784,7 +7810,7 @@ TEST_F(FormatTest, AllmanBraceBreaking) {
" c();\n"
" }\n"
"}\n",
BreakBeforeBrace);
AllmanBraceStyle);

verifyFormat("void f()\n"
"{\n"
Expand All @@ -7801,7 +7827,7 @@ TEST_F(FormatTest, AllmanBraceBreaking) {
" c();\n"
" } while (false)\n"
"}\n",
BreakBeforeBrace);
AllmanBraceStyle);

verifyFormat("void f(int a)\n"
"{\n"
Expand All @@ -7821,26 +7847,26 @@ TEST_F(FormatTest, AllmanBraceBreaking) {
" break;\n"
" }\n"
"}\n",
BreakBeforeBrace);
AllmanBraceStyle);

verifyFormat("enum X\n"
"{\n"
" Y = 0,\n"
"}\n",
BreakBeforeBrace);
AllmanBraceStyle);
verifyFormat("enum X\n"
"{\n"
" Y = 0\n"
"}\n",
BreakBeforeBrace);
AllmanBraceStyle);

verifyFormat("@interface BSApplicationController ()\n"
"{\n"
"@private\n"
" id _extraIvar;\n"
"}\n"
"@end\n",
BreakBeforeBrace);
AllmanBraceStyle);

verifyFormat("#ifdef _DEBUG\n"
"int foo(int i = 0)\n"
Expand All @@ -7850,7 +7876,7 @@ TEST_F(FormatTest, AllmanBraceBreaking) {
"{\n"
" return i;\n"
"}",
BreakBeforeBrace);
AllmanBraceStyle);

verifyFormat("void foo() {}\n"
"void bar()\n"
Expand All @@ -7862,45 +7888,45 @@ TEST_F(FormatTest, AllmanBraceBreaking) {
"{\n"
"}\n"
"#endif",
BreakBeforeBrace);
AllmanBraceStyle);

verifyFormat("void foobar() { int i = 5; }\n"
"#ifdef _DEBUG\n"
"void bar() {}\n"
"#else\n"
"void bar() { foobar(); }\n"
"#endif",
BreakBeforeBrace);
AllmanBraceStyle);

// This shouldn't affect ObjC blocks..
verifyFormat("[self doSomeThingWithACompletionHandler:^{\n"
" // ...\n"
" int i;\n"
"}];",
BreakBeforeBrace);
AllmanBraceStyle);
verifyFormat("void (^block)(void) = ^{\n"
" // ...\n"
" int i;\n"
"};",
BreakBeforeBrace);
AllmanBraceStyle);
// .. or dict literals.
verifyFormat("void f()\n"
"{\n"
" [object someMethod:@{ @\"a\" : @\"b\" }];\n"
"}",
BreakBeforeBrace);
AllmanBraceStyle);

BreakBeforeBrace.ColumnLimit = 19;
verifyFormat("void f() { int i; }", BreakBeforeBrace);
BreakBeforeBrace.ColumnLimit = 18;
AllmanBraceStyle.ColumnLimit = 19;
verifyFormat("void f() { int i; }", AllmanBraceStyle);
AllmanBraceStyle.ColumnLimit = 18;
verifyFormat("void f()\n"
"{\n"
" int i;\n"
"}",
BreakBeforeBrace);
BreakBeforeBrace.ColumnLimit = 80;
AllmanBraceStyle);
AllmanBraceStyle.ColumnLimit = 80;

FormatStyle BreakBeforeBraceShortIfs = BreakBeforeBrace;
FormatStyle BreakBeforeBraceShortIfs = AllmanBraceStyle;
BreakBeforeBraceShortIfs.AllowShortIfStatementsOnASingleLine = true;
BreakBeforeBraceShortIfs.AllowShortLoopsOnASingleLine = true;
verifyFormat("void f(bool b)\n"
Expand Down

0 comments on commit a043ced

Please sign in to comment.