diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3761,6 +3761,13 @@ void f (int a); vs. void f(); f (a); f(); + * ``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); + **SpaceBeforeRangeBasedForLoopColon** (``Boolean``) :versionbadge:`clang-format 7` If ``false``, spaces will be removed before range-based for loop 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 @@ -3376,12 +3376,20 @@ /// f (a); f(); /// \endcode bool BeforeNonEmptyParentheses; + /// 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; SpaceBeforeParensCustom() : AfterControlStatements(false), AfterForeachMacros(false), AfterFunctionDeclarationName(false), AfterFunctionDefinitionName(false), AfterIfMacros(false), - BeforeNonEmptyParentheses(false) {} + BeforeNonEmptyParentheses(false), AfterOperatorOverloading(false) {} bool operator==(const SpaceBeforeParensCustom &Other) const { return AfterControlStatements == Other.AfterControlStatements && @@ -3390,7 +3398,8 @@ Other.AfterFunctionDeclarationName && AfterFunctionDefinitionName == Other.AfterFunctionDefinitionName && AfterIfMacros == Other.AfterIfMacros && - BeforeNonEmptyParentheses == Other.BeforeNonEmptyParentheses; + BeforeNonEmptyParentheses == Other.BeforeNonEmptyParentheses && + AfterOperatorOverloading == Other.AfterOperatorOverloading; } }; 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 @@ -857,6 +857,8 @@ IO.mapOptional("AfterIfMacros", Spacing.AfterIfMacros); IO.mapOptional("BeforeNonEmptyParentheses", Spacing.BeforeNonEmptyParentheses); + IO.mapOptional("AfterOperatorOverloading", + Spacing.AfterOperatorOverloading); } }; 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/test/Format/space-before-parens.cpp b/clang/test/Format/space-before-parens.cpp new file mode 100644 --- /dev/null +++ b/clang/test/Format/space-before-parens.cpp @@ -0,0 +1,9 @@ +// RUN: clang-format -style="{SpaceBeforeParens: Custom, SpaceBeforeParensOptions: {AfterOperator: false}}" %s | FileCheck -strict-whitespace -check-prefix=CHECK1 %s +// Test space between overloaded operator and left parentheses +// RUN: clang-format -style="{SpaceBeforeParens: Custom, SpaceBeforeParensOptions: {AfterOperator: true}}" %s | FileCheck -strict-whitespace -check-prefix=CHECK2 %s +class Test { + auto func() -> int; + // CHECK1: {{^\ \ auto\ operator\+\+\(int\)\ \-\>\ int;$}} + // CHECK2: {{^\ \ auto\ operator\+\+\ \(int\)\ \-\>\ int;$}} + auto operator++(int) -> int; +};