From 6ac431c7bae27a42351d2c2ad03dddd5b005ffd5 Mon Sep 17 00:00:00 2001 From: Daniel Jasper Date: Tue, 2 Jul 2013 09:47:29 +0000 Subject: [PATCH] Fix formatting of long declarations with const type. Before (exceeding the column limit): LoooooooooooooooooooooooooooooooooooooooongType const LoooooooooooooooooooooooooooooooooooooooongVariable; After: LoooooooooooooooooooooooooooooooooooooooongType const LoooooooooooooooooooooooooooooooooooooooongVariable; git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@185418 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Format/TokenAnnotator.cpp | 35 ++++++++++++++++++++++++++------- unittests/Format/FormatTest.cpp | 5 +++++ 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp index f7cea124a8..04f1c7f8a3 100644 --- a/lib/Format/TokenAnnotator.cpp +++ b/lib/Format/TokenAnnotator.cpp @@ -585,13 +585,7 @@ private: } if (Current.Type == TT_Unknown) { - if (Current.Previous && Current.is(tok::identifier) && - ((Current.Previous->is(tok::identifier) && - Current.Previous->Tok.getIdentifierInfo()->getPPKeywordID() == - tok::pp_not_keyword) || - isSimpleTypeSpecifier(*Current.Previous) || - Current.Previous->Type == TT_PointerOrReference || - Current.Previous->Type == TT_TemplateCloser)) { + if (isStartOfName(Current)) { Contexts.back().FirstStartOfName = &Current; Current.Type = TT_StartOfName; NameFound = true; @@ -666,6 +660,33 @@ private: } } + /// \brief Take a guess at whether \p Tok starts a name of a function or + /// variable declaration. + /// + /// This is a heuristic based on whether \p Tok is an identifier following + /// something that is likely a type. + bool isStartOfName(const FormatToken &Tok) { + if (Tok.isNot(tok::identifier) || Tok.Previous == NULL) + return false; + + // Skip "const" as it does not have an influence on whether this is a name. + FormatToken *PreviousNotConst = Tok.Previous; + while (PreviousNotConst != NULL && PreviousNotConst->is(tok::kw_const)) + PreviousNotConst = PreviousNotConst->Previous; + + if (PreviousNotConst == NULL) + return false; + + bool IsPPKeyword = + PreviousNotConst->is(tok::identifier) && PreviousNotConst->Previous && + PreviousNotConst->Previous->is(tok::hash); + + return (!IsPPKeyword && PreviousNotConst->is(tok::identifier)) || + PreviousNotConst->Type == TT_PointerOrReference || + PreviousNotConst->Type == TT_TemplateCloser || + isSimpleTypeSpecifier(*PreviousNotConst); + } + /// \brief Return the type of the given token assuming it is * or &. TokenType determineStarAmpUsage(const FormatToken &Tok, bool IsExpression) { const FormatToken *PrevToken = Tok.getPreviousNoneComment(); diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index 6df7e9b0e9..c5a02b614d 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -3451,11 +3451,16 @@ TEST_F(FormatTest, BreaksLongDeclarations) { verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType\n" " LoooooooooooooooooooooooooooooooooooooooongVariable;", getGoogleStyle()); + verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType const\n" + " LoooooooooooooooooooooooooooooooooooooooongVariable;", + getGoogleStyle()); verifyFormat("LoooooooooooooooooooooooooooooooooooooooongReturnType\n" " LoooooooooooooooooooooooooooooooongFunctionDeclaration();", getGoogleStyle()); verifyFormat("LoooooooooooooooooooooooooooooooooooooooongReturnType\n" "LooooooooooooooooooooooooooooooooooongFunctionDefinition() {}"); + verifyFormat("LoooooooooooooooooooooooooooooooooooooooongReturnType const\n" + "LooooooooooooooooooooooooooooooooooongFunctionDefinition() {}"); // FIXME: Without the comment, this breaks after "(". verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType // break\n" -- 2.50.1