llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Kohei Asano (khei4) <details> <summary>Changes</summary> # What This patch introduces an option to insert a space between empty braces, especially for empty initializer. # Motivation WebKit has [its own `.clang-format` ](https://github.com/WebKit/WebKit/blob/main/.clang-format) and [clang-format has `basedOnStyle: WebKit`](https://clang.llvm.org/docs/ClangFormatStyleOptions.html#basedonstyle), but it's inconsistent with [internal style checker script](https://github.com/WebKit/WebKit/blob/main/Tools/Scripts/check-webkit-style), at least for the empty initializers. For example, the following line, tweaked from [WebKit source code](https://github.com/WebKit/WebKit/blob/main/Source/WebKit/UIProcess/Inspector/win/WebInspectorUIProxyWin.cpp#L222), would be checked by the script ```c++ toImpl(listenerRef)->use( {} ); ``` ```bash $ python Tools/Scripts/check-webkit-style ERROR: Source/WebKit/UIProcess/Inspector/win/WebInspectorUIProxyWin.cpp:222: Extra space after ( in function call [whitespace/parens] [4] ERROR: Source/WebKit/UIProcess/Inspector/win/WebInspectorUIProxyWin.cpp:222: Extra space before ) [whitespace/parens] [2] ERROR: Source/WebKit/UIProcess/Inspector/win/WebInspectorUIProxyWin.cpp:222: Missing space inside { }. [whitespace/braces] [5] ``` A space in empty braces is required, but one in (also for empty) parens isn't allowed. Current clang-format could insert a space in empty parenthesis and block simultaneously by turning on [SpacesInParensOptions.InEmptyParentheses](https://clang.llvm.org/docs/ClangFormatStyleOptions.html#spacesinparensoptions), but formatting only braces couldn't be achieved. So we want to insert a space only for braces. # Note I guess compatibility is important, but including braces in parens options might have been miss-leading. If more descriptive option name and desirable changes exist, I'm very happy to hear that :) --- Full diff: https://github.com/llvm/llvm-project/pull/93634.diff 6 Files Affected: - (modified) clang/docs/ClangFormatStyleOptions.rst (+13-1) - (modified) clang/include/clang/Format/Format.h (+17-4) - (modified) clang/lib/Format/Format.cpp (+1) - (modified) clang/lib/Format/TokenAnnotator.cpp (+5) - (modified) clang/unittests/Format/ConfigParseTest.cpp (+13-8) - (modified) clang/unittests/Format/FormatTest.cpp (+5) ``````````diff diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 6d092219877f9..a1944eec8582b 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -6237,18 +6237,30 @@ the configuration (without a prefix: ``Auto``). true: false: x = ( int32 )y vs. x = (int32)y - * ``bool InEmptyParentheses`` Put a space in parentheses only if the parentheses are empty i.e. '()' + * ``bool InEmptyParentheses`` Put a space in parentheses and braces only if they are empty i.e. '()' or '{}' .. code-block:: c++ true: false: void f( ) { vs. void f() { int x[] = {foo( ), bar( )}; int x[] = {foo(), bar()}; + T a = { }; T a = {}; if (true) { if (true) { f( ); f(); } } } } + * ``bool InEmptyBraces`` Put a space in *only* braces, not for parentheses, only if the braces are empty i.e. '{}' + + .. code-block:: c++ + + true: false: + void f() { vs. void f() { + T x = {}; T x = { }; + g(x, {}); g(x, { }); + } } + + * ``bool Other`` Put a space in parentheses not covered by preceding options. .. code-block:: c++ diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 274b45d1bc586..4482f7fb49788 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -4673,6 +4673,17 @@ struct FormatStyle { /// } } /// \endcode bool InEmptyParentheses; + /// Put a space in brackets only if the parentheses are empty i.e. '()' + /// \code + /// true: false: + /// void f( ) { vs. void f() { + /// int x[] = {foo( ), bar( )}; int x[] = {foo(), bar()}; + /// if (true) { if (true) { + /// f( ); f(); + /// } } + /// } } + /// \endcode + bool InEmptyBraces; /// Put a space in parentheses not covered by preceding options. /// \code /// true: false: @@ -4682,18 +4693,20 @@ struct FormatStyle { SpacesInParensCustom() : InConditionalStatements(false), InCStyleCasts(false), - InEmptyParentheses(false), Other(false) {} + InEmptyParentheses(false), InEmptyBraces(false), Other(false) {} SpacesInParensCustom(bool InConditionalStatements, bool InCStyleCasts, - bool InEmptyParentheses, bool Other) + bool InEmptyParentheses, bool InEmptyBraces, + bool Other) : InConditionalStatements(InConditionalStatements), InCStyleCasts(InCStyleCasts), InEmptyParentheses(InEmptyParentheses), - Other(Other) {} + InEmptyBraces(InEmptyBraces), Other(Other) {} bool operator==(const SpacesInParensCustom &R) const { return InConditionalStatements == R.InConditionalStatements && InCStyleCasts == R.InCStyleCasts && - InEmptyParentheses == R.InEmptyParentheses && Other == R.Other; + InEmptyParentheses == R.InEmptyParentheses && + InEmptyBraces == R.InEmptyBraces && Other == R.Other; } bool operator!=(const SpacesInParensCustom &R) const { return !(*this == R); diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 9cba0c2614eef..efcc48b910718 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -723,6 +723,7 @@ template <> struct MappingTraits<FormatStyle::SpacesInParensCustom> { IO.mapOptional("InCStyleCasts", Spaces.InCStyleCasts); IO.mapOptional("InConditionalStatements", Spaces.InConditionalStatements); IO.mapOptional("InEmptyParentheses", Spaces.InEmptyParentheses); + IO.mapOptional("InEmptyBraces", Spaces.InEmptyBraces); IO.mapOptional("Other", Spaces.Other); } }; diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 7c4c76a91f2c5..094c182c8d448 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -4341,6 +4341,11 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, Right.MatchingParen == &Left && Line.Children.empty()) { return Style.SpaceInEmptyBlock; } + if (Style.SpacesInParensOptions.InEmptyBraces && + (Left.is(tok::l_brace) && Left.isNot(BK_Block) && + Right.is(tok::r_brace) && Right.isNot(BK_Block))) { + return Style.SpacesInParensOptions.InEmptyBraces; + } if ((Left.is(tok::l_paren) && Right.is(tok::r_paren)) || (Left.is(tok::l_brace) && Left.isNot(BK_Block) && Right.is(tok::r_brace) && Right.isNot(BK_Block))) { diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp index 82e72f08ffb5e..c8918d4cec128 100644 --- a/clang/unittests/Format/ConfigParseTest.cpp +++ b/clang/unittests/Format/ConfigParseTest.cpp @@ -238,6 +238,7 @@ TEST(ConfigParseTest, ParsesConfigurationBools) { CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InCStyleCasts); CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InConditionalStatements); CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InEmptyParentheses); + CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InEmptyBraces); CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, Other); } @@ -619,20 +620,24 @@ TEST(ConfigParseTest, ParsesConfiguration) { FormatStyle::SIPO_Custom); Style.SpacesInParens = FormatStyle::SIPO_Never; Style.SpacesInParensOptions = {}; - CHECK_PARSE("SpacesInParentheses: true", SpacesInParensOptions, - FormatStyle::SpacesInParensCustom(true, false, false, true)); + CHECK_PARSE( + "SpacesInParentheses: true", SpacesInParensOptions, + FormatStyle::SpacesInParensCustom(true, false, false, false, true)); Style.SpacesInParens = FormatStyle::SIPO_Never; Style.SpacesInParensOptions = {}; - CHECK_PARSE("SpacesInConditionalStatement: true", SpacesInParensOptions, - FormatStyle::SpacesInParensCustom(true, false, false, false)); + CHECK_PARSE( + "SpacesInConditionalStatement: true", SpacesInParensOptions, + FormatStyle::SpacesInParensCustom(true, false, false, false, false)); Style.SpacesInParens = FormatStyle::SIPO_Never; Style.SpacesInParensOptions = {}; - CHECK_PARSE("SpacesInCStyleCastParentheses: true", SpacesInParensOptions, - FormatStyle::SpacesInParensCustom(false, true, false, false)); + CHECK_PARSE( + "SpacesInCStyleCastParentheses: true", SpacesInParensOptions, + FormatStyle::SpacesInParensCustom(false, true, false, false, false)); Style.SpacesInParens = FormatStyle::SIPO_Never; Style.SpacesInParensOptions = {}; - CHECK_PARSE("SpaceInEmptyParentheses: true", SpacesInParensOptions, - FormatStyle::SpacesInParensCustom(false, false, true, false)); + CHECK_PARSE( + "SpaceInEmptyParentheses: true", SpacesInParensOptions, + FormatStyle::SpacesInParensCustom(false, false, true, false, false)); Style.SpacesInParens = FormatStyle::SIPO_Never; Style.SpacesInParensOptions = {}; diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 2f0c0f0266774..f154941426f2c 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -14027,6 +14027,11 @@ TEST_F(FormatTest, LayoutCxx11BraceInitializers) { SpaceBetweenBraces.SpacesInParens = FormatStyle::SIPO_Custom; SpaceBetweenBraces.SpacesInParensOptions.InEmptyParentheses = true; verifyFormat("vector< int > x{ };", SpaceBetweenBraces); + SpaceBetweenBraces.SpacesInParens = FormatStyle::SIPO_Custom; + SpaceBetweenBraces.SpacesInParensOptions.InEmptyParentheses = false; + SpaceBetweenBraces.SpacesInParensOptions.Other = false; + SpaceBetweenBraces.SpacesInParensOptions.InEmptyBraces = true; + verifyFormat("T x = { };\nf(x, { });\ng();", SpaceBetweenBraces); } TEST_F(FormatTest, FormatsBracedListsInColumnLayout) { `````````` </details> https://github.com/llvm/llvm-project/pull/93634 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits