MyDeveloperDay created this revision. MyDeveloperDay added reviewers: curdeius, krasimir, klimek. MyDeveloperDay added projects: clang, clang-format. MyDeveloperDay requested review of this revision.
https://bugs.llvm.org/show_bug.cgi?id=48594 Empty or small templates were not being treated the same way as small classes especially when SplitEmptyRecord was set to true This revision aims to help this by identifying a case when we should try not to merge the lines together BraceWrapping: AfterStruct: true SplitEmptyRecord: true BreakBeforeBraces: Custom Input and expected formatted result: C++ template <class> struct rep { }; Actual output: C++ template <class> struct rep {}; Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D93839 Files: clang/lib/Format/UnwrappedLineFormatter.cpp clang/unittests/Format/FormatTest.cpp Index: clang/unittests/Format/FormatTest.cpp =================================================================== --- clang/unittests/Format/FormatTest.cpp +++ clang/unittests/Format/FormatTest.cpp @@ -9891,6 +9891,55 @@ "{\n" "} Foo_t;", Style); + + Style.BraceWrapping.SplitEmptyRecord = true; + Style.BraceWrapping.AfterStruct = true; + verifyFormat("class rep\n" + "{\n" + "};", + Style); + verifyFormat("struct rep\n" + "{\n" + "};", + Style); + verifyFormat("template <typename T> class rep\n" + "{\n" + "};", + Style); + verifyFormat("template <typename T> struct rep\n" + "{\n" + "};", + Style); + verifyFormat("class rep\n" + "{\n" + " int x;\n" + "};", + Style); + verifyFormat("struct rep\n" + "{\n" + " int x;\n" + "};", + Style); + verifyFormat("template <typename T> class rep\n" + "{\n" + " int x;\n" + "};", + Style); + verifyFormat("template <typename T> struct rep\n" + "{\n" + " int x;\n" + "};", + Style); + verifyFormat("template <typename T> class rep // Foo\n" + "{\n" + " int x;\n" + "};", + Style); + verifyFormat("template <typename T> struct rep // Bar\n" + "{\n" + " int x;\n" + "};", + Style); } TEST_F(FormatTest, SplitEmptyStruct) { Index: clang/lib/Format/UnwrappedLineFormatter.cpp =================================================================== --- clang/lib/Format/UnwrappedLineFormatter.cpp +++ clang/lib/Format/UnwrappedLineFormatter.cpp @@ -248,6 +248,11 @@ return !Style.BraceWrapping.SplitEmptyRecord && EmptyBlock ? tryMergeSimpleBlock(I, E, Limit) : 0; + + if (Tok && Tok->is(tok::kw_template) && + Style.BraceWrapping.SplitEmptyRecord && EmptyBlock) { + return 0; + } } // FIXME: TheLine->Level != 0 might or might not be the right check to do. @@ -355,6 +360,21 @@ if (TheLine->First->is(tok::l_brace) && I != AnnotatedLines.begin() && I[-1]->First->isOneOf(tok::kw_case, tok::kw_default)) return 0; + + if (TheLine->Last->is(tok::l_brace) && I != AnnotatedLines.begin() && + I[-1]->Last && Style.BraceWrapping.SplitEmptyRecord) { + const FormatToken *Previous = I[-1]->Last; + if (Previous && Previous->is(tok::comment)) { + Previous = Previous->getPreviousNonComment(); + } + if (Previous) { + const FormatToken *PreviousPrevious = Previous->getPreviousNonComment(); + if (PreviousPrevious && Previous->is(tok::identifier) && + PreviousPrevious->isOneOf(tok::kw_class, tok::kw_struct)) + return 0; + } + } + // Try to merge a block with left brace wrapped that wasn't yet covered if (TheLine->Last->is(tok::l_brace)) { return !Style.BraceWrapping.AfterFunction ||
Index: clang/unittests/Format/FormatTest.cpp =================================================================== --- clang/unittests/Format/FormatTest.cpp +++ clang/unittests/Format/FormatTest.cpp @@ -9891,6 +9891,55 @@ "{\n" "} Foo_t;", Style); + + Style.BraceWrapping.SplitEmptyRecord = true; + Style.BraceWrapping.AfterStruct = true; + verifyFormat("class rep\n" + "{\n" + "};", + Style); + verifyFormat("struct rep\n" + "{\n" + "};", + Style); + verifyFormat("template <typename T> class rep\n" + "{\n" + "};", + Style); + verifyFormat("template <typename T> struct rep\n" + "{\n" + "};", + Style); + verifyFormat("class rep\n" + "{\n" + " int x;\n" + "};", + Style); + verifyFormat("struct rep\n" + "{\n" + " int x;\n" + "};", + Style); + verifyFormat("template <typename T> class rep\n" + "{\n" + " int x;\n" + "};", + Style); + verifyFormat("template <typename T> struct rep\n" + "{\n" + " int x;\n" + "};", + Style); + verifyFormat("template <typename T> class rep // Foo\n" + "{\n" + " int x;\n" + "};", + Style); + verifyFormat("template <typename T> struct rep // Bar\n" + "{\n" + " int x;\n" + "};", + Style); } TEST_F(FormatTest, SplitEmptyStruct) { Index: clang/lib/Format/UnwrappedLineFormatter.cpp =================================================================== --- clang/lib/Format/UnwrappedLineFormatter.cpp +++ clang/lib/Format/UnwrappedLineFormatter.cpp @@ -248,6 +248,11 @@ return !Style.BraceWrapping.SplitEmptyRecord && EmptyBlock ? tryMergeSimpleBlock(I, E, Limit) : 0; + + if (Tok && Tok->is(tok::kw_template) && + Style.BraceWrapping.SplitEmptyRecord && EmptyBlock) { + return 0; + } } // FIXME: TheLine->Level != 0 might or might not be the right check to do. @@ -355,6 +360,21 @@ if (TheLine->First->is(tok::l_brace) && I != AnnotatedLines.begin() && I[-1]->First->isOneOf(tok::kw_case, tok::kw_default)) return 0; + + if (TheLine->Last->is(tok::l_brace) && I != AnnotatedLines.begin() && + I[-1]->Last && Style.BraceWrapping.SplitEmptyRecord) { + const FormatToken *Previous = I[-1]->Last; + if (Previous && Previous->is(tok::comment)) { + Previous = Previous->getPreviousNonComment(); + } + if (Previous) { + const FormatToken *PreviousPrevious = Previous->getPreviousNonComment(); + if (PreviousPrevious && Previous->is(tok::identifier) && + PreviousPrevious->isOneOf(tok::kw_class, tok::kw_struct)) + return 0; + } + } + // Try to merge a block with left brace wrapped that wasn't yet covered if (TheLine->Last->is(tok::l_brace)) { return !Style.BraceWrapping.AfterFunction ||
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits