[clang-format] Add an option to add a space between operator overloading and opening parentheses

This change adds an option AfterOverloadedOperator in SpaceBeforeParensOptions to add a space between overloaded operator and opening parentheses in clang-format.

Reviewed By: MyDeveloperDay, curdeius, HazardyKnusperkeks

Differential Revision: https://reviews.llvm.org/D116283
This commit is contained in:
Rajat Bajpai 2022-01-04 17:19:24 +01:00 committed by Marek Kurdej
parent 64e56f8356
commit da6b0d0b76
6 changed files with 59 additions and 4 deletions

View File

@ -3818,6 +3818,15 @@ the configuration (without a prefix: ``Auto``).
IF (...) vs. IF(...)
<conditional-body> <conditional-body>
* ``bool AfterOverloadedOperator`` 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);
object.operator++ (10); object.operator++(10);
* ``bool BeforeNonEmptyParentheses`` If ``true``, put a space before opening parentheses only if the
parentheses are not empty.

View File

@ -311,6 +311,9 @@ clang-format
- Improved C++20 Modules and Coroutines support.
- Option ``AfterOverloadedOperator`` has been added in ``SpaceBeforeParensOptions``
to allow space between overloaded operator and opening parentheses.
libclang
--------

View File

@ -3429,6 +3429,14 @@ struct FormatStyle {
/// <conditional-body> <conditional-body>
/// \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);
/// object.operator++ (10); object.operator++(10);
/// \endcode
bool AfterOverloadedOperator;
/// If ``true``, put a space before opening parentheses only if the
/// parentheses are not empty.
/// \code
@ -3442,7 +3450,7 @@ struct FormatStyle {
: AfterControlStatements(false), AfterForeachMacros(false),
AfterFunctionDeclarationName(false),
AfterFunctionDefinitionName(false), AfterIfMacros(false),
BeforeNonEmptyParentheses(false) {}
AfterOverloadedOperator(false), BeforeNonEmptyParentheses(false) {}
bool operator==(const SpaceBeforeParensCustom &Other) const {
return AfterControlStatements == Other.AfterControlStatements &&
@ -3451,6 +3459,7 @@ struct FormatStyle {
Other.AfterFunctionDeclarationName &&
AfterFunctionDefinitionName == Other.AfterFunctionDefinitionName &&
AfterIfMacros == Other.AfterIfMacros &&
AfterOverloadedOperator == Other.AfterOverloadedOperator &&
BeforeNonEmptyParentheses == Other.BeforeNonEmptyParentheses;
}
};

View File

@ -868,6 +868,7 @@ template <> struct MappingTraits<FormatStyle::SpaceBeforeParensCustom> {
IO.mapOptional("AfterFunctionDeclarationName",
Spacing.AfterFunctionDeclarationName);
IO.mapOptional("AfterIfMacros", Spacing.AfterIfMacros);
IO.mapOptional("AfterOverloadedOperator", Spacing.AfterOverloadedOperator);
IO.mapOptional("BeforeNonEmptyParentheses",
Spacing.BeforeNonEmptyParentheses);
}

View File

@ -2923,9 +2923,15 @@ unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line,
}
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.AfterOverloadedOperator)
return true;
if (Style.SpaceBeforeParensOptions.BeforeNonEmptyParentheses &&
Right.ParameterCount > 0)
return true;
return false;
}
bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,

View File

@ -14536,6 +14536,24 @@ TEST_F(FormatTest, ConfigurableSpaceBeforeParens) {
// verifyFormat("X A::operator++ (T);", SomeSpace2);
verifyFormat("int x = int (y);", SomeSpace2);
verifyFormat("auto lambda = []() { return 0; };", SomeSpace2);
FormatStyle SpaceAfterOverloadedOperator = getLLVMStyle();
SpaceAfterOverloadedOperator.SpaceBeforeParens = FormatStyle::SBPO_Custom;
SpaceAfterOverloadedOperator.SpaceBeforeParensOptions
.AfterOverloadedOperator = true;
verifyFormat("auto operator++ () -> int;", SpaceAfterOverloadedOperator);
verifyFormat("X A::operator++ ();", SpaceAfterOverloadedOperator);
verifyFormat("some_object.operator++ ();", SpaceAfterOverloadedOperator);
verifyFormat("auto func() -> int;", SpaceAfterOverloadedOperator);
SpaceAfterOverloadedOperator.SpaceBeforeParensOptions
.AfterOverloadedOperator = false;
verifyFormat("auto operator++() -> int;", SpaceAfterOverloadedOperator);
verifyFormat("X A::operator++();", SpaceAfterOverloadedOperator);
verifyFormat("some_object.operator++();", SpaceAfterOverloadedOperator);
verifyFormat("auto func() -> int;", SpaceAfterOverloadedOperator);
}
TEST_F(FormatTest, SpaceAfterLogicalNot) {
@ -18771,6 +18789,15 @@ TEST_F(FormatTest, ParsesConfigurationBools) {
CHECK_PARSE_NESTED_BOOL(BraceWrapping, SplitEmptyFunction);
CHECK_PARSE_NESTED_BOOL(BraceWrapping, SplitEmptyRecord);
CHECK_PARSE_NESTED_BOOL(BraceWrapping, SplitEmptyNamespace);
CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterControlStatements);
CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterForeachMacros);
CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions,
AfterFunctionDeclarationName);
CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions,
AfterFunctionDefinitionName);
CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterIfMacros);
CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterOverloadedOperator);
CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, BeforeNonEmptyParentheses);
}
#undef CHECK_PARSE_BOOL