https://github.com/owenca created https://github.com/llvm/llvm-project/pull/150166
Replace true/false with SAN_Exclaim/SAN_Never and add SAN_Always. Closes #149971 >From b5442f59d649b38086ccd91d40c7c291dd924cc8 Mon Sep 17 00:00:00 2001 From: Owen Pan <owenpi...@gmail.com> Date: Tue, 22 Jul 2025 22:07:05 -0700 Subject: [PATCH] [clang-format] Change SpaceAfterLogicalNot to enumeration type Replace true/false with SAN_Exclaim/SAN_Never and add SAN_Always. Closes #149971 --- clang/docs/ClangFormatStyleOptions.rst | 34 ++++++++++++++++++---- clang/include/clang/Format/Format.h | 31 ++++++++++++++++---- clang/lib/Format/Format.cpp | 14 ++++++++- clang/lib/Format/TokenAnnotator.cpp | 5 ++-- clang/unittests/Format/ConfigParseTest.cpp | 13 ++++++++- clang/unittests/Format/FormatTest.cpp | 9 ++++-- 6 files changed, 89 insertions(+), 17 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index d39ee49b432e5..ff91c4f63fc46 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -6118,13 +6118,37 @@ the configuration (without a prefix: ``Auto``). .. _SpaceAfterLogicalNot: -**SpaceAfterLogicalNot** (``Boolean``) :versionbadge:`clang-format 9` :ref:`¶ <SpaceAfterLogicalNot>` - If ``true``, a space is inserted after the logical not operator (``!``). +**SpaceAfterLogicalNot** (``SpaceAfterNotOptions``) :versionbadge:`clang-format 9` :ref:`¶ <SpaceAfterLogicalNot>` + Controls if a space is inserted after the logical not operator (``!`` or + ``not``). + + Possible values: + + * ``SAN_Never`` (in configuration: ``Never``) + Never insert a space after ``!``. + + .. code-block:: c++ + + return !someExpression(); + return not(a || b); + + * ``SAN_Exclaim`` (in configuration: ``Exclaim``) + Always insert a space after ``!``. + + .. code-block:: c++ + + return ! someExpression(); + return not(a || b); + + * ``SAN_Always`` (in configuration: ``Always``) + Always insert a space after both ``!`` and ``not``. + + .. code-block:: c++ + + return ! someExpression(); + return not (a || b); - .. code-block:: c++ - true: false: - ! someExpression(); vs. !someExpression(); .. _SpaceAfterOperatorKeyword: diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 7677604484f52..6398662fe7847 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -4483,13 +4483,32 @@ struct FormatStyle { /// \version 3.5 bool SpaceAfterCStyleCast; - /// If ``true``, a space is inserted after the logical not operator (``!``). - /// \code - /// true: false: - /// ! someExpression(); vs. !someExpression(); - /// \endcode + /// Space after logical not operator options. + enum SpaceAfterNotOptions : int8_t { + /// Never insert a space after ``!``. + /// \code + /// return !someExpression(); + /// return not(a || b); + /// \endcode + SAN_Never, + /// Always insert a space after ``!``. + /// \code + /// return ! someExpression(); + /// return not(a || b); + /// \endcode + SAN_Exclaim, + /// Always insert a space after both ``!`` and ``not``. + /// \code + /// return ! someExpression(); + /// return not (a || b); + /// \endcode + SAN_Always, + }; + + /// Controls if a space is inserted after the logical not operator (``!`` or + /// ``not``). /// \version 9 - bool SpaceAfterLogicalNot; + SpaceAfterNotOptions SpaceAfterLogicalNot; /// If ``true``, a space will be inserted after the ``operator`` keyword. /// \code diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 62feb3db0ed5e..3ce931a0ffdb6 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -711,6 +711,18 @@ struct ScalarEnumerationTraits<FormatStyle::SortUsingDeclarationsOptions> { } }; +template <> struct ScalarEnumerationTraits<FormatStyle::SpaceAfterNotOptions> { + static void enumeration(IO &IO, FormatStyle::SpaceAfterNotOptions &Value) { + IO.enumCase(Value, "Never", FormatStyle::SAN_Never); + IO.enumCase(Value, "Exclaim", FormatStyle::SAN_Exclaim); + IO.enumCase(Value, "Always", FormatStyle::SAN_Always); + + // For backward compatibility. + IO.enumCase(Value, "false", FormatStyle::SAN_Never); + IO.enumCase(Value, "true", FormatStyle::SAN_Exclaim); + } +}; + template <> struct ScalarEnumerationTraits<FormatStyle::SpaceAroundPointerQualifiersStyle> { static void @@ -1659,7 +1671,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { LLVMStyle.SortJavaStaticImport = FormatStyle::SJSIO_Before; LLVMStyle.SortUsingDeclarations = FormatStyle::SUD_LexicographicNumeric; LLVMStyle.SpaceAfterCStyleCast = false; - LLVMStyle.SpaceAfterLogicalNot = false; + LLVMStyle.SpaceAfterLogicalNot = FormatStyle::SAN_Never; LLVMStyle.SpaceAfterOperatorKeyword = false; LLVMStyle.SpaceAfterTemplateKeyword = true; LLVMStyle.SpaceAroundPointerQualifiers = FormatStyle::SAPQ_Default; diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 581bfbab0972d..e5b96a9e2f635 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -5476,9 +5476,10 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, if (Left.isNot(tok::exclaim)) return false; if (Left.TokenText == "!") - return Style.SpaceAfterLogicalNot; + return Style.SpaceAfterLogicalNot != FormatStyle::SAN_Never; assert(Left.TokenText == "not"); - return Right.isOneOf(tok::coloncolon, TT_UnaryOperator); + return Right.isOneOf(tok::coloncolon, TT_UnaryOperator) || + Style.SpaceAfterLogicalNot == FormatStyle::SAN_Always; } // If the next token is a binary operator or a selector name, we have diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp index 65d8b36c677bd..b71bcb20d00ca 100644 --- a/clang/unittests/Format/ConfigParseTest.cpp +++ b/clang/unittests/Format/ConfigParseTest.cpp @@ -205,7 +205,6 @@ TEST(ConfigParseTest, ParsesConfigurationBools) { CHECK_PARSE_BOOL(SpaceAfterCStyleCast); CHECK_PARSE_BOOL(SpaceAfterTemplateKeyword); CHECK_PARSE_BOOL(SpaceAfterOperatorKeyword); - CHECK_PARSE_BOOL(SpaceAfterLogicalNot); CHECK_PARSE_BOOL(SpaceBeforeAssignmentOperators); CHECK_PARSE_BOOL(SpaceBeforeCaseColon); CHECK_PARSE_BOOL(SpaceBeforeCpp11BracedList); @@ -654,6 +653,18 @@ TEST(ConfigParseTest, ParsesConfiguration) { CHECK_PARSE("AllowShortLambdasOnASingleLine: true", AllowShortLambdasOnASingleLine, FormatStyle::SLS_All); + CHECK_PARSE("SpaceAfterLogicalNot: Exclaim", SpaceAfterLogicalNot, + FormatStyle::SAN_Exclaim); + CHECK_PARSE("SpaceAfterLogicalNot: Never", SpaceAfterLogicalNot, + FormatStyle::SAN_Never); + CHECK_PARSE("SpaceAfterLogicalNot: Always", SpaceAfterLogicalNot, + FormatStyle::SAN_Always); + // For backward compatibility: + CHECK_PARSE("SpaceAfterLogicalNot: false", SpaceAfterLogicalNot, + FormatStyle::SAN_Never); + CHECK_PARSE("SpaceAfterLogicalNot: true", SpaceAfterLogicalNot, + FormatStyle::SAN_Exclaim); + Style.SpaceAroundPointerQualifiers = FormatStyle::SAPQ_Both; CHECK_PARSE("SpaceAroundPointerQualifiers: Default", SpaceAroundPointerQualifiers, FormatStyle::SAPQ_Default); diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index dbf6950446ef0..bd732d2b0aa81 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -17762,14 +17762,19 @@ TEST_F(FormatTest, ConfigurableSpaceBeforeParens) { } TEST_F(FormatTest, SpaceAfterLogicalNot) { - FormatStyle Spaces = getLLVMStyle(); - Spaces.SpaceAfterLogicalNot = true; + auto Spaces = getLLVMStyle(); + EXPECT_EQ(Spaces.SpaceAfterLogicalNot, FormatStyle::SAN_Never); + Spaces.SpaceAfterLogicalNot = FormatStyle::SAN_Exclaim; verifyFormat("bool x = ! y", Spaces); verifyFormat("if (! isFailure())", Spaces); verifyFormat("if (! (a && b))", Spaces); verifyFormat("\"Error!\"", Spaces); verifyFormat("! ! x", Spaces); + + Spaces.SpaceAfterLogicalNot = FormatStyle::SAN_Always; + verifyFormat("return ! (a || b);", Spaces); + verifyFormat("return not (a || b);", Spaces); } TEST_F(FormatTest, ConfigurableSpacesInParens) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits