diff options
author | Krasimir Georgiev <krasimir@google.com> | 2017-09-15 11:23:50 +0000 |
---|---|---|
committer | Krasimir Georgiev <krasimir@google.com> | 2017-09-15 11:23:50 +0000 |
commit | 57065b2de4d945670107a164ea557cdfd94643b7 (patch) | |
tree | 61c7027c8cd6687150ab6f3d9fb996c4ff5e0add | |
parent | 6d42a101dd0232c99d2358145f7d77e4de68596b (diff) |
[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!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@313354 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | docs/ClangFormatStyleOptions.rst | 15 | ||||
-rw-r--r-- | include/clang/Format/Format.h | 14 | ||||
-rw-r--r-- | lib/Format/Format.cpp | 21 | ||||
-rw-r--r-- | lib/Format/UnwrappedLineFormatter.cpp | 5 | ||||
-rw-r--r-- | lib/Format/UnwrappedLineParser.cpp | 7 | ||||
-rw-r--r-- | unittests/Format/FormatTest.cpp | 38 |
6 files changed, 87 insertions, 13 deletions
diff --git a/docs/ClangFormatStyleOptions.rst b/docs/ClangFormatStyleOptions.rst index 7b5ce52f51..48accc753a 100644 --- a/docs/ClangFormatStyleOptions.rst +++ b/docs/ClangFormatStyleOptions.rst @@ -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++ diff --git a/include/clang/Format/Format.h b/include/clang/Format/Format.h index 44f027ce81..302ced3f78 100644 --- a/include/clang/Format/Format.h +++ b/include/clang/Format/Format.h @@ -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: diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp index bacf92a86e..8663faf9e1 100644 --- a/lib/Format/Format.cpp +++ b/lib/Format/Format.cpp @@ -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; diff --git a/lib/Format/UnwrappedLineFormatter.cpp b/lib/Format/UnwrappedLineFormatter.cpp index 8dbfdda497..ff98008e85 100644 --- a/lib/Format/UnwrappedLineFormatter.cpp +++ b/lib/Format/UnwrappedLineFormatter.cpp @@ -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. diff --git a/lib/Format/UnwrappedLineParser.cpp b/lib/Format/UnwrappedLineParser.cpp index b15e52aeb2..40d133ff0d 100644 --- a/lib/Format/UnwrappedLineParser.cpp +++ b/lib/Format/UnwrappedLineParser.cpp @@ -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; } diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index c7685c6cfc..e974550f22 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -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); |