Allow breaking between a type and name in variable declarations.
This fixes llvm.org/PR14967 and is generall necessary to avoid
situations where the column limit is exceeded. The challenge is
restricting such lines splits, otherwise clang-format suddenly starts
breaking at bad places.
Before:
ReallyLongReturnType<TemplateParam1, TemplateParam2>
ReallyReallyLongFunctionName(
const std::string &SomeParameter,
const SomeType<string,
SomeOtherTemplateParameter> &ReallyReallyLongParameterName,
const SomeType<string,
SomeOtherTemplateParameter> &AnotherLongParameterName) {}
After:
ReallyLongReturnType<TemplateParam1, TemplateParam2>
ReallyReallyLongFunctionName(
const std::string &SomeParameter,
const SomeType<string, SomeOtherTemplateParameter> &
ReallyReallyLongParameterName,
const SomeType<string, SomeOtherTemplateParameter> &
AnotherLongParameterName) {}
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@175999 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp
index b7f43d5..86daa8d 100644
--- a/lib/Format/TokenAnnotator.cpp
+++ b/lib/Format/TokenAnnotator.cpp
@@ -83,7 +83,6 @@
: SourceMgr(SourceMgr), Lex(Lex), Line(Line), CurrentToken(&Line.First),
KeywordVirtualFound(false), Ident_in(Ident_in) {
Contexts.push_back(Context(1, /*IsExpression=*/ false));
- Contexts.back().LookForFunctionName = Line.MustBeDeclaration;
}
private:
@@ -348,6 +347,8 @@
case tok::l_paren:
if (!parseParens())
return false;
+ if (Line.MustBeDeclaration)
+ Line.MightBeFunctionDecl = true;
break;
case tok::l_square:
if (!parseSquare())
@@ -520,8 +521,7 @@
Context(unsigned BindingStrength, bool IsExpression)
: BindingStrength(BindingStrength), LongestObjCSelectorName(0),
ColonIsForRangeExpr(false), ColonIsObjCMethodExpr(false),
- FirstObjCSelectorName(NULL), IsExpression(IsExpression),
- LookForFunctionName(false) {}
+ FirstObjCSelectorName(NULL), IsExpression(IsExpression) {}
unsigned BindingStrength;
unsigned LongestObjCSelectorName;
@@ -529,7 +529,6 @@
bool ColonIsObjCMethodExpr;
AnnotatedToken *FirstObjCSelectorName;
bool IsExpression;
- bool LookForFunctionName;
};
/// \brief Puts a new \c Context onto the stack \c Contexts for the lifetime
@@ -572,9 +571,13 @@
}
if (Current.Type == TT_Unknown) {
- if (Contexts.back().LookForFunctionName && Current.is(tok::l_paren)) {
- findFunctionName(&Current);
- Contexts.back().LookForFunctionName = false;
+ if (Current.Parent && Current.is(tok::identifier) &&
+ ((Current.Parent->is(tok::identifier) &&
+ Current.Parent->FormatTok.Tok.getIdentifierInfo()
+ ->getPPKeywordID() == tok::pp_not_keyword) ||
+ Current.Parent->Type == TT_PointerOrReference ||
+ Current.Parent->Type == TT_TemplateCloser)) {
+ Current.Type = TT_StartOfName;
} else if (Current.is(tok::star) || Current.is(tok::amp)) {
Current.Type =
determineStarAmpUsage(Current, Contexts.back().IsExpression);
@@ -623,22 +626,6 @@
}
}
- /// \brief Starting from \p Current, this searches backwards for an
- /// identifier which could be the start of a function name and marks it.
- void findFunctionName(AnnotatedToken *Current) {
- AnnotatedToken *Parent = Current->Parent;
- while (Parent != NULL && Parent->Parent != NULL) {
- if (Parent->is(tok::identifier) &&
- (Parent->Parent->is(tok::identifier) ||
- Parent->Parent->Type == TT_PointerOrReference ||
- Parent->Parent->Type == TT_TemplateCloser)) {
- Parent->Type = TT_StartOfName;
- break;
- }
- Parent = Parent->Parent;
- }
- }
-
/// \brief Return the type of the given token assuming it is * or &.
TokenType
determineStarAmpUsage(const AnnotatedToken &Tok, bool IsExpression) {
@@ -883,8 +870,15 @@
const AnnotatedToken &Left = *Tok.Parent;
const AnnotatedToken &Right = Tok;
- if (Right.Type == TT_StartOfName)
- return Style.PenaltyReturnTypeOnItsOwnLine;
+ if (Right.Type == TT_StartOfName) {
+ if (Line.First.is(tok::kw_for))
+ return 3;
+ else if (Line.MightBeFunctionDecl && Right.BindingStrength == 1)
+ // FIXME: Clean up hack of using BindingStrength to find top-level names.
+ return Style.PenaltyReturnTypeOnItsOwnLine;
+ else
+ return 100;
+ }
if (Left.is(tok::l_brace) && Right.isNot(tok::l_brace))
return 50;
if (Left.is(tok::equal) && Right.is(tok::l_brace))
@@ -941,7 +935,7 @@
if (Level != prec::Unknown)
return Level;
-
+
return 3;
}
@@ -1099,12 +1093,6 @@
// change the "binding" behavior of a comment.
return false;
- // FIXME: We can probably remove this special case once we have implemented
- // breaking after types in general.
- if (Line.First.is(tok::kw_for) && !Right.Children.empty() &&
- Right.Children[0].is(tok::equal))
- return true;
-
// Allow breaking after a trailing 'const', e.g. after a method declaration,
// unless it is follow by ';', '{' or '='.
if (Left.is(tok::kw_const) && Left.Parent != NULL &&