[clang] [clang-format] Fix breaking enum braces when combined with export (PR #189128)
Björn Schäpers via cfe-commits
cfe-commits at lists.llvm.org
Sat Mar 28 08:27:18 PDT 2026
https://github.com/HazardyKnusperkeks updated https://github.com/llvm/llvm-project/pull/189128
>From 911f687a4791e03fd98921a7742e006dd4a1a233 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Sch=C3=A4pers?= <bjoern at hazardy.de>
Date: Sat, 28 Mar 2026 00:01:35 +0100
Subject: [PATCH 1/2] [clang-format] Fix breaking enum braces when combined
with export
This fixes #186684.
Also fix (not) breaking variables declared on the same line as the
closing brace.
And adapt whitesmith to that changes.
---
clang/lib/Format/Format.cpp | 6 ++++++
clang/lib/Format/TokenAnnotator.cpp | 3 ++-
clang/lib/Format/UnwrappedLineParser.cpp | 20 +++++++++++++++++---
clang/unittests/Format/FormatTest.cpp | 21 +++++++++++++++++++++
4 files changed, 46 insertions(+), 4 deletions(-)
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 2b0aa1735c895..93859d7ea9c4a 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -4115,10 +4115,14 @@ reformat(const FormatStyle &Style, StringRef Code,
expandPresetsBraceWrapping(Expanded);
expandPresetsSpaceBeforeParens(Expanded);
expandPresetsSpacesInParens(Expanded);
+
+ // These are handled by separate passes.
Expanded.InsertBraces = false;
Expanded.RemoveBracesLLVM = false;
Expanded.RemoveParentheses = FormatStyle::RPS_Leave;
Expanded.RemoveSemicolon = false;
+
+ // Make some sanity adjustments.
switch (Expanded.RequiresClausePosition) {
case FormatStyle::RCPS_SingleLine:
case FormatStyle::RCPS_WithPreceding:
@@ -4127,6 +4131,8 @@ reformat(const FormatStyle &Style, StringRef Code,
default:
break;
}
+ if (Expanded.BraceWrapping.AfterEnum)
+ Expanded.AllowShortEnumsOnASingleLine = false;
if (Expanded.DisableFormat)
return {tooling::Replacements(), 0};
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index d2cdc28a7da7b..646182a673129 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -6045,7 +6045,8 @@ bool TokenAnnotator::mustBreakBefore(AnnotatedLine &Line,
if (Style.BraceWrapping.AfterEnum) {
if (Line.startsWith(tok::kw_enum) ||
- Line.startsWith(tok::kw_typedef, tok::kw_enum)) {
+ Line.startsWith(tok::kw_typedef, tok::kw_enum) ||
+ Line.startsWith(tok::kw_export, tok::kw_enum)) {
return true;
}
// Ensure BraceWrapping for `public enum A {`.
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index a3e8a3e270e73..a42762882864a 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -3875,26 +3875,40 @@ bool UnwrappedLineParser::parseEnum() {
return true;
}
+ const bool ManageWhitesmithsBraces =
+ Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths;
+
if (!Style.AllowShortEnumsOnASingleLine &&
ShouldBreakBeforeBrace(Style, InitialToken,
Tokens->peekNextToken()->is(tok::r_brace))) {
addUnwrappedLine();
+
+ // If we're in Whitesmiths mode, indent the brace if we're not indenting
+ // the whole block.
+ if (ManageWhitesmithsBraces)
+ ++Line->Level;
}
// Parse enum body.
nextToken();
if (!Style.AllowShortEnumsOnASingleLine) {
addUnwrappedLine();
- Line->Level += 1;
+ if (!ManageWhitesmithsBraces)
+ ++Line->Level;
}
+ const size_t OpeningLineIndex = CurrentLines->empty()
+ ? UnwrappedLine::kInvalidIndex
+ : CurrentLines->size() - 1;
bool HasError = !parseBracedList(/*IsAngleBracket=*/false, /*IsEnum=*/true);
- if (!Style.AllowShortEnumsOnASingleLine)
- Line->Level -= 1;
+ if (!Style.AllowShortEnumsOnASingleLine && !ManageWhitesmithsBraces)
+ --Line->Level;
if (HasError) {
if (FormatTok->is(tok::semi))
nextToken();
addUnwrappedLine();
}
setPreviousRBraceType(TT_EnumRBrace);
+ if (ManageWhitesmithsBraces)
+ Line->MatchingOpeningBlockLineIndex = OpeningLineIndex;
return true;
// There is no addUnwrappedLine() here so that we fall through to parsing a
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 2701a7fca7346..faaeb998ac99c 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -2885,6 +2885,22 @@ TEST_F(FormatTest, ShortEnums) {
" C\n"
"} ShortEnum1, ShortEnum2;",
Style);
+
+ Style.AllowShortEnumsOnASingleLine = true;
+ verifyFormat("enum\n"
+ "{\n"
+ " A,\n"
+ " B,\n"
+ " C\n"
+ "} ShortEnum1, ShortEnum2;",
+ Style);
+ verifyFormat("export enum\n"
+ "{\n"
+ " A,\n"
+ " B,\n"
+ " C\n"
+ "} ShortEnum1, ShortEnum2;",
+ Style);
}
TEST_F(FormatTest, ShortCompoundRequirement) {
@@ -22143,6 +22159,11 @@ TEST_F(FormatTest, WhitesmithsBraceBreaking) {
" }",
WhitesmithsBraceStyle);
verifyFormat("enum X\n"
+ " {\n"
+ " Y = 0,\n"
+ " Z = 1\n"
+ " };\n"
+ "enum X\n"
" {\n"
" Y = 0,\n"
" Z = 1\n"
>From c56379bc546b43ae096179b781c5d246a01c4b59 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Sch=C3=A4pers?= <bjoern at hazardy.de>
Date: Sat, 28 Mar 2026 16:27:07 +0100
Subject: [PATCH 2/2] Review
---
clang/lib/Format/UnwrappedLineParser.cpp | 6 +++---
clang/unittests/Format/FormatTest.cpp | 13 +------------
2 files changed, 4 insertions(+), 15 deletions(-)
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index a42762882864a..ff01d8442f0d1 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -3895,9 +3895,9 @@ bool UnwrappedLineParser::parseEnum() {
if (!ManageWhitesmithsBraces)
++Line->Level;
}
- const size_t OpeningLineIndex = CurrentLines->empty()
- ? UnwrappedLine::kInvalidIndex
- : CurrentLines->size() - 1;
+ const auto OpeningLineIndex = CurrentLines->empty()
+ ? UnwrappedLine::kInvalidIndex
+ : CurrentLines->size() - 1;
bool HasError = !parseBracedList(/*IsAngleBracket=*/false, /*IsEnum=*/true);
if (!Style.AllowShortEnumsOnASingleLine && !ManageWhitesmithsBraces)
--Line->Level;
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index faaeb998ac99c..0f7a31af8a5e6 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -2887,13 +2887,6 @@ TEST_F(FormatTest, ShortEnums) {
Style);
Style.AllowShortEnumsOnASingleLine = true;
- verifyFormat("enum\n"
- "{\n"
- " A,\n"
- " B,\n"
- " C\n"
- "} ShortEnum1, ShortEnum2;",
- Style);
verifyFormat("export enum\n"
"{\n"
" A,\n"
@@ -22163,11 +22156,7 @@ TEST_F(FormatTest, WhitesmithsBraceBreaking) {
" Y = 0,\n"
" Z = 1\n"
" };\n"
- "enum X\n"
- " {\n"
- " Y = 0,\n"
- " Z = 1\n"
- " };",
+ "int i;",
WhitesmithsBraceStyle);
verifyFormat("@interface BSApplicationController ()\n"
More information about the cfe-commits
mailing list