summaryrefslogtreecommitdiffstats
path: root/clang/lib/Format/TokenAnnotator.cpp
diff options
context:
space:
mode:
authorDaniel Jasper <djasper@google.com>2014-07-09 07:50:33 +0000
committerDaniel Jasper <djasper@google.com>2014-07-09 07:50:33 +0000
commit4355e7f0effc788f1af2b48a531f650e1e40db39 (patch)
treeac6f8ba9d24bf11533cbc84e7031767f34422d7f /clang/lib/Format/TokenAnnotator.cpp
parent696b4a089cde5513973dc8e2cf17684d44e74aa5 (diff)
downloadbcm5719-llvm-4355e7f0effc788f1af2b48a531f650e1e40db39.tar.gz
bcm5719-llvm-4355e7f0effc788f1af2b48a531f650e1e40db39.zip
clang-format: Revamp function declaration/definition indentation.
Key changes: - Correctly (well ...) distinguish function declarations and variable declarations with ()-initialization. - Don't indent when breaking function declarations/definitions after the return type. - Indent variable declarations and typedefs when breaking after the type. This fixes llvm.org/PR17999. llvm-svn: 212591
Diffstat (limited to 'clang/lib/Format/TokenAnnotator.cpp')
-rw-r--r--clang/lib/Format/TokenAnnotator.cpp47
1 files changed, 43 insertions, 4 deletions
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index f68883da05b..56aa384e744 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -325,8 +325,6 @@ private:
return false;
}
}
- // No closing "}" found, this probably starts a definition.
- Line.StartsDefinition = true;
return true;
}
@@ -1201,6 +1199,43 @@ void TokenAnnotator::annotate(AnnotatedLine &Line) {
Line.First->CanBreakBefore = Line.First->MustBreakBefore;
}
+// This function heuristically determines whether 'Current' starts the name of a
+// function declaration.
+static bool isFunctionDeclarationName(const FormatToken &Current) {
+ if (Current.Type != TT_StartOfName ||
+ Current.NestingLevel != 0 ||
+ Current.Previous->Type == TT_StartOfName)
+ return false;
+ const FormatToken *Next = Current.Next;
+ for (; Next; Next = Next->Next) {
+ if (Next->Type == TT_TemplateOpener) {
+ Next = Next->MatchingParen;
+ } else if (Next->is(tok::coloncolon)) {
+ Next = Next->Next;
+ if (!Next || !Next->is(tok::identifier))
+ return false;
+ } else if (Next->is(tok::l_paren)) {
+ break;
+ } else {
+ return false;
+ }
+ }
+ if (!Next)
+ return false;
+ assert(Next->is(tok::l_paren));
+ if (Next->Next == Next->MatchingParen)
+ return true;
+ for (const FormatToken *Tok = Next->Next; Tok != Next->MatchingParen;
+ Tok = Tok->Next) {
+ if (Tok->is(tok::kw_const) || Tok->isSimpleTypeSpecifier() ||
+ Tok->Type == TT_PointerOrReference || Tok->Type == TT_StartOfName)
+ return true;
+ if (Tok->isOneOf(tok::l_brace, tok::string_literal) || Tok->Tok.isLiteral())
+ return false;
+ }
+ return false;
+}
+
void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) {
for (SmallVectorImpl<AnnotatedLine *>::iterator I = Line.Children.begin(),
E = Line.Children.end();
@@ -1215,6 +1250,8 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) {
FormatToken *Current = Line.First->Next;
bool InFunctionDecl = Line.MightBeFunctionDecl;
while (Current) {
+ if (isFunctionDeclarationName(*Current))
+ Current->Type = TT_FunctionDeclarationName;
if (Current->Type == TT_LineComment) {
if (Current->Previous->BlockKind == BK_BracedInit &&
Current->Previous->opensScope())
@@ -1320,7 +1357,8 @@ unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line,
if (Right.Type != TT_ObjCMethodExpr && Right.Type != TT_LambdaLSquare)
return 500;
}
- if (Right.Type == TT_StartOfName || Right.is(tok::kw_operator)) {
+ if (Right.Type == TT_StartOfName ||
+ Right.Type == TT_FunctionDeclarationName || Right.is(tok::kw_operator)) {
if (Line.First->is(tok::kw_for) && Right.PartOfMultiVariableDeclStmt)
return 3;
if (Left.Type == TT_StartOfName)
@@ -1674,7 +1712,8 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
return false;
if (Left.Tok.getObjCKeywordID() == tok::objc_interface)
return false;
- if (Right.Type == TT_StartOfName || Right.is(tok::kw_operator))
+ if (Right.Type == TT_StartOfName ||
+ Right.Type == TT_FunctionDeclarationName || Right.is(tok::kw_operator))
return true;
if (Right.isTrailingComment())
// We rely on MustBreakBefore being set correctly here as we should not
OpenPOWER on IntegriCloud