summaryrefslogtreecommitdiffstats
path: root/clang/lib/Format/ContinuationIndenter.cpp
diff options
context:
space:
mode:
authorDaniel Jasper <djasper@google.com>2013-12-23 07:29:06 +0000
committerDaniel Jasper <djasper@google.com>2013-12-23 07:29:06 +0000
commitb88b25feec83a945083c8a9d7eb9f4207ef08195 (patch)
tree42ffa2590fa185ea9d2385d0b6fae3dc3e962995 /clang/lib/Format/ContinuationIndenter.cpp
parenta650116adb60da5479cfad866bd77163d27c1013 (diff)
downloadbcm5719-llvm-b88b25feec83a945083c8a9d7eb9f4207ef08195.tar.gz
bcm5719-llvm-b88b25feec83a945083c8a9d7eb9f4207ef08195.zip
clang-format: Fix various problems in formatting ObjC blocks.
Among other things, this fixes llvm.org/PR15269. llvm-svn: 197900
Diffstat (limited to 'clang/lib/Format/ContinuationIndenter.cpp')
-rw-r--r--clang/lib/Format/ContinuationIndenter.cpp63
1 files changed, 48 insertions, 15 deletions
diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp
index c3eeb8fd678..7b3f5cb67fe 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -177,10 +177,8 @@ bool ContinuationIndenter::mustBreak(const LineState &State) {
State.Stack.back().FirstLessLess == 0)
return true;
- // FIXME: Comparing LongestObjCSelectorName to 0 is a hacky way of finding
- // out whether it is the first parameter. Clean this up.
if (Current.Type == TT_ObjCSelectorName &&
- Current.LongestObjCSelectorName == 0 &&
+ State.Stack.back().ObjCSelectorNameFound &&
State.Stack.back().BreakBeforeParameter)
return true;
if (Current.Type == TT_CtorInitializerColon &&
@@ -258,9 +256,12 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
Whitespaces.replaceWhitespace(Current, /*Newlines=*/0, /*IndentLevel=*/0,
Spaces, State.Column + Spaces);
- if (Current.Type == TT_ObjCSelectorName && State.Stack.back().ColonPos == 0) {
- if (State.Stack.back().Indent + Current.LongestObjCSelectorName >
- State.Column + Spaces + Current.ColumnWidth)
+ if (Current.Type == TT_ObjCSelectorName &&
+ !State.Stack.back().ObjCSelectorNameFound) {
+ if (Current.LongestObjCSelectorName == 0)
+ State.Stack.back().AlignColons = false;
+ else if (State.Stack.back().Indent + Current.LongestObjCSelectorName >
+ State.Column + Spaces + Current.ColumnWidth)
State.Stack.back().ColonPos =
State.Stack.back().Indent + Current.LongestObjCSelectorName;
else
@@ -280,7 +281,9 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
// Treat the condition inside an if as if it was a second function
// parameter, i.e. let nested calls have a continuation indent.
State.Stack.back().LastSpace = State.Column + 1; // 1 is length of "(".
- else if (Previous.is(tok::comma) || Previous.Type == TT_ObjCMethodExpr)
+ else if (Current.isNot(tok::comment) &&
+ (Previous.is(tok::comma) ||
+ (Previous.is(tok::colon) && Previous.Type == TT_ObjCMethodExpr)))
State.Stack.back().LastSpace = State.Column;
else if ((Previous.Type == TT_BinaryOperator ||
Previous.Type == TT_ConditionalExpr ||
@@ -381,10 +384,17 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
State.Column =
std::max(State.Stack.back().LastSpace, State.Stack.back().Indent);
} else if (Current.Type == TT_ObjCSelectorName) {
- if (State.Stack.back().ColonPos == 0) {
- State.Stack.back().ColonPos =
- State.Stack.back().Indent + Current.LongestObjCSelectorName;
- State.Column = State.Stack.back().ColonPos - Current.ColumnWidth;
+ if (!State.Stack.back().ObjCSelectorNameFound) {
+ if (Current.LongestObjCSelectorName == 0) {
+ State.Column = State.Stack.back().Indent;
+ State.Stack.back().AlignColons = false;
+ } else {
+ State.Stack.back().ColonPos =
+ State.Stack.back().Indent + Current.LongestObjCSelectorName;
+ State.Column = State.Stack.back().ColonPos - Current.ColumnWidth;
+ }
+ } else if (!State.Stack.back().AlignColons) {
+ State.Column = State.Stack.back().Indent;
} else if (State.Stack.back().ColonPos > Current.ColumnWidth) {
State.Column = State.Stack.back().ColonPos - Current.ColumnWidth;
} else {
@@ -397,9 +407,21 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
else
State.Column = ContinuationIndent;
} else if (Current.Type == TT_StartOfName ||
- Previous.isOneOf(tok::coloncolon, tok::equal) ||
- Previous.Type == TT_ObjCMethodExpr) {
+ Previous.isOneOf(tok::coloncolon, tok::equal)) {
+ State.Column = ContinuationIndent;
+ } else if (PreviousNonComment &&
+ PreviousNonComment->Type == TT_ObjCMethodExpr) {
State.Column = ContinuationIndent;
+ // FIXME: This is hacky, find a better way. The problem is that in an ObjC
+ // method expression, the block should be aligned to the line starting it,
+ // e.g.:
+ // [aaaaaaaaaaaaaaa aaaaaaaaa: \\ break for some reason
+ // ^(int *i) {
+ // // ...
+ // }];
+ // Thus, we set LastSpace of the next higher ParenLevel, to which we move
+ // when we consume all of the "}"'s FakeRParens at the "{".
+ State.Stack[State.Stack.size() - 2].LastSpace = ContinuationIndent;
} else if (Current.Type == TT_CtorInitializerColon) {
State.Column = State.FirstIndent + Style.ConstructorInitializerIndentWidth;
} else if (Current.Type == TT_CtorInitializerComma) {
@@ -449,7 +471,7 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
!PreviousNonComment->isOneOf(tok::comma, tok::semi) &&
PreviousNonComment->Type != TT_TemplateCloser &&
PreviousNonComment->Type != TT_BinaryOperator &&
- Current.Type != TT_BinaryOperator &&
+ Current.Type != TT_BinaryOperator &&
!PreviousNonComment->opensScope())
State.Stack.back().BreakBeforeParameter = true;
@@ -494,6 +516,8 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
if (Current.isMemberAccess())
State.Stack.back().StartOfFunctionCall =
Current.LastInChainOfCalls ? 0 : State.Column + Current.ColumnWidth;
+ if (Current.Type == TT_ObjCSelectorName)
+ State.Stack.back().ObjCSelectorNameFound = true;
if (Current.Type == TT_CtorInitializerColon) {
// Indent 2 from the column, so:
// SomeClass::SomeClass()
@@ -588,7 +612,16 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
// });
for (unsigned i = 0; i != Current.MatchingParen->FakeRParens; ++i)
State.Stack.pop_back();
- NewIndent = State.Stack.back().LastSpace + Style.IndentWidth;
+ bool IsObjCBlock =
+ Previous &&
+ (Previous->is(tok::caret) ||
+ (Previous->is(tok::r_paren) && Previous->MatchingParen &&
+ Previous->MatchingParen->Previous &&
+ Previous->MatchingParen->Previous->is(tok::caret)));
+ // For some reason, ObjC blocks are indented like continuations.
+ NewIndent =
+ State.Stack.back().LastSpace +
+ (IsObjCBlock ? Style.ContinuationIndentWidth : Style.IndentWidth);
++NewIndentLevel;
BreakBeforeParameter = true;
} else {
OpenPOWER on IntegriCloud