Let clang-format break after a function's return type.
Before:
TypeSpecDecl *TypeSpecDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *II,
Type *T) {}
After:
TypeSpecDecl *
TypeSpecDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
IdentifierInfo *II, Type *T) {}
This fixes llvm.org/PR14717.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@173688 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp
index 27d4710..3b5dfc1 100644
--- a/lib/Format/Format.cpp
+++ b/lib/Format/Format.cpp
@@ -40,7 +40,6 @@
TT_CastRParen,
TT_ConditionalExpr,
TT_CtorInitializerColon,
- TT_RangeBasedForLoopColon,
TT_ImplicitStringLiteral,
TT_LineComment,
TT_ObjCBlockLParen,
@@ -51,6 +50,8 @@
TT_OverloadedOperator,
TT_PointerOrReference,
TT_PureVirtualSpecifier,
+ TT_RangeBasedForLoopColon,
+ TT_StartOfName,
TT_TemplateCloser,
TT_TemplateOpener,
TT_TrailingUnaryOperator,
@@ -566,7 +567,8 @@
} else if (RootToken.is(tok::kw_for) && ParenLevel == 1 &&
Previous.is(tok::comma)) {
State.Column = State.ForLoopVariablePos;
- } else if (State.NextToken->Parent->ClosesTemplateDeclaration) {
+ } else if (State.NextToken->Parent->ClosesTemplateDeclaration ||
+ Current.Type == TT_StartOfName) {
State.Column = State.Stack[ParenLevel].Indent - 4;
} else if (Previous.Type == TT_BinaryOperator &&
State.Stack.back().AssignmentColumn != 0) {
@@ -895,7 +897,6 @@
void markEnd(AnnotatedToken &Right) { Right.Type = TT_ObjCMethodExpr; }
};
-
bool parseAngle() {
if (CurrentToken == NULL)
return false;
@@ -1289,7 +1290,9 @@
if (Line.Type == LT_Invalid)
return;
- determineTokenTypes(Line.First, /*IsExpression=*/ false);
+ bool LookForFunctionName = Line.MustBeDeclaration;
+ determineTokenTypes(Line.First, /*IsExpression=*/ false,
+ LookForFunctionName);
if (Line.First.Type == TT_ObjCMethodSpecifier)
Line.Type = LT_ObjCMethodDecl;
@@ -1308,7 +1311,8 @@
}
private:
- void determineTokenTypes(AnnotatedToken &Current, bool IsExpression) {
+ void determineTokenTypes(AnnotatedToken &Current, bool IsExpression,
+ bool LookForFunctionName) {
if (getPrecedence(Current) == prec::Assignment) {
IsExpression = true;
AnnotatedToken *Previous = Current.Parent;
@@ -1326,7 +1330,10 @@
IsExpression = true;
if (Current.Type == TT_Unknown) {
- if (Current.is(tok::star) || Current.is(tok::amp)) {
+ if (LookForFunctionName && Current.is(tok::l_paren)) {
+ findFunctionName(&Current);
+ LookForFunctionName = false;
+ } else if (Current.is(tok::star) || Current.is(tok::amp)) {
Current.Type = determineStarAmpUsage(Current, IsExpression);
} else if (Current.is(tok::minus) || Current.is(tok::plus) ||
Current.is(tok::caret)) {
@@ -1370,7 +1377,24 @@
}
if (!Current.Children.empty())
- determineTokenTypes(Current.Children[0], IsExpression);
+ determineTokenTypes(Current.Children[0], IsExpression,
+ LookForFunctionName);
+ }
+
+ /// \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 Returns the previous token ignoring comments.
@@ -1604,6 +1628,8 @@
// Don't break at ':' if identifier before it can beak.
return false;
}
+ if (Right.Type == TT_StartOfName)
+ return true;
if (Right.is(tok::colon) && Right.Type == TT_ObjCMethodExpr)
return false;
if (Left.is(tok::colon) && Left.Type == TT_ObjCMethodExpr)
diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp
index 417dc9e..6b9b84d 100644
--- a/unittests/Format/FormatTest.cpp
+++ b/unittests/Format/FormatTest.cpp
@@ -1504,13 +1504,13 @@
verifyFormat("int(*func)(void *);");
}
-TEST_F(FormatTest, DoesNotBreakBeforePointerOrReference) {
- verifyFormat("int *someFunction(int LoooooooooooooooongParam1,\n"
- " int LoooooooooooooooongParam2) {\n}");
+TEST_F(FormatTest, BreaksFunctionDeclarations) {
+ verifyFormat("int *someFunction(int LoooooooooooooooooooongParam1,\n"
+ " int LoooooooooooooooooooongParam2) {\n}");
verifyFormat(
- "TypeSpecDecl *TypeSpecDecl::Create(ASTContext &C, DeclContext *DC,\n"
- " SourceLocation L, IdentifierIn *II,\n"
- " Type *T) {\n}");
+ "TypeSpecDecl *\n"
+ "TypeSpecDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,\n"
+ " IdentifierIn *II, Type *T) {\n}");
}
TEST_F(FormatTest, LineStartsWithSpecialCharacter) {