Author: Paul Kirth Date: 2023-06-09T20:10:19Z New Revision: b6a718016c0fd7a0d883214ba19d88b6f96e3ae1
URL: https://github.com/llvm/llvm-project/commit/b6a718016c0fd7a0d883214ba19d88b6f96e3ae1 DIFF: https://github.com/llvm/llvm-project/commit/b6a718016c0fd7a0d883214ba19d88b6f96e3ae1.diff LOG: [clang-format] Add test case for issue 63170 After https://reviews.llvm.org/D151954 we've noticed some issues w/ clang-format behavior, as outlined in https://github.com/llvm/llvm-project/issues/63170. Valid C/C++ files, that were previously accepted, are now rejected by clang-format, emitting the message: "The new replacement overlaps with an existing replacement." This reverts commit 4b9764959dc4b8783e18747c1742ab164e4bc4ee and d2627cf88d2553a4c2e850430bdb908a4b7d2e52, which depends on it. Reviewed By: phosek Differential Revision: https://reviews.llvm.org/D152473 Added: clang/test/Format/overlapping-lines.cpp Modified: clang/docs/ClangFormatStyleOptions.rst clang/docs/ReleaseNotes.rst clang/include/clang/Format/Format.h clang/lib/Format/Format.cpp clang/lib/Format/UnwrappedLineFormatter.cpp clang/unittests/Format/ConfigParseTest.cpp clang/unittests/Format/FormatTest.cpp Removed: ################################################################################ diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index fa552d65e208a..8f23a4aa27a92 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3555,11 +3555,6 @@ the configuration (without a prefix: ``Auto``). false: import {VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying,} from "some/module.js" -.. _KeepEmptyLinesAtEOF: - -**KeepEmptyLinesAtEOF** (``Boolean``) :versionbadge:`clang-format 17` :ref:`¶ <KeepEmptyLinesAtEOF>` - Keep empty lines (up to ``MaxEmptyLinesToKeep``) at end of file. - .. _KeepEmptyLinesAtTheStartOfBlocks: **KeepEmptyLinesAtTheStartOfBlocks** (``Boolean``) :versionbadge:`clang-format 3.7` :ref:`¶ <KeepEmptyLinesAtTheStartOfBlocks>` diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index acd8c4d622a89..58e1039c4f133 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -707,7 +707,6 @@ clang-format - Fix all known issues associated with ``LambdaBodyIndentation: OuterScope``. - Add ``BracedInitializerIndentWidth`` which can be used to configure the indentation level of the contents of braced init lists. -- Add ``KeepEmptyLinesAtEOF`` to keep empty lines at end of file. libclang -------- diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 74b3e15918184..6a9d435174cdd 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2675,10 +2675,6 @@ struct FormatStyle { bool JavaScriptWrapImports; // clang-format on - /// Keep empty lines (up to ``MaxEmptyLinesToKeep``) at end of file. - /// \version 17 - bool KeepEmptyLinesAtEOF; - /// If true, the empty line at the start of blocks is kept. /// \code /// true: false: @@ -4368,7 +4364,6 @@ struct FormatStyle { JavaImportGroups == R.JavaImportGroups && JavaScriptQuotes == R.JavaScriptQuotes && JavaScriptWrapImports == R.JavaScriptWrapImports && - KeepEmptyLinesAtEOF == R.KeepEmptyLinesAtEOF && KeepEmptyLinesAtTheStartOfBlocks == R.KeepEmptyLinesAtTheStartOfBlocks && Language == R.Language && diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 5fee5e6c261a9..6e2b6a662e7e1 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -942,7 +942,6 @@ template <> struct MappingTraits<FormatStyle> { IO.mapOptional("JavaScriptWrapImports", Style.JavaScriptWrapImports); IO.mapOptional("KeepEmptyLinesAtTheStartOfBlocks", Style.KeepEmptyLinesAtTheStartOfBlocks); - IO.mapOptional("KeepEmptyLinesAtEOF", Style.KeepEmptyLinesAtEOF); IO.mapOptional("LambdaBodyIndentation", Style.LambdaBodyIndentation); IO.mapOptional("LineEnding", Style.LineEnding); IO.mapOptional("MacroBlockBegin", Style.MacroBlockBegin); @@ -1411,7 +1410,6 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { /*Hex=*/0, /*HexMinDigits=*/0}; LLVMStyle.JavaScriptQuotes = FormatStyle::JSQS_Leave; LLVMStyle.JavaScriptWrapImports = true; - LLVMStyle.KeepEmptyLinesAtEOF = false; LLVMStyle.KeepEmptyLinesAtTheStartOfBlocks = true; LLVMStyle.LambdaBodyIndentation = FormatStyle::LBI_Signature; LLVMStyle.LineEnding = FormatStyle::LE_DeriveLF; diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp index f229742b19d97..33be74dfe1b9f 100644 --- a/clang/lib/Format/UnwrappedLineFormatter.cpp +++ b/clang/lib/Format/UnwrappedLineFormatter.cpp @@ -1418,12 +1418,19 @@ unsigned UnwrappedLineFormatter::format( return Penalty; } -static auto newlinesBeforeLine(const AnnotatedLine &Line, - const AnnotatedLine *PreviousLine, - const AnnotatedLine *PrevPrevLine, - const SmallVectorImpl<AnnotatedLine *> &Lines, - const FormatStyle &Style) { - const auto &RootToken = *Line.First; +void UnwrappedLineFormatter::formatFirstToken( + const AnnotatedLine &Line, const AnnotatedLine *PreviousLine, + const AnnotatedLine *PrevPrevLine, + const SmallVectorImpl<AnnotatedLine *> &Lines, unsigned Indent, + unsigned NewlineIndent) { + FormatToken &RootToken = *Line.First; + if (RootToken.is(tok::eof)) { + unsigned Newlines = std::min(RootToken.NewlinesBefore, 1u); + unsigned TokenIndent = Newlines ? NewlineIndent : 0; + Whitespaces->replaceWhitespace(RootToken, Newlines, TokenIndent, + TokenIndent); + return; + } unsigned Newlines = std::min(RootToken.NewlinesBefore, Style.MaxEmptyLinesToKeep + 1); // Remove empty lines before "}" where applicable. @@ -1503,29 +1510,6 @@ static auto newlinesBeforeLine(const AnnotatedLine &Line, } } - return Newlines; -} - -void UnwrappedLineFormatter::formatFirstToken( - const AnnotatedLine &Line, const AnnotatedLine *PreviousLine, - const AnnotatedLine *PrevPrevLine, - const SmallVectorImpl<AnnotatedLine *> &Lines, unsigned Indent, - unsigned NewlineIndent) { - FormatToken &RootToken = *Line.First; - if (RootToken.is(tok::eof)) { - unsigned Newlines = - std::min(RootToken.NewlinesBefore, - Style.KeepEmptyLinesAtEOF ? Style.MaxEmptyLinesToKeep + 1 : 1); - unsigned TokenIndent = Newlines ? NewlineIndent : 0; - Whitespaces->replaceWhitespace(RootToken, Newlines, TokenIndent, - TokenIndent); - return; - } - - const auto Newlines = - RootToken.Finalized - ? RootToken.NewlinesBefore - : newlinesBeforeLine(Line, PreviousLine, PrevPrevLine, Lines, Style); if (Newlines) Indent = NewlineIndent; diff --git a/clang/test/Format/overlapping-lines.cpp b/clang/test/Format/overlapping-lines.cpp new file mode 100644 index 0000000000000..1a8b4785a506b --- /dev/null +++ b/clang/test/Format/overlapping-lines.cpp @@ -0,0 +1,8 @@ +// RUN: grep -Ev "// *[A-Z-]+:" %s | clang-format --style=Google 2>&1 | FileCheck %s +// CHECK-NOT: The new replacement overlaps with an existing replacement. + +#ifdef + + +#else +#endif diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp index 6c720ec22054c..169c93d1143eb 100644 --- a/clang/unittests/Format/ConfigParseTest.cpp +++ b/clang/unittests/Format/ConfigParseTest.cpp @@ -167,7 +167,6 @@ TEST(ConfigParseTest, ParsesConfigurationBools) { CHECK_PARSE_BOOL(IndentWrappedFunctionNames); CHECK_PARSE_BOOL(InsertBraces); CHECK_PARSE_BOOL(InsertNewlineAtEOF); - CHECK_PARSE_BOOL(KeepEmptyLinesAtEOF); CHECK_PARSE_BOOL(KeepEmptyLinesAtTheStartOfBlocks); CHECK_PARSE_BOOL(ObjCSpaceAfterProperty); CHECK_PARSE_BOOL(ObjCSpaceBeforeProtocolList); diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index adc1eda41a91a..fa53cbd262def 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -12856,22 +12856,6 @@ TEST_F(FormatTest, FormatsAfterAccessModifiers) { " void f() {}\n" "};\n", Style); - verifyFormat("struct foo {\n" - "#ifdef FOO\n" - "#else\n" - "private:\n" - "\n" - "#endif\n" - "};", - "struct foo {\n" - "#ifdef FOO\n" - "#else\n" - "private:\n" - "\n" - "\n" - "#endif\n" - "};", - Style); Style.EmptyLineAfterAccessModifier = FormatStyle::ELAAMS_Always; verifyFormat("struct foo {\n" @@ -25744,15 +25728,6 @@ TEST_F(FormatTest, InsertNewlineAtEOF) { verifyFormat("int i;\n", "int i;", Style); } -TEST_F(FormatTest, KeepEmptyLinesAtEOF) { - FormatStyle Style = getLLVMStyle(); - Style.KeepEmptyLinesAtEOF = true; - - const StringRef Code{"int i;\n\n"}; - verifyFormat(Code, Code, Style); - verifyFormat(Code, "int i;\n\n\n", Style); -} - TEST_F(FormatTest, SpaceAfterUDL) { verifyFormat("auto c = (4s).count();"); verifyFormat("auto x = 5s .count() == 5;"); @@ -25765,6 +25740,18 @@ TEST_F(FormatTest, InterfaceAsClassMemberName) { "}"); } +TEST_F(FormatTest, PreprocessorOverlappingRegions) { + verifyFormat("#ifdef\n\n" + "#else\n" + "#endif\n", + "#ifdef \n" + " \n" + "\n" + "#else \n" + "#endif \n", + getGoogleStyle()); +} + } // namespace } // namespace test } // namespace format _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits