[clang-format] New flag - BraceWrapping.AfterExternBlock

Summary:
Bug: https://bugs.llvm.org/show_bug.cgi?id=34016 - **"extern C part"**

**Problem:**

Due to the lack of "brace wrapping extern" flag, clang format does parse the block after **extern** keyword moving the opening bracket to the header line always!

**Patch description:**

A new style added, new configuration flag - **BraceWrapping.AfterExternBlock** that allows us to decide whether we want a break before brace or not.

Reviewers: djasper, krasimir

Reviewed By: krasimir

Subscribers: klimek, cfe-commits

Differential Revision: https://reviews.llvm.org/D37845

Contributed by @PriMee!

llvm-svn: 313354
This commit is contained in:
Krasimir Georgiev 2017-09-15 11:23:50 +00:00
parent 905e79c4dc
commit d6ce937f49
6 changed files with 87 additions and 13 deletions

View File

@ -661,6 +661,21 @@ the configuration (without a prefix: ``Auto``).
int x;
}
* ``bool AfterExternBlock`` Wrap extern blocks.
.. code-block:: c++
true:
extern "C"
{
int foo();
}
false:
extern "C" {
int foo();
}
* ``bool BeforeCatch`` Wrap before ``catch``.
.. code-block:: c++

View File

@ -681,6 +681,20 @@ struct FormatStyle {
/// }
/// \endcode
bool AfterUnion;
/// \brief Wrap extern blocks.
/// \code
/// true:
/// extern "C"
/// {
/// int foo();
/// }
///
/// false:
/// extern "C" {
/// int foo();
/// }
/// \endcode
bool AfterExternBlock;
/// \brief Wrap before ``catch``.
/// \code
/// true:

View File

@ -420,6 +420,7 @@ template <> struct MappingTraits<FormatStyle::BraceWrappingFlags> {
IO.mapOptional("AfterObjCDeclaration", Wrapping.AfterObjCDeclaration);
IO.mapOptional("AfterStruct", Wrapping.AfterStruct);
IO.mapOptional("AfterUnion", Wrapping.AfterUnion);
IO.mapOptional("AfterExternBlock", Wrapping.AfterExternBlock);
IO.mapOptional("BeforeCatch", Wrapping.BeforeCatch);
IO.mapOptional("BeforeElse", Wrapping.BeforeElse);
IO.mapOptional("IndentBraces", Wrapping.IndentBraces);
@ -500,9 +501,9 @@ static FormatStyle expandPresets(const FormatStyle &Style) {
if (Style.BreakBeforeBraces == FormatStyle::BS_Custom)
return Style;
FormatStyle Expanded = Style;
Expanded.BraceWrapping = {false, false, false, false, false, false,
false, false, false, false, false, true,
true, true};
Expanded.BraceWrapping = {false, false, false, false, false, false,
false, false, false, false, false, false,
true, true, true};
switch (Style.BreakBeforeBraces) {
case FormatStyle::BS_Linux:
Expanded.BraceWrapping.AfterClass = true;
@ -515,6 +516,7 @@ static FormatStyle expandPresets(const FormatStyle &Style) {
Expanded.BraceWrapping.AfterFunction = true;
Expanded.BraceWrapping.AfterStruct = true;
Expanded.BraceWrapping.AfterUnion = true;
Expanded.BraceWrapping.AfterExternBlock = true;
Expanded.BraceWrapping.SplitEmptyFunction = true;
Expanded.BraceWrapping.SplitEmptyRecord = false;
break;
@ -531,13 +533,14 @@ static FormatStyle expandPresets(const FormatStyle &Style) {
Expanded.BraceWrapping.AfterNamespace = true;
Expanded.BraceWrapping.AfterObjCDeclaration = true;
Expanded.BraceWrapping.AfterStruct = true;
Expanded.BraceWrapping.AfterExternBlock = true;
Expanded.BraceWrapping.BeforeCatch = true;
Expanded.BraceWrapping.BeforeElse = true;
break;
case FormatStyle::BS_GNU:
Expanded.BraceWrapping = {true, true, true, true, true, true,
true, true, true, true, true, true,
true, true};
Expanded.BraceWrapping = {true, true, true, true, true, true,
true, true, true, true, true, true,
true, true, true};
break;
case FormatStyle::BS_WebKit:
Expanded.BraceWrapping.AfterFunction = true;
@ -573,9 +576,9 @@ FormatStyle getLLVMStyle() {
LLVMStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_None;
LLVMStyle.BreakBeforeTernaryOperators = true;
LLVMStyle.BreakBeforeBraces = FormatStyle::BS_Attach;
LLVMStyle.BraceWrapping = {false, false, false, false, false, false,
false, false, false, false, false, true,
true, true};
LLVMStyle.BraceWrapping = {false, false, false, false, false, false,
false, false, false, false, false, false,
true, true, true};
LLVMStyle.BreakAfterJavaFieldAnnotations = false;
LLVMStyle.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon;
LLVMStyle.BreakBeforeInheritanceComma = false;

View File

@ -233,9 +233,10 @@ private:
if (Tok && Tok->is(tok::kw_typedef))
Tok = Tok->getNextNonComment();
if (Tok && Tok->isOneOf(tok::kw_class, tok::kw_struct, tok::kw_union,
Keywords.kw_interface))
tok::kw_extern, Keywords.kw_interface))
return !Style.BraceWrapping.SplitEmptyRecord && EmptyBlock
? tryMergeSimpleBlock(I, E, Limit) : 0;
? tryMergeSimpleBlock(I, E, Limit)
: 0;
}
// FIXME: TheLine->Level != 0 might or might not be the right check to do.

View File

@ -1039,7 +1039,12 @@ void UnwrappedLineParser::parseStructuralElement() {
if (FormatTok->Tok.is(tok::string_literal)) {
nextToken();
if (FormatTok->Tok.is(tok::l_brace)) {
parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/false);
if (Style.BraceWrapping.AfterExternBlock) {
addUnwrappedLine();
parseBlock(/*MustBeDeclaration=*/true);
} else {
parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/false);
}
addUnwrappedLine();
return;
}

View File

@ -1704,7 +1704,42 @@ TEST_F(FormatTest, FormatsCompactNamespaces) {
Style));
}
TEST_F(FormatTest, FormatsExternC) { verifyFormat("extern \"C\" {\nint a;"); }
TEST_F(FormatTest, FormatsExternC) {
verifyFormat("extern \"C\" {\nint a;");
verifyFormat("extern \"C\" {}");
verifyFormat("extern \"C\" {\n"
"int foo();\n"
"}");
verifyFormat("extern \"C\" int foo() {}");
verifyFormat("extern \"C\" int foo();");
verifyFormat("extern \"C\" int foo() {\n"
" int i = 42;\n"
" return i;\n"
"}");
FormatStyle Style = getLLVMStyle();
Style.BreakBeforeBraces = FormatStyle::BS_Custom;
Style.BraceWrapping.AfterFunction = true;
verifyFormat("extern \"C\" int foo() {}", Style);
verifyFormat("extern \"C\" int foo();", Style);
verifyFormat("extern \"C\" int foo()\n"
"{\n"
" int i = 42;\n"
" return i;\n"
"}",
Style);
Style.BraceWrapping.AfterExternBlock = true;
Style.BraceWrapping.SplitEmptyRecord = false;
verifyFormat("extern \"C\"\n"
"{}",
Style);
verifyFormat("extern \"C\"\n"
"{\n"
" int foo();\n"
"}",
Style);
}
TEST_F(FormatTest, FormatsInlineASM) {
verifyFormat("asm(\"xyz\" : \"=a\"(a), \"=d\"(b) : \"a\"(data));");
@ -9979,6 +10014,7 @@ TEST_F(FormatTest, ParsesConfigurationBools) {
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, IndentBraces);