diff options
Diffstat (limited to 'clang/lib/Format')
-rw-r--r-- | clang/lib/Format/Format.cpp | 293 | ||||
-rw-r--r-- | clang/lib/Format/TokenAnnotator.cpp | 397 | ||||
-rw-r--r-- | clang/lib/Format/TokenAnnotator.h | 202 | ||||
-rw-r--r-- | clang/lib/Format/UnwrappedLineParser.h | 194 | ||||
-rw-r--r-- | clang/lib/Format/WhitespaceManager.cpp | 7 | ||||
-rw-r--r-- | clang/lib/Format/WhitespaceManager.h | 2 |
6 files changed, 513 insertions, 582 deletions
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 797410ab11d..6fc0da58c23 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -228,12 +228,12 @@ std::string configurationAsText(const FormatStyle &Style) { // Returns the length of everything up to the first possible line break after // the ), ], } or > matching \c Tok. -static unsigned getLengthToMatchingParen(const AnnotatedToken &Tok) { +static unsigned getLengthToMatchingParen(const FormatToken &Tok) { if (Tok.MatchingParen == NULL) return 0; - AnnotatedToken *End = Tok.MatchingParen; - while (!End->Children.empty() && !End->Children[0].CanBreakBefore) { - End = &End->Children[0]; + FormatToken *End = Tok.MatchingParen; + while (End->Next && !End->Next->CanBreakBefore) { + End = End->Next; } return End->TotalLength - Tok.TotalLength + 1; } @@ -242,7 +242,7 @@ class UnwrappedLineFormatter { public: UnwrappedLineFormatter(const FormatStyle &Style, SourceManager &SourceMgr, const AnnotatedLine &Line, unsigned FirstIndent, - const AnnotatedToken &RootToken, + const FormatToken *RootToken, WhitespaceManager &Whitespaces) : Style(Style), SourceMgr(SourceMgr), Line(Line), FirstIndent(FirstIndent), RootToken(RootToken), @@ -253,7 +253,7 @@ public: // Initialize state dependent on indent. LineState State; State.Column = FirstIndent; - State.NextToken = &RootToken; + State.NextToken = RootToken; State.Stack.push_back( ParenState(FirstIndent, FirstIndent, /*AvoidBinPacking=*/ false, /*NoLineBreak=*/ false)); @@ -270,7 +270,7 @@ public: // If everything fits on a single line, just put it there. unsigned ColumnLimit = Style.ColumnLimit; if (NextLine && NextLine->InPPDirective && - !NextLine->First.FormatTok->HasUnescapedNewline) + !NextLine->First->HasUnescapedNewline) ColumnLimit = getColumnLimit(); if (Line.Last->TotalLength <= ColumnLimit - FirstIndent) { while (State.NextToken != NULL) { @@ -288,8 +288,8 @@ public: } private: - void DebugTokenState(const AnnotatedToken &AnnotatedTok) { - const Token &Tok = AnnotatedTok.FormatTok->Tok; + void DebugTokenState(const FormatToken &FormatTok) { + const Token &Tok = FormatTok.Tok; llvm::dbgs() << StringRef(SourceMgr.getCharacterData(Tok.getLocation()), Tok.getLength()); llvm::dbgs(); @@ -406,7 +406,7 @@ private: unsigned Column; /// \brief The token that needs to be next formatted. - const AnnotatedToken *NextToken; + const FormatToken *NextToken; /// \brief \c true if this line contains a continued for-loop section. bool LineContainsContinuedForLoopSection; @@ -475,22 +475,17 @@ private: /// If \p DryRun is \c false, also creates and stores the required /// \c Replacement. unsigned addTokenToState(bool Newline, bool DryRun, LineState &State) { - const AnnotatedToken &Current = *State.NextToken; - const AnnotatedToken &Previous = *State.NextToken->Parent; + const FormatToken &Current = *State.NextToken; + const FormatToken &Previous = *State.NextToken->Previous; if (State.Stack.size() == 0 || Current.Type == TT_ImplicitStringLiteral) { // FIXME: Is this correct? - int WhitespaceLength = - SourceMgr.getSpellingColumnNumber( - State.NextToken->FormatTok->WhitespaceRange.getEnd()) - - SourceMgr.getSpellingColumnNumber( - State.NextToken->FormatTok->WhitespaceRange.getBegin()); - State.Column += - WhitespaceLength + State.NextToken->FormatTok->TokenLength; - if (State.NextToken->Children.empty()) - State.NextToken = NULL; - else - State.NextToken = &State.NextToken->Children[0]; + int WhitespaceLength = SourceMgr.getSpellingColumnNumber( + State.NextToken->WhitespaceRange.getEnd()) - + SourceMgr.getSpellingColumnNumber( + State.NextToken->WhitespaceRange.getBegin()); + State.Column += WhitespaceLength + State.NextToken->TokenLength; + State.NextToken = State.NextToken->Next; return 0; } @@ -525,13 +520,11 @@ private: Line.StartsDefinition)) { State.Column = State.Stack.back().Indent; } else if (Current.Type == TT_ObjCSelectorName) { - if (State.Stack.back().ColonPos > Current.FormatTok->TokenLength) { - State.Column = - State.Stack.back().ColonPos - Current.FormatTok->TokenLength; + if (State.Stack.back().ColonPos > Current.TokenLength) { + State.Column = State.Stack.back().ColonPos - Current.TokenLength; } else { State.Column = State.Stack.back().Indent; - State.Stack.back().ColonPos = - State.Column + Current.FormatTok->TokenLength; + State.Stack.back().ColonPos = State.Column + Current.TokenLength; } } else if (Current.Type == TT_StartOfName || Previous.isOneOf(tok::coloncolon, tok::equal) || @@ -557,9 +550,9 @@ private: if (!DryRun) { unsigned NewLines = 1; if (Current.Type == TT_LineComment) - NewLines = - std::max(NewLines, std::min(Current.FormatTok->NewlinesBefore, - Style.MaxEmptyLinesToKeep + 1)); + NewLines = std::max( + NewLines, + std::min(Current.NewlinesBefore, Style.MaxEmptyLinesToKeep + 1)); Whitespaces.replaceWhitespace(Current, NewLines, State.Column, State.Column, Line.InPPDirective); } @@ -567,7 +560,7 @@ private: State.Stack.back().LastSpace = State.Column; if (Current.isOneOf(tok::arrow, tok::period) && Current.Type != TT_DesignatedInitializerPeriod) - State.Stack.back().LastSpace += Current.FormatTok->TokenLength; + State.Stack.back().LastSpace += Current.TokenLength; State.StartOfLineLevel = State.ParenLevel; State.LowestLevelOnLine = State.ParenLevel; @@ -576,7 +569,7 @@ private: for (unsigned i = 0, e = State.Stack.size() - 1; i != e; ++i) { State.Stack[i].BreakBeforeParameter = true; } - const AnnotatedToken *TokenBefore = Current.getPreviousNoneComment(); + const FormatToken *TokenBefore = Current.getPreviousNoneComment(); if (TokenBefore && !TokenBefore->isOneOf(tok::comma, tok::semi) && TokenBefore->Type != TT_TemplateCloser && TokenBefore->Type != TT_BinaryOperator && !TokenBefore->opensScope()) @@ -597,17 +590,16 @@ private: } } else { if (Current.is(tok::equal) && - (RootToken.is(tok::kw_for) || State.ParenLevel == 0) && + (RootToken->is(tok::kw_for) || State.ParenLevel == 0) && State.Stack.back().VariablePos == 0) { State.Stack.back().VariablePos = State.Column; // Move over * and & if they are bound to the variable name. - const AnnotatedToken *Tok = &Previous; - while (Tok && - State.Stack.back().VariablePos >= Tok->FormatTok->TokenLength) { - State.Stack.back().VariablePos -= Tok->FormatTok->TokenLength; + const FormatToken *Tok = &Previous; + while (Tok && State.Stack.back().VariablePos >= Tok->TokenLength) { + State.Stack.back().VariablePos -= Tok->TokenLength; if (Tok->SpacesRequiredBefore != 0) break; - Tok = Tok->Parent; + Tok = Tok->Previous; } if (Previous.PartOfMultiVariableDeclStmt) State.Stack.back().LastSpace = State.Stack.back().VariablePos; @@ -622,12 +614,12 @@ private: if (Current.Type == TT_ObjCSelectorName && State.Stack.back().ColonPos == 0) { if (State.Stack.back().Indent + Current.LongestObjCSelectorName > - State.Column + Spaces + Current.FormatTok->TokenLength) + State.Column + Spaces + Current.TokenLength) State.Stack.back().ColonPos = State.Stack.back().Indent + Current.LongestObjCSelectorName; else State.Stack.back().ColonPos = - State.Column + Spaces + Current.FormatTok->TokenLength; + State.Column + Spaces + Current.TokenLength; } if (Previous.opensScope() && Previous.Type != TT_ObjCMethodExpr && @@ -647,7 +639,7 @@ private: else if ((Previous.Type == TT_BinaryOperator || Previous.Type == TT_ConditionalExpr || Previous.Type == TT_CtorInitializerColon) && - !(getPrecedence(Previous) == prec::Assignment && + !(Previous.getPrecedence() == prec::Assignment && Current.FakeLParens.empty())) // Always indent relative to the RHS of the expression unless this is a // simple assignment without binary expression on the RHS. @@ -666,7 +658,7 @@ private: /// \brief Mark the next token as consumed in \p State and modify its stacks /// accordingly. unsigned moveStateToNextToken(LineState &State, bool DryRun) { - const AnnotatedToken &Current = *State.NextToken; + const FormatToken &Current = *State.NextToken; assert(State.Stack.size()); if (Current.Type == TT_InheritanceColon) @@ -678,8 +670,7 @@ private: if (Current.isOneOf(tok::period, tok::arrow) && Line.Type == LT_BuilderTypeCall && State.ParenLevel == 0) State.Stack.back().StartOfFunctionCall = - Current.LastInChainOfCalls ? 0 : State.Column + - Current.FormatTok->TokenLength; + Current.LastInChainOfCalls ? 0 : State.Column + Current.TokenLength; if (Current.Type == TT_CtorInitializerColon) { // Indent 2 from the column, so: // SomeClass::SomeClass() @@ -702,14 +693,14 @@ private: State.Stack.back().Indent += 4; // Insert scopes created by fake parenthesis. - const AnnotatedToken *Previous = Current.getPreviousNoneComment(); + const FormatToken *Previous = Current.getPreviousNoneComment(); // Don't add extra indentation for the first fake parenthesis after // 'return', assignements or opening <({[. The indentation for these cases // is special cased. bool SkipFirstExtraIndent = Current.is(tok::kw_return) || (Previous && (Previous->opensScope() || - getPrecedence(*Previous) == prec::Assignment)); + Previous->getPrecedence() == prec::Assignment)); for (SmallVector<prec::Level, 4>::const_reverse_iterator I = Current.FakeLParens.rbegin(), E = Current.FakeLParens.rend(); @@ -741,7 +732,7 @@ private: bool AvoidBinPacking; if (Current.is(tok::l_brace)) { NewIndent = Style.IndentWidth + LastSpace; - const AnnotatedToken *NextNoComment = Current.getNextNoneComment(); + const FormatToken *NextNoComment = Current.getNextNoneComment(); AvoidBinPacking = NextNoComment && NextNoComment->Type == TT_DesignatedInitializerPeriod; } else { @@ -766,7 +757,7 @@ private: // If we encounter a closing ), ], } or >, we can remove a level from our // stacks. if (Current.isOneOf(tok::r_paren, tok::r_square) || - (Current.is(tok::r_brace) && State.NextToken != &RootToken) || + (Current.is(tok::r_brace) && State.NextToken != RootToken) || State.NextToken->Type == TT_TemplateCloser) { State.Stack.pop_back(); --State.ParenLevel; @@ -788,12 +779,9 @@ private: State.StartOfStringLiteral = 0; } - State.Column += Current.FormatTok->TokenLength; + State.Column += Current.TokenLength; - if (State.NextToken->Children.empty()) - State.NextToken = NULL; - else - State.NextToken = &State.NextToken->Children[0]; + State.NextToken = State.NextToken->Next; return breakProtrudingToken(Current, State, DryRun); } @@ -806,34 +794,32 @@ private: /// Note that the penalty of the token protruding the allowed line length is /// already handled in \c addNextStateToQueue; the returned penalty will only /// cover the cost of the additional line breaks. - unsigned breakProtrudingToken(const AnnotatedToken &Current, LineState &State, + unsigned breakProtrudingToken(const FormatToken &Current, LineState &State, bool DryRun) { unsigned UnbreakableTailLength = Current.UnbreakableTailLength; llvm::OwningPtr<BreakableToken> Token; - unsigned StartColumn = State.Column - Current.FormatTok->TokenLength; + unsigned StartColumn = State.Column - Current.TokenLength; unsigned OriginalStartColumn = - SourceMgr.getSpellingColumnNumber( - Current.FormatTok->getStartOfNonWhitespace()) - + SourceMgr.getSpellingColumnNumber(Current.getStartOfNonWhitespace()) - 1; if (Current.is(tok::string_literal) && Current.Type != TT_ImplicitStringLiteral) { // Only break up default narrow strings. - const char *LiteralData = SourceMgr.getCharacterData( - Current.FormatTok->getStartOfNonWhitespace()); + const char *LiteralData = + SourceMgr.getCharacterData(Current.getStartOfNonWhitespace()); if (!LiteralData || *LiteralData != '"') return 0; - Token.reset(new BreakableStringLiteral(*Current.FormatTok, StartColumn)); + Token.reset(new BreakableStringLiteral(Current, StartColumn)); } else if (Current.Type == TT_BlockComment) { - BreakableBlockComment *BBC = - new BreakableBlockComment(Style, *Current.FormatTok, StartColumn, - OriginalStartColumn, !Current.Parent); + BreakableBlockComment *BBC = new BreakableBlockComment( + Style, Current, StartColumn, OriginalStartColumn, !Current.Previous); Token.reset(BBC); } else if (Current.Type == TT_LineComment && - (Current.Parent == NULL || - Current.Parent->Type != TT_ImplicitStringLiteral)) { - Token.reset(new BreakableLineComment(*Current.FormatTok, StartColumn)); + (Current.Previous == NULL || + Current.Previous->Type != TT_ImplicitStringLiteral)) { + Token.reset(new BreakableLineComment(Current, StartColumn)); } else { return 0; } @@ -972,10 +958,10 @@ private: reconstructPath(State, Current->Previous); DEBUG({ if (Current->NewLine) { - llvm::dbgs() - << "Penalty for splitting before " - << Current->Previous->State.NextToken->FormatTok->Tok.getName() - << ": " << Current->Previous->State.NextToken->SplitPenalty << "\n"; + llvm::dbgs() << "Penalty for splitting before " + << Current->Previous->State.NextToken->Tok.getName() + << ": " << Current->Previous->State.NextToken->SplitPenalty + << "\n"; } }); addTokenToState(Current->NewLine, false, State); @@ -1008,8 +994,9 @@ private: /// \brief Returns \c true, if a line break after \p State is allowed. bool canBreak(const LineState &State) { - const AnnotatedToken &Current = *State.NextToken; - const AnnotatedToken &Previous = *Current.Parent; + const FormatToken &Current = *State.NextToken; + const FormatToken &Previous = *Current.Previous; + assert(&Previous == Current.Previous); if (!Current.CanBreakBefore && !(Current.is(tok::r_brace) && State.Stack.back().BreakBeforeClosingBrace)) @@ -1017,8 +1004,8 @@ private: // The opening "{" of a braced list has to be on the same line as the first // element if it is nested in another braced init list or function call. if (!Current.MustBreakBefore && Previous.is(tok::l_brace) && - Previous.Parent && - Previous.Parent->isOneOf(tok::l_brace, tok::l_paren, tok::comma)) + Previous.Previous && + Previous.Previous->isOneOf(tok::l_brace, tok::l_paren, tok::comma)) return false; // This prevents breaks like: // ... @@ -1033,8 +1020,8 @@ private: /// \brief Returns \c true, if a line break after \p State is mandatory. bool mustBreak(const LineState &State) { - const AnnotatedToken &Current = *State.NextToken; - const AnnotatedToken &Previous = *Current.Parent; + const FormatToken &Current = *State.NextToken; + const FormatToken &Previous = *Current.Previous; if (Current.MustBreakBefore || Current.Type == TT_InlineASMColon) return true; if (Current.is(tok::r_brace) && State.Stack.back().BreakBeforeClosingBrace) @@ -1053,7 +1040,7 @@ private: if (Previous.Type == TT_BinaryOperator && Current.Type != TT_BinaryOperator && // Special case for ">>". !Previous.isOneOf(tok::lessless, tok::question) && - getPrecedence(Previous) != prec::Assignment && + Previous.getPrecedence() != prec::Assignment && State.Stack.back().BreakBeforeParameter) return true; @@ -1075,8 +1062,8 @@ private: // Returns the total number of columns required for the remaining tokens. unsigned getRemainingLength(const LineState &State) { - if (State.NextToken && State.NextToken->Parent) - return Line.Last->TotalLength - State.NextToken->Parent->TotalLength; + if (State.NextToken && State.NextToken->Previous) + return Line.Last->TotalLength - State.NextToken->Previous->TotalLength; return 0; } @@ -1084,7 +1071,7 @@ private: SourceManager &SourceMgr; const AnnotatedLine &Line; const unsigned FirstIndent; - const AnnotatedToken &RootToken; + const FormatToken *RootToken; WhitespaceManager &Whitespaces; llvm::SpecificBumpPtrAllocator<StateNode> Allocator; @@ -1244,25 +1231,25 @@ public: // FIXME: Can/should this be done in the UnwrappedLineParser? const AnnotatedLine *NextNoneCommentLine = NULL; for (unsigned i = AnnotatedLines.size() - 1; i > 0; --i) { - if (NextNoneCommentLine && AnnotatedLines[i].First.is(tok::comment) && - AnnotatedLines[i].First.Children.empty()) + if (NextNoneCommentLine && AnnotatedLines[i].First->is(tok::comment) && + !AnnotatedLines[i].First->Next) AnnotatedLines[i].Level = NextNoneCommentLine->Level; else NextNoneCommentLine = - AnnotatedLines[i].First.isNot(tok::r_brace) ? &AnnotatedLines[i] - : NULL; + AnnotatedLines[i].First->isNot(tok::r_brace) ? &AnnotatedLines[i] + : NULL; } std::vector<int> IndentForLevel; bool PreviousLineWasTouched = false; - const AnnotatedToken *PreviousLineLastToken = 0; + const FormatToken *PreviousLineLastToken = 0; bool FormatPPDirective = false; for (std::vector<AnnotatedLine>::iterator I = AnnotatedLines.begin(), E = AnnotatedLines.end(); I != E; ++I) { const AnnotatedLine &TheLine = *I; - const FormatToken *FirstTok = TheLine.First.FormatTok; - int Offset = getIndentOffset(TheLine.First); + const FormatToken *FirstTok = TheLine.First; + int Offset = getIndentOffset(*TheLine.First); // Check whether this line is part of a formatted preprocessor directive. if (FirstTok->HasUnescapedNewline) @@ -1281,10 +1268,10 @@ public: tryFitMultipleLinesInOne(Indent, I, E); bool WasMoved = PreviousLineWasTouched && FirstTok->NewlinesBefore == 0; - if (TheLine.First.is(tok::eof)) { + if (TheLine.First->is(tok::eof)) { if (PreviousLineWasTouched) { unsigned NewLines = std::min(FirstTok->NewlinesBefore, 1u); - Whitespaces.replaceWhitespace(TheLine.First, NewLines, /*Indent*/ 0, + Whitespaces.replaceWhitespace(*TheLine.First, NewLines, /*Indent*/ 0, /*TargetColumn*/ 0); } } else if (TheLine.Type != LT_Invalid && @@ -1294,7 +1281,7 @@ public: // Insert a break even if there is a structural error in case where // we break apart a line consisting of multiple unwrapped lines. (FirstTok->NewlinesBefore == 0 || !StructuralError)) { - formatFirstToken(TheLine.First, PreviousLineLastToken, Indent, + formatFirstToken(*TheLine.First, PreviousLineLastToken, Indent, TheLine.InPPDirective); } else { Indent = LevelIndent = @@ -1309,21 +1296,19 @@ public: } else { // Format the first token if necessary, and notify the WhitespaceManager // about the unchanged whitespace. - for (const AnnotatedToken *Tok = &TheLine.First; Tok != NULL; - Tok = Tok->Children.empty() ? NULL : &Tok->Children[0]) { - if (Tok == &TheLine.First && - (Tok->FormatTok->NewlinesBefore > 0 || Tok->FormatTok->IsFirst)) { - unsigned LevelIndent = SourceMgr.getSpellingColumnNumber( - Tok->FormatTok->Tok.getLocation()) - - 1; + for (const FormatToken *Tok = TheLine.First; Tok != NULL; + Tok = Tok->Next) { + if (Tok == TheLine.First && + (Tok->NewlinesBefore > 0 || Tok->IsFirst)) { + unsigned LevelIndent = + SourceMgr.getSpellingColumnNumber(Tok->Tok.getLocation()) - 1; // Remove trailing whitespace of the previous line if it was // touched. if (PreviousLineWasTouched || touchesEmptyLineBefore(TheLine)) { formatFirstToken(*Tok, PreviousLineLastToken, LevelIndent, TheLine.InPPDirective); } else { - Whitespaces.addUntouchableToken(*Tok->FormatTok, - TheLine.InPPDirective); + Whitespaces.addUntouchableToken(*Tok, TheLine.InPPDirective); } if (static_cast<int>(LevelIndent) - Offset >= 0) @@ -1331,8 +1316,7 @@ public: if (Tok->isNot(tok::comment)) IndentForLevel[TheLine.Level] = LevelIndent; } else { - Whitespaces.addUntouchableToken(*Tok->FormatTok, - TheLine.InPPDirective); + Whitespaces.addUntouchableToken(*Tok, TheLine.InPPDirective); } } // If we did not reformat this unwrapped line, the column at the end of @@ -1351,16 +1335,15 @@ private: unsigned CountBoundToType = 0; bool HasCpp03IncompatibleFormat = false; for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) { - if (AnnotatedLines[i].First.Children.empty()) + if (!AnnotatedLines[i].First->Next) continue; - AnnotatedToken *Tok = &AnnotatedLines[i].First.Children[0]; - while (!Tok->Children.empty()) { + FormatToken *Tok = AnnotatedLines[i].First->Next; + while (Tok->Next) { if (Tok->Type == TT_PointerOrReference) { - bool SpacesBefore = Tok->FormatTok->WhitespaceRange.getBegin() != - Tok->FormatTok->WhitespaceRange.getEnd(); - bool SpacesAfter = - Tok->Children[0].FormatTok->WhitespaceRange.getBegin() != - Tok->Children[0].FormatTok->WhitespaceRange.getEnd(); + bool SpacesBefore = + Tok->WhitespaceRange.getBegin() != Tok->WhitespaceRange.getEnd(); + bool SpacesAfter = Tok->Next->WhitespaceRange.getBegin() != + Tok->Next->WhitespaceRange.getEnd(); if (SpacesBefore && !SpacesAfter) ++CountBoundToVariable; else if (!SpacesBefore && SpacesAfter) @@ -1368,11 +1351,10 @@ private: } if (Tok->Type == TT_TemplateCloser && - Tok->Parent->Type == TT_TemplateCloser && - Tok->FormatTok->WhitespaceRange.getBegin() == - Tok->FormatTok->WhitespaceRange.getEnd()) + Tok->Previous->Type == TT_TemplateCloser && + Tok->WhitespaceRange.getBegin() == Tok->WhitespaceRange.getEnd()) HasCpp03IncompatibleFormat = true; - Tok = &Tok->Children[0]; + Tok = Tok->Next; } } if (Style.DerivePointerBinding) { @@ -1404,7 +1386,7 @@ private: /// /// For example, 'public:' labels in classes are offset by 1 or 2 /// characters to the left from their level. - int getIndentOffset(const AnnotatedToken &RootToken) { + int getIndentOffset(const FormatToken &RootToken) { if (RootToken.isAccessSpecifier(false) || RootToken.isObjCAccessSpecifier()) return Style.AccessModifierOffset; return 0; @@ -1432,13 +1414,13 @@ private: if (I->Last->is(tok::l_brace)) { tryMergeSimpleBlock(I, E, Limit); } else if (Style.AllowShortIfStatementsOnASingleLine && - I->First.is(tok::kw_if)) { + I->First->is(tok::kw_if)) { tryMergeSimpleControlStatement(I, E, Limit); } else if (Style.AllowShortLoopsOnASingleLine && - I->First.isOneOf(tok::kw_for, tok::kw_while)) { + I->First->isOneOf(tok::kw_for, tok::kw_while)) { tryMergeSimpleControlStatement(I, E, Limit); - } else if (I->InPPDirective && (I->First.FormatTok->HasUnescapedNewline || - I->First.FormatTok->IsFirst)) { + } else if (I->InPPDirective && + (I->First->HasUnescapedNewline || I->First->IsFirst)) { tryMergeSimplePPDirective(I, E, Limit); } } @@ -1449,11 +1431,10 @@ private: if (Limit == 0) return; AnnotatedLine &Line = *I; - if (!(I + 1)->InPPDirective || - (I + 1)->First.FormatTok->HasUnescapedNewline) + if (!(I + 1)->InPPDirective || (I + 1)->First->HasUnescapedNewline) return; if (I + 2 != E && (I + 2)->InPPDirective && - !(I + 2)->First.FormatTok->HasUnescapedNewline) + !(I + 2)->First->HasUnescapedNewline) return; if (1 + (I + 1)->Last->TotalLength > Limit) return; @@ -1466,21 +1447,20 @@ private: if (Limit == 0) return; if ((I + 1)->InPPDirective != I->InPPDirective || - ((I + 1)->InPPDirective && - (I + 1)->First.FormatTok->HasUnescapedNewline)) + ((I + 1)->InPPDirective && (I + 1)->First->HasUnescapedNewline)) return; AnnotatedLine &Line = *I; if (Line.Last->isNot(tok::r_paren)) return; if (1 + (I + 1)->Last->TotalLength > Limit) return; - if ((I + 1)->First.isOneOf(tok::semi, tok::kw_if, tok::kw_for, - tok::kw_while) || - (I + 1)->First.Type == TT_LineComment) + if ((I + 1)->First->isOneOf(tok::semi, tok::kw_if, tok::kw_for, + tok::kw_while) || + (I + 1)->First->Type == TT_LineComment) return; // Only inline simple if's (no nested if or else). - if (I + 2 != E && Line.First.is(tok::kw_if) && - (I + 2)->First.is(tok::kw_else)) + if (I + 2 != E && Line.First->is(tok::kw_if) && + (I + 2)->First->is(tok::kw_else)) return; join(Line, *(++I)); } @@ -1496,14 +1476,14 @@ private: // we're not in a control flow statement and the last token is an opening // brace. AnnotatedLine &Line = *I; - if (Line.First.isOneOf(tok::kw_if, tok::kw_while, tok::kw_do, tok::r_brace, - tok::kw_else, tok::kw_try, tok::kw_catch, - tok::kw_for, tok::kw_namespace, - // This gets rid of all ObjC @ keywords and methods. - tok::at, tok::minus, tok::plus)) + if (Line.First->isOneOf(tok::kw_if, tok::kw_while, tok::kw_do, tok::r_brace, + tok::kw_else, tok::kw_try, tok::kw_catch, + tok::kw_for, tok::kw_namespace, + // This gets rid of all ObjC @ keywords and methods. + tok::at, tok::minus, tok::plus)) return; - AnnotatedToken *Tok = &(I + 1)->First; + FormatToken *Tok = (I + 1)->First; if (Tok->getNextNoneComment() == NULL && Tok->is(tok::r_brace) && !Tok->MustBreakBefore) { // We merge empty blocks even if the line exceeds the column limit. @@ -1524,11 +1504,11 @@ private: do { if (Tok->isOneOf(tok::l_brace, tok::r_brace)) return; - Tok = Tok->Children.empty() ? NULL : &Tok->Children.back(); + Tok = Tok->Next; } while (Tok != NULL); // Last, check that the third line contains a single closing brace. - Tok = &(I + 2)->First; + Tok = (I + 2)->First; if (Tok->getNextNoneComment() != NULL || Tok->isNot(tok::r_brace) || Tok->MustBreakBefore) return; @@ -1546,12 +1526,14 @@ private: } void join(AnnotatedLine &A, const AnnotatedLine &B) { - unsigned LengthA = A.Last->TotalLength + B.First.SpacesRequiredBefore; - A.Last->Children.push_back(B.First); - while (!A.Last->Children.empty()) { - A.Last->Children[0].Parent = A.Last; - A.Last->Children[0].TotalLength += LengthA; - A.Last = &A.Last->Children[0]; + assert(!A.Last->Next); + assert(!B.First->Previous); + A.Last->Next = B.First; + B.First->Previous = A.Last; + unsigned LengthA = A.Last->TotalLength + B.First->SpacesRequiredBefore; + for (FormatToken *Tok = B.First; Tok; Tok = Tok->Next) { + Tok->TotalLength += LengthA; + A.Last = Tok; } } @@ -1567,8 +1549,8 @@ private: } bool touchesLine(const AnnotatedLine &TheLine) { - const FormatToken *First = TheLine.First.FormatTok; - const FormatToken *Last = TheLine.Last->FormatTok; + const FormatToken *First = TheLine.First; + const FormatToken *Last = TheLine.Last; CharSourceRange LineRange = CharSourceRange::getCharRange( First->WhitespaceRange.getBegin().getLocWithOffset( First->LastNewlineOffset), @@ -1579,7 +1561,7 @@ private: bool touchesPPDirective(std::vector<AnnotatedLine>::iterator I, std::vector<AnnotatedLine>::iterator E) { for (; I != E; ++I) { - if (I->First.FormatTok->HasUnescapedNewline) + if (I->First->HasUnescapedNewline) return false; if (touchesLine(*I)) return true; @@ -1588,7 +1570,7 @@ private: } bool touchesEmptyLineBefore(const AnnotatedLine &TheLine) { - const FormatToken *First = TheLine.First.FormatTok; + const FormatToken *First = TheLine.First; CharSourceRange LineRange = CharSourceRange::getCharRange( First->WhitespaceRange.getBegin(), First->WhitespaceRange.getBegin().getLocWithOffset( @@ -1603,23 +1585,22 @@ private: /// \brief Add a new line and the required indent before the first Token /// of the \c UnwrappedLine if there was no structural parsing error. /// Returns the indent level of the \c UnwrappedLine. - void formatFirstToken(const AnnotatedToken &RootToken, - const AnnotatedToken *PreviousToken, unsigned Indent, + void formatFirstToken(const FormatToken &RootToken, + const FormatToken *PreviousToken, unsigned Indent, bool InPPDirective) { - const FormatToken *Tok = RootToken.FormatTok; - unsigned Newlines = - std::min(Tok->NewlinesBefore, Style.MaxEmptyLinesToKeep + 1); - if (Newlines == 0 && !Tok->IsFirst) + std::min(RootToken.NewlinesBefore, Style.MaxEmptyLinesToKeep + 1); + if (Newlines == 0 && !RootToken.IsFirst) Newlines = 1; // Insert extra new line before access specifiers. if (PreviousToken && PreviousToken->isOneOf(tok::semi, tok::r_brace) && - RootToken.isAccessSpecifier() && Tok->NewlinesBefore == 1) + RootToken.isAccessSpecifier() && RootToken.NewlinesBefore == 1) ++Newlines; - Whitespaces.replaceWhitespace(RootToken, Newlines, Indent, Indent, - InPPDirective && !Tok->HasUnescapedNewline); + Whitespaces.replaceWhitespace( + RootToken, Newlines, Indent, Indent, + InPPDirective && !RootToken.HasUnescapedNewline); } FormatStyle Style; diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index ebbafcd3814..9a1a2ab44b0 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -21,56 +21,6 @@ namespace clang { namespace format { -bool AnnotatedToken::isUnaryOperator() const { - switch (FormatTok->Tok.getKind()) { - case tok::plus: - case tok::plusplus: - case tok::minus: - case tok::minusminus: - case tok::exclaim: - case tok::tilde: - case tok::kw_sizeof: - case tok::kw_alignof: - return true; - default: - return false; - } -} - -bool AnnotatedToken::isBinaryOperator() const { - // Comma is a binary operator, but does not behave as such wrt. formatting. - return getPrecedence(*this) > prec::Comma; -} - -bool AnnotatedToken::isTrailingComment() const { - return is(tok::comment) && - (Children.empty() || Children[0].FormatTok->NewlinesBefore > 0); -} - -AnnotatedToken *AnnotatedToken::getPreviousNoneComment() const { - AnnotatedToken *Tok = Parent; - while (Tok != NULL && Tok->is(tok::comment)) - Tok = Tok->Parent; - return Tok; -} - -const AnnotatedToken *AnnotatedToken::getNextNoneComment() const { - const AnnotatedToken *Tok = Children.empty() ? NULL : &Children[0]; - while (Tok != NULL && Tok->is(tok::comment)) - Tok = Tok->Children.empty() ? NULL : &Tok->Children[0]; - return Tok; -} - -bool AnnotatedToken::closesScope() const { - return isOneOf(tok::r_paren, tok::r_brace, tok::r_square) || - Type == TT_TemplateCloser; -} - -bool AnnotatedToken::opensScope() const { - return isOneOf(tok::l_paren, tok::l_brace, tok::l_square) || - Type == TT_TemplateOpener; -} - /// \brief A parser that gathers additional information about tokens. /// /// The \c TokenAnnotator tries to match parenthesis and square brakets and @@ -80,7 +30,7 @@ class AnnotatingParser { public: AnnotatingParser(SourceManager &SourceMgr, Lexer &Lex, AnnotatedLine &Line, IdentifierInfo &Ident_in) - : SourceMgr(SourceMgr), Lex(Lex), Line(Line), CurrentToken(&Line.First), + : SourceMgr(SourceMgr), Lex(Lex), Line(Line), CurrentToken(Line.First), KeywordVirtualFound(false), NameFound(false), Ident_in(Ident_in) { Contexts.push_back(Context(tok::unknown, 1, /*IsExpression=*/ false)); } @@ -90,7 +40,7 @@ private: if (CurrentToken == NULL) return false; ScopedContextCreator ContextCreator(*this, tok::less, 10); - AnnotatedToken *Left = CurrentToken->Parent; + FormatToken *Left = CurrentToken->Previous; Contexts.back().IsExpression = false; while (CurrentToken != NULL) { if (CurrentToken->is(tok::greater)) { @@ -103,9 +53,9 @@ private: if (CurrentToken->isOneOf(tok::r_paren, tok::r_square, tok::r_brace, tok::question, tok::colon)) return false; - if (CurrentToken->Parent->isOneOf(tok::pipepipe, tok::ampamp) && - CurrentToken->Parent->Type != TT_PointerOrReference && - Line.First.isNot(tok::kw_template)) + if (CurrentToken->Previous->isOneOf(tok::pipepipe, tok::ampamp) && + CurrentToken->Previous->Type != TT_PointerOrReference && + Line.First->isNot(tok::kw_template)) return false; updateParameterCount(Left, CurrentToken); if (!consumeToken()) @@ -124,14 +74,14 @@ private: Contexts.size() == 2 && Contexts[0].ColonIsForRangeExpr; bool StartsObjCMethodExpr = false; - AnnotatedToken *Left = CurrentToken->Parent; + FormatToken *Left = CurrentToken->Previous; if (CurrentToken->is(tok::caret)) { // ^( starts a block. Left->Type = TT_ObjCBlockLParen; - } else if (AnnotatedToken *MaybeSel = Left->Parent) { + } else if (FormatToken *MaybeSel = Left->Previous) { // @selector( starts a selector. - if (MaybeSel->isObjCAtKeyword(tok::objc_selector) && MaybeSel->Parent && - MaybeSel->Parent->is(tok::at)) { + if (MaybeSel->isObjCAtKeyword(tok::objc_selector) && MaybeSel->Previous && + MaybeSel->Previous->is(tok::at)) { StartsObjCMethodExpr = true; } } @@ -147,20 +97,20 @@ private: // 'identifier' '*' 'identifier' followed by not '=' -- this // '*' has to be a binary operator but determineStarAmpUsage() will // categorize it as an unary operator, so set the right type here. - if (LookForDecls && !CurrentToken->Children.empty()) { - AnnotatedToken &Prev = *CurrentToken->Parent; - AnnotatedToken &Next = CurrentToken->Children[0]; - if (Prev.Parent->is(tok::identifier) && - Prev.isOneOf(tok::star, tok::amp, tok::ampamp) && - CurrentToken->is(tok::identifier) && Next.isNot(tok::equal)) { - Prev.Type = TT_BinaryOperator; + if (LookForDecls && CurrentToken->Next) { + FormatToken *Prev = CurrentToken->Previous; + FormatToken *Next = CurrentToken->Next; + if (Prev->Previous->is(tok::identifier) && + Prev->isOneOf(tok::star, tok::amp, tok::ampamp) && + CurrentToken->is(tok::identifier) && Next->isNot(tok::equal)) { + Prev->Type = TT_BinaryOperator; LookForDecls = false; } } if (CurrentToken->is(tok::r_paren)) { - if (MightBeFunctionType && !CurrentToken->Children.empty() && - CurrentToken->Children[0].isOneOf(tok::l_paren, tok::l_square)) + if (MightBeFunctionType && CurrentToken->Next && + CurrentToken->Next->isOneOf(tok::l_paren, tok::l_square)) Left->Type = TT_FunctionTypeLParen; Left->MatchingParen = CurrentToken; CurrentToken->MatchingParen = Left; @@ -178,8 +128,9 @@ private: } if (CurrentToken->isOneOf(tok::r_square, tok::r_brace)) return false; - if (CurrentToken->Parent->Type == TT_PointerOrReference && - CurrentToken->Parent->Parent->isOneOf(tok::l_paren, tok::coloncolon)) + if (CurrentToken->Previous->Type == TT_PointerOrReference && + CurrentToken->Previous->Previous->isOneOf(tok::l_paren, + tok::coloncolon)) MightBeFunctionType = true; updateParameterCount(Left, CurrentToken); if (!consumeToken()) @@ -195,16 +146,15 @@ private: // A '[' could be an index subscript (after an indentifier or after // ')' or ']'), it could be the start of an Objective-C method // expression, or it could the the start of an Objective-C array literal. - AnnotatedToken *Left = CurrentToken->Parent; - AnnotatedToken *Parent = Left->getPreviousNoneComment(); + FormatToken *Left = CurrentToken->Previous; + FormatToken *Parent = Left->getPreviousNoneComment(); bool StartsObjCMethodExpr = Contexts.back().CanBeExpression && (!Parent || Parent->isOneOf(tok::colon, tok::l_square, tok::l_paren, tok::kw_return, tok::kw_throw) || Parent->isUnaryOperator() || Parent->Type == TT_ObjCForIn || Parent->Type == TT_CastRParen || - getBinOpPrecedence(Parent->FormatTok->Tok.getKind(), true, true) > - prec::Unknown); + getBinOpPrecedence(Parent->Tok.getKind(), true, true) > prec::Unknown); ScopedContextCreator ContextCreator(*this, tok::l_square, 10); Contexts.back().IsExpression = true; bool StartsObjCArrayLiteral = Parent && Parent->is(tok::at); @@ -218,8 +168,7 @@ private: while (CurrentToken != NULL) { if (CurrentToken->is(tok::r_square)) { - if (!CurrentToken->Children.empty() && - CurrentToken->Children[0].is(tok::l_paren)) { + if (CurrentToken->Next && CurrentToken->Next->is(tok::l_paren)) { // An ObjC method call is rarely followed by an open parenthesis. // FIXME: Do we incorrectly label ":" with this? StartsObjCMethodExpr = false; @@ -255,9 +204,9 @@ private: bool parseBrace() { if (CurrentToken != NULL) { ScopedContextCreator ContextCreator(*this, tok::l_brace, 1); - AnnotatedToken *Left = CurrentToken->Parent; + FormatToken *Left = CurrentToken->Previous; - AnnotatedToken *Parent = Left->getPreviousNoneComment(); + FormatToken *Parent = Left->getPreviousNoneComment(); bool StartsObjCDictLiteral = Parent && Parent->is(tok::at); if (StartsObjCDictLiteral) { Contexts.back().ColonIsObjCDictLiteral = true; @@ -285,7 +234,7 @@ private: return true; } - void updateParameterCount(AnnotatedToken *Left, AnnotatedToken *Current) { + void updateParameterCount(FormatToken *Left, FormatToken *Current) { if (Current->is(tok::comma)) ++Left->ParameterCount; else if (Left->ParameterCount == 0 && Current->isNot(tok::comment)) @@ -312,39 +261,38 @@ private: if (!parseAngle()) return false; if (CurrentToken != NULL) - CurrentToken->Parent->ClosesTemplateDeclaration = true; + CurrentToken->Previous->ClosesTemplateDeclaration = true; return true; } return false; } bool consumeToken() { - AnnotatedToken *Tok = CurrentToken; + FormatToken *Tok = CurrentToken; next(); - switch (Tok->FormatTok->Tok.getKind()) { + switch (Tok->Tok.getKind()) { case tok::plus: case tok::minus: - if (Tok->Parent == NULL && Line.MustBeDeclaration) + if (Tok->Previous == NULL && Line.MustBeDeclaration) Tok->Type = TT_ObjCMethodSpecifier; break; case tok::colon: - if (Tok->Parent == NULL) + if (Tok->Previous == NULL) return false; // Colons from ?: are handled in parseConditional(). - if (Tok->Parent->is(tok::r_paren) && Contexts.size() == 1) { + if (Tok->Previous->is(tok::r_paren) && Contexts.size() == 1) { Tok->Type = TT_CtorInitializerColon; } else if (Contexts.back().ColonIsObjCDictLiteral) { Tok->Type = TT_ObjCDictLiteral; } else if (Contexts.back().ColonIsObjCMethodExpr || - Line.First.Type == TT_ObjCMethodSpecifier) { + Line.First->Type == TT_ObjCMethodSpecifier) { Tok->Type = TT_ObjCMethodExpr; - Tok->Parent->Type = TT_ObjCSelectorName; - if (Tok->Parent->FormatTok->TokenLength > + Tok->Previous->Type = TT_ObjCSelectorName; + if (Tok->Previous->TokenLength > Contexts.back().LongestObjCSelectorName) - Contexts.back().LongestObjCSelectorName = - Tok->Parent->FormatTok->TokenLength; + Contexts.back().LongestObjCSelectorName = Tok->Previous->TokenLength; if (Contexts.back().FirstObjCSelectorName == NULL) - Contexts.back().FirstObjCSelectorName = Tok->Parent; + Contexts.back().FirstObjCSelectorName = Tok->Previous; } else if (Contexts.back().ColonIsForRangeExpr) { Tok->Type = TT_RangeBasedForLoopColon; } else if (Contexts.size() == 1) { @@ -395,7 +343,7 @@ private: return false; case tok::r_brace: // Lines can start with '}'. - if (Tok->Parent != NULL) + if (Tok->Previous != NULL) return false; break; case tok::greater: @@ -409,8 +357,8 @@ private: } if (CurrentToken) { CurrentToken->Type = TT_OverloadedOperatorLParen; - if (CurrentToken->Parent->Type == TT_BinaryOperator) - CurrentToken->Parent->Type = TT_OverloadedOperator; + if (CurrentToken->Previous->Type == TT_BinaryOperator) + CurrentToken->Previous->Type = TT_OverloadedOperator; } break; case tok::question: @@ -420,8 +368,8 @@ private: parseTemplateDeclaration(); break; case tok::identifier: - if (Line.First.is(tok::kw_for) && - Tok->FormatTok->Tok.getIdentifierInfo() == &Ident_in) + if (Line.First->is(tok::kw_for) && + Tok->Tok.getIdentifierInfo() == &Ident_in) Tok->Type = TT_ObjCForIn; break; case tok::comma: @@ -439,8 +387,7 @@ private: if (CurrentToken != NULL && CurrentToken->is(tok::less)) { next(); while (CurrentToken != NULL) { - if (CurrentToken->isNot(tok::comment) || - !CurrentToken->Children.empty()) + if (CurrentToken->isNot(tok::comment) || CurrentToken->Next) CurrentToken->Type = TT_ImplicitStringLiteral; next(); } @@ -472,10 +419,9 @@ private: return; // Hashes in the middle of a line can lead to any strange token // sequence. - if (CurrentToken->FormatTok->Tok.getIdentifierInfo() == NULL) + if (CurrentToken->Tok.getIdentifierInfo() == NULL) return; - switch ( - CurrentToken->FormatTok->Tok.getIdentifierInfo()->getPPKeywordID()) { + switch (CurrentToken->Tok.getIdentifierInfo()->getPPKeywordID()) { case tok::pp_include: case tok::pp_import: parseIncludeDirective(); @@ -498,7 +444,7 @@ private: public: LineType parseLine() { int PeriodsAndArrows = 0; - AnnotatedToken *LastPeriodOrArrow = NULL; + FormatToken *LastPeriodOrArrow = NULL; bool CanBeBuilderTypeStmt = true; if (CurrentToken->is(tok::hash)) { parsePreprocessorDirective(); @@ -511,10 +457,10 @@ public: ++PeriodsAndArrows; LastPeriodOrArrow = CurrentToken; } - AnnotatedToken *TheToken = CurrentToken; + FormatToken *TheToken = CurrentToken; if (!consumeToken()) return LT_Invalid; - if (getPrecedence(*TheToken) > prec::Assignment && + if (TheToken->getPrecedence() > prec::Assignment && TheToken->Type == TT_BinaryOperator) CanBeBuilderTypeStmt = false; } @@ -527,7 +473,7 @@ public: return LT_BuilderTypeCall; } - if (Line.First.Type == TT_ObjCMethodSpecifier) { + if (Line.First->Type == TT_ObjCMethodSpecifier) { if (Contexts.back().FirstObjCSelectorName != NULL) Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = Contexts.back().LongestObjCSelectorName; @@ -544,10 +490,8 @@ private: CurrentToken->BindingStrength = Contexts.back().BindingStrength; } - if (CurrentToken != NULL && !CurrentToken->Children.empty()) - CurrentToken = &CurrentToken->Children[0]; - else - CurrentToken = NULL; + if (CurrentToken != NULL) + CurrentToken = CurrentToken->Next; // Reset token type in case we have already looked at it and then recovered // from an error (e.g. failure to find the matching >). @@ -572,8 +516,8 @@ private: bool ColonIsForRangeExpr; bool ColonIsObjCDictLiteral; bool ColonIsObjCMethodExpr; - AnnotatedToken *FirstObjCSelectorName; - AnnotatedToken *FirstStartOfName; + FormatToken *FirstObjCSelectorName; + FormatToken *FirstStartOfName; bool IsExpression; bool CanBeExpression; }; @@ -594,13 +538,13 @@ private: ~ScopedContextCreator() { P.Contexts.pop_back(); } }; - void determineTokenType(AnnotatedToken &Current) { - if (getPrecedence(Current) == prec::Assignment && - (!Current.Parent || Current.Parent->isNot(tok::kw_operator))) { + void determineTokenType(FormatToken &Current) { + if (Current.getPrecedence() == prec::Assignment && + (!Current.Previous || Current.Previous->isNot(tok::kw_operator))) { Contexts.back().IsExpression = true; - for (AnnotatedToken *Previous = Current.Parent; + for (FormatToken *Previous = Current.Previous; Previous && Previous->isNot(tok::comma); - Previous = Previous->Parent) { + Previous = Previous->Previous) { if (Previous->is(tok::r_square)) Previous = Previous->MatchingParen; if (Previous->Type == TT_BinaryOperator && @@ -611,15 +555,15 @@ private: } else if (Current.isOneOf(tok::kw_return, tok::kw_throw) || (Current.is(tok::l_paren) && !Line.MustBeDeclaration && !Line.InPPDirective && - (!Current.Parent || Current.Parent->isNot(tok::kw_for)))) { + (!Current.Previous || Current.Previous->isNot(tok::kw_for)))) { Contexts.back().IsExpression = true; } else if (Current.isOneOf(tok::r_paren, tok::greater, tok::comma)) { - for (AnnotatedToken *Previous = Current.Parent; + for (FormatToken *Previous = Current.Previous; Previous && Previous->isOneOf(tok::star, tok::amp); - Previous = Previous->Parent) + Previous = Previous->Previous) Previous->Type = TT_PointerOrReference; - } else if (Current.Parent && - Current.Parent->Type == TT_CtorInitializerColon) { + } else if (Current.Previous && + Current.Previous->Type == TT_CtorInitializerColon) { Contexts.back().IsExpression = true; } else if (Current.is(tok::kw_new)) { Contexts.back().CanBeExpression = false; @@ -629,14 +573,13 @@ private: } if (Current.Type == TT_Unknown) { - if (Current.Parent && Current.is(tok::identifier) && - ((Current.Parent->is(tok::identifier) && - Current.Parent->FormatTok->Tok.getIdentifierInfo() - ->getPPKeywordID() == + if (Current.Previous && Current.is(tok::identifier) && + ((Current.Previous->is(tok::identifier) && + Current.Previous->Tok.getIdentifierInfo()->getPPKeywordID() == tok::pp_not_keyword) || - isSimpleTypeSpecifier(*Current.Parent) || - Current.Parent->Type == TT_PointerOrReference || - Current.Parent->Type == TT_TemplateCloser)) { + isSimpleTypeSpecifier(*Current.Previous) || + Current.Previous->Type == TT_PointerOrReference || + Current.Previous->Type == TT_TemplateCloser)) { Contexts.back().FirstStartOfName = &Current; Current.Type = TT_StartOfName; NameFound = true; @@ -652,29 +595,29 @@ private: } else if (Current.isBinaryOperator()) { Current.Type = TT_BinaryOperator; } else if (Current.is(tok::comment)) { - std::string Data(Lexer::getSpelling(Current.FormatTok->Tok, SourceMgr, - Lex.getLangOpts())); + std::string Data( + Lexer::getSpelling(Current.Tok, SourceMgr, Lex.getLangOpts())); if (StringRef(Data).startswith("//")) Current.Type = TT_LineComment; else Current.Type = TT_BlockComment; } else if (Current.is(tok::r_paren)) { - bool ParensNotExpr = - !Current.Parent || Current.Parent->Type == TT_PointerOrReference || - Current.Parent->Type == TT_TemplateCloser; + bool ParensNotExpr = !Current.Previous || + Current.Previous->Type == TT_PointerOrReference || + Current.Previous->Type == TT_TemplateCloser; bool ParensCouldEndDecl = - !Current.Children.empty() && - Current.Children[0].isOneOf(tok::equal, tok::semi, tok::l_brace); + Current.Next && + Current.Next->isOneOf(tok::equal, tok::semi, tok::l_brace); bool IsSizeOfOrAlignOf = - Current.MatchingParen && Current.MatchingParen->Parent && - Current.MatchingParen->Parent->isOneOf(tok::kw_sizeof, - tok::kw_alignof); + Current.MatchingParen && Current.MatchingParen->Previous && + Current.MatchingParen->Previous->isOneOf(tok::kw_sizeof, + tok::kw_alignof); if (ParensNotExpr && !ParensCouldEndDecl && !IsSizeOfOrAlignOf && Contexts.back().IsExpression) // FIXME: We need to get smarter and understand more cases of casts. Current.Type = TT_CastRParen; - } else if (Current.is(tok::at) && Current.Children.size()) { - switch (Current.Children[0].FormatTok->Tok.getObjCKeywordID()) { + } else if (Current.is(tok::at) && Current.Next) { + switch (Current.Next->Tok.getObjCKeywordID()) { case tok::objc_interface: case tok::objc_implementation: case tok::objc_protocol: @@ -687,7 +630,7 @@ private: break; } } else if (Current.is(tok::period)) { - AnnotatedToken *PreviousNoComment= Current.getPreviousNoneComment(); + FormatToken *PreviousNoComment = Current.getPreviousNoneComment(); if (PreviousNoComment && PreviousNoComment->isOneOf(tok::comma, tok::l_brace)) Current.Type = TT_DesignatedInitializerPeriod; @@ -696,13 +639,12 @@ private: } /// \brief Return the type of the given token assuming it is * or &. - TokenType determineStarAmpUsage(const AnnotatedToken &Tok, - bool IsExpression) { - const AnnotatedToken *PrevToken = Tok.getPreviousNoneComment(); + TokenType determineStarAmpUsage(const FormatToken &Tok, bool IsExpression) { + const FormatToken *PrevToken = Tok.getPreviousNoneComment(); if (PrevToken == NULL) return TT_UnaryOperator; - const AnnotatedToken *NextToken = Tok.getNextNoneComment(); + const FormatToken *NextToken = Tok.getNextNoneComment(); if (NextToken == NULL) return TT_Unknown; @@ -720,9 +662,9 @@ private: if (NextToken->is(tok::l_square)) return TT_PointerOrReference; - if (PrevToken->FormatTok->Tok.isLiteral() || + if (PrevToken->Tok.isLiteral() || PrevToken->isOneOf(tok::r_paren, tok::r_square) || - NextToken->FormatTok->Tok.isLiteral() || NextToken->isUnaryOperator()) + NextToken->Tok.isLiteral() || NextToken->isUnaryOperator()) return TT_BinaryOperator; // It is very unlikely that we are going to find a pointer or reference type @@ -733,8 +675,8 @@ private: return TT_PointerOrReference; } - TokenType determinePlusMinusCaretUsage(const AnnotatedToken &Tok) { - const AnnotatedToken *PrevToken = Tok.getPreviousNoneComment(); + TokenType determinePlusMinusCaretUsage(const FormatToken &Tok) { + const FormatToken *PrevToken = Tok.getPreviousNoneComment(); if (PrevToken == NULL) return TT_UnaryOperator; @@ -753,8 +695,8 @@ private: } /// \brief Determine whether ++/-- are pre- or post-increments/-decrements. - TokenType determineIncrementUsage(const AnnotatedToken &Tok) { - const AnnotatedToken *PrevToken = Tok.getPreviousNoneComment(); + TokenType determineIncrementUsage(const FormatToken &Tok) { + const FormatToken *PrevToken = Tok.getPreviousNoneComment(); if (PrevToken == NULL) return TT_UnaryOperator; if (PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::identifier)) @@ -766,8 +708,8 @@ private: // FIXME: This is copy&pasted from Sema. Put it in a common place and remove // duplication. /// \brief Determine whether the token kind starts a simple-type-specifier. - bool isSimpleTypeSpecifier(const AnnotatedToken &Tok) const { - switch (Tok.FormatTok->Tok.getKind()) { + bool isSimpleTypeSpecifier(const FormatToken &Tok) const { + switch (Tok.Tok.getKind()) { case tok::kw_short: case tok::kw_long: case tok::kw___int64: @@ -801,7 +743,7 @@ private: SourceManager &SourceMgr; Lexer &Lex; AnnotatedLine &Line; - AnnotatedToken *CurrentToken; + FormatToken *CurrentToken; bool KeywordVirtualFound; bool NameFound; IdentifierInfo &Ident_in; @@ -811,7 +753,7 @@ private: /// operator precedence. class ExpressionParser { public: - ExpressionParser(AnnotatedLine &Line) : Current(&Line.First) {} + ExpressionParser(AnnotatedLine &Line) : Current(Line.First) {} /// \brief Parse expressions with the given operatore precedence. void parse(int Precedence = 0) { @@ -823,7 +765,7 @@ public: next(); } - AnnotatedToken *Start = Current; + FormatToken *Start = Current; bool OperatorFound = false; while (Current) { @@ -837,7 +779,7 @@ public: else if (Current->is(tok::semi) || Current->Type == TT_InlineASMColon) CurrentPrecedence = 1; else if (Current->Type == TT_BinaryOperator || Current->is(tok::comma)) - CurrentPrecedence = 1 + (int) getPrecedence(*Current); + CurrentPrecedence = 1 + (int) Current->getPrecedence(); } // At the end of the line or when an operator with higher precedence is @@ -847,7 +789,7 @@ public: if (OperatorFound) { Start->FakeLParens.push_back(prec::Level(Precedence - 1)); if (Current) - ++Current->Parent->FakeRParens; + ++Current->Previous->FakeRParens; } return; } @@ -872,10 +814,10 @@ public: private: void next() { if (Current != NULL) - Current = Current->Children.empty() ? NULL : &Current->Children[0]; + Current = Current->Next; } - AnnotatedToken *Current; + FormatToken *Current; }; void TokenAnnotator::annotate(AnnotatedLine &Line) { @@ -887,22 +829,22 @@ void TokenAnnotator::annotate(AnnotatedLine &Line) { ExpressionParser ExprParser(Line); ExprParser.parse(); - if (Line.First.Type == TT_ObjCMethodSpecifier) + if (Line.First->Type == TT_ObjCMethodSpecifier) Line.Type = LT_ObjCMethodDecl; - else if (Line.First.Type == TT_ObjCDecl) + else if (Line.First->Type == TT_ObjCDecl) Line.Type = LT_ObjCDecl; - else if (Line.First.Type == TT_ObjCProperty) + else if (Line.First->Type == TT_ObjCProperty) Line.Type = LT_ObjCProperty; - Line.First.SpacesRequiredBefore = 1; - Line.First.MustBreakBefore = Line.First.FormatTok->MustBreakBefore; - Line.First.CanBreakBefore = Line.First.MustBreakBefore; + Line.First->SpacesRequiredBefore = 1; + Line.First->CanBreakBefore = Line.First->MustBreakBefore; } void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) { - if (Line.First.Children.empty()) + Line.First->TotalLength = Line.First->TokenLength; + if (!Line.First->Next) return; - AnnotatedToken *Current = &Line.First.Children[0]; + FormatToken *Current = Line.First->Next; while (Current != NULL) { if (Current->Type == TT_LineComment) Current->SpacesRequiredBefore = Style.SpacesBeforeTrailingComments; @@ -910,19 +852,18 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) { Current->SpacesRequiredBefore = spaceRequiredBefore(Line, *Current) ? 1 : 0; - if (Current->FormatTok->MustBreakBefore) { - Current->MustBreakBefore = true; + if (Current->MustBreakBefore) { } else if (Current->Type == TT_LineComment) { - Current->MustBreakBefore = Current->FormatTok->NewlinesBefore > 0; - } else if (Current->Parent->isTrailingComment() || + Current->MustBreakBefore = Current->NewlinesBefore > 0; + } else if (Current->Previous->isTrailingComment() || (Current->is(tok::string_literal) && - Current->Parent->is(tok::string_literal))) { + Current->Previous->is(tok::string_literal))) { Current->MustBreakBefore = true; - } else if (Current->is(tok::lessless) && !Current->Children.empty() && - Current->Parent->is(tok::string_literal) && - Current->Children[0].is(tok::string_literal)) { + } else if (Current->is(tok::lessless) && Current->Next && + Current->Previous->is(tok::string_literal) && + Current->Next->is(tok::string_literal)) { Current->MustBreakBefore = true; - } else if (Current->Parent->ClosesTemplateDeclaration && + } else if (Current->Previous->ClosesTemplateDeclaration && Style.AlwaysBreakTemplateDeclarations) { Current->MustBreakBefore = true; } else { @@ -931,10 +872,10 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) { Current->CanBreakBefore = Current->MustBreakBefore || canBreakBefore(Line, *Current); if (Current->MustBreakBefore) - Current->TotalLength = Current->Parent->TotalLength + Style.ColumnLimit; + Current->TotalLength = Current->Previous->TotalLength + Style.ColumnLimit; else Current->TotalLength = - Current->Parent->TotalLength + Current->FormatTok->TokenLength + + Current->Previous->TotalLength + Current->TokenLength + Current->SpacesRequiredBefore; // FIXME: Only calculate this if CanBreakBefore is true once static // initializers etc. are sorted out. @@ -942,7 +883,7 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) { Current->SplitPenalty = 20 * Current->BindingStrength + splitPenalty(Line, *Current); - Current = Current->Children.empty() ? NULL : &Current->Children[0]; + Current = Current->Next; } calculateUnbreakableTailLengths(Line); @@ -953,7 +894,7 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) { void TokenAnnotator::calculateUnbreakableTailLengths(AnnotatedLine &Line) { unsigned UnbreakableTailLength = 0; - AnnotatedToken *Current = Line.Last; + FormatToken *Current = Line.Last; while (Current != NULL) { Current->UnbreakableTailLength = UnbreakableTailLength; if (Current->CanBreakBefore || @@ -961,16 +902,16 @@ void TokenAnnotator::calculateUnbreakableTailLengths(AnnotatedLine &Line) { UnbreakableTailLength = 0; } else { UnbreakableTailLength += - Current->FormatTok->TokenLength + Current->SpacesRequiredBefore; + Current->TokenLength + Current->SpacesRequiredBefore; } - Current = Current->Parent; + Current = Current->Previous; } } unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line, - const AnnotatedToken &Tok) { - const AnnotatedToken &Left = *Tok.Parent; - const AnnotatedToken &Right = Tok; + const FormatToken &Tok) { + const FormatToken &Left = *Tok.Previous; + const FormatToken &Right = Tok; if (Left.is(tok::semi)) return 0; @@ -978,7 +919,7 @@ unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line, return 1; if (Right.Type == TT_StartOfName) { - if (Line.First.is(tok::kw_for) && Right.PartOfMultiVariableDeclStmt) + if (Line.First->is(tok::kw_for) && Right.PartOfMultiVariableDeclStmt) return 3; else if (Line.MightBeFunctionDecl && Right.BindingStrength == 1) // FIXME: Clean up hack of using BindingStrength to find top-level names. @@ -1012,7 +953,7 @@ unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line, return 150; // In for-loops, prefer breaking at ',' and ';'. - if (Line.First.is(tok::kw_for) && Left.is(tok::equal)) + if (Line.First->is(tok::kw_for) && Left.is(tok::equal)) return 4; // In Objective-C method expressions, prefer breaking before "param:" over @@ -1029,8 +970,8 @@ unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line, if (Right.is(tok::lessless)) { if (Left.is(tok::string_literal)) { - StringRef Content = StringRef(Left.FormatTok->Tok.getLiteralData(), - Left.FormatTok->TokenLength); + StringRef Content = + StringRef(Left.Tok.getLiteralData(), Left.TokenLength); Content = Content.drop_back(1).drop_front(1).trim(); if (Content.size() > 1 && (Content.back() == ':' || Content.back() == '=')) @@ -1040,7 +981,7 @@ unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line, } if (Left.Type == TT_ConditionalExpr) return prec::Conditional; - prec::Level Level = getPrecedence(Left); + prec::Level Level = Left.getPrecedence(); if (Level != prec::Unknown) return Level; @@ -1049,8 +990,8 @@ unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line, } bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, - const AnnotatedToken &Left, - const AnnotatedToken &Right) { + const FormatToken &Left, + const FormatToken &Right) { if (Right.is(tok::hashhash)) return Left.is(tok::hash); if (Left.isOneOf(tok::hashhash, tok::hash)) @@ -1077,18 +1018,18 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, if (Left.is(tok::less) || Right.isOneOf(tok::greater, tok::less)) return false; if (Right.Type == TT_PointerOrReference) - return Left.FormatTok->Tok.isLiteral() || + return Left.Tok.isLiteral() || ((Left.Type != TT_PointerOrReference) && Left.isNot(tok::l_paren) && !Style.PointerBindsToType); if (Right.Type == TT_FunctionTypeLParen && Left.isNot(tok::l_paren) && (Left.Type != TT_PointerOrReference || Style.PointerBindsToType)) return true; if (Left.Type == TT_PointerOrReference) - return Right.FormatTok->Tok.isLiteral() || + return Right.Tok.isLiteral() || ((Right.Type != TT_PointerOrReference) && Right.isNot(tok::l_paren) && Style.PointerBindsToType && - Left.Parent && - !Left.Parent->isOneOf(tok::l_paren, tok::coloncolon)); + Left.Previous && + !Left.Previous->isOneOf(tok::l_paren, tok::coloncolon)); if (Right.is(tok::star) && Left.is(tok::l_paren)) return false; if (Left.is(tok::l_square)) @@ -1109,8 +1050,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, tok::kw_return, tok::kw_catch, tok::kw_new, tok::kw_delete, tok::semi); } - if (Left.is(tok::at) && - Right.FormatTok->Tok.getObjCKeywordID() != tok::objc_not_keyword) + if (Left.is(tok::at) && Right.Tok.getObjCKeywordID() != tok::objc_not_keyword) return false; if (Left.is(tok::l_brace) && Right.is(tok::r_brace)) return false; // No spaces in "{}". @@ -1130,58 +1070,58 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, } bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, - const AnnotatedToken &Tok) { - if (Tok.FormatTok->Tok.getIdentifierInfo() && - Tok.Parent->FormatTok->Tok.getIdentifierInfo()) + const FormatToken &Tok) { + if (Tok.Tok.getIdentifierInfo() && Tok.Previous->Tok.getIdentifierInfo()) return true; // Never ever merge two identifiers. if (Line.Type == LT_ObjCMethodDecl) { - if (Tok.Parent->Type == TT_ObjCMethodSpecifier) + if (Tok.Previous->Type == TT_ObjCMethodSpecifier) return true; - if (Tok.Parent->is(tok::r_paren) && Tok.is(tok::identifier)) + if (Tok.Previous->is(tok::r_paren) && Tok.is(tok::identifier)) // Don't space between ')' and <id> return false; } if (Line.Type == LT_ObjCProperty && - (Tok.is(tok::equal) || Tok.Parent->is(tok::equal))) + (Tok.is(tok::equal) || Tok.Previous->is(tok::equal))) return false; - if (Tok.Parent->is(tok::comma)) + if (Tok.Previous->is(tok::comma)) return true; if (Tok.is(tok::comma)) return false; if (Tok.Type == TT_CtorInitializerColon || Tok.Type == TT_ObjCBlockLParen) return true; - if (Tok.Parent->FormatTok->Tok.is(tok::kw_operator)) + if (Tok.Previous->Tok.is(tok::kw_operator)) return false; if (Tok.Type == TT_OverloadedOperatorLParen) return false; if (Tok.is(tok::colon)) - return !Line.First.isOneOf(tok::kw_case, tok::kw_default) && + return !Line.First->isOneOf(tok::kw_case, tok::kw_default) && Tok.getNextNoneComment() != NULL && Tok.Type != TT_ObjCMethodExpr; - if (Tok.Parent->Type == TT_UnaryOperator || Tok.Parent->Type == TT_CastRParen) + if (Tok.Previous->Type == TT_UnaryOperator || + Tok.Previous->Type == TT_CastRParen) return false; - if (Tok.Parent->is(tok::greater) && Tok.is(tok::greater)) { + if (Tok.Previous->is(tok::greater) && Tok.is(tok::greater)) { return Tok.Type == TT_TemplateCloser && - Tok.Parent->Type == TT_TemplateCloser && + Tok.Previous->Type == TT_TemplateCloser && Style.Standard != FormatStyle::LS_Cpp11; } if (Tok.isOneOf(tok::arrowstar, tok::periodstar) || - Tok.Parent->isOneOf(tok::arrowstar, tok::periodstar)) + Tok.Previous->isOneOf(tok::arrowstar, tok::periodstar)) return false; - if (Tok.Type == TT_BinaryOperator || Tok.Parent->Type == TT_BinaryOperator) + if (Tok.Type == TT_BinaryOperator || Tok.Previous->Type == TT_BinaryOperator) return true; - if (Tok.Parent->Type == TT_TemplateCloser && Tok.is(tok::l_paren)) + if (Tok.Previous->Type == TT_TemplateCloser && Tok.is(tok::l_paren)) return false; - if (Tok.is(tok::less) && Line.First.is(tok::hash)) + if (Tok.is(tok::less) && Line.First->is(tok::hash)) return true; if (Tok.Type == TT_TrailingUnaryOperator) return false; - return spaceRequiredBetween(Line, *Tok.Parent, Tok); + return spaceRequiredBetween(Line, *Tok.Previous, Tok); } bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, - const AnnotatedToken &Right) { - const AnnotatedToken &Left = *Right.Parent; + const FormatToken &Right) { + const FormatToken &Left = *Right.Previous; if (Right.Type == TT_StartOfName) return true; if (Right.is(tok::colon) && @@ -1209,8 +1149,8 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, return false; if (Left.is(tok::equal) && Line.Type == LT_VirtualFunctionDecl) return false; - if (Left.is(tok::l_paren) && Right.is(tok::l_paren) && Left.Parent && - Left.Parent->is(tok::kw___attribute)) + if (Left.is(tok::l_paren) && Right.is(tok::l_paren) && Left.Previous && + Left.Previous->is(tok::kw___attribute)) return false; if (Right.Type == TT_LineComment) @@ -1225,8 +1165,8 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, // 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 && - Left.Parent->is(tok::r_paren)) + if (Left.is(tok::kw_const) && Left.Previous != NULL && + Left.Previous->is(tok::r_paren)) return !Right.isOneOf(tok::l_brace, tok::semi, tok::equal); if (Right.is(tok::kw___attribute)) @@ -1246,17 +1186,16 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, void TokenAnnotator::printDebugInfo(const AnnotatedLine &Line) { llvm::errs() << "AnnotatedTokens:\n"; - const AnnotatedToken *Tok = &Line.First; + const FormatToken *Tok = Line.First; while (Tok) { - llvm::errs() - << " M=" << Tok->MustBreakBefore << " C=" << Tok->CanBreakBefore - << " T=" << Tok->Type << " S=" << Tok->SpacesRequiredBefore - << " P=" << Tok->SplitPenalty - << " Name=" << Tok->FormatTok->Tok.getName() << " FakeLParens="; + llvm::errs() << " M=" << Tok->MustBreakBefore + << " C=" << Tok->CanBreakBefore << " T=" << Tok->Type << " S=" + << Tok->SpacesRequiredBefore << " P=" << Tok->SplitPenalty + << " Name=" << Tok->Tok.getName() << " FakeLParens="; for (unsigned i = 0, e = Tok->FakeLParens.size(); i != e; ++i) llvm::errs() << Tok->FakeLParens[i] << "/"; llvm::errs() << " FakeRParens=" << Tok->FakeRParens << "\n"; - Tok = Tok->Children.empty() ? NULL : &Tok->Children[0]; + Tok = Tok->Next; } llvm::errs() << "----\n"; } diff --git a/clang/lib/Format/TokenAnnotator.h b/clang/lib/Format/TokenAnnotator.h index dba5e4d44c8..a0d680c91df 100644 --- a/clang/lib/Format/TokenAnnotator.h +++ b/clang/lib/Format/TokenAnnotator.h @@ -17,7 +17,6 @@ #define LLVM_CLANG_FORMAT_TOKEN_ANNOTATOR_H #include "UnwrappedLineParser.h" -#include "clang/Basic/OperatorPrecedence.h" #include "clang/Format/Format.h" #include <string> @@ -27,40 +26,6 @@ class SourceManager; namespace format { -enum TokenType { - TT_BinaryOperator, - TT_BlockComment, - TT_CastRParen, - TT_ConditionalExpr, - TT_CtorInitializerColon, - TT_DesignatedInitializerPeriod, - TT_ImplicitStringLiteral, - TT_InlineASMColon, - TT_InheritanceColon, - TT_FunctionTypeLParen, - TT_LineComment, - TT_ObjCArrayLiteral, - TT_ObjCBlockLParen, - TT_ObjCDecl, - TT_ObjCDictLiteral, - TT_ObjCForIn, - TT_ObjCMethodExpr, - TT_ObjCMethodSpecifier, - TT_ObjCProperty, - TT_ObjCSelectorName, - TT_OverloadedOperator, - TT_OverloadedOperatorLParen, - TT_PointerOrReference, - TT_PureVirtualSpecifier, - TT_RangeBasedForLoopColon, - TT_StartOfName, - TT_TemplateCloser, - TT_TemplateOpener, - TT_TrailingUnaryOperator, - TT_UnaryOperator, - TT_Unknown -}; - enum LineType { LT_Invalid, LT_Other, @@ -72,133 +37,6 @@ enum LineType { LT_ObjCProperty // An @property line. }; -class AnnotatedToken { -public: - explicit AnnotatedToken(FormatToken *FormatTok) - : FormatTok(FormatTok), Type(TT_Unknown), SpacesRequiredBefore(0), - CanBreakBefore(false), MustBreakBefore(false), - ClosesTemplateDeclaration(false), MatchingParen(NULL), - ParameterCount(0), TotalLength(FormatTok->TokenLength), - UnbreakableTailLength(0), BindingStrength(0), SplitPenalty(0), - LongestObjCSelectorName(0), Parent(NULL), FakeRParens(0), - LastInChainOfCalls(false), PartOfMultiVariableDeclStmt(false) {} - - bool is(tok::TokenKind Kind) const { return FormatTok->Tok.is(Kind); } - - bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const { - return is(K1) || is(K2); - } - - bool isOneOf(tok::TokenKind K1, tok::TokenKind K2, tok::TokenKind K3) const { - return is(K1) || is(K2) || is(K3); - } - - bool isOneOf( - tok::TokenKind K1, tok::TokenKind K2, tok::TokenKind K3, - tok::TokenKind K4, tok::TokenKind K5 = tok::NUM_TOKENS, - tok::TokenKind K6 = tok::NUM_TOKENS, tok::TokenKind K7 = tok::NUM_TOKENS, - tok::TokenKind K8 = tok::NUM_TOKENS, tok::TokenKind K9 = tok::NUM_TOKENS, - tok::TokenKind K10 = tok::NUM_TOKENS, - tok::TokenKind K11 = tok::NUM_TOKENS, - tok::TokenKind K12 = tok::NUM_TOKENS) const { - return is(K1) || is(K2) || is(K3) || is(K4) || is(K5) || is(K6) || is(K7) || - is(K8) || is(K9) || is(K10) || is(K11) || is(K12); - } - - bool isNot(tok::TokenKind Kind) const { return FormatTok->Tok.isNot(Kind); } - - bool isObjCAtKeyword(tok::ObjCKeywordKind Kind) const { - return FormatTok->Tok.isObjCAtKeyword(Kind); - } - - bool isAccessSpecifier(bool ColonRequired = true) const { - return isOneOf(tok::kw_public, tok::kw_protected, tok::kw_private) && - (!ColonRequired || - (!Children.empty() && Children[0].is(tok::colon))); - } - - bool isObjCAccessSpecifier() const { - return is(tok::at) && !Children.empty() && - (Children[0].isObjCAtKeyword(tok::objc_public) || - Children[0].isObjCAtKeyword(tok::objc_protected) || - Children[0].isObjCAtKeyword(tok::objc_package) || - Children[0].isObjCAtKeyword(tok::objc_private)); - } - - /// \brief Returns whether \p Tok is ([{ or a template opening <. - bool opensScope() const; - /// \brief Returns whether \p Tok is )]} or a template opening >. - bool closesScope() const; - - bool isUnaryOperator() const; - bool isBinaryOperator() const; - bool isTrailingComment() const; - - FormatToken *FormatTok; - - TokenType Type; - - unsigned SpacesRequiredBefore; - bool CanBreakBefore; - bool MustBreakBefore; - - bool ClosesTemplateDeclaration; - - AnnotatedToken *MatchingParen; - - /// \brief Number of parameters, if this is "(", "[" or "<". - /// - /// This is initialized to 1 as we don't need to distinguish functions with - /// 0 parameters from functions with 1 parameter. Thus, we can simply count - /// the number of commas. - unsigned ParameterCount; - - /// \brief The total length of the line up to and including this token. - unsigned TotalLength; - - /// \brief The length of following tokens until the next natural split point, - /// or the next token that can be broken. - unsigned UnbreakableTailLength; - - // FIXME: Come up with a 'cleaner' concept. - /// \brief The binding strength of a token. This is a combined value of - /// operator precedence, parenthesis nesting, etc. - unsigned BindingStrength; - - /// \brief Penalty for inserting a line break before this token. - unsigned SplitPenalty; - - /// \brief If this is the first ObjC selector name in an ObjC method - /// definition or call, this contains the length of the longest name. - unsigned LongestObjCSelectorName; - - std::vector<AnnotatedToken> Children; - AnnotatedToken *Parent; - - /// \brief Stores the number of required fake parentheses and the - /// corresponding operator precedence. - /// - /// If multiple fake parentheses start at a token, this vector stores them in - /// reverse order, i.e. inner fake parenthesis first. - SmallVector<prec::Level, 4> FakeLParens; - /// \brief Insert this many fake ) after this token for correct indentation. - unsigned FakeRParens; - - /// \brief Is this the last "." or "->" in a builder-type call? - bool LastInChainOfCalls; - - /// \brief Is this token part of a \c DeclStmt defining multiple variables? - /// - /// Only set if \c Type == \c TT_StartOfName. - bool PartOfMultiVariableDeclStmt; - - /// \brief Returns the previous token ignoring comments. - AnnotatedToken *getPreviousNoneComment() const; - - /// \brief Returns the next token ignoring comments. - const AnnotatedToken *getNextNoneComment() const; -}; - class AnnotatedLine { public: AnnotatedLine(const UnwrappedLine &Line) @@ -207,31 +45,19 @@ public: MustBeDeclaration(Line.MustBeDeclaration), MightBeFunctionDecl(false), StartsDefinition(false) { assert(!Line.Tokens.empty()); - AnnotatedToken *Current = &First; + FormatToken *Current = First; for (std::list<FormatToken *>::const_iterator I = ++Line.Tokens.begin(), E = Line.Tokens.end(); I != E; ++I) { - Current->Children.push_back(AnnotatedToken(*I)); - Current->Children[0].Parent = Current; - Current = &Current->Children[0]; + Current->Next = *I; + (*I)->Previous = Current; + Current = Current->Next; } Last = Current; } - AnnotatedLine(const AnnotatedLine &Other) - : First(Other.First), Type(Other.Type), Level(Other.Level), - InPPDirective(Other.InPPDirective), - MustBeDeclaration(Other.MustBeDeclaration), - MightBeFunctionDecl(Other.MightBeFunctionDecl), - StartsDefinition(Other.StartsDefinition) { - Last = &First; - while (!Last->Children.empty()) { - Last->Children[0].Parent = Last; - Last = &Last->Children[0]; - } - } - AnnotatedToken First; - AnnotatedToken *Last; + FormatToken *First; + FormatToken *Last; LineType Type; unsigned Level; @@ -241,10 +67,6 @@ public: bool StartsDefinition; }; -inline prec::Level getPrecedence(const AnnotatedToken &Tok) { - return getBinOpPrecedence(Tok.FormatTok->Tok.getKind(), true, true); -} - /// \brief Determines extra information about the tokens comprising an /// \c UnwrappedLine. class TokenAnnotator { @@ -259,16 +81,14 @@ public: private: /// \brief Calculate the penalty for splitting before \c Tok. - unsigned splitPenalty(const AnnotatedLine &Line, const AnnotatedToken &Tok); + unsigned splitPenalty(const AnnotatedLine &Line, const FormatToken &Tok); - bool spaceRequiredBetween(const AnnotatedLine &Line, - const AnnotatedToken &Left, - const AnnotatedToken &Right); + bool spaceRequiredBetween(const AnnotatedLine &Line, const FormatToken &Left, + const FormatToken &Right); - bool spaceRequiredBefore(const AnnotatedLine &Line, - const AnnotatedToken &Tok); + bool spaceRequiredBefore(const AnnotatedLine &Line, const FormatToken &Tok); - bool canBreakBefore(const AnnotatedLine &Line, const AnnotatedToken &Right); + bool canBreakBefore(const AnnotatedLine &Line, const FormatToken &Right); void printDebugInfo(const AnnotatedLine &Line); diff --git a/clang/lib/Format/UnwrappedLineParser.h b/clang/lib/Format/UnwrappedLineParser.h index 8e925597422..350885e2c80 100644 --- a/clang/lib/Format/UnwrappedLineParser.h +++ b/clang/lib/Format/UnwrappedLineParser.h @@ -17,6 +17,7 @@ #define LLVM_CLANG_FORMAT_UNWRAPPED_LINE_PARSER_H #include "clang/Basic/IdentifierTable.h" +#include "clang/Basic/OperatorPrecedence.h" #include "clang/Format/Format.h" #include "clang/Lex/Lexer.h" #include <list> @@ -24,12 +25,52 @@ namespace clang { namespace format { +enum TokenType { + TT_BinaryOperator, + TT_BlockComment, + TT_CastRParen, + TT_ConditionalExpr, + TT_CtorInitializerColon, + TT_DesignatedInitializerPeriod, + TT_ImplicitStringLiteral, + TT_InlineASMColon, + TT_InheritanceColon, + TT_FunctionTypeLParen, + TT_LineComment, + TT_ObjCArrayLiteral, + TT_ObjCBlockLParen, + TT_ObjCDecl, + TT_ObjCDictLiteral, + TT_ObjCForIn, + TT_ObjCMethodExpr, + TT_ObjCMethodSpecifier, + TT_ObjCProperty, + TT_ObjCSelectorName, + TT_OverloadedOperator, + TT_OverloadedOperatorLParen, + TT_PointerOrReference, + TT_PureVirtualSpecifier, + TT_RangeBasedForLoopColon, + TT_StartOfName, + TT_TemplateCloser, + TT_TemplateOpener, + TT_TrailingUnaryOperator, + TT_UnaryOperator, + TT_Unknown +}; + /// \brief A wrapper around a \c Token storing information about the /// whitespace characters preceeding it. struct FormatToken { FormatToken() : NewlinesBefore(0), HasUnescapedNewline(false), LastNewlineOffset(0), - TokenLength(0), IsFirst(false), MustBreakBefore(false) {} + TokenLength(0), IsFirst(false), MustBreakBefore(false), + Type(TT_Unknown), SpacesRequiredBefore(0), CanBreakBefore(false), + ClosesTemplateDeclaration(false), ParameterCount(0), TotalLength(0), + UnbreakableTailLength(0), BindingStrength(0), SplitPenalty(0), + LongestObjCSelectorName(0), FakeRParens(0), LastInChainOfCalls(false), + PartOfMultiVariableDeclStmt(false), MatchingParen(NULL), Previous(NULL), + Next(NULL) {} /// \brief The \c Token. Token Tok; @@ -80,6 +121,157 @@ struct FormatToken { /// escaped newlines. StringRef TokenText; + TokenType Type; + + unsigned SpacesRequiredBefore; + bool CanBreakBefore; + + bool ClosesTemplateDeclaration; + + /// \brief Number of parameters, if this is "(", "[" or "<". + /// + /// This is initialized to 1 as we don't need to distinguish functions with + /// 0 parameters from functions with 1 parameter. Thus, we can simply count + /// the number of commas. + unsigned ParameterCount; + + /// \brief The total length of the line up to and including this token. + unsigned TotalLength; + + /// \brief The length of following tokens until the next natural split point, + /// or the next token that can be broken. + unsigned UnbreakableTailLength; + + // FIXME: Come up with a 'cleaner' concept. + /// \brief The binding strength of a token. This is a combined value of + /// operator precedence, parenthesis nesting, etc. + unsigned BindingStrength; + + /// \brief Penalty for inserting a line break before this token. + unsigned SplitPenalty; + + /// \brief If this is the first ObjC selector name in an ObjC method + /// definition or call, this contains the length of the longest name. + unsigned LongestObjCSelectorName; + + /// \brief Stores the number of required fake parentheses and the + /// corresponding operator precedence. + /// + /// If multiple fake parentheses start at a token, this vector stores them in + /// reverse order, i.e. inner fake parenthesis first. + SmallVector<prec::Level, 4> FakeLParens; + /// \brief Insert this many fake ) after this token for correct indentation. + unsigned FakeRParens; + + /// \brief Is this the last "." or "->" in a builder-type call? + bool LastInChainOfCalls; + + /// \brief Is this token part of a \c DeclStmt defining multiple variables? + /// + /// Only set if \c Type == \c TT_StartOfName. + bool PartOfMultiVariableDeclStmt; + + bool is(tok::TokenKind Kind) const { return Tok.is(Kind); } + + bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const { + return is(K1) || is(K2); + } + + bool isOneOf(tok::TokenKind K1, tok::TokenKind K2, tok::TokenKind K3) const { + return is(K1) || is(K2) || is(K3); + } + + bool isOneOf(tok::TokenKind K1, tok::TokenKind K2, tok::TokenKind K3, + tok::TokenKind K4, tok::TokenKind K5 = tok::NUM_TOKENS, + tok::TokenKind K6 = tok::NUM_TOKENS, + tok::TokenKind K7 = tok::NUM_TOKENS, + tok::TokenKind K8 = tok::NUM_TOKENS, + tok::TokenKind K9 = tok::NUM_TOKENS, + tok::TokenKind K10 = tok::NUM_TOKENS, + tok::TokenKind K11 = tok::NUM_TOKENS, + tok::TokenKind K12 = tok::NUM_TOKENS) const { + return is(K1) || is(K2) || is(K3) || is(K4) || is(K5) || is(K6) || is(K7) || + is(K8) || is(K9) || is(K10) || is(K11) || is(K12); + } + + bool isNot(tok::TokenKind Kind) const { return Tok.isNot(Kind); } + + bool isObjCAtKeyword(tok::ObjCKeywordKind Kind) const { + return Tok.isObjCAtKeyword(Kind); + } + + bool isAccessSpecifier(bool ColonRequired = true) const { + return isOneOf(tok::kw_public, tok::kw_protected, tok::kw_private) && + (!ColonRequired || (Next && Next->is(tok::colon))); + } + + bool isObjCAccessSpecifier() const { + return is(tok::at) && Next && (Next->isObjCAtKeyword(tok::objc_public) || + Next->isObjCAtKeyword(tok::objc_protected) || + Next->isObjCAtKeyword(tok::objc_package) || + Next->isObjCAtKeyword(tok::objc_private)); + } + + /// \brief Returns whether \p Tok is ([{ or a template opening <. + bool opensScope() const { + return isOneOf(tok::l_paren, tok::l_brace, tok::l_square) || + Type == TT_TemplateOpener; + + } + /// \brief Returns whether \p Tok is )]} or a template opening >. + bool closesScope() const { + return isOneOf(tok::r_paren, tok::r_brace, tok::r_square) || + Type == TT_TemplateCloser; + } + + bool isUnaryOperator() const { + switch (Tok.getKind()) { + case tok::plus: + case tok::plusplus: + case tok::minus: + case tok::minusminus: + case tok::exclaim: + case tok::tilde: + case tok::kw_sizeof: + case tok::kw_alignof: + return true; + default: + return false; + } + } + bool isBinaryOperator() const { + // Comma is a binary operator, but does not behave as such wrt. formatting. + return getPrecedence() > prec::Comma; + } + bool isTrailingComment() const { + return is(tok::comment) && (!Next || Next->NewlinesBefore > 0); + } + + prec::Level getPrecedence() const { + return getBinOpPrecedence(Tok.getKind(), true, true); + } + + /// \brief Returns the previous token ignoring comments. + FormatToken *getPreviousNoneComment() const { + FormatToken *Tok = Previous; + while (Tok != NULL && Tok->is(tok::comment)) + Tok = Tok->Previous; + return Tok; + } + + /// \brief Returns the next token ignoring comments. + const FormatToken *getNextNoneComment() const { + const FormatToken *Tok = Next; + while (Tok != NULL && Tok->is(tok::comment)) + Tok = Tok->Next; + return Tok; + } + + FormatToken *MatchingParen; + + FormatToken *Previous; + FormatToken *Next; + private: // Disallow copying. FormatToken(const FormatToken &); diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index 069b0c497d1..e6e4e015f95 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -38,14 +38,13 @@ WhitespaceManager::Change::Change( CurrentLinePrefix(CurrentLinePrefix), Kind(Kind), ContinuesPPDirective(ContinuesPPDirective), Spaces(Spaces) {} -void WhitespaceManager::replaceWhitespace(const AnnotatedToken &Tok, +void WhitespaceManager::replaceWhitespace(const FormatToken &Tok, unsigned Newlines, unsigned Spaces, unsigned StartOfTokenColumn, bool InPPDirective) { Changes.push_back( - Change(true, Tok.FormatTok->WhitespaceRange, Spaces, StartOfTokenColumn, - Newlines, "", "", Tok.FormatTok->Tok.getKind(), - InPPDirective && !Tok.FormatTok->IsFirst)); + Change(true, Tok.WhitespaceRange, Spaces, StartOfTokenColumn, Newlines, + "", "", Tok.Tok.getKind(), InPPDirective && !Tok.IsFirst)); } void WhitespaceManager::addUntouchableToken(const FormatToken &Tok, diff --git a/clang/lib/Format/WhitespaceManager.h b/clang/lib/Format/WhitespaceManager.h index cdd8f1d10f3..25b7690a154 100644 --- a/clang/lib/Format/WhitespaceManager.h +++ b/clang/lib/Format/WhitespaceManager.h @@ -42,7 +42,7 @@ public: /// \brief Replaces the whitespace in front of \p Tok. Only call once for /// each \c AnnotatedToken. - void replaceWhitespace(const AnnotatedToken &Tok, unsigned Newlines, + void replaceWhitespace(const FormatToken &Tok, unsigned Newlines, unsigned Spaces, unsigned StartOfTokenColumn, bool InPPDirective = false); |