https://github.com/AhmedKamel10 updated https://github.com/llvm/llvm-project/pull/216892
>From a5f9dabdcb38468862cbf520497db5b99d3457ad Mon Sep 17 00:00:00 2001 From: ahmedkamel10 <[email protected]> Date: Tue, 18 Aug 2026 03:40:15 +0300 Subject: [PATCH 1/3] [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\");"); >From 153e3474f7f5b165ba2aa7d131a2c45cf92bc580 Mon Sep 17 00:00:00 2001 From: ahmedkamel10 <[email protected]> Date: Tue, 18 Aug 2026 23:25:49 +0300 Subject: [PATCH 2/3] [clang-format] Add TT_ExportLBrace and support AfterExportBlock brace wrapping --- clang/include/clang/Format/Format.h | 19 ++++++++++--------- clang/lib/Format/FormatToken.h | 1 + clang/lib/Format/TokenAnnotator.cpp | 2 +- clang/lib/Format/UnwrappedLineFormatter.cpp | 6 ++---- clang/lib/Format/UnwrappedLineParser.cpp | 3 +-- clang/unittests/Format/TokenAnnotatorTest.cpp | 8 ++++++++ 6 files changed, 23 insertions(+), 16 deletions(-) diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 94333fa37cf9e..82d8465bd08f6 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -1535,6 +1535,15 @@ struct FormatStyle { /// } /// \endcode bool AfterUnion; + /// Wrap export blocks. + /// \code + /// true: false: + /// export vs. export { + /// { int foo(); + /// int foo(); } + /// } + /// \endcode + bool AfterExportBlock; /// Wrap extern blocks. /// \code /// true: @@ -1549,15 +1558,7 @@ 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/FormatToken.h b/clang/lib/Format/FormatToken.h index 4a2982eaa3a17..691ecdd24f448 100644 --- a/clang/lib/Format/FormatToken.h +++ b/clang/lib/Format/FormatToken.h @@ -80,6 +80,7 @@ namespace format { TYPE(EnumLBrace) \ TYPE(EnumRBrace) \ TYPE(EnumUnderlyingTypeColon) \ + TYPE(ExportLBrace) \ TYPE(FatArrow) \ TYPE(ForEachMacro) \ TYPE(FunctionAnnotationRParen) \ diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index b6c33279b0aca..8f064e38a691b 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -2137,7 +2137,7 @@ class AnnotatingParser { TT_RecordLBrace, TT_StructLBrace, TT_UnionLBrace, TT_RequiresClause, TT_RequiresClauseInARequiresExpression, TT_RequiresExpression, TT_RequiresExpressionLParen, TT_RequiresExpressionLBrace, - TT_CompoundRequirementLBrace, TT_BracedListLBrace, + TT_CompoundRequirementLBrace, TT_BracedListLBrace, TT_ExportLBrace, TT_FunctionLikeMacro)) { CurrentToken->setType(TT_Unknown); } diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp index a806bc8494ea0..50cb6b7dd11df 100644 --- a/clang/lib/Format/UnwrappedLineFormatter.cpp +++ b/clang/lib/Format/UnwrappedLineFormatter.cpp @@ -938,11 +938,9 @@ 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)) { + Line.First->is(TT_ExportLBrace)) { return 0; } diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 2b2e393271bdb..b6a95d2aa174b 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -3311,12 +3311,11 @@ void UnwrappedLineParser::parseNamespace() { } void UnwrappedLineParser::parseCppExportBlock() { - if (FormatTok->is(tok::l_brace)) { + FormatTok->setType(TT_ExportLBrace); if (Style.BraceWrapping.AfterExportBlock) addUnwrappedLine(); } - parseNamespaceOrExportBlock(/*AddLevels=*/Style.IndentExportBlock ? 1 : 0); } diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index ae9e0b6b8e74c..f297c4a091abc 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -694,6 +694,14 @@ TEST_F(TokenAnnotatorTest, UnderstandsEnums) { EXPECT_TOKEN(Tokens[3], tok::r_brace, TT_EnumRBrace); } +TEST_F(TokenAnnotatorTest, UnderstandsExportBlock) { + auto Tokens = annotate("export {\n" + "int foo();\n" + "}"); + ASSERT_EQ(Tokens.size(), 9u); + EXPECT_TOKEN(Tokens[1], tok::l_brace, TT_ExportLBrace); +} + TEST_F(TokenAnnotatorTest, UnderstandsDefaultedAndDeletedFunctions) { auto Tokens = annotate("auto operator<=>(const T &) const & = default;"); ASSERT_EQ(Tokens.size(), 14u) << Tokens; >From 915fa0642101092e47b8f035d62702956dc707f4 Mon Sep 17 00:00:00 2001 From: ahmedkamel10 <[email protected]> Date: Wed, 19 Aug 2026 16:21:33 +0300 Subject: [PATCH 3/3] [clang-format] Use setFinalizedType for TT_ExportLBrace --- clang/include/clang/Format/Format.h | 1 - clang/lib/Format/TokenAnnotator.cpp | 2 +- clang/lib/Format/UnwrappedLineParser.cpp | 2 +- clang/unittests/Format/TokenAnnotatorTest.cpp | 2 +- 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 82d8465bd08f6..f4e3479392f6f 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -1558,7 +1558,6 @@ struct FormatStyle { /// } /// \endcode bool AfterExternBlock; // Partially superseded by IndentExternBlock - /// Wrap before `catch`. /// \code /// true: diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 8f064e38a691b..b6c33279b0aca 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -2137,7 +2137,7 @@ class AnnotatingParser { TT_RecordLBrace, TT_StructLBrace, TT_UnionLBrace, TT_RequiresClause, TT_RequiresClauseInARequiresExpression, TT_RequiresExpression, TT_RequiresExpressionLParen, TT_RequiresExpressionLBrace, - TT_CompoundRequirementLBrace, TT_BracedListLBrace, TT_ExportLBrace, + TT_CompoundRequirementLBrace, TT_BracedListLBrace, TT_FunctionLikeMacro)) { CurrentToken->setType(TT_Unknown); } diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index b6a95d2aa174b..621804b060fad 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -3312,7 +3312,7 @@ void UnwrappedLineParser::parseNamespace() { void UnwrappedLineParser::parseCppExportBlock() { if (FormatTok->is(tok::l_brace)) { - FormatTok->setType(TT_ExportLBrace); + FormatTok->setFinalizedType(TT_ExportLBrace); if (Style.BraceWrapping.AfterExportBlock) addUnwrappedLine(); } diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index f297c4a091abc..b71147aaf1bc2 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -698,7 +698,7 @@ TEST_F(TokenAnnotatorTest, UnderstandsExportBlock) { auto Tokens = annotate("export {\n" "int foo();\n" "}"); - ASSERT_EQ(Tokens.size(), 9u); + ASSERT_EQ(Tokens.size(), 9u) << Tokens; EXPECT_TOKEN(Tokens[1], tok::l_brace, TT_ExportLBrace); } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
