Author: reuk Date: Sat Mar 30 05:32:35 2019 New Revision: 357344 URL: http://llvm.org/viewvc/llvm-project?rev=357344&view=rev Log: [clang-format]: Add NonEmptyParentheses spacing option
This patch aims to add support for the following rules from the JUCE coding standards: - Always put a space before an open parenthesis that contains text - e.g. foo (123); - Never put a space before an empty pair of open/close parenthesis - e.g. foo(); Patch by Reuben Thomas Differential Revision: https://reviews.llvm.org/D55170 Modified: cfe/trunk/include/clang/Format/Format.h cfe/trunk/lib/Format/Format.cpp cfe/trunk/lib/Format/TokenAnnotator.cpp cfe/trunk/lib/Format/TokenAnnotator.h cfe/trunk/unittests/Format/FormatTest.cpp Modified: cfe/trunk/include/clang/Format/Format.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Format/Format.h?rev=357344&r1=357343&r2=357344&view=diff ============================================================================== --- cfe/trunk/include/clang/Format/Format.h (original) +++ cfe/trunk/include/clang/Format/Format.h Sat Mar 30 05:32:35 2019 @@ -1690,6 +1690,17 @@ struct FormatStyle { /// } /// \endcode SBPO_ControlStatements, + /// Put a space before opening parentheses only if the parentheses are not + /// empty i.e. '()' + /// \code + /// void() { + /// if (true) { + /// f(); + /// g (x, y, z); + /// } + /// } + /// \endcode + SBPO_NonEmptyParentheses, /// Always put a space before opening parentheses, except when it's /// prohibited by the syntax rules (in function-like macro definitions) or /// when determined by other style rules (after unary operators, opening Modified: cfe/trunk/lib/Format/Format.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=357344&r1=357343&r2=357344&view=diff ============================================================================== --- cfe/trunk/lib/Format/Format.cpp (original) +++ cfe/trunk/lib/Format/Format.cpp Sat Mar 30 05:32:35 2019 @@ -285,6 +285,8 @@ struct ScalarEnumerationTraits<FormatSty IO.enumCase(Value, "Never", FormatStyle::SBPO_Never); IO.enumCase(Value, "ControlStatements", FormatStyle::SBPO_ControlStatements); + IO.enumCase(Value, "NonEmptyParentheses", + FormatStyle::SBPO_NonEmptyParentheses); IO.enumCase(Value, "Always", FormatStyle::SBPO_Always); // For backward compatibility. Modified: cfe/trunk/lib/Format/TokenAnnotator.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=357344&r1=357343&r2=357344&view=diff ============================================================================== --- cfe/trunk/lib/Format/TokenAnnotator.cpp (original) +++ cfe/trunk/lib/Format/TokenAnnotator.cpp Sat Mar 30 05:32:35 2019 @@ -2453,6 +2453,12 @@ unsigned TokenAnnotator::splitPenalty(co return 3; } +bool TokenAnnotator::spaceRequiredBeforeParens(const FormatToken &Right) const { + return Style.SpaceBeforeParens == FormatStyle::SBPO_Always || + (Style.SpaceBeforeParens == FormatStyle::SBPO_NonEmptyParentheses && + Right.ParameterCount > 0); +} + bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, const FormatToken &Left, const FormatToken &Right) { @@ -2599,9 +2605,9 @@ bool TokenAnnotator::spaceRequiredBetwee (Left.isOneOf(tok::kw_try, Keywords.kw___except, tok::kw_catch, tok::kw_new, tok::kw_delete) && (!Left.Previous || Left.Previous->isNot(tok::period))))) || - (Style.SpaceBeforeParens == FormatStyle::SBPO_Always && + (spaceRequiredBeforeParens(Right) && (Left.is(tok::identifier) || Left.isFunctionLikeKeyword() || - Left.is(tok::r_paren) || + Left.is(tok::r_paren) || Left.isSimpleTypeSpecifier() || (Left.is(tok::r_square) && Left.MatchingParen && Left.MatchingParen->is(TT_LambdaLSquare))) && Line.Type != LT_PreprocessorDirective); @@ -2795,7 +2801,7 @@ bool TokenAnnotator::spaceRequiredBefore Left.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow)) return true; if (Right.is(TT_OverloadedOperatorLParen)) - return Style.SpaceBeforeParens == FormatStyle::SBPO_Always; + return spaceRequiredBeforeParens(Right); if (Left.is(tok::comma)) return true; if (Right.is(tok::comma)) @@ -2879,7 +2885,7 @@ bool TokenAnnotator::spaceRequiredBefore return true; if (Left.is(TT_TemplateCloser) && Right.is(tok::l_paren) && Right.isNot(TT_FunctionTypeLParen)) - return Style.SpaceBeforeParens == FormatStyle::SBPO_Always; + return spaceRequiredBeforeParens(Right); if (Right.is(TT_TemplateOpener) && Left.is(tok::r_paren) && Left.MatchingParen && Left.MatchingParen->is(TT_OverloadedOperatorLParen)) return false; Modified: cfe/trunk/lib/Format/TokenAnnotator.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.h?rev=357344&r1=357343&r2=357344&view=diff ============================================================================== --- cfe/trunk/lib/Format/TokenAnnotator.h (original) +++ cfe/trunk/lib/Format/TokenAnnotator.h Sat Mar 30 05:32:35 2019 @@ -164,6 +164,8 @@ private: unsigned splitPenalty(const AnnotatedLine &Line, const FormatToken &Tok, bool InFunctionDecl); + bool spaceRequiredBeforeParens(const FormatToken &Right) const; + bool spaceRequiredBetween(const AnnotatedLine &Line, const FormatToken &Left, const FormatToken &Right); Modified: cfe/trunk/unittests/Format/FormatTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=357344&r1=357343&r2=357344&view=diff ============================================================================== --- cfe/trunk/unittests/Format/FormatTest.cpp (original) +++ cfe/trunk/unittests/Format/FormatTest.cpp Sat Mar 30 05:32:35 2019 @@ -9627,6 +9627,60 @@ TEST_F(FormatTest, ConfigurableSpaceBefo verifyFormat("T A::operator() ();", Space); verifyFormat("X A::operator++ (T);", Space); verifyFormat("auto lambda = [] () { return 0; };", Space); + verifyFormat("int x = int (y);", Space); + + FormatStyle SomeSpace = getLLVMStyle(); + SomeSpace.SpaceBeforeParens = FormatStyle::SBPO_NonEmptyParentheses; + + verifyFormat("[]() -> float {}", SomeSpace); + verifyFormat("[] (auto foo) {}", SomeSpace); + verifyFormat("[foo]() -> int {}", SomeSpace); + verifyFormat("int f();", SomeSpace); + verifyFormat("void f (int a, T b) {\n" + " while (true)\n" + " continue;\n" + "}", + SomeSpace); + verifyFormat("if (true)\n" + " f();\n" + "else if (true)\n" + " f();", + SomeSpace); + verifyFormat("do {\n" + " do_something();\n" + "} while (something());", + SomeSpace); + verifyFormat("switch (x) {\n" + "default:\n" + " break;\n" + "}", + SomeSpace); + verifyFormat("A::A() : a (1) {}", SomeSpace); + verifyFormat("void f() __attribute__ ((asdf));", SomeSpace); + verifyFormat("*(&a + 1);\n" + "&((&a)[1]);\n" + "a[(b + c) * d];\n" + "(((a + 1) * 2) + 3) * 4;", + SomeSpace); + verifyFormat("#define A(x) x", SomeSpace); + verifyFormat("#define A (x) x", SomeSpace); + verifyFormat("#if defined(x)\n" + "#endif", + SomeSpace); + verifyFormat("auto i = std::make_unique<int> (5);", SomeSpace); + verifyFormat("size_t x = sizeof (x);", SomeSpace); + verifyFormat("auto f (int x) -> decltype (x);", SomeSpace); + verifyFormat("int f (T x) noexcept (x.create());", SomeSpace); + verifyFormat("alignas (128) char a[128];", SomeSpace); + verifyFormat("size_t x = alignof (MyType);", SomeSpace); + verifyFormat("static_assert (sizeof (char) == 1, \"Impossible!\");", + SomeSpace); + verifyFormat("int f() throw (Deprecated);", SomeSpace); + verifyFormat("typedef void (*cb) (int);", SomeSpace); + verifyFormat("T A::operator()();", SomeSpace); + verifyFormat("X A::operator++ (T);", SomeSpace); + verifyFormat("int x = int (y);", SomeSpace); + verifyFormat("auto lambda = []() { return 0; };", SomeSpace); } TEST_F(FormatTest, ConfigurableSpacesInParentheses) { @@ -11413,6 +11467,8 @@ TEST_F(FormatTest, ParsesConfiguration) FormatStyle::SBPO_Always); CHECK_PARSE("SpaceBeforeParens: ControlStatements", SpaceBeforeParens, FormatStyle::SBPO_ControlStatements); + CHECK_PARSE("SpaceBeforeParens: NonEmptyParentheses", SpaceBeforeParens, + FormatStyle::SBPO_NonEmptyParentheses); // For backward compatibility: CHECK_PARSE("SpaceAfterControlStatementKeyword: false", SpaceBeforeParens, FormatStyle::SBPO_Never); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits