Skip to content

Commit f870bbc

Browse files
committed
[clang-format] Add SpaceInEmptyBraces option
Also set it to SIEB_Always for WebKit style. Closes #85525. Closes #93635.
1 parent 3d38a92 commit f870bbc

File tree

8 files changed

+155
-30
lines changed

8 files changed

+155
-30
lines changed

clang/docs/ClangFormatStyleOptions.rst

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6483,13 +6483,51 @@ the configuration (without a prefix: ``Auto``).
64836483
.. _SpaceInEmptyBlock:
64846484

64856485
**SpaceInEmptyBlock** (``Boolean``) :versionbadge:`clang-format 10` :ref:`<SpaceInEmptyBlock>`
6486-
If ``true``, spaces will be inserted into ``{}``.
6486+
This option is **deprecated**. See ``Block`` of ``SpaceInEmptyBraces``.
6487+
6488+
.. _SpaceInEmptyBraces:
6489+
6490+
**SpaceInEmptyBraces** (``SpaceInEmptyBracesStyle``) :versionbadge:`clang-format 22` :ref:`<SpaceInEmptyBraces>`
6491+
Specifies when to insert a space in empty braces.
6492+
6493+
.. note::
6494+
6495+
This option doesn't apply to initializer braces if
6496+
``Cpp11BracedListStyle`` is set to ``true``.
6497+
6498+
Possible values:
6499+
6500+
* ``SIEB_Always`` (in configuration: ``Always``)
6501+
Always insert a space in empty braces.
6502+
6503+
.. code-block:: c++
6504+
6505+
void f() { }
6506+
class Unit { };
6507+
auto a = [] { };
6508+
int x{ };
6509+
6510+
* ``SIEB_Block`` (in configuration: ``Block``)
6511+
Only insert a space in empty blocks.
6512+
6513+
.. code-block:: c++
6514+
6515+
void f() { }
6516+
class Unit { };
6517+
auto a = [] { };
6518+
int x{};
6519+
6520+
* ``SIEB_Never`` (in configuration: ``Never``)
6521+
Never insert a space in empty braces.
6522+
6523+
.. code-block:: c++
6524+
6525+
void f() {}
6526+
class Unit {};
6527+
auto a = [] {};
6528+
int x{};
64876529

6488-
.. code-block:: c++
64896530

6490-
true: false:
6491-
void f() { } vs. void f() {}
6492-
while (true) { } while (true) {}
64936531

64946532
.. _SpaceInEmptyParentheses:
64956533

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ AST Matchers
274274

275275
clang-format
276276
------------
277+
- Add ``SpaceInEmptyBraces`` option and set it to ``Always`` for WebKit style.
277278

278279
libclang
279280
--------

