Index: docs/ClangFormatStyleOptions.rst =================================================================== --- docs/ClangFormatStyleOptions.rst +++ docs/ClangFormatStyleOptions.rst @@ -1681,6 +1681,23 @@ int a = 5; vs. int a=5; a += 42 a+=42; +**SpaceBeforeCtorInitializerColon** (``bool``) + If ``false``, spaces will be removed before constructor initializer + colon. + + .. code-block:: c++ + + true: false: + Foo::Foo() : a(a) {} Foo::Foo(): a(a) {} + +**SpaceBeforeInheritanceColon** (``bool``) + If ``false``, spaces will be removed before inheritance colon. + + .. code-block:: c++ + + true: false: + class Foo : Bar {} vs. class Foo: Bar {} + **SpaceBeforeParens** (``SpaceBeforeParensOptions``) Defines in which cases to put a space before opening parentheses. @@ -1725,6 +1742,15 @@ +**SpaceBeforeRangeBasedForLoopColon** (``bool``) + If ``false``, spaces will be removed before range-based for loop + colon. + + .. code-block:: c++ + + true: false: + for (auto v : values) {} vs. for(auto v: values) {} + **SpaceInEmptyParentheses** (``bool``) If ``true``, spaces may be inserted into ``()``. Index: include/clang/Format/Format.h =================================================================== --- include/clang/Format/Format.h +++ include/clang/Format/Format.h @@ -1525,6 +1525,21 @@ /// \endcode bool SpaceBeforeAssignmentOperators; + /// \brief If ``false``, spaces will be removed before constructor initializer + /// colon. + /// \code + /// true: false: + /// Foo::Foo() : a(a) {} Foo::Foo(): a(a) {} + /// \endcode + bool SpaceBeforeCtorInitializerColon; + + /// \brief If ``false``, spaces will be removed before inheritance colon. + /// \code + /// true: false: + /// class Foo : Bar {} vs. class Foo: Bar {} + /// \endcode + bool SpaceBeforeInheritanceColon; + /// \brief Different ways to put a space before opening parentheses. enum SpaceBeforeParensOptions { /// Never put a space before opening parentheses. @@ -1563,6 +1578,14 @@ /// \brief Defines in which cases to put a space before opening parentheses. SpaceBeforeParensOptions SpaceBeforeParens; + /// \brief If ``false``, spaces will be removed before range-based for loop + /// colon. + /// \code + /// true: false: + /// for (auto v : values) {} vs. for(auto v: values) {} + /// \endcode + bool SpaceBeforeRangeBasedForLoopColon; + /// \brief If ``true``, spaces may be inserted into ``()``. /// \code /// true: false: @@ -1744,7 +1767,12 @@ SpaceAfterCStyleCast == R.SpaceAfterCStyleCast && SpaceAfterTemplateKeyword == R.SpaceAfterTemplateKeyword && SpaceBeforeAssignmentOperators == R.SpaceBeforeAssignmentOperators && + SpaceBeforeCtorInitializerColon == + R.SpaceBeforeCtorInitializerColon && + SpaceBeforeInheritanceColon == R.SpaceBeforeInheritanceColon && SpaceBeforeParens == R.SpaceBeforeParens && + SpaceBeforeRangeBasedForLoopColon == + R.SpaceBeforeRangeBasedForLoopColon && SpaceInEmptyParentheses == R.SpaceInEmptyParentheses && SpacesBeforeTrailingComments == R.SpacesBeforeTrailingComments && SpacesInAngles == R.SpacesInAngles && Index: lib/Format/Format.cpp =================================================================== --- lib/Format/Format.cpp +++ lib/Format/Format.cpp @@ -411,7 +411,13 @@ Style.SpaceAfterTemplateKeyword); IO.mapOptional("SpaceBeforeAssignmentOperators", Style.SpaceBeforeAssignmentOperators); + IO.mapOptional("SpaceBeforeCtorInitializerColon", + Style.SpaceBeforeCtorInitializerColon); + IO.mapOptional("SpaceBeforeInheritanceColon", + Style.SpaceBeforeInheritanceColon); IO.mapOptional("SpaceBeforeParens", Style.SpaceBeforeParens); + IO.mapOptional("SpaceBeforeRangeBasedForLoopColon", + Style.SpaceBeforeRangeBasedForLoopColon); IO.mapOptional("SpaceInEmptyParentheses", Style.SpaceInEmptyParentheses); IO.mapOptional("SpacesBeforeTrailingComments", Style.SpacesBeforeTrailingComments); @@ -662,7 +668,10 @@ LLVMStyle.SpacesInCStyleCastParentheses = false; LLVMStyle.SpaceAfterCStyleCast = false; LLVMStyle.SpaceAfterTemplateKeyword = true; + LLVMStyle.SpaceBeforeCtorInitializerColon = true; + LLVMStyle.SpaceBeforeInheritanceColon = true; LLVMStyle.SpaceBeforeParens = FormatStyle::SBPO_ControlStatements; + LLVMStyle.SpaceBeforeRangeBasedForLoopColon = true; LLVMStyle.SpaceBeforeAssignmentOperators = true; LLVMStyle.SpacesInAngles = false; Index: lib/Format/TokenAnnotator.cpp =================================================================== --- lib/Format/TokenAnnotator.cpp +++ lib/Format/TokenAnnotator.cpp @@ -2575,8 +2575,15 @@ return true; if (Right.is(tok::comma)) return false; - if (Right.isOneOf(TT_CtorInitializerColon, TT_ObjCBlockLParen)) + if (Right.is(TT_ObjCBlockLParen)) return true; + if (Right.is(TT_CtorInitializerColon)) + return Style.SpaceBeforeCtorInitializerColon; + if (Right.is(TT_InheritanceColon) && !Style.SpaceBeforeInheritanceColon) + return false; + if (Right.is(TT_RangeBasedForLoopColon) && + !Style.SpaceBeforeRangeBasedForLoopColon) + return false; if (Right.is(tok::colon)) { if (Line.First->isOneOf(tok::kw_case, tok::kw_default) || !Right.getNextNonComment() || Right.getNextNonComment()->is(tok::semi)) Index: unittests/Format/FormatTest.cpp =================================================================== --- unittests/Format/FormatTest.cpp +++ unittests/Format/FormatTest.cpp @@ -8933,6 +8933,114 @@ verifyFormat("a or_eq 8;", Spaces); } +TEST_F(FormatTest, ConfigurableSpaceBeforeColon) { + verifyFormat("class Foo : public Bar {};"); + verifyFormat("Foo::Foo() : foo(1) {}"); + verifyFormat("for (auto a : b) {\n}"); + verifyFormat("int x = a ? b : c;"); + verifyFormat("{\n" + "label0:\n" + " int x = 0;\n" + "}"); + verifyFormat("switch (x) {\n" + "case 1:\n" + "default:\n" + "}"); + + FormatStyle CtorInitializerStyle = getLLVMStyleWithColumns(30); + CtorInitializerStyle.SpaceBeforeCtorInitializerColon = false; + verifyFormat("class Foo : public Bar {};", CtorInitializerStyle); + verifyFormat("Foo::Foo(): foo(1) {}", CtorInitializerStyle); + verifyFormat("for (auto a : b) {\n}", CtorInitializerStyle); + verifyFormat("int x = a ? b : c;", CtorInitializerStyle); + verifyFormat("{\n" + "label1:\n" + " int x = 0;\n" + "}", + CtorInitializerStyle); + verifyFormat("switch (x) {\n" + "case 1:\n" + "default:\n" + "}", + CtorInitializerStyle); + CtorInitializerStyle.BreakConstructorInitializers = + FormatStyle::BCIS_AfterColon; + verifyFormat("Fooooooooooo::Fooooooooooo():\n" + " aaaaaaaaaaaaaaaa(1),\n" + " bbbbbbbbbbbbbbbb(2) {}", + CtorInitializerStyle); + CtorInitializerStyle.BreakConstructorInitializers = + FormatStyle::BCIS_BeforeComma; + verifyFormat("Fooooooooooo::Fooooooooooo()\n" + " : aaaaaaaaaaaaaaaa(1)\n" + " , bbbbbbbbbbbbbbbb(2) {}", + CtorInitializerStyle); + CtorInitializerStyle.BreakConstructorInitializers = + FormatStyle::BCIS_BeforeColon; + verifyFormat("Fooooooooooo::Fooooooooooo()\n" + " : aaaaaaaaaaaaaaaa(1),\n" + " bbbbbbbbbbbbbbbb(2) {}", + CtorInitializerStyle); + CtorInitializerStyle.ConstructorInitializerIndentWidth = 0; + verifyFormat("Fooooooooooo::Fooooooooooo()\n" + ": aaaaaaaaaaaaaaaa(1),\n" + " bbbbbbbbbbbbbbbb(2) {}", + CtorInitializerStyle); + + FormatStyle InheritanceStyle = getLLVMStyle(); + InheritanceStyle.SpaceBeforeInheritanceColon = false; + verifyFormat("class Foo: public Bar {};", InheritanceStyle); + verifyFormat("Foo::Foo() : foo(1) {}", InheritanceStyle); + verifyFormat("for (auto a : b) {\n}", InheritanceStyle); + verifyFormat("int x = a ? b : c;", InheritanceStyle); + verifyFormat("{\n" + "label2:\n" + " int x = 0;\n" + "}", + InheritanceStyle); + verifyFormat("switch (x) {\n" + "case 1:\n" + "default:\n" + "}", + InheritanceStyle); + + FormatStyle ForLoopStyle = getLLVMStyle(); + ForLoopStyle.SpaceBeforeRangeBasedForLoopColon = false; + verifyFormat("class Foo : public Bar {};", ForLoopStyle); + verifyFormat("Foo::Foo() : foo(1) {}", ForLoopStyle); + verifyFormat("for (auto a: b) {\n}", ForLoopStyle); + verifyFormat("int x = a ? b : c;", ForLoopStyle); + verifyFormat("{\n" + "label2:\n" + " int x = 0;\n" + "}", + ForLoopStyle); + verifyFormat("switch (x) {\n" + "case 1:\n" + "default:\n" + "}", + ForLoopStyle); + + FormatStyle NoSpaceStyle = getLLVMStyle(); + NoSpaceStyle.SpaceBeforeCtorInitializerColon = false; + NoSpaceStyle.SpaceBeforeInheritanceColon = false; + NoSpaceStyle.SpaceBeforeRangeBasedForLoopColon = false; + verifyFormat("class Foo: public Bar {};", NoSpaceStyle); + verifyFormat("Foo::Foo(): foo(1) {}", NoSpaceStyle); + verifyFormat("for (auto a: b) {\n}", NoSpaceStyle); + verifyFormat("int x = a ? b : c;", NoSpaceStyle); + verifyFormat("{\n" + "label3:\n" + " int x = 0;\n" + "}", + NoSpaceStyle); + verifyFormat("switch (x) {\n" + "case 1:\n" + "default:\n" + "}", + NoSpaceStyle); +} + TEST_F(FormatTest, AlignConsecutiveAssignments) { FormatStyle Alignment = getLLVMStyle(); Alignment.AlignConsecutiveAssignments = false; @@ -10274,6 +10382,9 @@ CHECK_PARSE_BOOL(SpaceAfterCStyleCast); CHECK_PARSE_BOOL(SpaceAfterTemplateKeyword); CHECK_PARSE_BOOL(SpaceBeforeAssignmentOperators); + CHECK_PARSE_BOOL(SpaceBeforeCtorInitializerColon); + CHECK_PARSE_BOOL(SpaceBeforeInheritanceColon); + CHECK_PARSE_BOOL(SpaceBeforeRangeBasedForLoopColon); CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterClass); CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterControlStatement);