diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3752,6 +3752,13 @@ IF (...) vs. IF(...) + * ``bool AfterOperatorOverloading`` If ``true``, put a space between operator overloading and opening parentheses. + + .. code-block:: c++ + + true: false: + void operator++ (int a); vs. void operator++(int a); + * ``bool BeforeNonEmptyParentheses`` If ``true``, put a space before opening parentheses only if the parentheses are not empty. 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 @@ -3368,6 +3368,13 @@ /// /// \endcode bool AfterIfMacros; + /// If ``true``, put a space between operator overloading and opening + /// parentheses. + /// \code + /// true: false: + /// void operator++ (int a); vs. void operator++(int a); + /// \endcode + bool AfterOperatorOverloading; /// If ``true``, put a space before opening parentheses only if the /// parentheses are not empty. /// \code @@ -3381,7 +3388,7 @@ : AfterControlStatements(false), AfterForeachMacros(false), AfterFunctionDeclarationName(false), AfterFunctionDefinitionName(false), AfterIfMacros(false), - BeforeNonEmptyParentheses(false) {} + AfterOperatorOverloading(false), BeforeNonEmptyParentheses(false) {} bool operator==(const SpaceBeforeParensCustom &Other) const { return AfterControlStatements == Other.AfterControlStatements && @@ -3390,6 +3397,7 @@ Other.AfterFunctionDeclarationName && AfterFunctionDefinitionName == Other.AfterFunctionDefinitionName && AfterIfMacros == Other.AfterIfMacros && + AfterOperatorOverloading == Other.AfterOperatorOverloading && BeforeNonEmptyParentheses == Other.BeforeNonEmptyParentheses; } }; 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 @@ -855,6 +855,8 @@ IO.mapOptional("AfterFunctionDeclarationName", Spacing.AfterFunctionDeclarationName); IO.mapOptional("AfterIfMacros", Spacing.AfterIfMacros); + IO.mapOptional("AfterOperatorOverloading", + Spacing.AfterOperatorOverloading); IO.mapOptional("BeforeNonEmptyParentheses", Spacing.BeforeNonEmptyParentheses); } diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -2921,9 +2921,15 @@ } bool TokenAnnotator::spaceRequiredBeforeParens(const FormatToken &Right) const { - return Style.SpaceBeforeParens == FormatStyle::SBPO_Always || - (Style.SpaceBeforeParensOptions.BeforeNonEmptyParentheses && - Right.ParameterCount > 0); + if (Style.SpaceBeforeParens == FormatStyle::SBPO_Always) + return true; + if (Right.is(TT_OverloadedOperatorLParen) && + Style.SpaceBeforeParensOptions.AfterOperatorOverloading) + return true; + if (Style.SpaceBeforeParensOptions.BeforeNonEmptyParentheses && + Right.ParameterCount > 0) + return true; + return false; } bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, 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 @@ -14542,6 +14542,22 @@ // verifyFormat("X A::operator++ (T);", SomeSpace2); verifyFormat("int x = int (y);", SomeSpace2); verifyFormat("auto lambda = []() { return 0; };", SomeSpace2); + + FormatStyle SpaceAfterOperatorOverloading = getLLVMStyle(); + SpaceAfterOperatorOverloading.SpaceBeforeParens = FormatStyle::SBPO_Custom; + SpaceAfterOperatorOverloading.SpaceBeforeParensOptions + .AfterOperatorOverloading = true; + + verifyFormat("auto operator++ () -> int;", SpaceAfterOperatorOverloading); + verifyFormat("X A::operator++ ();", SpaceAfterOperatorOverloading); + verifyFormat("auto func() -> int;", SpaceAfterOperatorOverloading); + + SpaceAfterOperatorOverloading.SpaceBeforeParensOptions + .AfterOperatorOverloading = false; + + verifyFormat("auto operator++() -> int;", SpaceAfterOperatorOverloading); + verifyFormat("X A::operator++();", SpaceAfterOperatorOverloading); + verifyFormat("auto func() -> int;", SpaceAfterOperatorOverloading); } TEST_F(FormatTest, SpaceAfterLogicalNot) {