clang/include/clang/Format/Format.h

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4813,14 +4813,45 @@ struct FormatStyle {
48134813
/// \version 7
48144814
bool SpaceBeforeRangeBasedForLoopColon;
48154815

4816-
/// If ``true``, spaces will be inserted into ``{}``.
4817-
/// \code
4818-
/// true: false:
4819-
/// void f() { } vs. void f() {}
4820-
/// while (true) { } while (true) {}
4821-
/// \endcode
4816+
/// This option is **deprecated**. See ``Block`` of ``SpaceInEmptyBraces``.
48224817
/// \version 10
4823-
bool SpaceInEmptyBlock;
4818+
// bool SpaceInEmptyBlock;
4819+
4820+
/// Style of when to insert a space in empty braces.
4821+
enum SpaceInEmptyBracesStyle : int8_t {
4822+
/// Always insert a space in empty braces.
4823+
/// \code
4824+
/// void f() { }
4825+
/// class Unit { };
4826+
/// auto a = [] { };
4827+
/// int x{ };
4828+
/// \endcode
4829+
SIEB_Always,
4830+
/// Only insert a space in empty blocks.
4831+
/// \code
4832+
/// void f() { }
4833+
/// class Unit { };
4834+
/// auto a = [] { };
4835+
/// int x{};
4836+
/// \endcode
4837+
SIEB_Block,
4838+
/// Never insert a space in empty braces.
4839+
/// \code
4840+
/// void f() {}
4841+
/// class Unit {};
4842+
/// auto a = [] {};
4843+
/// int x{};
4844+
/// \endcode
4845+
SIEB_Never
4846+
};
4847+
4848+
/// Specifies when to insert a space in empty braces.
4849+
/// \note
4850+
/// This option doesn't apply to initializer braces if
4851+
/// ``Cpp11BracedListStyle`` is set to ``true``.
4852+
/// \endnote
4853+
/// \version 22
4854+
SpaceInEmptyBracesStyle SpaceInEmptyBraces;
48244855

48254856
/// If ``true``, spaces may be inserted into ``()``.
48264857
/// This option is **deprecated**. See ``InEmptyParentheses`` of
@@ -5494,7 +5525,7 @@ struct FormatStyle {
54945525
SpaceBeforeRangeBasedForLoopColon ==
54955526
R.SpaceBeforeRangeBasedForLoopColon &&
54965527
SpaceBeforeSquareBrackets == R.SpaceBeforeSquareBrackets &&
5497-
SpaceInEmptyBlock == R.SpaceInEmptyBlock &&
5528+
SpaceInEmptyBraces == R.SpaceInEmptyBraces &&
54985529
SpacesBeforeTrailingComments == R.SpacesBeforeTrailingComments &&
54995530
SpacesInAngles == R.SpacesInAngles &&
55005531
SpacesInContainerLiterals == R.SpacesInContainerLiterals &&

clang/lib/Format/Format.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,15 @@ struct ScalarEnumerationTraits<FormatStyle::SpaceBeforeParensStyle> {
763763
}
764764
};
765765

766+
template <>
767+
struct ScalarEnumerationTraits<FormatStyle::SpaceInEmptyBracesStyle> {
768+
static void enumeration(IO &IO, FormatStyle::SpaceInEmptyBracesStyle &Value) {
769+
IO.enumCase(Value, "Always", FormatStyle::SIEB_Always);
770+
IO.enumCase(Value, "Block", FormatStyle::SIEB_Block);
771+
IO.enumCase(Value, "Never", FormatStyle::SIEB_Never);
772+
}
773+
};
774+
766775
template <> struct ScalarEnumerationTraits<FormatStyle::SpacesInAnglesStyle> {
767776
static void enumeration(IO &IO, FormatStyle::SpacesInAnglesStyle &Value) {
768777
IO.enumCase(Value, "Never", FormatStyle::SIAS_Never);
@@ -931,6 +940,7 @@ template <> struct MappingTraits<FormatStyle> {
931940
bool DeriveLineEnding = true;
932941
bool UseCRLF = false;
933942

943+
bool SpaceInEmptyBlock = false;
934944
bool SpaceInEmptyParentheses = false;
935945
bool SpacesInConditionalStatement = false;
936946
bool SpacesInCStyleCastParentheses = false;
@@ -960,6 +970,7 @@ template <> struct MappingTraits<FormatStyle> {
960970
IO.mapOptional("PointerBindsToType", Style.PointerAlignment);
961971
IO.mapOptional("SpaceAfterControlStatementKeyword",
962972
Style.SpaceBeforeParens);
973+
IO.mapOptional("SpaceInEmptyBlock", SpaceInEmptyBlock);
963974
IO.mapOptional("SpaceInEmptyParentheses", SpaceInEmptyParentheses);
964975
IO.mapOptional("SpacesInConditionalStatement",
965976
SpacesInConditionalStatement);
@@ -1193,7 +1204,7 @@ template <> struct MappingTraits<FormatStyle> {
11931204
Style.SpaceBeforeRangeBasedForLoopColon);
11941205
IO.mapOptional("SpaceBeforeSquareBrackets",
11951206
Style.SpaceBeforeSquareBrackets);
1196-
IO.mapOptional("SpaceInEmptyBlock", Style.SpaceInEmptyBlock);
1207+
IO.mapOptional("SpaceInEmptyBraces", Style.SpaceInEmptyBraces);
11971208
IO.mapOptional("SpacesBeforeTrailingComments",
11981209
Style.SpacesBeforeTrailingComments);
11991210
IO.mapOptional("SpacesInAngles", Style.SpacesInAngles);
@@ -1276,6 +1287,13 @@ template <> struct MappingTraits<FormatStyle> {
12761287
Style.LineEnding = FormatStyle::LE_DeriveCRLF;
12771288
}
12781289

1290+
// If SpaceInEmptyBlock was specified but SpaceInEmptyBraces was not,
1291+
// initialize the latter from the former for backward compatibility.
1292+
if (SpaceInEmptyBlock &&
1293+
Style.SpaceInEmptyBraces == FormatStyle::SIEB_Never) {
1294+
Style.SpaceInEmptyBraces = FormatStyle::SIEB_Block;
1295+
}
1296+
12791297
if (Style.SpacesInParens != FormatStyle::SIPO_Custom &&
12801298
(SpacesInParentheses || SpaceInEmptyParentheses ||
12811299
SpacesInConditionalStatement || SpacesInCStyleCastParentheses)) {
@@ -1677,7 +1695,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
16771695
LLVMStyle.SpaceBeforeParensOptions.AfterIfMacros = true;
16781696
LLVMStyle.SpaceBeforeRangeBasedForLoopColon = true;
16791697
LLVMStyle.SpaceBeforeSquareBrackets = false;
1680-
LLVMStyle.SpaceInEmptyBlock = false;
1698+
LLVMStyle.SpaceInEmptyBraces = FormatStyle::SIEB_Never;
16811699
LLVMStyle.SpacesBeforeTrailingComments = 1;
16821700
LLVMStyle.SpacesInAngles = FormatStyle::SIAS_Never;
16831701
LLVMStyle.SpacesInContainerLiterals = true;
@@ -1984,7 +2002,7 @@ FormatStyle getWebKitStyle() {
19842002
Style.ObjCSpaceAfterProperty = true;
19852003
Style.PointerAlignment = FormatStyle::PAS_Left;
19862004
Style.SpaceBeforeCpp11BracedList = true;
1987-
Style.SpaceInEmptyBlock = true;
2005+
Style.SpaceInEmptyBraces = FormatStyle::SIEB_Always;
19882006
return Style;
19892007
}
19902008

clang/lib/Format/TokenAnnotator.cpp

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4513,16 +4513,9 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
45134513
return Left.is(tok::hash);
45144514
if (Left.isOneOf(tok::hashhash, tok::hash))
45154515
return Right.is(tok::hash);
4516-
if (Left.is(BK_Block) && Right.is(tok::r_brace) &&
4517-
Right.MatchingParen == &Left && Line.Children.empty()) {
4518-
return Style.SpaceInEmptyBlock;
4519-
}
45204516
if (Style.SpacesInParens == FormatStyle::SIPO_Custom) {
4521-
if ((Left.is(tok::l_paren) && Right.is(tok::r_paren)) ||
4522-
(Left.is(tok::l_brace) && Left.isNot(BK_Block) &&
4523-
Right.is(tok::r_brace) && Right.isNot(BK_Block))) {
4517+
if (Left.is(tok::l_paren) && Right.is(tok::r_paren))
45244518
return Style.SpacesInParensOptions.InEmptyParentheses;
4525-
}
45264519
if (Style.SpacesInParensOptions.ExceptDoubleParentheses &&
45274520
Left.is(tok::r_paren) && Right.is(tok::r_paren)) {
45284521
auto *InnerLParen = Left.MatchingParen;
@@ -4800,8 +4793,6 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
48004793
Right.is(TT_ArraySubscriptLSquare))) {
48014794
return false;
48024795
}
4803-
if (Left.is(tok::l_brace) && Right.is(tok::r_brace))
4804-
return !Left.Children.empty(); // No spaces in "{}".
48054796
if ((Left.is(tok::l_brace) && Left.isNot(BK_Block)) ||
48064797
(Right.is(tok::r_brace) && Right.MatchingParen &&
48074798
Right.MatchingParen->isNot(BK_Block))) {
@@ -4983,6 +4974,17 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
49834974
if (Left.is(tok::star) && Right.is(tok::comment))
49844975
return true;
49854976

4977+
if (Left.is(tok::l_brace) && Right.is(tok::r_brace) &&
4978+
Left.Children.empty()) {
4979+
if (Left.is(BK_Block))
4980+
return Style.SpaceInEmptyBraces != FormatStyle::SIEB_Never;
4981+
if (Style.Cpp11BracedListStyle) {
4982+
return Style.SpacesInParens == FormatStyle::SIPO_Custom &&
4983+
Style.SpacesInParensOptions.InEmptyParentheses;
4984+
}
4985+
return Style.SpaceInEmptyBraces == FormatStyle::SIEB_Always;
4986+
}
4987+
49864988
const auto *BeforeLeft = Left.Previous;
49874989

49884990
if (IsCpp) {

clang/lib/Format/UnwrappedLineFormatter.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -864,7 +864,8 @@ class LineJoiner {
864864
if (ShouldMerge()) {
865865
// We merge empty blocks even if the line exceeds the column limit.
866866
Tok->SpacesRequiredBefore =
867-
(Style.SpaceInEmptyBlock || Line.Last->is(tok::comment)) ? 1 : 0;
867+
Style.SpaceInEmptyBraces != FormatStyle::SIEB_Never ||
868+
Line.Last->is(tok::comment);
868869
Tok->CanBreakBefore = true;
869870
return 1;
870871
} else if (Limit != 0 && !Line.startsWithNamespace() &&

clang/unittests/Format/ConfigParseTest.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,6 @@ TEST(ConfigParseTest, ParsesConfigurationBools) {
200200
CHECK_PARSE_BOOL(RemoveSemicolon);
201201
CHECK_PARSE_BOOL(SkipMacroDefinitionBody);
202202
CHECK_PARSE_BOOL(SpacesInSquareBrackets);
203-
CHECK_PARSE_BOOL(SpaceInEmptyBlock);
204203
CHECK_PARSE_BOOL(SpacesInContainerLiterals);
205204
CHECK_PARSE_BOOL(SpaceAfterCStyleCast);
206205
CHECK_PARSE_BOOL(SpaceAfterTemplateKeyword);
@@ -688,6 +687,17 @@ TEST(ConfigParseTest, ParsesConfiguration) {
688687
SpaceBeforeParens,
689688
FormatStyle::SBPO_ControlStatementsExceptControlMacros);
690689

690+
Style.SpaceInEmptyBraces = FormatStyle::SIEB_Never;
691+
CHECK_PARSE("SpaceInEmptyBraces: Always", SpaceInEmptyBraces,
692+
FormatStyle::SIEB_Always);
693+
CHECK_PARSE("SpaceInEmptyBraces: Block", SpaceInEmptyBraces,
694+
FormatStyle::SIEB_Block);
695+
CHECK_PARSE("SpaceInEmptyBraces: Never", SpaceInEmptyBraces,
696+
FormatStyle::SIEB_Never);
697+
// For backward compatibility:
698+
CHECK_PARSE("SpaceInEmptyBlock: true", SpaceInEmptyBraces,
699+
FormatStyle::SIEB_Block);
700+
691701
// For backward compatibility:
692702
Style.SpacesInParens = FormatStyle::SIPO_Never;
693703
Style.SpacesInParensOptions = {};

clang/unittests/Format/FormatTest.cpp

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7055,7 +7055,7 @@ TEST_F(FormatTest, PutEmptyBlocksIntoOneLine) {
70557055
verifyFormat("enum E {};");
70567056
verifyFormat("enum E {}");
70577057
FormatStyle Style = getLLVMStyle();
7058-
Style.SpaceInEmptyBlock = true;
7058+
Style.SpaceInEmptyBraces = FormatStyle::SIEB_Block;
70597059
verifyFormat("void f() { }", "void f() {}", Style);
70607060
Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Empty;
70617061
verifyFormat("{ }", Style);
@@ -7083,7 +7083,7 @@ TEST_F(FormatTest, PutEmptyBlocksIntoOneLine) {
70837083
Style);
70847084

70857085
Style = getLLVMStyle(FormatStyle::LK_CSharp);
7086-
Style.SpaceInEmptyBlock = true;
7086+
Style.SpaceInEmptyBraces = FormatStyle::SIEB_Block;
70877087
verifyFormat("Event += () => { };", Style);
70887088
}
70897089

@@ -25584,6 +25584,30 @@ TEST_F(FormatTest, SpacesInConditionalStatement) {
2558425584
verifyFormat("MYIF( a )\n return;\nelse\n return;", Spaces);
2558525585
}
2558625586

25587+
TEST_F(FormatTest, SpaceInEmptyBraces) {
25588+
constexpr StringRef Code("void f() {}\n"
25589+
"class Unit {};\n"
25590+
"auto a = [] {};\n"
25591+
"int x{};");
25592+
verifyFormat(Code);
25593+
25594+
auto Style = getWebKitStyle();
25595+
EXPECT_EQ(Style.SpaceInEmptyBraces, FormatStyle::SIEB_Always);
25596+
25597+
verifyFormat("void f() { }\n"
25598+
"class Unit { };\n"
25599+
"auto a = [] { };\n"
25600+
"int x { };",
25601+
Code, Style);
25602+
25603+
Style.SpaceInEmptyBraces = FormatStyle::SIEB_Block;
25604+
verifyFormat("void f() { }\n"
25605+
"class Unit { };\n"
25606+
"auto a = [] { };\n"
25607+
"int x {};",
25608+
Code, Style);
25609+
}
25610+
2558725611
TEST_F(FormatTest, AlternativeOperators) {
2558825612
// Test case for ensuring alternate operators are not
2558925613
// combined with their right most neighbour.

0 commit comments

Comments
 (0)