[PATCH] D14052: clang-format: Format std::function template parameter consistently inside function

Jean-Philippe Dufraigne via cfe-commits cfe-commits at lists.llvm.org
Sun Oct 25 17:43:04 PDT 2015

jeanphilippeD created this revision.
jeanphilippeD added a reviewer: djasper.
jeanphilippeD added a subscriber: cfe-commits.
Herald added a subscriber: klimek.

The function type declared in an std::function template parameter is confused for a cast:

Pass: "std::function< void(int, int) > fct;", Spaces);
Fail: "void inFunction() { std::function< void(int, int) > fct; }",
Actual result "void inFunction() { std::function< void(int, int)> fct; }" (no space between ")>")

Root cause:
-Inside a function definition, Line.MustBeDeclaration is not true.
-This allows the context IsExpression to be true.
"Contexts.back().IsExpression = !ParametersOfFunctionType && !IsForOrCatch;"
-which then allow the right parenthesis to be marked incorrectly as cast, and the left there after.
"if (ParensAreType && !ParensCouldEndDecl && !IsSizeOfOrAlignOf &&
        (Contexts.size() > 1 && Contexts[Contexts.size() - 2].IsExpression))
      IsCast = true;"

Because at the time of this marking, the angle bracket is not yet established as a template opener and closer, this fix address the issue by resetting the type to unknown for the parenthesis.(Unknown is the type the parenthesis hold in the case the line must be a declaration).
It seems there should be a better alternative, but I am not sure where I should look.

The tests are updated in 2 places as this incorrect deduction result in incorrect spacing  before the angle bracket, but also inside the parenthesis if space is required there but not in cast.

Run all the test in FormatTests project and spot checked clang format output for TokenAnnotator.cpp and FormatTest.cpp is the same before and after the patch.



Index: unittests/Format/FormatTest.cpp
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -8398,8 +8398,6 @@
   verifyFormat("call( x, y, z );", Spaces);
   verifyFormat("call();", Spaces);
   verifyFormat("std::function<void( int, int )> callback;", Spaces);
-  verifyFormat("void inFunction() { std::function<void( int, int )> fct; }",
-               Spaces);
   verifyFormat("while ( (bool)1 )\n"
                "  continue;",
@@ -10635,9 +10633,6 @@
   verifyFormat("f< int, float >();", Spaces);
   verifyFormat("template <> g() {}", Spaces);
   verifyFormat("template < std::vector< int > > f() {}", Spaces);
-  verifyFormat("std::function< void(int, int) > fct;", Spaces);
-  verifyFormat("void inFunction() { std::function< void(int, int) > fct; }",
-               Spaces);
   Spaces.Standard = FormatStyle::LS_Cpp03;
   Spaces.SpacesInAngles = true;
Index: lib/Format/TokenAnnotator.cpp
--- lib/Format/TokenAnnotator.cpp
+++ lib/Format/TokenAnnotator.cpp
@@ -67,12 +67,6 @@
         Left->MatchingParen = CurrentToken;
         CurrentToken->MatchingParen = Left;
         CurrentToken->Type = TT_TemplateCloser;
-        if (CurrentToken->Previous->is(TT_CastRParen) &&
-            CurrentToken->Previous->MatchingParen) {
-          // Fix incorrect cast detection
-          CurrentToken->Previous->Type = TT_Unknown;
-          CurrentToken->Previous->MatchingParen->Type = TT_Unknown;
-        }
         return true;

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D14052.38366.patch
Type: text/x-patch
Size: 1649 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20151026/40ad0b5a/attachment.bin>

More information about the cfe-commits mailing list