https://github.com/AhmedKamel10 created
https://github.com/llvm/llvm-project/pull/216892
### Summary
Adds the `BraceWrapping.AfterExportBlock` option to `clang-format`. This allows
users configuring `BreakBeforeBraces: Custom` to specify whether the opening
brace of a C++20 `export` block should be wrapped onto a new line.
### Examples
```c++
// BraceWrapping.AfterExportBlock = true
export
{
int foo();
}
// BraceWrapping.AfterExportBlock = false
export {
int foo();
}
>From a5f9dabdcb38468862cbf520497db5b99d3457ad Mon Sep 17 00:00:00 2001
From: ahmedkamel10 <[email protected]>
Date: Tue, 18 Aug 2026 03:40:15 +0300
Subject: [PATCH] [clang-format] Add BraceWrapping.AfterExportBlock option
---
clang/docs/ClangFormatStyleOptions.md | 10 ++++++++++
clang/include/clang/Format/Format.h | 9 +++++++++
clang/lib/Format/Format.cpp | 6 ++++++
clang/lib/Format/UnwrappedLineFormatter.cpp | 11 ++++++++++-
clang/lib/Format/UnwrappedLineParser.cpp | 6 ++++++
clang/unittests/Format/FormatTest.cpp | 21 +++++++++++++++++++++
6 files changed, 62 insertions(+), 1 deletion(-)
diff --git a/clang/docs/ClangFormatStyleOptions.md
b/clang/docs/ClangFormatStyleOptions.md
index 9b962e6e1e083..e14fadb41d296 100644
--- a/clang/docs/ClangFormatStyleOptions.md
+++ b/clang/docs/ClangFormatStyleOptions.md
@@ -2597,6 +2597,16 @@ the configuration (without a prefix: `Auto`).
}
```
+ - `bool AfterExportBlock` Wrap export blocks.
+
+ ```c++
+ true: false:
+ export export {
+ { int foo();
+ int foo(); }
+ }
+ ```
+
- `bool BeforeCatch` Wrap before `catch`.
```c++
diff --git a/clang/include/clang/Format/Format.h
b/clang/include/clang/Format/Format.h
index 3948337d2fc3d..94333fa37cf9e 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -1549,6 +1549,15 @@ struct FormatStyle {
/// }
/// \endcode
bool AfterExternBlock; // Partially superseded by IndentExternBlock
+ /// Wrap export blocks.
+ /// \code
+ /// true: false:
+ /// export export {
+ /// { int foo();
+ /// int foo(); }
+ /// }
+ /// \endcode
+ bool AfterExportBlock;
/// Wrap before `catch`.
/// \code
/// true:
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 2b6e65efbf026..275d8f59d8ebc 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -220,6 +220,7 @@ template <> struct
MappingTraits<FormatStyle::BraceWrappingFlags> {
IO.mapOptional("AfterControlStatement", Wrapping.AfterControlStatement);
IO.mapOptional("AfterEnum", Wrapping.AfterEnum);
IO.mapOptional("AfterExternBlock", Wrapping.AfterExternBlock);
+ IO.mapOptional("AfterExportBlock", Wrapping.AfterExportBlock);
IO.mapOptional("AfterFunction", Wrapping.AfterFunction);
IO.mapOptional("AfterNamespace", Wrapping.AfterNamespace);
IO.mapOptional("AfterObjCDeclaration", Wrapping.AfterObjCDeclaration);
@@ -1725,6 +1726,7 @@ static void expandPresetsBraceWrapping(FormatStyle
&Expanded) {
/*AfterStruct=*/false,
/*AfterUnion=*/false,
/*AfterExternBlock=*/false,
+ /*AfterExportBlock=*/false,
/*BeforeCatch=*/false,
/*BeforeElse=*/false,
/*BeforeLambdaBody=*/false,
@@ -1746,6 +1748,7 @@ static void expandPresetsBraceWrapping(FormatStyle
&Expanded) {
Expanded.BraceWrapping.AfterStruct = true;
Expanded.BraceWrapping.AfterUnion = true;
Expanded.BraceWrapping.AfterExternBlock = true;
+ Expanded.BraceWrapping.AfterExportBlock = true;
Expanded.BraceWrapping.SplitEmptyFunction = true;
Expanded.BraceWrapping.SplitEmptyRecord = false;
break;
@@ -1765,6 +1768,7 @@ static void expandPresetsBraceWrapping(FormatStyle
&Expanded) {
Expanded.BraceWrapping.AfterStruct = true;
Expanded.BraceWrapping.AfterUnion = true;
Expanded.BraceWrapping.AfterExternBlock = true;
+ Expanded.BraceWrapping.AfterExportBlock = true;
Expanded.BraceWrapping.BeforeCatch = true;
Expanded.BraceWrapping.BeforeElse = true;
Expanded.BraceWrapping.BeforeLambdaBody = true;
@@ -1795,6 +1799,7 @@ static void expandPresetsBraceWrapping(FormatStyle
&Expanded) {
/*AfterStruct=*/true,
/*AfterUnion=*/true,
/*AfterExternBlock=*/true,
+ /*AfterExportBlock=*/true,
/*BeforeCatch=*/true,
/*BeforeElse=*/true,
/*BeforeLambdaBody=*/true,
@@ -1897,6 +1902,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind
Language) {
/*AfterStruct=*/false,
/*AfterUnion=*/false,
/*AfterExternBlock=*/false,
+ /*AfterExportBlock=*/false,
/*BeforeCatch=*/false,
/*BeforeElse=*/false,
/*BeforeLambdaBody=*/false,
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp
b/clang/lib/Format/UnwrappedLineFormatter.cpp
index 7afc7a46dd1c0..a806bc8494ea0 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -444,7 +444,8 @@ class LineJoiner {
if (TheLine->Last->is(tok::l_brace) && FirstNonComment != TheLine->Last &&
(FirstNonComment->isOneOf(tok::kw_if, tok::kw_while, tok::kw_for,
TT_ForEachMacro) ||
- TheLine->startsWithExportBlock())) {
+ (TheLine->startsWithExportBlock() &&
+ !Style.BraceWrapping.AfterExportBlock))) {
return Style.AllowShortBlocksOnASingleLine != FormatStyle::SBS_Never
? tryMergeSimpleBlock(I, E, Limit)
: 0;
@@ -937,6 +938,14 @@ class LineJoiner {
}
if (Line.endsWith(tok::l_brace)) {
+ // Refuse to merge export blocks if the style requires the brace to be on
+ // a new line.
+ if (Style.BraceWrapping.AfterExportBlock &&
+ Line.First->is(tok::l_brace) && I > AnnotatedLines.begin() &&
+ I[-1]->startsWith(tok::kw_export)) {
+ return 0;
+ }
+
if (Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Never &&
Line.First->is(TT_BlockLBrace)) {
return 0;
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp
b/clang/lib/Format/UnwrappedLineParser.cpp
index da6465548bb3e..2b2e393271bdb 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -3311,6 +3311,12 @@ void UnwrappedLineParser::parseNamespace() {
}
void UnwrappedLineParser::parseCppExportBlock() {
+
+ if (FormatTok->is(tok::l_brace)) {
+ if (Style.BraceWrapping.AfterExportBlock)
+ addUnwrappedLine();
+ }
+
parseNamespaceOrExportBlock(/*AddLevels=*/Style.IndentExportBlock ? 1 : 0);
}
diff --git a/clang/unittests/Format/FormatTest.cpp
b/clang/unittests/Format/FormatTest.cpp
index 6f604167f785c..718e6530c2a90 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -4931,6 +4931,27 @@ TEST_F(FormatTest, IndentExternBlockStyle) {
Style);
}
+TEST_F(FormatTest, BraceWrappingAfterExportBlock) {
+ FormatStyle Style = getLLVMStyle();
+ Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+
+ Style.BraceWrapping.AfterExportBlock = true;
+ verifyFormat("export\n"
+ "{\n"
+ " int foo();\n"
+ "}",
+ "export {\n"
+ " int foo();\n"
+ "}",
+ Style);
+
+ Style.BraceWrapping.AfterExportBlock = false;
+ verifyFormat("export {\n"
+ " int foo();\n"
+ "}",
+ Style);
+}
+
TEST_F(FormatTest, FormatsInlineASM) {
verifyFormat("asm(\"xyz\" : \"=a\"(a), \"=d\"(b) : \"a\"(data));");
verifyFormat("asm(\"nop\" ::: \"memory\");");
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits