diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -2685,8 +2685,8 @@ .. _DeriveLineEnding: **DeriveLineEnding** (``Boolean``) :versionbadge:`clang-format 10` :ref:`¶ ` - Analyze the formatted file for the most used line ending (``\r\n`` - or ``\n``). ``UseCRLF`` is only used as a fallback if none can be derived. + This option is **deprecated**. See ``DeriveLF`` and ``DeriveCRLF`` of + ``LineEnding``. .. _DerivePointerAlignment: @@ -3583,6 +3583,27 @@ +.. _LineEnding: + +**LineEnding** (``LineEndingStyle``) :versionbadge:`clang-format 16` :ref:`¶ ` + Line ending style (``\n`` or ``\r\n``) to use. + + Possible values: + + * ``LE_LF`` (in configuration: ``LF``) + Use ``\n``. + + * ``LE_CRLF`` (in configuration: ``CRLF``) + Use ``\r\n``. + + * ``LE_DeriveLF`` (in configuration: ``DeriveLF``) + Use ``\n`` unless the input has more lines ending in ``\r\n``. + + * ``LE_DeriveCRLF`` (in configuration: ``DeriveCRLF``) + Use ``\r\n`` unless the input has more lines ending in ``\n``. + + + .. _MacroBlockBegin: **MacroBlockBegin** (``String``) :versionbadge:`clang-format 3.7` :ref:`¶ ` @@ -5114,8 +5135,7 @@ .. _UseCRLF: **UseCRLF** (``Boolean``) :versionbadge:`clang-format 10` :ref:`¶ ` - Use ``\r\n`` instead of ``\n`` for line breaks. - Also used as fallback if ``DeriveLineEnding`` is true. + This option is **deprecated**. See ``LF`` and ``CRLF`` of ``LineEnding``. .. _UseTab: diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -912,6 +912,7 @@ - Add ``BreakAfterAttributes`` option for breaking after a group of C++11 attributes before a function declaration/definition name. - Add ``InsertNewlineAtEOF`` option for inserting a newline at EOF if missing. +- Add ``LineEnding`` option to deprecate ``DeriveLineEnding`` and ``UseCRLF``. clang-extdef-mapping -------------------- diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2006,10 +2006,10 @@ /// \version 3.4 bool Cpp11BracedListStyle; - /// \brief Analyze the formatted file for the most used line ending (``\r\n`` - /// or ``\n``). ``UseCRLF`` is only used as a fallback if none can be derived. + /// This option is **deprecated**. See ``DeriveLF`` and ``DeriveCRLF`` of + /// ``LineEnding``. /// \version 10 - bool DeriveLineEnding; + // bool DeriveLineEnding; /// If ``true``, analyze the formatted file for the most common /// alignment of ``&`` and ``*``. @@ -2695,6 +2695,22 @@ /// \version 3.5 LanguageKind Language; + /// Line ending style. + enum LineEndingStyle : int8_t { + /// Use ``\n``. + LE_LF, + /// Use ``\r\n``. + LE_CRLF, + /// Use ``\n`` unless the input has more lines ending in ``\r\n``. + LE_DeriveLF, + /// Use ``\r\n`` unless the input has more lines ending in ``\n``. + LE_DeriveCRLF, + }; + + /// Line ending style (``\n`` or ``\r\n``) to use. + /// \version 16 + LineEndingStyle LineEnding; + /// A regular expression matching macros that start a block. /// \code /// # With: @@ -4051,10 +4067,9 @@ /// \version 9 std::vector TypenameMacros; - /// \brief Use ``\r\n`` instead of ``\n`` for line breaks. - /// Also used as fallback if ``DeriveLineEnding`` is true. + /// This option is **deprecated**. See ``LF`` and ``CRLF`` of ``LineEnding``. /// \version 10 - bool UseCRLF; + // bool UseCRLF; /// Different ways to use tab in formatting. enum UseTabStyle : int8_t { @@ -4144,7 +4159,6 @@ R.ConstructorInitializerIndentWidth && ContinuationIndentWidth == R.ContinuationIndentWidth && Cpp11BracedListStyle == R.Cpp11BracedListStyle && - DeriveLineEnding == R.DeriveLineEnding && DerivePointerAlignment == R.DerivePointerAlignment && DisableFormat == R.DisableFormat && EmptyLineAfterAccessModifier == R.EmptyLineAfterAccessModifier && @@ -4181,7 +4195,7 @@ R.KeepEmptyLinesAtTheStartOfBlocks && Language == R.Language && LambdaBodyIndentation == R.LambdaBodyIndentation && - MacroBlockBegin == R.MacroBlockBegin && + LineEnding == R.LineEnding && MacroBlockBegin == R.MacroBlockBegin && MacroBlockEnd == R.MacroBlockEnd && MaxEmptyLinesToKeep == R.MaxEmptyLinesToKeep && NamespaceIndentation == R.NamespaceIndentation && @@ -4248,8 +4262,7 @@ Standard == R.Standard && StatementAttributeLikeMacros == R.StatementAttributeLikeMacros && StatementMacros == R.StatementMacros && TabWidth == R.TabWidth && - TypenameMacros == R.TypenameMacros && UseCRLF == R.UseCRLF && - UseTab == R.UseTab && + TypenameMacros == R.TypenameMacros && UseTab == R.UseTab && WhitespaceSensitiveMacros == R.WhitespaceSensitiveMacros; } diff --git a/clang/lib/Format/DefinitionBlockSeparator.cpp b/clang/lib/Format/DefinitionBlockSeparator.cpp --- a/clang/lib/Format/DefinitionBlockSeparator.cpp +++ b/clang/lib/Format/DefinitionBlockSeparator.cpp @@ -69,11 +69,11 @@ (Style.SeparateDefinitionBlocks == FormatStyle::SDS_Always ? 1 : 0) + 1; WhitespaceManager Whitespaces( Env.getSourceManager(), Style, - Style.DeriveLineEnding + Style.LineEnding > FormatStyle::LE_CRLF ? WhitespaceManager::inputUsesCRLF( Env.getSourceManager().getBufferData(Env.getFileID()), - Style.UseCRLF) - : Style.UseCRLF); + Style.LineEnding == FormatStyle::LE_DeriveCRLF) + : Style.LineEnding == FormatStyle::LE_CRLF); for (unsigned I = 0; I < Lines.size(); ++I) { const auto &CurrentLine = Lines[I]; if (CurrentLine->InPPDirective) diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -403,6 +403,15 @@ } }; +template <> struct ScalarEnumerationTraits { + static void enumeration(IO &IO, FormatStyle::LineEndingStyle &Value) { + IO.enumCase(Value, "LF", FormatStyle::LE_LF); + IO.enumCase(Value, "CRLF", FormatStyle::LE_CRLF); + IO.enumCase(Value, "DeriveLF", FormatStyle::LE_DeriveLF); + IO.enumCase(Value, "DeriveCRLF", FormatStyle::LE_DeriveCRLF); + } +}; + template <> struct ScalarEnumerationTraits { static void enumeration(IO &IO, @@ -784,6 +793,9 @@ bool BreakBeforeInheritanceComma = false; bool BreakConstructorInitializersBeforeComma = false; + bool DeriveLineEnding = true; + bool UseCRLF = false; + // For backward compatibility. if (!IO.outputting()) { IO.mapOptional("AlignEscapedNewlinesLeft", Style.AlignEscapedNewlines); @@ -794,6 +806,7 @@ BreakConstructorInitializersBeforeComma); IO.mapOptional("ConstructorInitializerAllOnOneLineOrOnePerLine", OnCurrentLine); + IO.mapOptional("DeriveLineEnding", DeriveLineEnding); IO.mapOptional("DerivePointerBinding", Style.DerivePointerAlignment); IO.mapOptional("IndentFunctionDeclarationAfterType", Style.IndentWrappedFunctionNames); @@ -801,6 +814,7 @@ IO.mapOptional("PointerBindsToType", Style.PointerAlignment); IO.mapOptional("SpaceAfterControlStatementKeyword", Style.SpaceBeforeParens); + IO.mapOptional("UseCRLF", UseCRLF); } IO.mapOptional("AccessModifierOffset", Style.AccessModifierOffset); @@ -871,7 +885,6 @@ Style.ConstructorInitializerIndentWidth); IO.mapOptional("ContinuationIndentWidth", Style.ContinuationIndentWidth); IO.mapOptional("Cpp11BracedListStyle", Style.Cpp11BracedListStyle); - IO.mapOptional("DeriveLineEnding", Style.DeriveLineEnding); IO.mapOptional("DerivePointerAlignment", Style.DerivePointerAlignment); IO.mapOptional("DisableFormat", Style.DisableFormat); IO.mapOptional("EmptyLineAfterAccessModifier", @@ -908,6 +921,7 @@ IO.mapOptional("KeepEmptyLinesAtTheStartOfBlocks", Style.KeepEmptyLinesAtTheStartOfBlocks); IO.mapOptional("LambdaBodyIndentation", Style.LambdaBodyIndentation); + IO.mapOptional("LineEnding", Style.LineEnding); IO.mapOptional("MacroBlockBegin", Style.MacroBlockBegin); IO.mapOptional("MacroBlockEnd", Style.MacroBlockEnd); IO.mapOptional("MaxEmptyLinesToKeep", Style.MaxEmptyLinesToKeep); @@ -1003,7 +1017,6 @@ IO.mapOptional("StatementMacros", Style.StatementMacros); IO.mapOptional("TabWidth", Style.TabWidth); IO.mapOptional("TypenameMacros", Style.TypenameMacros); - IO.mapOptional("UseCRLF", Style.UseCRLF); IO.mapOptional("UseTab", Style.UseTab); IO.mapOptional("WhitespaceSensitiveMacros", Style.WhitespaceSensitiveMacros); @@ -1052,6 +1065,13 @@ else if (!OnNextLine) Style.PackConstructorInitializers = FormatStyle::PCIS_CurrentLine; } + + if (Style.LineEnding == FormatStyle::LE_DeriveLF) { + if (!DeriveLineEnding) + Style.LineEnding = UseCRLF ? FormatStyle::LE_CRLF : FormatStyle::LE_LF; + else if (UseCRLF) + Style.LineEnding = FormatStyle::LE_DeriveCRLF; + } } }; @@ -1329,7 +1349,6 @@ LLVMStyle.ConstructorInitializerIndentWidth = 4; LLVMStyle.ContinuationIndentWidth = 4; LLVMStyle.Cpp11BracedListStyle = true; - LLVMStyle.DeriveLineEnding = true; LLVMStyle.DerivePointerAlignment = false; LLVMStyle.DisableFormat = false; LLVMStyle.EmptyLineAfterAccessModifier = FormatStyle::ELAAMS_Never; @@ -1363,6 +1382,7 @@ LLVMStyle.JavaScriptWrapImports = true; LLVMStyle.KeepEmptyLinesAtTheStartOfBlocks = true; LLVMStyle.LambdaBodyIndentation = FormatStyle::LBI_Signature; + LLVMStyle.LineEnding = FormatStyle::LE_DeriveLF; LLVMStyle.MaxEmptyLinesToKeep = 1; LLVMStyle.NamespaceIndentation = FormatStyle::NI_None; LLVMStyle.ObjCBinPackProtocolList = FormatStyle::BPS_Auto; @@ -1416,7 +1436,6 @@ LLVMStyle.StatementMacros.push_back("Q_UNUSED"); LLVMStyle.StatementMacros.push_back("QT_REQUIRE_VERSION"); LLVMStyle.TabWidth = 8; - LLVMStyle.UseCRLF = false; LLVMStyle.UseTab = FormatStyle::UT_Never; LLVMStyle.WhitespaceSensitiveMacros.push_back("BOOST_PP_STRINGIZE"); LLVMStyle.WhitespaceSensitiveMacros.push_back("CF_SWIFT_NAME"); @@ -2190,11 +2209,11 @@ WhitespaceManager Whitespaces( Env.getSourceManager(), Style, - Style.DeriveLineEnding + Style.LineEnding > FormatStyle::LE_CRLF ? WhitespaceManager::inputUsesCRLF( Env.getSourceManager().getBufferData(Env.getFileID()), - Style.UseCRLF) - : Style.UseCRLF); + Style.LineEnding == FormatStyle::LE_DeriveCRLF) + : Style.LineEnding == FormatStyle::LE_CRLF); ContinuationIndenter Indenter(Style, Tokens.getKeywords(), Env.getSourceManager(), Whitespaces, Encoding, BinPackInconclusiveFunctions); diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp --- a/clang/unittests/Format/ConfigParseTest.cpp +++ b/clang/unittests/Format/ConfigParseTest.cpp @@ -155,7 +155,6 @@ CHECK_PARSE_BOOL(BreakBeforeTernaryOperators); CHECK_PARSE_BOOL(BreakStringLiterals); CHECK_PARSE_BOOL(CompactNamespaces); - CHECK_PARSE_BOOL(DeriveLineEnding); CHECK_PARSE_BOOL(DerivePointerAlignment); CHECK_PARSE_BOOL_FIELD(DerivePointerAlignment, "DerivePointerBinding"); CHECK_PARSE_BOOL(DisableFormat); @@ -193,7 +192,6 @@ CHECK_PARSE_BOOL(SpaceBeforeInheritanceColon); CHECK_PARSE_BOOL(SpaceBeforeRangeBasedForLoopColon); CHECK_PARSE_BOOL(SpaceBeforeSquareBrackets); - CHECK_PARSE_BOOL(UseCRLF); CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterCaseLabel); CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterClass); @@ -886,6 +884,20 @@ FormatStyle::ABS_Leave); CHECK_PARSE("BreakAfterAttributes: Never", BreakAfterAttributes, FormatStyle::ABS_Never); + + const auto DefaultLineEnding = FormatStyle::LE_DeriveLF; + CHECK_PARSE("LineEnding: LF", LineEnding, FormatStyle::LE_LF); + CHECK_PARSE("LineEnding: CRLF", LineEnding, FormatStyle::LE_CRLF); + CHECK_PARSE("LineEnding: DeriveCRLF", LineEnding, FormatStyle::LE_DeriveCRLF); + CHECK_PARSE("LineEnding: DeriveLF", LineEnding, DefaultLineEnding); + // For backward compatibility: + CHECK_PARSE("DeriveLineEnding: false", LineEnding, FormatStyle::LE_LF); + Style.LineEnding = DefaultLineEnding; + CHECK_PARSE("DeriveLineEnding: false\n" + "UseCRLF: true", + LineEnding, FormatStyle::LE_CRLF); + Style.LineEnding = DefaultLineEnding; + CHECK_PARSE("UseCRLF: true", LineEnding, FormatStyle::LE_DeriveCRLF); } TEST(ConfigParseTest, ParsesConfigurationWithLanguages) { diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -22218,8 +22218,7 @@ FormatStyle style = getLLVMStyle(); - style.DeriveLineEnding = true; - style.UseCRLF = false; + EXPECT_EQ(style.LineEnding, FormatStyle::LE_DeriveLF); EXPECT_EQ("union FooBarBazQux {\n" " int foo;\n" " int bar;\n" @@ -22231,7 +22230,7 @@ " int baz;\n" "};", style)); - style.UseCRLF = true; + style.LineEnding = FormatStyle::LE_DeriveCRLF; EXPECT_EQ("union FooBarBazQux {\r\n" " int foo;\r\n" " int bar;\r\n" @@ -22244,8 +22243,7 @@ "};", style)); - style.DeriveLineEnding = false; - style.UseCRLF = false; + style.LineEnding = FormatStyle::LE_LF; EXPECT_EQ("union FooBarBazQux {\n" " int foo;\n" " int bar;\n" @@ -22259,7 +22257,7 @@ " int qux;\r\n" "};", style)); - style.UseCRLF = true; + style.LineEnding = FormatStyle::LE_CRLF; EXPECT_EQ("union FooBarBazQux {\r\n" " int foo;\r\n" " int bar;\r\n" @@ -22274,8 +22272,7 @@ "};", style)); - style.DeriveLineEnding = true; - style.UseCRLF = false; + style.LineEnding = FormatStyle::LE_DeriveLF; EXPECT_EQ("union FooBarBazQux {\r\n" " int foo;\r\n" " int bar;\r\n" @@ -22289,7 +22286,7 @@ " int qux;\r\n" "};", style)); - style.UseCRLF = true; + style.LineEnding = FormatStyle::LE_DeriveCRLF; EXPECT_EQ("union FooBarBazQux {\n" " int foo;\n" " int bar;\n"