From 395228fdc343df39c2507e414dc1406a185c6d37 Mon Sep 17 00:00:00 2001 From: Daniel Jasper Date: Wed, 8 May 2013 14:58:20 +0000 Subject: [PATCH] Fix formatting of pointers to members. Before: int(S::*func)(void *); After: int (S::*func)(void *); git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@181438 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Format/TokenAnnotator.cpp | 13 ++++++------- lib/Format/TokenAnnotator.h | 5 ++++- unittests/Format/FormatTest.cpp | 17 +++++++++-------- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp index c736e9012f..ab9c8c8859 100644 --- a/lib/Format/TokenAnnotator.cpp +++ b/lib/Format/TokenAnnotator.cpp @@ -173,6 +173,9 @@ private: } if (CurrentToken->isOneOf(tok::r_square, tok::r_brace)) return false; + if (CurrentToken->Parent->Type == TT_PointerOrReference && + CurrentToken->Parent->Parent->isOneOf(tok::l_paren, tok::coloncolon)) + Left->DefinesFunctionType = true; updateParameterCount(Left, CurrentToken); if (!consumeToken()) return false; @@ -1025,6 +1028,9 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, return Left.FormatTok.Tok.isLiteral() || ((Left.Type != TT_PointerOrReference) && Left.isNot(tok::l_paren) && !Style.PointerBindsToType); + if (Right.DefinesFunctionType && + (Left.Type != TT_PointerOrReference || Style.PointerBindsToType)) + return true; if (Left.Type == TT_PointerOrReference) return Right.FormatTok.Tok.isLiteral() || ((Right.Type != TT_PointerOrReference) && @@ -1091,13 +1097,6 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, if (Tok.is(tok::colon)) return !Line.First.isOneOf(tok::kw_case, tok::kw_default) && Tok.getNextNoneComment() != NULL && Tok.Type != TT_ObjCMethodExpr; - if (Tok.is(tok::l_paren) && !Tok.Children.empty() && - Tok.Children[0].Type == TT_PointerOrReference && - !Tok.Children[0].Children.empty() && - Tok.Children[0].Children[0].isNot(tok::r_paren) && - Tok.Parent->isNot(tok::l_paren) && - (Tok.Parent->Type != TT_PointerOrReference || Style.PointerBindsToType)) - return true; if (Tok.Parent->Type == TT_UnaryOperator || Tok.Parent->Type == TT_CastRParen) return false; if (Tok.Type == TT_UnaryOperator) diff --git a/lib/Format/TokenAnnotator.h b/lib/Format/TokenAnnotator.h index b364082391..a2080b5b6f 100644 --- a/lib/Format/TokenAnnotator.h +++ b/lib/Format/TokenAnnotator.h @@ -75,7 +75,7 @@ public: CanBreakBefore(false), MustBreakBefore(false), ClosesTemplateDeclaration(false), MatchingParen(NULL), ParameterCount(0), BindingStrength(0), SplitPenalty(0), - LongestObjCSelectorName(0), Parent(NULL), + LongestObjCSelectorName(0), DefinesFunctionType(false), Parent(NULL), FakeRParens(0), LastInChainOfCalls(false), PartOfMultiVariableDeclStmt(false), NoMoreTokensOnLevel(false) {} @@ -164,6 +164,9 @@ public: /// definition or call, this contains the length of the longest name. unsigned LongestObjCSelectorName; + /// \brief \c true if this is a "(" that starts a function type definition. + bool DefinesFunctionType; + std::vector Children; AnnotatedToken *Parent; diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index 3a97abe5b2..715c55fd48 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -2417,14 +2417,15 @@ TEST_F(FormatTest, UnderstandsBinaryOperators) { TEST_F(FormatTest, UnderstandsPointersToMembers) { verifyFormat("int A::*x;"); - // FIXME: Recognize pointers to member functions. - //verifyFormat("int (S::*func)(void *);"); - verifyFormat("int(S::*func)(void *);"); - verifyFormat("(a->*f)();"); - verifyFormat("a->*x;"); - verifyFormat("(a.*f)();"); - verifyFormat("((*a).*f)();"); - verifyFormat("a.*x;"); + verifyFormat("int (S::*func)(void *);"); + verifyFormat("typedef bool (Class::*Member)() const;"); + verifyFormat("void f() {\n" + " (a->*f)();\n" + " a->*x;\n" + " (a.*f)();\n" + " ((*a).*f)();\n" + " a.*x;\n" + "}"); } TEST_F(FormatTest, UnderstandsUnaryOperators) { -- 2.40.0