diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -5432,13 +5432,42 @@ } } } } - * ``bool Other`` Put a space in parentheses not covered by preceding options. + * ``bool InFunctionCalls`` Put a space in parentheses of function calls. .. code-block:: c++ true: false: t f( Deleted & ) & = delete; vs. t f(Deleted &) & = delete; + * ``bool InFunctionDeclarations`` Put a space in parentheses of function declarations. + + .. code-block:: c++ + + true: false: + void foo( int bar ); vs. void foo(int bar); + + * ``bool InFunctionDefinitions`` Put a space in parentheses of function definitions. + + .. code-block:: c++ + + true: false: + void foo( int bar ) { } vs. void foo(int bar) { } + + * ``bool InOverloadedOperators`` Put a space in parentheses of overloaded operators. + + .. code-block:: c++ + + true: false: + void operator++( int a ) vs. void operator++(int a) + object.operator++( 10 ) vs. object.operator++(10) + + * ``bool Other`` Put a space in parentheses not covered by preceding options. + + .. code-block:: c++ + + true: false: + x = ( y + z ); vs. x = (y+z); + .. _SpacesInParentheses: diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -173,6 +173,9 @@ ------------ - Add ``InAttributeSpecifiers`` style option to ``SpacesInParensOptions`` to control addition of spaces after the ``__attribute__`` keyword. +- Add ``InFunctionCalls``, ``InFunctionDeclarations``, + ``InFunctionDefinitions``, and ``InOverloadedOperators`` style options to + ``SpacesInParensOptions`` to control addition of spaces. libclang -------- 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 @@ -4334,30 +4334,69 @@ /// } } /// \endcode bool InEmptyParentheses; - /// Put a space in parentheses not covered by preceding options. + /// Put a space in parentheses of function calls. /// \code /// true: false: /// t f( Deleted & ) & = delete; vs. t f(Deleted &) & = delete; /// \endcode + bool InFunctionCalls; + /// Put a space in parentheses of function declarations. + /// \code + /// true: false: + /// void foo( int bar ); vs. void foo(int bar); + /// \endcode + bool InFunctionDeclarations; + /// Put a space in parentheses of function definitions. + /// \code + /// true: false: + /// void foo( int bar ) { } vs. void foo(int bar) { } + /// \endcode + bool InFunctionDefinitions; + /// Put a space in parentheses of overloaded operators. + /// \code + /// true: false: + /// void operator++( int a ) vs. void operator++(int a) + /// object.operator++( 10 ) vs. object.operator++(10) + /// \endcode + bool InOverloadedOperators; + /// Put a space in parentheses not covered by preceding options. + /// \code + /// true: false: + /// x = ( y + z ); vs. x = (y+z); + /// \endcode bool Other; SpacesInParensCustom() : InAttributeSpecifiers(false), InConditionalStatements(false), - InCStyleCasts(false), InEmptyParentheses(false), Other(false) {} + InCStyleCasts(false), InEmptyParentheses(false), + InFunctionCalls(false), InFunctionDeclarations(false), + InFunctionDefinitions(false), InOverloadedOperators(false), + Other(false) {} SpacesInParensCustom(bool InAttributeSpecifiers, bool InConditionalStatements, bool InCStyleCasts, - bool InEmptyParentheses, bool Other) + bool InEmptyParentheses, bool InFunctionCalls, + bool InFunctionDeclarations, + bool InFunctionDefinitions, bool InOverloadedOperators, + bool Other) : InAttributeSpecifiers(InAttributeSpecifiers), InConditionalStatements(InConditionalStatements), InCStyleCasts(InCStyleCasts), InEmptyParentheses(InEmptyParentheses), - Other(Other) {} + InFunctionCalls(InFunctionCalls), + InFunctionDeclarations(InFunctionDeclarations), + InFunctionDefinitions(InFunctionDefinitions), + InOverloadedOperators(InOverloadedOperators), Other(Other) {} bool operator==(const SpacesInParensCustom &R) const { return InAttributeSpecifiers == R.InAttributeSpecifiers && InConditionalStatements == R.InConditionalStatements && InCStyleCasts == R.InCStyleCasts && - InEmptyParentheses == R.InEmptyParentheses && Other == R.Other; + InEmptyParentheses == R.InEmptyParentheses && + InFunctionCalls == R.InFunctionCalls && + InFunctionDeclarations == R.InFunctionDeclarations && + InFunctionDefinitions == R.InFunctionDefinitions && + InOverloadedOperators == R.InOverloadedOperators && + Other == R.Other; } bool operator!=(const SpacesInParensCustom &R) const { return !(*this == R); 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 @@ -728,6 +728,10 @@ IO.mapOptional("InCStyleCasts", Spaces.InCStyleCasts); IO.mapOptional("InConditionalStatements", Spaces.InConditionalStatements); IO.mapOptional("InEmptyParentheses", Spaces.InEmptyParentheses); + IO.mapOptional("InFunctionCalls", Spaces.InFunctionCalls); + IO.mapOptional("InFunctionDeclarations", Spaces.InFunctionDeclarations); + IO.mapOptional("InFunctionDefinitions", Spaces.InFunctionDefinitions); + IO.mapOptional("InOverloadedOperators", Spaces.InOverloadedOperators); IO.mapOptional("Other", Spaces.Other); } }; @@ -1161,6 +1165,10 @@ SpacesInCStyleCastParentheses; Style.SpacesInParensOptions.InEmptyParentheses = SpaceInEmptyParentheses; + Style.SpacesInParensOptions.InFunctionCalls = true; + Style.SpacesInParensOptions.InFunctionDeclarations = true; + Style.SpacesInParensOptions.InFunctionDefinitions = true; + Style.SpacesInParensOptions.InOverloadedOperators = true; Style.SpacesInParensOptions.Other = true; } else { Style.SpacesInParensOptions = {}; 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 @@ -3823,6 +3823,31 @@ (Right.Next && Right.Next->is(TT_AttributeParen))) { return Style.SpacesInParensOptions.InAttributeSpecifiers; } + // Function declaration or definition + if ((Left.Previous && Left.Previous->is(TT_FunctionDeclarationName)) || + (Right.MatchingParen && Right.MatchingParen->Previous && + Right.MatchingParen->Previous->is(TT_FunctionDeclarationName))) { + if (Line.MightBeFunctionDecl) + if (Line.mightBeFunctionDefinition()) + return Style.SpacesInParensOptions.InFunctionDefinitions; + else + return Style.SpacesInParensOptions.InFunctionDeclarations; + else + return Style.SpacesInParensOptions.Other; + } + if (Left.is(TT_OverloadedOperatorLParen) || + (Right.MatchingParen && + Right.MatchingParen->is(TT_OverloadedOperatorLParen))) { + return Style.SpacesInParensOptions.InOverloadedOperators; + } + if (((Left.ParameterCount > 0 && Left.Previous && + Left.Previous->is(tok::identifier)) || + (Right.MatchingParen && Right.MatchingParen->ParameterCount > 0 && + Right.MatchingParen->Previous && + Right.MatchingParen->Previous->is(tok::identifier))) && + (Line.Type != LT_PreprocessorDirective)) { + return Style.SpacesInParensOptions.InFunctionCalls; + } return Style.SpacesInParensOptions.Other; } if (Right.isOneOf(tok::semi, tok::comma)) 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 @@ -226,6 +226,10 @@ CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InCStyleCasts); CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InConditionalStatements); CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InEmptyParentheses); + CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InFunctionCalls); + CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InFunctionDeclarations); + CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InFunctionDefinitions); + CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InOverloadedOperators); CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, Other); } @@ -600,23 +604,23 @@ Style.SpacesInParens = FormatStyle::SIPO_Never; Style.SpacesInParensOptions = {}; CHECK_PARSE("SpacesInParentheses: true", SpacesInParensOptions, - FormatStyle::SpacesInParensCustom(true, true, false, false, - true)); + FormatStyle::SpacesInParensCustom(true, true, false, false, true, + true, true, true, true)); Style.SpacesInParens = FormatStyle::SIPO_Never; Style.SpacesInParensOptions = {}; CHECK_PARSE("SpacesInConditionalStatement: true", SpacesInParensOptions, FormatStyle::SpacesInParensCustom(false, true, false, false, - false)); + false, false, false, false, false)); Style.SpacesInParens = FormatStyle::SIPO_Never; Style.SpacesInParensOptions = {}; CHECK_PARSE("SpacesInCStyleCastParentheses: true", SpacesInParensOptions, FormatStyle::SpacesInParensCustom(false, false, true, false, - false)); + false, false, false, false, false)); Style.SpacesInParens = FormatStyle::SIPO_Never; Style.SpacesInParensOptions = {}; CHECK_PARSE("SpaceInEmptyParentheses: true", SpacesInParensOptions, FormatStyle::SpacesInParensCustom(false, false, false, true, - false)); + false, false, false, false, false)); Style.SpacesInParens = FormatStyle::SIPO_Never; Style.SpacesInParensOptions = {}; 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 @@ -11040,7 +11040,8 @@ verifyFormat("SomeType MemberFunction(const Deleted &) &;", Spaces); Spaces.SpacesInParensOptions.InCStyleCasts = false; - Spaces.SpacesInParensOptions.Other = true; + Spaces.SpacesInParensOptions.InFunctionDeclarations = true; + Spaces.SpacesInParensOptions.InOverloadedOperators = true; verifyFormat("Deleted &operator=( const Deleted & ) & = default;", Spaces); verifyFormat("SomeType MemberFunction( const Deleted & ) & = delete;", Spaces); @@ -13678,6 +13679,7 @@ SpaceBetweenBraces.SpacesInAngles = FormatStyle::SIAS_Always; SpaceBetweenBraces.SpacesInParens = FormatStyle::SIPO_Custom; SpaceBetweenBraces.SpacesInParensOptions.Other = true; + SpaceBetweenBraces.SpacesInParensOptions.InFunctionCalls = true; SpaceBetweenBraces.SpacesInSquareBrackets = true; verifyFormat("vector< int > x{ 1, 2, 3, 4 };", SpaceBetweenBraces); verifyFormat("f( {}, { {}, {} }, MyMap[ { k, v } ] );", SpaceBetweenBraces); @@ -16753,6 +16755,7 @@ Spaces.SpacesInParensOptions.Other = true; Spaces.SpacesInParensOptions.InConditionalStatements = true; Spaces.SpacesInParensOptions.InAttributeSpecifiers = true; + Spaces.SpacesInParensOptions.InFunctionCalls = true; verifyFormat("do_something( ::globalVar );", Spaces); verifyFormat("call( x, y, z );", Spaces); verifyFormat("call();", Spaces); @@ -16780,7 +16783,7 @@ "}", Spaces); verifyFormat("SomeType *__attribute__( ( attr ) ) *a = NULL;", Spaces); - verifyFormat("void __attribute__( ( naked ) ) foo( int bar )", Spaces); + verifyFormat("void __attribute__( ( x ) ) foo(int y) { return; }", Spaces); verifyFormat("void f() __attribute__( ( asdf ) );", Spaces); Spaces.SpacesInParens = FormatStyle::SIPO_Custom; @@ -16795,6 +16798,142 @@ verifyFormat("my_int a = ( my_int )sizeof(int);", Spaces); verifyFormat("#define x (( int )-1)", Spaces); + // Run the first set of tests again with: + Spaces.SpacesInParens = FormatStyle::SIPO_Custom; + Spaces.SpacesInParensOptions = {}; + Spaces.SpacesInParensOptions.InFunctionDeclarations = true; + verifyFormat("do_something(::globalVar);", Spaces); + verifyFormat("call(x, y, z);", Spaces); + verifyFormat("call();", Spaces); + verifyFormat("std::function callback;", Spaces); + verifyFormat("void inFunction() { std::function fct; }", + Spaces); + verifyFormat("while ((bool)1)\n" + " continue;", + Spaces); + verifyFormat("for (;;)\n" + " continue;", + Spaces); + verifyFormat("if (true)\n" + " f();\n" + "else if (true)\n" + " f();", + Spaces); + verifyFormat("do {\n" + " do_something((int)i);\n" + "} while (something());", + Spaces); + verifyFormat("switch (x) {\n" + "default:\n" + " break;\n" + "}", + Spaces); + verifyFormat("SomeType *__attribute__((attr)) *a = NULL;", Spaces); + verifyFormat("void __attribute__((naked)) foo( int bar );", Spaces); + verifyFormat("void f( int g ) __attribute__((asdf));", Spaces); + verifyFormat("int f();", Spaces); + verifyFormat("void f(int a, T b) {}", Spaces); + verifyFormat("void __attribute__((asdf)) f(int a, T b) {}", Spaces); + verifyFormat("A::A() : a(1) {}", Spaces); + verifyFormat("void f( int bar ) __attribute__((asdf));", Spaces); + verifyFormat("void __attribute__((asdf)) f( int bar );", Spaces); + verifyFormat("#define A(x) x", Spaces); + verifyFormat("#define A (x) x", Spaces); + verifyFormat("#if defined(x)\n" + "#endif", + Spaces); + verifyFormat("auto i = std::make_unique(5);", Spaces); + verifyFormat("size_t x = sizeof(x);", Spaces); + verifyFormat("auto f( int x ) -> decltype(x);", Spaces); + verifyFormat("auto f( int x ) -> typeof(x);", Spaces); + verifyFormat("auto f( int x ) -> _Atomic(x);", Spaces); + verifyFormat("auto f( int x ) -> __underlying_type(x);", Spaces); + verifyFormat("int f( T x ) noexcept(x.create());", Spaces); + verifyFormat("alignas(128) char a[128];", Spaces); + verifyFormat("size_t x = alignof(MyType);", Spaces); + verifyFormat("static_assert(sizeof(char) == 1, \"Impossible!\");", + Spaces); + verifyFormat("int f( int g ) throw(Deprecated);", Spaces); + verifyFormat("typedef void (*cb)(int);", Spaces); + verifyFormat("int x = int(y);", Spaces); + + // Run a subset with: + Spaces.SpacesInParensOptions.InFunctionDeclarations = false; + Spaces.SpacesInParensOptions.InFunctionDefinitions = true; + verifyFormat("do_something(::globalVar);", Spaces); + verifyFormat("call(x, y, z);", Spaces); + verifyFormat("call();", Spaces); + verifyFormat("std::function callback;", Spaces); + verifyFormat("void inFunction( int x ) { std::function f; }", + Spaces); + verifyFormat("SomeType *__attribute__((attr)) *a = NULL;", Spaces); + verifyFormat("void __attribute__((naked)) foo(int bar);", Spaces); + verifyFormat("void f(int g) __attribute__((asdf));", Spaces); + verifyFormat("int f();", Spaces); + verifyFormat("void f( int a, T b ) {}", Spaces); + verifyFormat("void __attribute__((asdf)) f( int a, T b ) {}", Spaces); + verifyFormat("A::A() : a(1) {}", Spaces); + verifyFormat("void f(int bar) __attribute__((asdf));", Spaces); + verifyFormat("void __attribute__((asdf)) f(int bar);", Spaces); + verifyFormat("#define A(x) x", Spaces); + verifyFormat("#define A (x) x", Spaces); + verifyFormat("#if defined(x)\n" + "#endif", + Spaces); + verifyFormat("auto i = std::make_unique(5);", Spaces); + verifyFormat("size_t x = sizeof(x);", Spaces); + verifyFormat("auto f(int x) -> decltype(x);", Spaces); + verifyFormat("auto f(int x) -> typeof(x);", Spaces); + verifyFormat("auto f(int x) -> _Atomic(x);", Spaces); + verifyFormat("auto f(int x) -> __underlying_type(x);", Spaces); + verifyFormat("int f(T x) noexcept(x.create());", Spaces); + verifyFormat("alignas(128) char a[128];", Spaces); + verifyFormat("size_t x = alignof(MyType);", Spaces); + verifyFormat("static_assert(sizeof(char) == 1, \"Impossible!\");", + Spaces); + verifyFormat("int f(int g) throw(Deprecated);", Spaces); + verifyFormat("typedef void (*cb)(int);", Spaces); + verifyFormat("int x = int(y);", Spaces); + + // Run a subset with: + Spaces.SpacesInParensOptions.InFunctionDeclarations = false; + Spaces.SpacesInParensOptions.InFunctionDefinitions = false; + Spaces.SpacesInParensOptions.InFunctionCalls = true; + verifyFormat("do_something( ::globalVar );", Spaces); + verifyFormat("call( x, y, z );", Spaces); + verifyFormat("call();", Spaces); + verifyFormat("std::function callback;", Spaces); + verifyFormat("void inFunction(int x) { std::function f; }", + Spaces); + verifyFormat("SomeType *__attribute__((attr)) *a = NULL;", Spaces); + verifyFormat("void __attribute__((naked)) foo(int bar);", Spaces); + verifyFormat("void f(int g) __attribute__((asdf));", Spaces); + verifyFormat("int f();", Spaces); + verifyFormat("void f(int a, T b) {}", Spaces); + verifyFormat("void __attribute__((asdf)) f(int a, T b) {}", Spaces); + verifyFormat("A::A() : a( 1 ) {}", Spaces); + verifyFormat("void f(int bar) __attribute__((asdf));", Spaces); + verifyFormat("void __attribute__((asdf)) f(int bar);", Spaces); + verifyFormat("#define A (x) x", Spaces); + verifyFormat("#define A(x) x", Spaces); + verifyFormat("#if defined(x)\n" + "#endif", + Spaces); + verifyFormat("auto i = std::make_unique(5);", Spaces); + verifyFormat("size_t x = sizeof(x);", Spaces); + verifyFormat("auto f(int x) -> decltype(x);", Spaces); + verifyFormat("auto f(int x) -> typeof(x);", Spaces); + verifyFormat("auto f(int x) -> _Atomic(x);", Spaces); + verifyFormat("auto f(int x) -> __underlying_type(x);", Spaces); + verifyFormat("int f(T x) noexcept(x.create());", Spaces); + verifyFormat("alignas(128) char a[128];", Spaces); + verifyFormat("size_t x = alignof(MyType);", Spaces); + verifyFormat("static_assert(sizeof(char) == 1, \"Impossible!\");", + Spaces); + verifyFormat("int f(int g) throw(Deprecated);", Spaces); + verifyFormat("typedef void (*cb)(int);", Spaces); + verifyFormat("int x = int(y);", Spaces); + // Run the first set of tests again with: Spaces.SpacesInParens = FormatStyle::SIPO_Custom; Spaces.SpacesInParensOptions = {}; @@ -23823,6 +23962,7 @@ Style.SpacesInParensOptions.InCStyleCasts = true; verifyFormat("x = ( _Atomic(uint64_t) )*a;", Style); Style.SpacesInParensOptions.InCStyleCasts = false; + Style.SpacesInParensOptions.InFunctionCalls = true; Style.SpacesInParensOptions.Other = true; verifyFormat("x = (_Atomic( uint64_t ))*a;", Style); verifyFormat("x = (_Atomic( uint64_t ))&a;", Style);