diff options
| author | 2017-10-04 20:27:34 +0000 | |
|---|---|---|
| committer | 2017-10-04 20:27:34 +0000 | |
| commit | 31eb748944903b7f4f38afda9851951ca9dfc1ae (patch) | |
| tree | 9b95b6ea45d0874d75eb05b90c0840e191416439 /gnu/llvm/tools/clang/lib/Format/UnwrappedLineFormatter.cpp | |
| parent | Don't try to handle IPv4-compatible IPv6 addresses (diff) | |
| download | wireguard-openbsd-31eb748944903b7f4f38afda9851951ca9dfc1ae.tar.xz wireguard-openbsd-31eb748944903b7f4f38afda9851951ca9dfc1ae.zip | |
Import LLVM 5.0.0 release including clang, lld and lldb.
Diffstat (limited to 'gnu/llvm/tools/clang/lib/Format/UnwrappedLineFormatter.cpp')
| -rw-r--r-- | gnu/llvm/tools/clang/lib/Format/UnwrappedLineFormatter.cpp | 163 |
1 files changed, 127 insertions, 36 deletions
diff --git a/gnu/llvm/tools/clang/lib/Format/UnwrappedLineFormatter.cpp b/gnu/llvm/tools/clang/lib/Format/UnwrappedLineFormatter.cpp index d7f1c4232d8..2005a282292 100644 --- a/gnu/llvm/tools/clang/lib/Format/UnwrappedLineFormatter.cpp +++ b/gnu/llvm/tools/clang/lib/Format/UnwrappedLineFormatter.cpp @@ -66,6 +66,13 @@ public: Indent += Offset; } + /// \brief Update the indent state given that \p Line indent should be + /// skipped. + void skipLine(const AnnotatedLine &Line) { + while (IndentForLevel.size() <= Line.Level) + IndentForLevel.push_back(Indent); + } + /// \brief Update the level indent to adapt to the given \p Line. /// /// When a line is not formatted, we move the subsequent lines on the same @@ -127,12 +134,28 @@ private: unsigned Indent = 0; }; +bool isNamespaceDeclaration(const AnnotatedLine *Line) { + const FormatToken *NamespaceTok = Line->First; + return NamespaceTok && NamespaceTok->getNamespaceToken(); +} + +bool isEndOfNamespace(const AnnotatedLine *Line, + const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) { + if (!Line->startsWith(tok::r_brace)) + return false; + size_t StartLineIndex = Line->MatchingOpeningBlockLineIndex; + if (StartLineIndex == UnwrappedLine::kInvalidIndex) + return false; + assert(StartLineIndex < AnnotatedLines.size()); + return isNamespaceDeclaration(AnnotatedLines[StartLineIndex]); +} + class LineJoiner { public: LineJoiner(const FormatStyle &Style, const AdditionalKeywords &Keywords, const SmallVectorImpl<AnnotatedLine *> &Lines) - : Style(Style), Keywords(Keywords), End(Lines.end()), - Next(Lines.begin()) {} + : Style(Style), Keywords(Keywords), End(Lines.end()), Next(Lines.begin()), + AnnotatedLines(Lines) {} /// \brief Returns the next line, merging multiple lines into one if possible. const AnnotatedLine *getNextMergedLine(bool DryRun, @@ -142,7 +165,7 @@ public: const AnnotatedLine *Current = *Next; IndentTracker.nextLine(*Current); unsigned MergedLines = - tryFitMultipleLinesInOne(IndentTracker.getIndent(), Next, End); + tryFitMultipleLinesInOne(IndentTracker, Next, End); if (MergedLines > 0 && Style.ColumnLimit == 0) // Disallow line merging if there is a break at the start of one of the // input lines. @@ -159,9 +182,11 @@ public: private: /// \brief Calculates how many lines can be merged into 1 starting at \p I. unsigned - tryFitMultipleLinesInOne(unsigned Indent, + tryFitMultipleLinesInOne(LevelIndentTracker &IndentTracker, SmallVectorImpl<AnnotatedLine *>::const_iterator I, SmallVectorImpl<AnnotatedLine *>::const_iterator E) { + const unsigned Indent = IndentTracker.getIndent(); + // Can't join the last line with anything. if (I + 1 == E) return 0; @@ -186,15 +211,74 @@ private: ? 0 : Limit - TheLine->Last->TotalLength; + if (TheLine->Last->is(TT_FunctionLBrace) && + TheLine->First == TheLine->Last && + !Style.BraceWrapping.SplitEmptyFunction && + I[1]->First->is(tok::r_brace)) + return tryMergeSimpleBlock(I, E, Limit); + + // Handle empty record blocks where the brace has already been wrapped + if (TheLine->Last->is(tok::l_brace) && TheLine->First == TheLine->Last && + I != AnnotatedLines.begin()) { + bool EmptyBlock = I[1]->First->is(tok::r_brace); + + const FormatToken *Tok = I[-1]->First; + if (Tok && Tok->is(tok::comment)) + Tok = Tok->getNextNonComment(); + + if (Tok && Tok->getNamespaceToken()) + return !Style.BraceWrapping.SplitEmptyNamespace && EmptyBlock + ? tryMergeSimpleBlock(I, E, Limit) : 0; + + if (Tok && Tok->is(tok::kw_typedef)) + Tok = Tok->getNextNonComment(); + if (Tok && Tok->isOneOf(tok::kw_class, tok::kw_struct, tok::kw_union, + Keywords.kw_interface)) + return !Style.BraceWrapping.SplitEmptyRecord && EmptyBlock + ? tryMergeSimpleBlock(I, E, Limit) : 0; + } + // FIXME: TheLine->Level != 0 might or might not be the right check to do. // If necessary, change to something smarter. bool MergeShortFunctions = Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_All || (Style.AllowShortFunctionsOnASingleLine >= FormatStyle::SFS_Empty && I[1]->First->is(tok::r_brace)) || - (Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Inline && + (Style.AllowShortFunctionsOnASingleLine & FormatStyle::SFS_InlineOnly && TheLine->Level != 0); + if (Style.CompactNamespaces) { + if (isNamespaceDeclaration(TheLine)) { + int i = 0; + unsigned closingLine = TheLine->MatchingOpeningBlockLineIndex - 1; + for (; I + 1 + i != E && isNamespaceDeclaration(I[i + 1]) && + closingLine == I[i + 1]->MatchingOpeningBlockLineIndex && + I[i + 1]->Last->TotalLength < Limit; + i++, closingLine--) { + // No extra indent for compacted namespaces + IndentTracker.skipLine(*I[i + 1]); + + Limit -= I[i + 1]->Last->TotalLength; + } + return i; + } + + if (isEndOfNamespace(TheLine, AnnotatedLines)) { + int i = 0; + unsigned openingLine = TheLine->MatchingOpeningBlockLineIndex - 1; + for (; I + 1 + i != E && isEndOfNamespace(I[i + 1], AnnotatedLines) && + openingLine == I[i + 1]->MatchingOpeningBlockLineIndex; + i++, openingLine--) { + // No space between consecutive braces + I[i + 1]->First->SpacesRequiredBefore = !I[i]->Last->is(tok::r_brace); + + // Indent like the outer-most namespace + IndentTracker.nextLine(*I[i + 1]); + } + return i; + } + } + if (TheLine->Last->is(TT_FunctionLBrace) && TheLine->First != TheLine->Last) { return MergeShortFunctions ? tryMergeSimpleBlock(I, E, Limit) : 0; @@ -215,7 +299,10 @@ private: Limit -= 2; unsigned MergedLines = 0; - if (MergeShortFunctions) { + if (MergeShortFunctions || + (Style.AllowShortFunctionsOnASingleLine >= FormatStyle::SFS_Empty && + I[1]->First == I[1]->Last && I + 2 != E && + I[2]->First->is(tok::r_brace))) { MergedLines = tryMergeSimpleBlock(I + 1, E, Limit); // If we managed to merge the block, count the function header, which is // on a separate line. @@ -365,8 +452,11 @@ private: } else if (Limit != 0 && !Line.startsWith(tok::kw_namespace) && !startsExternCBlock(Line)) { // We don't merge short records. - if (Line.First->isOneOf(tok::kw_class, tok::kw_union, tok::kw_struct, - Keywords.kw_interface)) + FormatToken *RecordTok = + Line.First->is(tok::kw_typedef) ? Line.First->Next : Line.First; + if (RecordTok && + RecordTok->isOneOf(tok::kw_class, tok::kw_union, tok::kw_struct, + Keywords.kw_interface)) return 0; // Check that we still have three lines and they fit into the limit. @@ -449,6 +539,7 @@ private: const SmallVectorImpl<AnnotatedLine *>::const_iterator End; SmallVectorImpl<AnnotatedLine *>::const_iterator Next; + const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines; }; static void markFinalized(FormatToken *Tok) { @@ -530,34 +621,33 @@ protected: if (Previous.Children[0]->First->MustBreakBefore) return false; - // Cannot merge multiple statements into a single line. - if (Previous.Children.size() > 1) - return false; - // Cannot merge into one line if this line ends on a comment. if (Previous.is(tok::comment)) return false; + // Cannot merge multiple statements into a single line. + if (Previous.Children.size() > 1) + return false; + + const AnnotatedLine *Child = Previous.Children[0]; // We can't put the closing "}" on a line with a trailing comment. - if (Previous.Children[0]->Last->isTrailingComment()) + if (Child->Last->isTrailingComment()) return false; // If the child line exceeds the column limit, we wouldn't want to merge it. // We add +2 for the trailing " }". if (Style.ColumnLimit > 0 && - Previous.Children[0]->Last->TotalLength + State.Column + 2 > - Style.ColumnLimit) + Child->Last->TotalLength + State.Column + 2 > Style.ColumnLimit) return false; if (!DryRun) { Whitespaces->replaceWhitespace( - *Previous.Children[0]->First, - /*Newlines=*/0, /*IndentLevel=*/0, /*Spaces=*/1, + *Child->First, /*Newlines=*/0, /*Spaces=*/1, /*StartOfTokenColumn=*/State.Column, State.Line->InPPDirective); } - Penalty += formatLine(*Previous.Children[0], State.Column + 1, DryRun); + Penalty += formatLine(*Child, State.Column + 1, DryRun); - State.Column += 1 + Previous.Children[0]->Last->TotalLength; + State.Column += 1 + Child->Last->TotalLength; return true; } @@ -612,7 +702,8 @@ public: LineState State = Indenter->getInitialState(FirstIndent, &Line, DryRun); while (State.NextToken) { formatChildren(State, /*Newline=*/false, DryRun, Penalty); - Indenter->addTokenToState(State, /*Newline=*/false, DryRun); + Indenter->addTokenToState( + State, /*Newline=*/State.NextToken->MustBreakBefore, DryRun); } return Penalty; } @@ -836,13 +927,15 @@ UnwrappedLineFormatter::format(const SmallVectorImpl<AnnotatedLine *> &Lines, bool ShouldFormat = TheLine.Affected || FixIndentation; // We cannot format this line; if the reason is that the line had a // parsing error, remember that. - if (ShouldFormat && TheLine.Type == LT_Invalid && IncompleteFormat) - *IncompleteFormat = true; + if (ShouldFormat && TheLine.Type == LT_Invalid && Status) { + Status->FormatComplete = false; + Status->Line = + SourceMgr.getSpellingLineNumber(TheLine.First->Tok.getLocation()); + } if (ShouldFormat && TheLine.Type != LT_Invalid) { if (!DryRun) - formatFirstToken(*TheLine.First, PreviousLine, TheLine.Level, Indent, - TheLine.InPPDirective); + formatFirstToken(TheLine, PreviousLine, Indent); NextLine = Joiner.getNextMergedLine(DryRun, IndentTracker); unsigned ColumnLimit = getColumnLimit(TheLine.InPPDirective, NextLine); @@ -882,9 +975,8 @@ UnwrappedLineFormatter::format(const SmallVectorImpl<AnnotatedLine *> &Lines, TheLine.LeadingEmptyLinesAffected); // Format the first token. if (ReformatLeadingWhitespace) - formatFirstToken(*TheLine.First, PreviousLine, TheLine.Level, - TheLine.First->OriginalColumn, - TheLine.InPPDirective); + formatFirstToken(TheLine, PreviousLine, + TheLine.First->OriginalColumn); else Whitespaces->addUntouchableToken(*TheLine.First, TheLine.InPPDirective); @@ -904,15 +996,14 @@ UnwrappedLineFormatter::format(const SmallVectorImpl<AnnotatedLine *> &Lines, return Penalty; } -void UnwrappedLineFormatter::formatFirstToken(FormatToken &RootToken, +void UnwrappedLineFormatter::formatFirstToken(const AnnotatedLine &Line, const AnnotatedLine *PreviousLine, - unsigned IndentLevel, - unsigned Indent, - bool InPPDirective) { + unsigned Indent) { + FormatToken& RootToken = *Line.First; if (RootToken.is(tok::eof)) { unsigned Newlines = std::min(RootToken.NewlinesBefore, 1u); - Whitespaces->replaceWhitespace(RootToken, Newlines, /*IndentLevel=*/0, - /*Spaces=*/0, /*TargetColumn=*/0); + Whitespaces->replaceWhitespace(RootToken, Newlines, /*Spaces=*/0, + /*StartOfTokenColumn=*/0); return; } unsigned Newlines = @@ -944,9 +1035,9 @@ void UnwrappedLineFormatter::formatFirstToken(FormatToken &RootToken, (!PreviousLine->InPPDirective || !RootToken.HasUnescapedNewline)) Newlines = std::min(1u, Newlines); - Whitespaces->replaceWhitespace(RootToken, Newlines, IndentLevel, Indent, - Indent, InPPDirective && - !RootToken.HasUnescapedNewline); + Whitespaces->replaceWhitespace(RootToken, Newlines, Indent, Indent, + Line.InPPDirective && + !RootToken.HasUnescapedNewline); } unsigned |
