10b57cec5SDimitry Andric //===--- UnwrappedLineFormatter.cpp - Format C++ code ---------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "UnwrappedLineFormatter.h" 1006c3fb27SDimitry Andric #include "FormatToken.h" 110b57cec5SDimitry Andric #include "NamespaceEndCommentsFixer.h" 120b57cec5SDimitry Andric #include "WhitespaceManager.h" 130b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 140b57cec5SDimitry Andric #include <queue> 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #define DEBUG_TYPE "format-formatter" 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric namespace clang { 190b57cec5SDimitry Andric namespace format { 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric namespace { 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric bool startsExternCBlock(const AnnotatedLine &Line) { 240b57cec5SDimitry Andric const FormatToken *Next = Line.First->getNextNonComment(); 250b57cec5SDimitry Andric const FormatToken *NextNext = Next ? Next->getNextNonComment() : nullptr; 260b57cec5SDimitry Andric return Line.startsWith(tok::kw_extern) && Next && Next->isStringLiteral() && 270b57cec5SDimitry Andric NextNext && NextNext->is(tok::l_brace); 280b57cec5SDimitry Andric } 290b57cec5SDimitry Andric 3081ad6265SDimitry Andric bool isRecordLBrace(const FormatToken &Tok) { 3181ad6265SDimitry Andric return Tok.isOneOf(TT_ClassLBrace, TT_EnumLBrace, TT_RecordLBrace, 3281ad6265SDimitry Andric TT_StructLBrace, TT_UnionLBrace); 3381ad6265SDimitry Andric } 3481ad6265SDimitry Andric 350b57cec5SDimitry Andric /// Tracks the indent level of \c AnnotatedLines across levels. 360b57cec5SDimitry Andric /// 370b57cec5SDimitry Andric /// \c nextLine must be called for each \c AnnotatedLine, after which \c 380b57cec5SDimitry Andric /// getIndent() will return the indent for the last line \c nextLine was called 390b57cec5SDimitry Andric /// with. 400b57cec5SDimitry Andric /// If the line is not formatted (and thus the indent does not change), calling 410b57cec5SDimitry Andric /// \c adjustToUnmodifiedLine after the call to \c nextLine will cause 420b57cec5SDimitry Andric /// subsequent lines on the same level to be indented at the same level as the 430b57cec5SDimitry Andric /// given line. 440b57cec5SDimitry Andric class LevelIndentTracker { 450b57cec5SDimitry Andric public: 460b57cec5SDimitry Andric LevelIndentTracker(const FormatStyle &Style, 470b57cec5SDimitry Andric const AdditionalKeywords &Keywords, unsigned StartLevel, 480b57cec5SDimitry Andric int AdditionalIndent) 490b57cec5SDimitry Andric : Style(Style), Keywords(Keywords), AdditionalIndent(AdditionalIndent) { 500b57cec5SDimitry Andric for (unsigned i = 0; i != StartLevel; ++i) 510b57cec5SDimitry Andric IndentForLevel.push_back(Style.IndentWidth * i + AdditionalIndent); 520b57cec5SDimitry Andric } 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric /// Returns the indent for the current line. 550b57cec5SDimitry Andric unsigned getIndent() const { return Indent; } 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric /// Update the indent state given that \p Line is going to be formatted 580b57cec5SDimitry Andric /// next. 590b57cec5SDimitry Andric void nextLine(const AnnotatedLine &Line) { 60*0fca6ea1SDimitry Andric Offset = getIndentOffset(Line); 610b57cec5SDimitry Andric // Update the indent level cache size so that we can rely on it 620b57cec5SDimitry Andric // having the right size in adjustToUnmodifiedline. 6306c3fb27SDimitry Andric if (Line.Level >= IndentForLevel.size()) 6406c3fb27SDimitry Andric IndentForLevel.resize(Line.Level + 1, -1); 65bdd1243dSDimitry Andric if (Style.IndentPPDirectives != FormatStyle::PPDIS_None && 66bdd1243dSDimitry Andric (Line.InPPDirective || 67bdd1243dSDimitry Andric (Style.IndentPPDirectives == FormatStyle::PPDIS_BeforeHash && 68bdd1243dSDimitry Andric Line.Type == LT_CommentAbovePPDirective))) { 69bdd1243dSDimitry Andric unsigned PPIndentWidth = 70fe6060f1SDimitry Andric (Style.PPIndentWidth >= 0) ? Style.PPIndentWidth : Style.IndentWidth; 71bdd1243dSDimitry Andric Indent = Line.InMacroBody 72bdd1243dSDimitry Andric ? Line.PPLevel * PPIndentWidth + 73bdd1243dSDimitry Andric (Line.Level - Line.PPLevel) * Style.IndentWidth 74bdd1243dSDimitry Andric : Line.Level * PPIndentWidth; 75bdd1243dSDimitry Andric Indent += AdditionalIndent; 760b57cec5SDimitry Andric } else { 7706c3fb27SDimitry Andric // When going to lower levels, forget previous higher levels so that we 7806c3fb27SDimitry Andric // recompute future higher levels. But don't forget them if we enter a PP 7906c3fb27SDimitry Andric // directive, since these do not terminate a C++ code block. 8006c3fb27SDimitry Andric if (!Line.InPPDirective) { 8106c3fb27SDimitry Andric assert(Line.Level <= IndentForLevel.size()); 8206c3fb27SDimitry Andric IndentForLevel.resize(Line.Level + 1); 8306c3fb27SDimitry Andric } 840eae32dcSDimitry Andric Indent = getIndent(Line.Level); 850b57cec5SDimitry Andric } 860b57cec5SDimitry Andric if (static_cast<int>(Indent) + Offset >= 0) 870b57cec5SDimitry Andric Indent += Offset; 88bdd1243dSDimitry Andric if (Line.IsContinuation) 895ffd83dbSDimitry Andric Indent = Line.Level * Style.IndentWidth + Style.ContinuationIndentWidth; 900b57cec5SDimitry Andric } 910b57cec5SDimitry Andric 920b57cec5SDimitry Andric /// Update the level indent to adapt to the given \p Line. 930b57cec5SDimitry Andric /// 940b57cec5SDimitry Andric /// When a line is not formatted, we move the subsequent lines on the same 950b57cec5SDimitry Andric /// level to the same indent. 960b57cec5SDimitry Andric /// Note that \c nextLine must have been called before this method. 970b57cec5SDimitry Andric void adjustToUnmodifiedLine(const AnnotatedLine &Line) { 987a6dacacSDimitry Andric if (Line.InPPDirective || Line.IsContinuation) 9906c3fb27SDimitry Andric return; 10006c3fb27SDimitry Andric assert(Line.Level < IndentForLevel.size()); 10106c3fb27SDimitry Andric if (Line.First->is(tok::comment) && IndentForLevel[Line.Level] != -1) 10206c3fb27SDimitry Andric return; 1030b57cec5SDimitry Andric unsigned LevelIndent = Line.First->OriginalColumn; 1040b57cec5SDimitry Andric if (static_cast<int>(LevelIndent) - Offset >= 0) 1050b57cec5SDimitry Andric LevelIndent -= Offset; 1060b57cec5SDimitry Andric IndentForLevel[Line.Level] = LevelIndent; 1070b57cec5SDimitry Andric } 1080b57cec5SDimitry Andric 1090b57cec5SDimitry Andric private: 1100b57cec5SDimitry Andric /// Get the offset of the line relatively to the level. 1110b57cec5SDimitry Andric /// 1120b57cec5SDimitry Andric /// For example, 'public:' labels in classes are offset by 1 or 2 1130b57cec5SDimitry Andric /// characters to the left from their level. 114*0fca6ea1SDimitry Andric int getIndentOffset(const AnnotatedLine &Line) { 1150eae32dcSDimitry Andric if (Style.Language == FormatStyle::LK_Java || Style.isJavaScript() || 11681ad6265SDimitry Andric Style.isCSharp()) { 1170b57cec5SDimitry Andric return 0; 11881ad6265SDimitry Andric } 1191fd87a68SDimitry Andric 120*0fca6ea1SDimitry Andric auto IsAccessModifier = [&](const FormatToken &RootToken) { 121*0fca6ea1SDimitry Andric if (Line.Type == LT_AccessModifier || RootToken.isObjCAccessSpecifier()) 1221fd87a68SDimitry Andric return true; 123*0fca6ea1SDimitry Andric 124*0fca6ea1SDimitry Andric const auto *Next = RootToken.Next; 125*0fca6ea1SDimitry Andric 1261fd87a68SDimitry Andric // Handle Qt signals. 127*0fca6ea1SDimitry Andric if (RootToken.isOneOf(Keywords.kw_signals, Keywords.kw_qsignals) && 128*0fca6ea1SDimitry Andric Next && Next->is(tok::colon)) { 1291fd87a68SDimitry Andric return true; 13081ad6265SDimitry Andric } 131*0fca6ea1SDimitry Andric 132*0fca6ea1SDimitry Andric if (Next && Next->isOneOf(Keywords.kw_slots, Keywords.kw_qslots) && 133*0fca6ea1SDimitry Andric Next->Next && Next->Next->is(tok::colon)) { 134*0fca6ea1SDimitry Andric return true; 135*0fca6ea1SDimitry Andric } 136*0fca6ea1SDimitry Andric 1371fd87a68SDimitry Andric // Handle malformed access specifier e.g. 'private' without trailing ':'. 138*0fca6ea1SDimitry Andric return !Next && RootToken.isAccessSpecifier(false); 1391fd87a68SDimitry Andric }; 1401fd87a68SDimitry Andric 141*0fca6ea1SDimitry Andric if (IsAccessModifier(*Line.First)) { 142349cc55cSDimitry Andric // The AccessModifierOffset may be overridden by IndentAccessModifiers, 143fe6060f1SDimitry Andric // in which case we take a negative value of the IndentWidth to simulate 144fe6060f1SDimitry Andric // the upper indent level. 145fe6060f1SDimitry Andric return Style.IndentAccessModifiers ? -Style.IndentWidth 146fe6060f1SDimitry Andric : Style.AccessModifierOffset; 147fe6060f1SDimitry Andric } 148*0fca6ea1SDimitry Andric 1490b57cec5SDimitry Andric return 0; 1500b57cec5SDimitry Andric } 1510b57cec5SDimitry Andric 1520b57cec5SDimitry Andric /// Get the indent of \p Level from \p IndentForLevel. 1530b57cec5SDimitry Andric /// 1540b57cec5SDimitry Andric /// \p IndentForLevel must contain the indent for the level \c l 1550b57cec5SDimitry Andric /// at \p IndentForLevel[l], or a value < 0 if the indent for 1560b57cec5SDimitry Andric /// that level is unknown. 1570eae32dcSDimitry Andric unsigned getIndent(unsigned Level) const { 15806c3fb27SDimitry Andric assert(Level < IndentForLevel.size()); 1590b57cec5SDimitry Andric if (IndentForLevel[Level] != -1) 1600b57cec5SDimitry Andric return IndentForLevel[Level]; 1610b57cec5SDimitry Andric if (Level == 0) 1620b57cec5SDimitry Andric return 0; 1630eae32dcSDimitry Andric return getIndent(Level - 1) + Style.IndentWidth; 1640b57cec5SDimitry Andric } 1650b57cec5SDimitry Andric 1660b57cec5SDimitry Andric const FormatStyle &Style; 1670b57cec5SDimitry Andric const AdditionalKeywords &Keywords; 1680b57cec5SDimitry Andric const unsigned AdditionalIndent; 1690b57cec5SDimitry Andric 17006c3fb27SDimitry Andric /// The indent in characters for each level. It remembers the indent of 17106c3fb27SDimitry Andric /// previous lines (that are not PP directives) of equal or lower levels. This 17206c3fb27SDimitry Andric /// is used to align formatted lines to the indent of previous non-formatted 17306c3fb27SDimitry Andric /// lines. Think about the --lines parameter of clang-format. 174753f127fSDimitry Andric SmallVector<int> IndentForLevel; 1750b57cec5SDimitry Andric 1760b57cec5SDimitry Andric /// Offset of the current line relative to the indent level. 1770b57cec5SDimitry Andric /// 1780b57cec5SDimitry Andric /// For example, the 'public' keywords is often indented with a negative 1790b57cec5SDimitry Andric /// offset. 1800b57cec5SDimitry Andric int Offset = 0; 1810b57cec5SDimitry Andric 1820b57cec5SDimitry Andric /// The current line's indent. 1830b57cec5SDimitry Andric unsigned Indent = 0; 1840b57cec5SDimitry Andric }; 1850b57cec5SDimitry Andric 1860b57cec5SDimitry Andric const FormatToken *getMatchingNamespaceToken( 1870b57cec5SDimitry Andric const AnnotatedLine *Line, 1880b57cec5SDimitry Andric const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) { 1890b57cec5SDimitry Andric if (!Line->startsWith(tok::r_brace)) 1900b57cec5SDimitry Andric return nullptr; 1910b57cec5SDimitry Andric size_t StartLineIndex = Line->MatchingOpeningBlockLineIndex; 1920b57cec5SDimitry Andric if (StartLineIndex == UnwrappedLine::kInvalidIndex) 1930b57cec5SDimitry Andric return nullptr; 1940b57cec5SDimitry Andric assert(StartLineIndex < AnnotatedLines.size()); 1950b57cec5SDimitry Andric return AnnotatedLines[StartLineIndex]->First->getNamespaceToken(); 1960b57cec5SDimitry Andric } 1970b57cec5SDimitry Andric 1980b57cec5SDimitry Andric StringRef getNamespaceTokenText(const AnnotatedLine *Line) { 1990b57cec5SDimitry Andric const FormatToken *NamespaceToken = Line->First->getNamespaceToken(); 2000b57cec5SDimitry Andric return NamespaceToken ? NamespaceToken->TokenText : StringRef(); 2010b57cec5SDimitry Andric } 2020b57cec5SDimitry Andric 2030b57cec5SDimitry Andric StringRef getMatchingNamespaceTokenText( 2040b57cec5SDimitry Andric const AnnotatedLine *Line, 2050b57cec5SDimitry Andric const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) { 2060b57cec5SDimitry Andric const FormatToken *NamespaceToken = 2070b57cec5SDimitry Andric getMatchingNamespaceToken(Line, AnnotatedLines); 2080b57cec5SDimitry Andric return NamespaceToken ? NamespaceToken->TokenText : StringRef(); 2090b57cec5SDimitry Andric } 2100b57cec5SDimitry Andric 2110b57cec5SDimitry Andric class LineJoiner { 2120b57cec5SDimitry Andric public: 2130b57cec5SDimitry Andric LineJoiner(const FormatStyle &Style, const AdditionalKeywords &Keywords, 2140b57cec5SDimitry Andric const SmallVectorImpl<AnnotatedLine *> &Lines) 2150b57cec5SDimitry Andric : Style(Style), Keywords(Keywords), End(Lines.end()), Next(Lines.begin()), 2160b57cec5SDimitry Andric AnnotatedLines(Lines) {} 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric /// Returns the next line, merging multiple lines into one if possible. 2190b57cec5SDimitry Andric const AnnotatedLine *getNextMergedLine(bool DryRun, 2200b57cec5SDimitry Andric LevelIndentTracker &IndentTracker) { 2210b57cec5SDimitry Andric if (Next == End) 2220b57cec5SDimitry Andric return nullptr; 2230b57cec5SDimitry Andric const AnnotatedLine *Current = *Next; 2240b57cec5SDimitry Andric IndentTracker.nextLine(*Current); 2250b57cec5SDimitry Andric unsigned MergedLines = tryFitMultipleLinesInOne(IndentTracker, Next, End); 22681ad6265SDimitry Andric if (MergedLines > 0 && Style.ColumnLimit == 0) { 2270b57cec5SDimitry Andric // Disallow line merging if there is a break at the start of one of the 2280b57cec5SDimitry Andric // input lines. 2290b57cec5SDimitry Andric for (unsigned i = 0; i < MergedLines; ++i) 2300b57cec5SDimitry Andric if (Next[i + 1]->First->NewlinesBefore > 0) 2310b57cec5SDimitry Andric MergedLines = 0; 23281ad6265SDimitry Andric } 2330b57cec5SDimitry Andric if (!DryRun) 2340b57cec5SDimitry Andric for (unsigned i = 0; i < MergedLines; ++i) 2350b57cec5SDimitry Andric join(*Next[0], *Next[i + 1]); 2360b57cec5SDimitry Andric Next = Next + MergedLines + 1; 2370b57cec5SDimitry Andric return Current; 2380b57cec5SDimitry Andric } 2390b57cec5SDimitry Andric 2400b57cec5SDimitry Andric private: 2410b57cec5SDimitry Andric /// Calculates how many lines can be merged into 1 starting at \p I. 2420b57cec5SDimitry Andric unsigned 2430b57cec5SDimitry Andric tryFitMultipleLinesInOne(LevelIndentTracker &IndentTracker, 2440b57cec5SDimitry Andric SmallVectorImpl<AnnotatedLine *>::const_iterator I, 2450b57cec5SDimitry Andric SmallVectorImpl<AnnotatedLine *>::const_iterator E) { 2460b57cec5SDimitry Andric const unsigned Indent = IndentTracker.getIndent(); 2470b57cec5SDimitry Andric 2480b57cec5SDimitry Andric // Can't join the last line with anything. 2490b57cec5SDimitry Andric if (I + 1 == E) 2500b57cec5SDimitry Andric return 0; 2510b57cec5SDimitry Andric // We can never merge stuff if there are trailing line comments. 2520b57cec5SDimitry Andric const AnnotatedLine *TheLine = *I; 2530b57cec5SDimitry Andric if (TheLine->Last->is(TT_LineComment)) 2540b57cec5SDimitry Andric return 0; 25581ad6265SDimitry Andric const auto &NextLine = *I[1]; 25681ad6265SDimitry Andric if (NextLine.Type == LT_Invalid || NextLine.First->MustBreakBefore) 2570b57cec5SDimitry Andric return 0; 2580b57cec5SDimitry Andric if (TheLine->InPPDirective && 25981ad6265SDimitry Andric (!NextLine.InPPDirective || NextLine.First->HasUnescapedNewline)) { 2600b57cec5SDimitry Andric return 0; 26181ad6265SDimitry Andric } 2620b57cec5SDimitry Andric 2630b57cec5SDimitry Andric if (Style.ColumnLimit > 0 && Indent > Style.ColumnLimit) 2640b57cec5SDimitry Andric return 0; 2650b57cec5SDimitry Andric 2660b57cec5SDimitry Andric unsigned Limit = 2670b57cec5SDimitry Andric Style.ColumnLimit == 0 ? UINT_MAX : Style.ColumnLimit - Indent; 2680b57cec5SDimitry Andric // If we already exceed the column limit, we set 'Limit' to 0. The different 2690b57cec5SDimitry Andric // tryMerge..() functions can then decide whether to still do merging. 2700b57cec5SDimitry Andric Limit = TheLine->Last->TotalLength > Limit 2710b57cec5SDimitry Andric ? 0 2720b57cec5SDimitry Andric : Limit - TheLine->Last->TotalLength; 2730b57cec5SDimitry Andric 2740b57cec5SDimitry Andric if (TheLine->Last->is(TT_FunctionLBrace) && 2750b57cec5SDimitry Andric TheLine->First == TheLine->Last && 2760b57cec5SDimitry Andric !Style.BraceWrapping.SplitEmptyFunction && 27781ad6265SDimitry Andric NextLine.First->is(tok::r_brace)) { 2780b57cec5SDimitry Andric return tryMergeSimpleBlock(I, E, Limit); 27981ad6265SDimitry Andric } 2800b57cec5SDimitry Andric 28181ad6265SDimitry Andric const auto *PreviousLine = I != AnnotatedLines.begin() ? I[-1] : nullptr; 28281ad6265SDimitry Andric // Handle empty record blocks where the brace has already been wrapped. 28381ad6265SDimitry Andric if (PreviousLine && TheLine->Last->is(tok::l_brace) && 28481ad6265SDimitry Andric TheLine->First == TheLine->Last) { 28581ad6265SDimitry Andric bool EmptyBlock = NextLine.First->is(tok::r_brace); 2860b57cec5SDimitry Andric 28781ad6265SDimitry Andric const FormatToken *Tok = PreviousLine->First; 2880b57cec5SDimitry Andric if (Tok && Tok->is(tok::comment)) 2890b57cec5SDimitry Andric Tok = Tok->getNextNonComment(); 2900b57cec5SDimitry Andric 29181ad6265SDimitry Andric if (Tok && Tok->getNamespaceToken()) { 2920b57cec5SDimitry Andric return !Style.BraceWrapping.SplitEmptyNamespace && EmptyBlock 2930b57cec5SDimitry Andric ? tryMergeSimpleBlock(I, E, Limit) 2940b57cec5SDimitry Andric : 0; 29581ad6265SDimitry Andric } 2960b57cec5SDimitry Andric 2970b57cec5SDimitry Andric if (Tok && Tok->is(tok::kw_typedef)) 2980b57cec5SDimitry Andric Tok = Tok->getNextNonComment(); 2990b57cec5SDimitry Andric if (Tok && Tok->isOneOf(tok::kw_class, tok::kw_struct, tok::kw_union, 30081ad6265SDimitry Andric tok::kw_extern, Keywords.kw_interface)) { 3010b57cec5SDimitry Andric return !Style.BraceWrapping.SplitEmptyRecord && EmptyBlock 3020b57cec5SDimitry Andric ? tryMergeSimpleBlock(I, E, Limit) 3030b57cec5SDimitry Andric : 0; 30481ad6265SDimitry Andric } 305e8d8bef9SDimitry Andric 306e8d8bef9SDimitry Andric if (Tok && Tok->is(tok::kw_template) && 307e8d8bef9SDimitry Andric Style.BraceWrapping.SplitEmptyRecord && EmptyBlock) { 308e8d8bef9SDimitry Andric return 0; 309e8d8bef9SDimitry Andric } 3100b57cec5SDimitry Andric } 3110b57cec5SDimitry Andric 31281ad6265SDimitry Andric auto ShouldMergeShortFunctions = [this, &I, &NextLine, PreviousLine, 31381ad6265SDimitry Andric TheLine]() { 31404eeddc0SDimitry Andric if (Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_All) 31504eeddc0SDimitry Andric return true; 31681ad6265SDimitry Andric if (Style.AllowShortFunctionsOnASingleLine >= FormatStyle::SFS_Empty && 31781ad6265SDimitry Andric NextLine.First->is(tok::r_brace)) { 31804eeddc0SDimitry Andric return true; 31981ad6265SDimitry Andric } 32004eeddc0SDimitry Andric 32104eeddc0SDimitry Andric if (Style.AllowShortFunctionsOnASingleLine & 32204eeddc0SDimitry Andric FormatStyle::SFS_InlineOnly) { 32304eeddc0SDimitry Andric // Just checking TheLine->Level != 0 is not enough, because it 32404eeddc0SDimitry Andric // provokes treating functions inside indented namespaces as short. 32581ad6265SDimitry Andric if (Style.isJavaScript() && TheLine->Last->is(TT_FunctionLBrace)) 32604eeddc0SDimitry Andric return true; 32704eeddc0SDimitry Andric 32881ad6265SDimitry Andric if (TheLine->Level != 0) { 32981ad6265SDimitry Andric if (!PreviousLine) 33004eeddc0SDimitry Andric return false; 33104eeddc0SDimitry Andric 33204eeddc0SDimitry Andric // TODO: Use IndentTracker to avoid loop? 33304eeddc0SDimitry Andric // Find the last line with lower level. 33481ad6265SDimitry Andric const AnnotatedLine *Line = nullptr; 33581ad6265SDimitry Andric for (auto J = I - 1; J >= AnnotatedLines.begin(); --J) { 33681ad6265SDimitry Andric assert(*J); 33781ad6265SDimitry Andric if (!(*J)->InPPDirective && !(*J)->isComment() && 33881ad6265SDimitry Andric (*J)->Level < TheLine->Level) { 33981ad6265SDimitry Andric Line = *J; 34004eeddc0SDimitry Andric break; 34181ad6265SDimitry Andric } 34281ad6265SDimitry Andric } 34381ad6265SDimitry Andric 34481ad6265SDimitry Andric if (!Line) 34581ad6265SDimitry Andric return false; 34604eeddc0SDimitry Andric 34704eeddc0SDimitry Andric // Check if the found line starts a record. 3485f757f3fSDimitry Andric const auto *LastNonComment = Line->getLastNonComment(); 34981ad6265SDimitry Andric // There must be another token (usually `{`), because we chose a 35081ad6265SDimitry Andric // non-PPDirective and non-comment line that has a smaller level. 35181ad6265SDimitry Andric assert(LastNonComment); 35281ad6265SDimitry Andric return isRecordLBrace(*LastNonComment); 35304eeddc0SDimitry Andric } 35404eeddc0SDimitry Andric } 35504eeddc0SDimitry Andric 35604eeddc0SDimitry Andric return false; 35704eeddc0SDimitry Andric }; 35804eeddc0SDimitry Andric 35981ad6265SDimitry Andric bool MergeShortFunctions = ShouldMergeShortFunctions(); 36081ad6265SDimitry Andric 3615f757f3fSDimitry Andric const auto *FirstNonComment = TheLine->getFirstNonComment(); 36281ad6265SDimitry Andric if (!FirstNonComment) 36381ad6265SDimitry Andric return 0; 36481ad6265SDimitry Andric // FIXME: There are probably cases where we should use FirstNonComment 36581ad6265SDimitry Andric // instead of TheLine->First. 3660b57cec5SDimitry Andric 3670b57cec5SDimitry Andric if (Style.CompactNamespaces) { 36806c3fb27SDimitry Andric if (const auto *NSToken = TheLine->First->getNamespaceToken()) { 36906c3fb27SDimitry Andric int J = 1; 37006c3fb27SDimitry Andric assert(TheLine->MatchingClosingBlockLineIndex > 0); 37106c3fb27SDimitry Andric for (auto ClosingLineIndex = TheLine->MatchingClosingBlockLineIndex - 1; 37206c3fb27SDimitry Andric I + J != E && NSToken->TokenText == getNamespaceTokenText(I[J]) && 37306c3fb27SDimitry Andric ClosingLineIndex == I[J]->MatchingClosingBlockLineIndex && 37406c3fb27SDimitry Andric I[J]->Last->TotalLength < Limit; 37506c3fb27SDimitry Andric ++J, --ClosingLineIndex) { 37606c3fb27SDimitry Andric Limit -= I[J]->Last->TotalLength; 3770b57cec5SDimitry Andric 37806c3fb27SDimitry Andric // Reduce indent level for bodies of namespaces which were compacted, 37906c3fb27SDimitry Andric // but only if their content was indented in the first place. 38006c3fb27SDimitry Andric auto *ClosingLine = AnnotatedLines.begin() + ClosingLineIndex + 1; 3815f757f3fSDimitry Andric const int OutdentBy = I[J]->Level - TheLine->Level; 3825f757f3fSDimitry Andric assert(OutdentBy >= 0); 38306c3fb27SDimitry Andric for (auto *CompactedLine = I + J; CompactedLine <= ClosingLine; 38406c3fb27SDimitry Andric ++CompactedLine) { 3855f757f3fSDimitry Andric if (!(*CompactedLine)->InPPDirective) { 3865f757f3fSDimitry Andric const int Level = (*CompactedLine)->Level; 3875f757f3fSDimitry Andric (*CompactedLine)->Level = std::max(Level - OutdentBy, 0); 3885f757f3fSDimitry Andric } 3890b57cec5SDimitry Andric } 39006c3fb27SDimitry Andric } 39106c3fb27SDimitry Andric return J - 1; 3920b57cec5SDimitry Andric } 3930b57cec5SDimitry Andric 3940b57cec5SDimitry Andric if (auto nsToken = getMatchingNamespaceToken(TheLine, AnnotatedLines)) { 3950b57cec5SDimitry Andric int i = 0; 3960b57cec5SDimitry Andric unsigned openingLine = TheLine->MatchingOpeningBlockLineIndex - 1; 3970b57cec5SDimitry Andric for (; I + 1 + i != E && 3980b57cec5SDimitry Andric nsToken->TokenText == 3990b57cec5SDimitry Andric getMatchingNamespaceTokenText(I[i + 1], AnnotatedLines) && 4000b57cec5SDimitry Andric openingLine == I[i + 1]->MatchingOpeningBlockLineIndex; 40181ad6265SDimitry Andric i++, --openingLine) { 40281ad6265SDimitry Andric // No space between consecutive braces. 4035f757f3fSDimitry Andric I[i + 1]->First->SpacesRequiredBefore = 4045f757f3fSDimitry Andric I[i]->Last->isNot(tok::r_brace); 4050b57cec5SDimitry Andric 40681ad6265SDimitry Andric // Indent like the outer-most namespace. 4070b57cec5SDimitry Andric IndentTracker.nextLine(*I[i + 1]); 4080b57cec5SDimitry Andric } 4090b57cec5SDimitry Andric return i; 4100b57cec5SDimitry Andric } 4110b57cec5SDimitry Andric } 4120b57cec5SDimitry Andric 4135f757f3fSDimitry Andric const auto *LastNonComment = TheLine->getLastNonComment(); 4145f757f3fSDimitry Andric assert(LastNonComment); 4155f757f3fSDimitry Andric // FIXME: There are probably cases where we should use LastNonComment 4165f757f3fSDimitry Andric // instead of TheLine->Last. 4175f757f3fSDimitry Andric 41881ad6265SDimitry Andric // Try to merge a function block with left brace unwrapped. 4195f757f3fSDimitry Andric if (LastNonComment->is(TT_FunctionLBrace) && 4205f757f3fSDimitry Andric TheLine->First != LastNonComment) { 4210b57cec5SDimitry Andric return MergeShortFunctions ? tryMergeSimpleBlock(I, E, Limit) : 0; 4225f757f3fSDimitry Andric } 42381ad6265SDimitry Andric // Try to merge a control statement block with left brace unwrapped. 42481ad6265SDimitry Andric if (TheLine->Last->is(tok::l_brace) && FirstNonComment != TheLine->Last && 42581ad6265SDimitry Andric FirstNonComment->isOneOf(tok::kw_if, tok::kw_while, tok::kw_for, 42604eeddc0SDimitry Andric TT_ForEachMacro)) { 427a7dea167SDimitry Andric return Style.AllowShortBlocksOnASingleLine != FormatStyle::SBS_Never 4280b57cec5SDimitry Andric ? tryMergeSimpleBlock(I, E, Limit) 4290b57cec5SDimitry Andric : 0; 4300b57cec5SDimitry Andric } 43181ad6265SDimitry Andric // Try to merge a control statement block with left brace wrapped. 43281ad6265SDimitry Andric if (NextLine.First->is(tok::l_brace)) { 43381ad6265SDimitry Andric if ((TheLine->First->isOneOf(tok::kw_if, tok::kw_else, tok::kw_while, 4344824e7fdSDimitry Andric tok::kw_for, tok::kw_switch, tok::kw_try, 4354824e7fdSDimitry Andric tok::kw_do, TT_ForEachMacro) || 436a7dea167SDimitry Andric (TheLine->First->is(tok::r_brace) && TheLine->First->Next && 437a7dea167SDimitry Andric TheLine->First->Next->isOneOf(tok::kw_else, tok::kw_catch))) && 438a7dea167SDimitry Andric Style.BraceWrapping.AfterControlStatement == 439a7dea167SDimitry Andric FormatStyle::BWACS_MultiLine) { 44081ad6265SDimitry Andric // If possible, merge the next line's wrapped left brace with the 44181ad6265SDimitry Andric // current line. Otherwise, leave it on the next line, as this is a 44281ad6265SDimitry Andric // multi-line control statement. 44381ad6265SDimitry Andric return (Style.ColumnLimit == 0 || TheLine->Level * Style.IndentWidth + 44481ad6265SDimitry Andric TheLine->Last->TotalLength <= 44581ad6265SDimitry Andric Style.ColumnLimit) 446a7dea167SDimitry Andric ? 1 447a7dea167SDimitry Andric : 0; 44881ad6265SDimitry Andric } 44981ad6265SDimitry Andric if (TheLine->First->isOneOf(tok::kw_if, tok::kw_else, tok::kw_while, 45004eeddc0SDimitry Andric tok::kw_for, TT_ForEachMacro)) { 451a7dea167SDimitry Andric return (Style.BraceWrapping.AfterControlStatement == 452a7dea167SDimitry Andric FormatStyle::BWACS_Always) 4530b57cec5SDimitry Andric ? tryMergeSimpleBlock(I, E, Limit) 4540b57cec5SDimitry Andric : 0; 45581ad6265SDimitry Andric } 45681ad6265SDimitry Andric if (TheLine->First->isOneOf(tok::kw_else, tok::kw_catch) && 457480093f4SDimitry Andric Style.BraceWrapping.AfterControlStatement == 458480093f4SDimitry Andric FormatStyle::BWACS_MultiLine) { 459480093f4SDimitry Andric // This case if different from the upper BWACS_MultiLine processing 460480093f4SDimitry Andric // in that a preceding r_brace is not on the same line as else/catch 461480093f4SDimitry Andric // most likely because of BeforeElse/BeforeCatch set to true. 462480093f4SDimitry Andric // If the line length doesn't fit ColumnLimit, leave l_brace on the 463480093f4SDimitry Andric // next line to respect the BWACS_MultiLine. 464480093f4SDimitry Andric return (Style.ColumnLimit == 0 || 465480093f4SDimitry Andric TheLine->Last->TotalLength <= Style.ColumnLimit) 466480093f4SDimitry Andric ? 1 467480093f4SDimitry Andric : 0; 4680b57cec5SDimitry Andric } 46981ad6265SDimitry Andric } 47081ad6265SDimitry Andric if (PreviousLine && TheLine->First->is(tok::l_brace)) { 47181ad6265SDimitry Andric switch (PreviousLine->First->Tok.getKind()) { 47281ad6265SDimitry Andric case tok::at: 47381ad6265SDimitry Andric // Don't merge block with left brace wrapped after ObjC special blocks. 47481ad6265SDimitry Andric if (PreviousLine->First->Next) { 47581ad6265SDimitry Andric tok::ObjCKeywordKind kwId = 47681ad6265SDimitry Andric PreviousLine->First->Next->Tok.getObjCKeywordID(); 47781ad6265SDimitry Andric if (kwId == tok::objc_autoreleasepool || 47881ad6265SDimitry Andric kwId == tok::objc_synchronized) { 4790b57cec5SDimitry Andric return 0; 4800b57cec5SDimitry Andric } 48181ad6265SDimitry Andric } 48281ad6265SDimitry Andric break; 48381ad6265SDimitry Andric 48481ad6265SDimitry Andric case tok::kw_case: 48581ad6265SDimitry Andric case tok::kw_default: 48681ad6265SDimitry Andric // Don't merge block with left brace wrapped after case labels. 4870b57cec5SDimitry Andric return 0; 488e8d8bef9SDimitry Andric 48981ad6265SDimitry Andric default: 49081ad6265SDimitry Andric break; 49181ad6265SDimitry Andric } 49281ad6265SDimitry Andric } 49381ad6265SDimitry Andric 494e8d8bef9SDimitry Andric // Don't merge an empty template class or struct if SplitEmptyRecords 495e8d8bef9SDimitry Andric // is defined. 49681ad6265SDimitry Andric if (PreviousLine && Style.BraceWrapping.SplitEmptyRecord && 49781ad6265SDimitry Andric TheLine->Last->is(tok::l_brace) && PreviousLine->Last) { 49881ad6265SDimitry Andric const FormatToken *Previous = PreviousLine->Last; 499e8d8bef9SDimitry Andric if (Previous) { 500e8d8bef9SDimitry Andric if (Previous->is(tok::comment)) 501e8d8bef9SDimitry Andric Previous = Previous->getPreviousNonComment(); 502e8d8bef9SDimitry Andric if (Previous) { 50381ad6265SDimitry Andric if (Previous->is(tok::greater) && !PreviousLine->InPPDirective) 504e8d8bef9SDimitry Andric return 0; 505e8d8bef9SDimitry Andric if (Previous->is(tok::identifier)) { 506e8d8bef9SDimitry Andric const FormatToken *PreviousPrevious = 507e8d8bef9SDimitry Andric Previous->getPreviousNonComment(); 508e8d8bef9SDimitry Andric if (PreviousPrevious && 50981ad6265SDimitry Andric PreviousPrevious->isOneOf(tok::kw_class, tok::kw_struct)) { 510e8d8bef9SDimitry Andric return 0; 511e8d8bef9SDimitry Andric } 512e8d8bef9SDimitry Andric } 513e8d8bef9SDimitry Andric } 514e8d8bef9SDimitry Andric } 5150eae32dcSDimitry Andric } 51681ad6265SDimitry Andric 517*0fca6ea1SDimitry Andric if (TheLine->First->is(TT_SwitchExpressionLabel)) { 518*0fca6ea1SDimitry Andric return Style.AllowShortCaseExpressionOnASingleLine 519*0fca6ea1SDimitry Andric ? tryMergeShortCaseLabels(I, E, Limit) 520*0fca6ea1SDimitry Andric : 0; 521*0fca6ea1SDimitry Andric } 522*0fca6ea1SDimitry Andric 52381ad6265SDimitry Andric if (TheLine->Last->is(tok::l_brace)) { 52481ad6265SDimitry Andric bool ShouldMerge = false; 52581ad6265SDimitry Andric // Try to merge records. 52681ad6265SDimitry Andric if (TheLine->Last->is(TT_EnumLBrace)) { 5270eae32dcSDimitry Andric ShouldMerge = Style.AllowShortEnumsOnASingleLine; 5285f757f3fSDimitry Andric } else if (TheLine->Last->is(TT_RequiresExpressionLBrace)) { 5295f757f3fSDimitry Andric ShouldMerge = Style.AllowShortCompoundRequirementOnASingleLine; 53081ad6265SDimitry Andric } else if (TheLine->Last->isOneOf(TT_ClassLBrace, TT_StructLBrace)) { 53181ad6265SDimitry Andric // NOTE: We use AfterClass (whereas AfterStruct exists) for both classes 53281ad6265SDimitry Andric // and structs, but it seems that wrapping is still handled correctly 53381ad6265SDimitry Andric // elsewhere. 53481ad6265SDimitry Andric ShouldMerge = !Style.BraceWrapping.AfterClass || 53581ad6265SDimitry Andric (NextLine.First->is(tok::r_brace) && 53681ad6265SDimitry Andric !Style.BraceWrapping.SplitEmptyRecord); 53706c3fb27SDimitry Andric } else if (TheLine->InPPDirective || 53806c3fb27SDimitry Andric !TheLine->First->isOneOf(tok::kw_class, tok::kw_enum, 53906c3fb27SDimitry Andric tok::kw_struct)) { 54081ad6265SDimitry Andric // Try to merge a block with left brace unwrapped that wasn't yet 54181ad6265SDimitry Andric // covered. 5420eae32dcSDimitry Andric ShouldMerge = !Style.BraceWrapping.AfterFunction || 54381ad6265SDimitry Andric (NextLine.First->is(tok::r_brace) && 5440eae32dcSDimitry Andric !Style.BraceWrapping.SplitEmptyFunction); 5450eae32dcSDimitry Andric } 5460eae32dcSDimitry Andric return ShouldMerge ? tryMergeSimpleBlock(I, E, Limit) : 0; 5470b57cec5SDimitry Andric } 54881ad6265SDimitry Andric 54981ad6265SDimitry Andric // Try to merge a function block with left brace wrapped. 55081ad6265SDimitry Andric if (NextLine.First->is(TT_FunctionLBrace) && 5510b57cec5SDimitry Andric Style.BraceWrapping.AfterFunction) { 55281ad6265SDimitry Andric if (NextLine.Last->is(TT_LineComment)) 5530b57cec5SDimitry Andric return 0; 5540b57cec5SDimitry Andric 5550b57cec5SDimitry Andric // Check for Limit <= 2 to account for the " {". 5560b57cec5SDimitry Andric if (Limit <= 2 || (Style.ColumnLimit == 0 && containsMustBreak(TheLine))) 5570b57cec5SDimitry Andric return 0; 5580b57cec5SDimitry Andric Limit -= 2; 5590b57cec5SDimitry Andric 5600b57cec5SDimitry Andric unsigned MergedLines = 0; 5610b57cec5SDimitry Andric if (MergeShortFunctions || 5620b57cec5SDimitry Andric (Style.AllowShortFunctionsOnASingleLine >= FormatStyle::SFS_Empty && 56381ad6265SDimitry Andric NextLine.First == NextLine.Last && I + 2 != E && 5640b57cec5SDimitry Andric I[2]->First->is(tok::r_brace))) { 5650b57cec5SDimitry Andric MergedLines = tryMergeSimpleBlock(I + 1, E, Limit); 5660b57cec5SDimitry Andric // If we managed to merge the block, count the function header, which is 5670b57cec5SDimitry Andric // on a separate line. 5680b57cec5SDimitry Andric if (MergedLines > 0) 5690b57cec5SDimitry Andric ++MergedLines; 5700b57cec5SDimitry Andric } 5710b57cec5SDimitry Andric return MergedLines; 5720b57cec5SDimitry Andric } 573fe6060f1SDimitry Andric auto IsElseLine = [&TheLine]() -> bool { 574fe6060f1SDimitry Andric const FormatToken *First = TheLine->First; 575fe6060f1SDimitry Andric if (First->is(tok::kw_else)) 576fe6060f1SDimitry Andric return true; 577fe6060f1SDimitry Andric 578fe6060f1SDimitry Andric return First->is(tok::r_brace) && First->Next && 579fe6060f1SDimitry Andric First->Next->is(tok::kw_else); 580fe6060f1SDimitry Andric }; 581fe6060f1SDimitry Andric if (TheLine->First->is(tok::kw_if) || 582fe6060f1SDimitry Andric (IsElseLine() && (Style.AllowShortIfStatementsOnASingleLine == 583fe6060f1SDimitry Andric FormatStyle::SIS_AllIfsAndElse))) { 5840b57cec5SDimitry Andric return Style.AllowShortIfStatementsOnASingleLine 5850b57cec5SDimitry Andric ? tryMergeSimpleControlStatement(I, E, Limit) 5860b57cec5SDimitry Andric : 0; 5870b57cec5SDimitry Andric } 58804eeddc0SDimitry Andric if (TheLine->First->isOneOf(tok::kw_for, tok::kw_while, tok::kw_do, 58904eeddc0SDimitry Andric TT_ForEachMacro)) { 5900b57cec5SDimitry Andric return Style.AllowShortLoopsOnASingleLine 5910b57cec5SDimitry Andric ? tryMergeSimpleControlStatement(I, E, Limit) 5920b57cec5SDimitry Andric : 0; 5930b57cec5SDimitry Andric } 5940b57cec5SDimitry Andric if (TheLine->First->isOneOf(tok::kw_case, tok::kw_default)) { 5950b57cec5SDimitry Andric return Style.AllowShortCaseLabelsOnASingleLine 5960b57cec5SDimitry Andric ? tryMergeShortCaseLabels(I, E, Limit) 5970b57cec5SDimitry Andric : 0; 5980b57cec5SDimitry Andric } 5990b57cec5SDimitry Andric if (TheLine->InPPDirective && 6000b57cec5SDimitry Andric (TheLine->First->HasUnescapedNewline || TheLine->First->IsFirst)) { 6010b57cec5SDimitry Andric return tryMergeSimplePPDirective(I, E, Limit); 6020b57cec5SDimitry Andric } 6030b57cec5SDimitry Andric return 0; 6040b57cec5SDimitry Andric } 6050b57cec5SDimitry Andric 6060b57cec5SDimitry Andric unsigned 6070b57cec5SDimitry Andric tryMergeSimplePPDirective(SmallVectorImpl<AnnotatedLine *>::const_iterator I, 6080b57cec5SDimitry Andric SmallVectorImpl<AnnotatedLine *>::const_iterator E, 6090b57cec5SDimitry Andric unsigned Limit) { 6100b57cec5SDimitry Andric if (Limit == 0) 6110b57cec5SDimitry Andric return 0; 6120b57cec5SDimitry Andric if (I + 2 != E && I[2]->InPPDirective && !I[2]->First->HasUnescapedNewline) 6130b57cec5SDimitry Andric return 0; 6140b57cec5SDimitry Andric if (1 + I[1]->Last->TotalLength > Limit) 6150b57cec5SDimitry Andric return 0; 6160b57cec5SDimitry Andric return 1; 6170b57cec5SDimitry Andric } 6180b57cec5SDimitry Andric 6190b57cec5SDimitry Andric unsigned tryMergeSimpleControlStatement( 6200b57cec5SDimitry Andric SmallVectorImpl<AnnotatedLine *>::const_iterator I, 6210b57cec5SDimitry Andric SmallVectorImpl<AnnotatedLine *>::const_iterator E, unsigned Limit) { 6220b57cec5SDimitry Andric if (Limit == 0) 6230b57cec5SDimitry Andric return 0; 624a7dea167SDimitry Andric if (Style.BraceWrapping.AfterControlStatement == 625a7dea167SDimitry Andric FormatStyle::BWACS_Always && 626a7dea167SDimitry Andric I[1]->First->is(tok::l_brace) && 62781ad6265SDimitry Andric Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Never) { 6280b57cec5SDimitry Andric return 0; 62981ad6265SDimitry Andric } 6300b57cec5SDimitry Andric if (I[1]->InPPDirective != (*I)->InPPDirective || 63181ad6265SDimitry Andric (I[1]->InPPDirective && I[1]->First->HasUnescapedNewline)) { 6320b57cec5SDimitry Andric return 0; 63381ad6265SDimitry Andric } 6340b57cec5SDimitry Andric Limit = limitConsideringMacros(I + 1, E, Limit); 6350b57cec5SDimitry Andric AnnotatedLine &Line = **I; 6365f757f3fSDimitry Andric if (Line.First->isNot(tok::kw_do) && Line.First->isNot(tok::kw_else) && 6375f757f3fSDimitry Andric Line.Last->isNot(tok::kw_else) && Line.Last->isNot(tok::r_paren)) { 6385ffd83dbSDimitry Andric return 0; 63981ad6265SDimitry Andric } 64004eeddc0SDimitry Andric // Only merge `do while` if `do` is the only statement on the line. 6415f757f3fSDimitry Andric if (Line.First->is(tok::kw_do) && Line.Last->isNot(tok::kw_do)) 6420b57cec5SDimitry Andric return 0; 6430b57cec5SDimitry Andric if (1 + I[1]->Last->TotalLength > Limit) 6440b57cec5SDimitry Andric return 0; 64504eeddc0SDimitry Andric // Don't merge with loops, ifs, a single semicolon or a line comment. 6460b57cec5SDimitry Andric if (I[1]->First->isOneOf(tok::semi, tok::kw_if, tok::kw_for, tok::kw_while, 64781ad6265SDimitry Andric TT_ForEachMacro, TT_LineComment)) { 6480b57cec5SDimitry Andric return 0; 64981ad6265SDimitry Andric } 6500b57cec5SDimitry Andric // Only inline simple if's (no nested if or else), unless specified 651fe6060f1SDimitry Andric if (Style.AllowShortIfStatementsOnASingleLine == 652fe6060f1SDimitry Andric FormatStyle::SIS_WithoutElse) { 6530b57cec5SDimitry Andric if (I + 2 != E && Line.startsWith(tok::kw_if) && 65481ad6265SDimitry Andric I[2]->First->is(tok::kw_else)) { 6550b57cec5SDimitry Andric return 0; 6560b57cec5SDimitry Andric } 65781ad6265SDimitry Andric } 6580b57cec5SDimitry Andric return 1; 6590b57cec5SDimitry Andric } 6600b57cec5SDimitry Andric 6610b57cec5SDimitry Andric unsigned 6620b57cec5SDimitry Andric tryMergeShortCaseLabels(SmallVectorImpl<AnnotatedLine *>::const_iterator I, 6630b57cec5SDimitry Andric SmallVectorImpl<AnnotatedLine *>::const_iterator E, 6640b57cec5SDimitry Andric unsigned Limit) { 6650b57cec5SDimitry Andric if (Limit == 0 || I + 1 == E || 66681ad6265SDimitry Andric I[1]->First->isOneOf(tok::kw_case, tok::kw_default)) { 6670b57cec5SDimitry Andric return 0; 66881ad6265SDimitry Andric } 6690b57cec5SDimitry Andric if (I[0]->Last->is(tok::l_brace) || I[1]->First->is(tok::l_brace)) 6700b57cec5SDimitry Andric return 0; 6710b57cec5SDimitry Andric unsigned NumStmts = 0; 6720b57cec5SDimitry Andric unsigned Length = 0; 6730b57cec5SDimitry Andric bool EndsWithComment = false; 6740b57cec5SDimitry Andric bool InPPDirective = I[0]->InPPDirective; 675bdd1243dSDimitry Andric bool InMacroBody = I[0]->InMacroBody; 6760b57cec5SDimitry Andric const unsigned Level = I[0]->Level; 6770b57cec5SDimitry Andric for (; NumStmts < 3; ++NumStmts) { 6780b57cec5SDimitry Andric if (I + 1 + NumStmts == E) 6790b57cec5SDimitry Andric break; 6800b57cec5SDimitry Andric const AnnotatedLine *Line = I[1 + NumStmts]; 6810b57cec5SDimitry Andric if (Line->InPPDirective != InPPDirective) 6820b57cec5SDimitry Andric break; 683bdd1243dSDimitry Andric if (Line->InMacroBody != InMacroBody) 684bdd1243dSDimitry Andric break; 6850b57cec5SDimitry Andric if (Line->First->isOneOf(tok::kw_case, tok::kw_default, tok::r_brace)) 6860b57cec5SDimitry Andric break; 6870b57cec5SDimitry Andric if (Line->First->isOneOf(tok::kw_if, tok::kw_for, tok::kw_switch, 6880b57cec5SDimitry Andric tok::kw_while) || 68981ad6265SDimitry Andric EndsWithComment) { 6900b57cec5SDimitry Andric return 0; 69181ad6265SDimitry Andric } 6920b57cec5SDimitry Andric if (Line->First->is(tok::comment)) { 6930b57cec5SDimitry Andric if (Level != Line->Level) 6940b57cec5SDimitry Andric return 0; 6950b57cec5SDimitry Andric SmallVectorImpl<AnnotatedLine *>::const_iterator J = I + 2 + NumStmts; 6960b57cec5SDimitry Andric for (; J != E; ++J) { 6970b57cec5SDimitry Andric Line = *J; 6980b57cec5SDimitry Andric if (Line->InPPDirective != InPPDirective) 6990b57cec5SDimitry Andric break; 7000b57cec5SDimitry Andric if (Line->First->isOneOf(tok::kw_case, tok::kw_default, tok::r_brace)) 7010b57cec5SDimitry Andric break; 7020b57cec5SDimitry Andric if (Line->First->isNot(tok::comment) || Level != Line->Level) 7030b57cec5SDimitry Andric return 0; 7040b57cec5SDimitry Andric } 7050b57cec5SDimitry Andric break; 7060b57cec5SDimitry Andric } 7070b57cec5SDimitry Andric if (Line->Last->is(tok::comment)) 7080b57cec5SDimitry Andric EndsWithComment = true; 7090b57cec5SDimitry Andric Length += I[1 + NumStmts]->Last->TotalLength + 1; // 1 for the space. 7100b57cec5SDimitry Andric } 7110b57cec5SDimitry Andric if (NumStmts == 0 || NumStmts == 3 || Length > Limit) 7120b57cec5SDimitry Andric return 0; 7130b57cec5SDimitry Andric return NumStmts; 7140b57cec5SDimitry Andric } 7150b57cec5SDimitry Andric 7160b57cec5SDimitry Andric unsigned 7170b57cec5SDimitry Andric tryMergeSimpleBlock(SmallVectorImpl<AnnotatedLine *>::const_iterator I, 7180b57cec5SDimitry Andric SmallVectorImpl<AnnotatedLine *>::const_iterator E, 7190b57cec5SDimitry Andric unsigned Limit) { 72081ad6265SDimitry Andric // Don't merge with a preprocessor directive. 72181ad6265SDimitry Andric if (I[1]->Type == LT_PreprocessorDirective) 72281ad6265SDimitry Andric return 0; 72381ad6265SDimitry Andric 7240b57cec5SDimitry Andric AnnotatedLine &Line = **I; 7250b57cec5SDimitry Andric 7260b57cec5SDimitry Andric // Don't merge ObjC @ keywords and methods. 7270b57cec5SDimitry Andric // FIXME: If an option to allow short exception handling clauses on a single 7280b57cec5SDimitry Andric // line is added, change this to not return for @try and friends. 7290b57cec5SDimitry Andric if (Style.Language != FormatStyle::LK_Java && 73081ad6265SDimitry Andric Line.First->isOneOf(tok::at, tok::minus, tok::plus)) { 7310b57cec5SDimitry Andric return 0; 73281ad6265SDimitry Andric } 7330b57cec5SDimitry Andric 7340b57cec5SDimitry Andric // Check that the current line allows merging. This depends on whether we 7350b57cec5SDimitry Andric // are in a control flow statements as well as several style flags. 7364824e7fdSDimitry Andric if (Line.First->is(tok::kw_case) || 73781ad6265SDimitry Andric (Line.First->Next && Line.First->Next->is(tok::kw_else))) { 7380b57cec5SDimitry Andric return 0; 73981ad6265SDimitry Andric } 7400b57cec5SDimitry Andric // default: in switch statement 7410b57cec5SDimitry Andric if (Line.First->is(tok::kw_default)) { 7420b57cec5SDimitry Andric const FormatToken *Tok = Line.First->getNextNonComment(); 7430b57cec5SDimitry Andric if (Tok && Tok->is(tok::colon)) 7440b57cec5SDimitry Andric return 0; 7450b57cec5SDimitry Andric } 746bdd1243dSDimitry Andric 747bdd1243dSDimitry Andric auto IsCtrlStmt = [](const auto &Line) { 748bdd1243dSDimitry Andric return Line.First->isOneOf(tok::kw_if, tok::kw_else, tok::kw_while, 749bdd1243dSDimitry Andric tok::kw_do, tok::kw_for, TT_ForEachMacro); 750bdd1243dSDimitry Andric }; 751bdd1243dSDimitry Andric 752bdd1243dSDimitry Andric const bool IsSplitBlock = 753bdd1243dSDimitry Andric Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Never || 754bdd1243dSDimitry Andric (Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Empty && 755bdd1243dSDimitry Andric I[1]->First->isNot(tok::r_brace)); 756bdd1243dSDimitry Andric 757bdd1243dSDimitry Andric if (IsCtrlStmt(Line) || 758bdd1243dSDimitry Andric Line.First->isOneOf(tok::kw_try, tok::kw___try, tok::kw_catch, 759bdd1243dSDimitry Andric tok::kw___finally, tok::r_brace, 760bdd1243dSDimitry Andric Keywords.kw___except)) { 761bdd1243dSDimitry Andric if (IsSplitBlock) 7620b57cec5SDimitry Andric return 0; 7630b57cec5SDimitry Andric // Don't merge when we can't except the case when 7640b57cec5SDimitry Andric // the control statement block is empty 7650b57cec5SDimitry Andric if (!Style.AllowShortIfStatementsOnASingleLine && 7664824e7fdSDimitry Andric Line.First->isOneOf(tok::kw_if, tok::kw_else) && 7670b57cec5SDimitry Andric !Style.BraceWrapping.AfterControlStatement && 7685f757f3fSDimitry Andric I[1]->First->isNot(tok::r_brace)) { 7690b57cec5SDimitry Andric return 0; 77081ad6265SDimitry Andric } 7710b57cec5SDimitry Andric if (!Style.AllowShortIfStatementsOnASingleLine && 7724824e7fdSDimitry Andric Line.First->isOneOf(tok::kw_if, tok::kw_else) && 773a7dea167SDimitry Andric Style.BraceWrapping.AfterControlStatement == 774a7dea167SDimitry Andric FormatStyle::BWACS_Always && 7755f757f3fSDimitry Andric I + 2 != E && I[2]->First->isNot(tok::r_brace)) { 7760b57cec5SDimitry Andric return 0; 77781ad6265SDimitry Andric } 7780b57cec5SDimitry Andric if (!Style.AllowShortLoopsOnASingleLine && 77904eeddc0SDimitry Andric Line.First->isOneOf(tok::kw_while, tok::kw_do, tok::kw_for, 78004eeddc0SDimitry Andric TT_ForEachMacro) && 7810b57cec5SDimitry Andric !Style.BraceWrapping.AfterControlStatement && 7825f757f3fSDimitry Andric I[1]->First->isNot(tok::r_brace)) { 7830b57cec5SDimitry Andric return 0; 78481ad6265SDimitry Andric } 7850b57cec5SDimitry Andric if (!Style.AllowShortLoopsOnASingleLine && 78604eeddc0SDimitry Andric Line.First->isOneOf(tok::kw_while, tok::kw_do, tok::kw_for, 78704eeddc0SDimitry Andric TT_ForEachMacro) && 788a7dea167SDimitry Andric Style.BraceWrapping.AfterControlStatement == 789a7dea167SDimitry Andric FormatStyle::BWACS_Always && 7905f757f3fSDimitry Andric I + 2 != E && I[2]->First->isNot(tok::r_brace)) { 7910b57cec5SDimitry Andric return 0; 79281ad6265SDimitry Andric } 7930b57cec5SDimitry Andric // FIXME: Consider an option to allow short exception handling clauses on 7940b57cec5SDimitry Andric // a single line. 7950b57cec5SDimitry Andric // FIXME: This isn't covered by tests. 7960b57cec5SDimitry Andric // FIXME: For catch, __except, __finally the first token on the line 7970b57cec5SDimitry Andric // is '}', so this isn't correct here. 7980b57cec5SDimitry Andric if (Line.First->isOneOf(tok::kw_try, tok::kw___try, tok::kw_catch, 79981ad6265SDimitry Andric Keywords.kw___except, tok::kw___finally)) { 8000b57cec5SDimitry Andric return 0; 8010b57cec5SDimitry Andric } 80281ad6265SDimitry Andric } 8030b57cec5SDimitry Andric 804*0fca6ea1SDimitry Andric if (Line.endsWith(tok::l_brace)) { 805*0fca6ea1SDimitry Andric if (Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Never && 806*0fca6ea1SDimitry Andric Line.First->is(TT_BlockLBrace)) { 807*0fca6ea1SDimitry Andric return 0; 808*0fca6ea1SDimitry Andric } 809*0fca6ea1SDimitry Andric 810bdd1243dSDimitry Andric if (IsSplitBlock && Line.First == Line.Last && 811bdd1243dSDimitry Andric I > AnnotatedLines.begin() && 812bdd1243dSDimitry Andric (I[-1]->endsWith(tok::kw_else) || IsCtrlStmt(*I[-1]))) { 813bdd1243dSDimitry Andric return 0; 814bdd1243dSDimitry Andric } 8150b57cec5SDimitry Andric FormatToken *Tok = I[1]->First; 81681ad6265SDimitry Andric auto ShouldMerge = [Tok]() { 81781ad6265SDimitry Andric if (Tok->isNot(tok::r_brace) || Tok->MustBreakBefore) 81881ad6265SDimitry Andric return false; 81981ad6265SDimitry Andric const FormatToken *Next = Tok->getNextNonComment(); 82081ad6265SDimitry Andric return !Next || Next->is(tok::semi); 82181ad6265SDimitry Andric }; 82281ad6265SDimitry Andric 82381ad6265SDimitry Andric if (ShouldMerge()) { 8240b57cec5SDimitry Andric // We merge empty blocks even if the line exceeds the column limit. 8255f757f3fSDimitry Andric Tok->SpacesRequiredBefore = 8265f757f3fSDimitry Andric (Style.SpaceInEmptyBlock || Line.Last->is(tok::comment)) ? 1 : 0; 8270b57cec5SDimitry Andric Tok->CanBreakBefore = true; 8280b57cec5SDimitry Andric return 1; 8290b57cec5SDimitry Andric } else if (Limit != 0 && !Line.startsWithNamespace() && 8300b57cec5SDimitry Andric !startsExternCBlock(Line)) { 8310b57cec5SDimitry Andric // We don't merge short records. 83281ad6265SDimitry Andric if (isRecordLBrace(*Line.Last)) 8330b57cec5SDimitry Andric return 0; 8340b57cec5SDimitry Andric 8350b57cec5SDimitry Andric // Check that we still have three lines and they fit into the limit. 8360b57cec5SDimitry Andric if (I + 2 == E || I[2]->Type == LT_Invalid) 8370b57cec5SDimitry Andric return 0; 8380b57cec5SDimitry Andric Limit = limitConsideringMacros(I + 2, E, Limit); 8390b57cec5SDimitry Andric 8400b57cec5SDimitry Andric if (!nextTwoLinesFitInto(I, Limit)) 8410b57cec5SDimitry Andric return 0; 8420b57cec5SDimitry Andric 8430b57cec5SDimitry Andric // Second, check that the next line does not contain any braces - if it 8440b57cec5SDimitry Andric // does, readability declines when putting it into a single line. 8450b57cec5SDimitry Andric if (I[1]->Last->is(TT_LineComment)) 8460b57cec5SDimitry Andric return 0; 8470b57cec5SDimitry Andric do { 848e8d8bef9SDimitry Andric if (Tok->is(tok::l_brace) && Tok->isNot(BK_BracedInit)) 8490b57cec5SDimitry Andric return 0; 8500b57cec5SDimitry Andric Tok = Tok->Next; 8510b57cec5SDimitry Andric } while (Tok); 8520b57cec5SDimitry Andric 8530b57cec5SDimitry Andric // Last, check that the third line starts with a closing brace. 8540b57cec5SDimitry Andric Tok = I[2]->First; 8550b57cec5SDimitry Andric if (Tok->isNot(tok::r_brace)) 8560b57cec5SDimitry Andric return 0; 8570b57cec5SDimitry Andric 8580b57cec5SDimitry Andric // Don't merge "if (a) { .. } else {". 8590b57cec5SDimitry Andric if (Tok->Next && Tok->Next->is(tok::kw_else)) 8600b57cec5SDimitry Andric return 0; 8610b57cec5SDimitry Andric 862a7dea167SDimitry Andric // Don't merge a trailing multi-line control statement block like: 863a7dea167SDimitry Andric // } else if (foo && 864a7dea167SDimitry Andric // bar) 865a7dea167SDimitry Andric // { <-- current Line 866a7dea167SDimitry Andric // baz(); 867a7dea167SDimitry Andric // } 8684824e7fdSDimitry Andric if (Line.First == Line.Last && Line.First->isNot(TT_FunctionLBrace) && 869a7dea167SDimitry Andric Style.BraceWrapping.AfterControlStatement == 87081ad6265SDimitry Andric FormatStyle::BWACS_MultiLine) { 871a7dea167SDimitry Andric return 0; 87281ad6265SDimitry Andric } 873a7dea167SDimitry Andric 8740b57cec5SDimitry Andric return 2; 8750b57cec5SDimitry Andric } 8760b57cec5SDimitry Andric } else if (I[1]->First->is(tok::l_brace)) { 8770b57cec5SDimitry Andric if (I[1]->Last->is(TT_LineComment)) 8780b57cec5SDimitry Andric return 0; 8790b57cec5SDimitry Andric 8800b57cec5SDimitry Andric // Check for Limit <= 2 to account for the " {". 8810b57cec5SDimitry Andric if (Limit <= 2 || (Style.ColumnLimit == 0 && containsMustBreak(*I))) 8820b57cec5SDimitry Andric return 0; 8830b57cec5SDimitry Andric Limit -= 2; 8840b57cec5SDimitry Andric unsigned MergedLines = 0; 885a7dea167SDimitry Andric if (Style.AllowShortBlocksOnASingleLine != FormatStyle::SBS_Never || 8860b57cec5SDimitry Andric (I[1]->First == I[1]->Last && I + 2 != E && 8870b57cec5SDimitry Andric I[2]->First->is(tok::r_brace))) { 8880b57cec5SDimitry Andric MergedLines = tryMergeSimpleBlock(I + 1, E, Limit); 8890b57cec5SDimitry Andric // If we managed to merge the block, count the statement header, which 8900b57cec5SDimitry Andric // is on a separate line. 8910b57cec5SDimitry Andric if (MergedLines > 0) 8920b57cec5SDimitry Andric ++MergedLines; 8930b57cec5SDimitry Andric } 8940b57cec5SDimitry Andric return MergedLines; 8950b57cec5SDimitry Andric } 8960b57cec5SDimitry Andric return 0; 8970b57cec5SDimitry Andric } 8980b57cec5SDimitry Andric 8990b57cec5SDimitry Andric /// Returns the modified column limit for \p I if it is inside a macro and 9000b57cec5SDimitry Andric /// needs a trailing '\'. 9010b57cec5SDimitry Andric unsigned 9020b57cec5SDimitry Andric limitConsideringMacros(SmallVectorImpl<AnnotatedLine *>::const_iterator I, 9030b57cec5SDimitry Andric SmallVectorImpl<AnnotatedLine *>::const_iterator E, 9040b57cec5SDimitry Andric unsigned Limit) { 9050b57cec5SDimitry Andric if (I[0]->InPPDirective && I + 1 != E && 9065f757f3fSDimitry Andric !I[1]->First->HasUnescapedNewline && I[1]->First->isNot(tok::eof)) { 9070b57cec5SDimitry Andric return Limit < 2 ? 0 : Limit - 2; 9080b57cec5SDimitry Andric } 9090b57cec5SDimitry Andric return Limit; 9100b57cec5SDimitry Andric } 9110b57cec5SDimitry Andric 9120b57cec5SDimitry Andric bool nextTwoLinesFitInto(SmallVectorImpl<AnnotatedLine *>::const_iterator I, 9130b57cec5SDimitry Andric unsigned Limit) { 9140b57cec5SDimitry Andric if (I[1]->First->MustBreakBefore || I[2]->First->MustBreakBefore) 9150b57cec5SDimitry Andric return false; 9160b57cec5SDimitry Andric return 1 + I[1]->Last->TotalLength + 1 + I[2]->Last->TotalLength <= Limit; 9170b57cec5SDimitry Andric } 9180b57cec5SDimitry Andric 9190b57cec5SDimitry Andric bool containsMustBreak(const AnnotatedLine *Line) { 92006c3fb27SDimitry Andric assert(Line->First); 92106c3fb27SDimitry Andric // Ignore the first token, because in this situation, it applies more to the 92206c3fb27SDimitry Andric // last token of the previous line. 92306c3fb27SDimitry Andric for (const FormatToken *Tok = Line->First->Next; Tok; Tok = Tok->Next) 9240b57cec5SDimitry Andric if (Tok->MustBreakBefore) 9250b57cec5SDimitry Andric return true; 9260b57cec5SDimitry Andric return false; 9270b57cec5SDimitry Andric } 9280b57cec5SDimitry Andric 9290b57cec5SDimitry Andric void join(AnnotatedLine &A, const AnnotatedLine &B) { 9300b57cec5SDimitry Andric assert(!A.Last->Next); 9310b57cec5SDimitry Andric assert(!B.First->Previous); 9320b57cec5SDimitry Andric if (B.Affected) 9330b57cec5SDimitry Andric A.Affected = true; 9340b57cec5SDimitry Andric A.Last->Next = B.First; 9350b57cec5SDimitry Andric B.First->Previous = A.Last; 9360b57cec5SDimitry Andric B.First->CanBreakBefore = true; 9370b57cec5SDimitry Andric unsigned LengthA = A.Last->TotalLength + B.First->SpacesRequiredBefore; 9380b57cec5SDimitry Andric for (FormatToken *Tok = B.First; Tok; Tok = Tok->Next) { 9390b57cec5SDimitry Andric Tok->TotalLength += LengthA; 9400b57cec5SDimitry Andric A.Last = Tok; 9410b57cec5SDimitry Andric } 9420b57cec5SDimitry Andric } 9430b57cec5SDimitry Andric 9440b57cec5SDimitry Andric const FormatStyle &Style; 9450b57cec5SDimitry Andric const AdditionalKeywords &Keywords; 9460b57cec5SDimitry Andric const SmallVectorImpl<AnnotatedLine *>::const_iterator End; 9470b57cec5SDimitry Andric 9480b57cec5SDimitry Andric SmallVectorImpl<AnnotatedLine *>::const_iterator Next; 9490b57cec5SDimitry Andric const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines; 9500b57cec5SDimitry Andric }; 9510b57cec5SDimitry Andric 9520b57cec5SDimitry Andric static void markFinalized(FormatToken *Tok) { 9535f757f3fSDimitry Andric if (Tok->is(tok::hash) && !Tok->Previous && Tok->Next && 9545f757f3fSDimitry Andric Tok->Next->isOneOf(tok::pp_if, tok::pp_ifdef, tok::pp_ifndef, 9555f757f3fSDimitry Andric tok::pp_elif, tok::pp_elifdef, tok::pp_elifndef, 9565f757f3fSDimitry Andric tok::pp_else, tok::pp_endif)) { 9575f757f3fSDimitry Andric Tok = Tok->Next; 9585f757f3fSDimitry Andric } 9590b57cec5SDimitry Andric for (; Tok; Tok = Tok->Next) { 96006c3fb27SDimitry Andric if (Tok->MacroCtx && Tok->MacroCtx->Role == MR_ExpandedArg) { 96106c3fb27SDimitry Andric // In the first pass we format all macro arguments in the expanded token 96206c3fb27SDimitry Andric // stream. Instead of finalizing the macro arguments, we mark that they 96306c3fb27SDimitry Andric // will be modified as unexpanded arguments (as part of the macro call 96406c3fb27SDimitry Andric // formatting) in the next pass. 96506c3fb27SDimitry Andric Tok->MacroCtx->Role = MR_UnexpandedArg; 966297eecfbSDimitry Andric // Reset whether spaces or a line break are required before this token, as 967297eecfbSDimitry Andric // that is context dependent, and that context may change when formatting 968297eecfbSDimitry Andric // the macro call. For example, given M(x) -> 2 * x, and the macro call 969297eecfbSDimitry Andric // M(var), the token 'var' will have SpacesRequiredBefore = 1 after being 97006c3fb27SDimitry Andric // formatted as part of the expanded macro, but SpacesRequiredBefore = 0 97106c3fb27SDimitry Andric // for its position within the macro call. 97206c3fb27SDimitry Andric Tok->SpacesRequiredBefore = 0; 973297eecfbSDimitry Andric if (!Tok->MustBreakBeforeFinalized) 974297eecfbSDimitry Andric Tok->MustBreakBefore = 0; 97506c3fb27SDimitry Andric } else { 9760b57cec5SDimitry Andric Tok->Finalized = true; 97706c3fb27SDimitry Andric } 9780b57cec5SDimitry Andric } 9790b57cec5SDimitry Andric } 9800b57cec5SDimitry Andric 9810b57cec5SDimitry Andric #ifndef NDEBUG 9820b57cec5SDimitry Andric static void printLineState(const LineState &State) { 9830b57cec5SDimitry Andric llvm::dbgs() << "State: "; 9840b57cec5SDimitry Andric for (const ParenState &P : State.Stack) { 9850b57cec5SDimitry Andric llvm::dbgs() << (P.Tok ? P.Tok->TokenText : "F") << "|" << P.Indent << "|" 9860b57cec5SDimitry Andric << P.LastSpace << "|" << P.NestedBlockIndent << " "; 9870b57cec5SDimitry Andric } 9880b57cec5SDimitry Andric llvm::dbgs() << State.NextToken->TokenText << "\n"; 9890b57cec5SDimitry Andric } 9900b57cec5SDimitry Andric #endif 9910b57cec5SDimitry Andric 9920b57cec5SDimitry Andric /// Base class for classes that format one \c AnnotatedLine. 9930b57cec5SDimitry Andric class LineFormatter { 9940b57cec5SDimitry Andric public: 9950b57cec5SDimitry Andric LineFormatter(ContinuationIndenter *Indenter, WhitespaceManager *Whitespaces, 9960b57cec5SDimitry Andric const FormatStyle &Style, 9970b57cec5SDimitry Andric UnwrappedLineFormatter *BlockFormatter) 9980b57cec5SDimitry Andric : Indenter(Indenter), Whitespaces(Whitespaces), Style(Style), 9990b57cec5SDimitry Andric BlockFormatter(BlockFormatter) {} 10000b57cec5SDimitry Andric virtual ~LineFormatter() {} 10010b57cec5SDimitry Andric 10020b57cec5SDimitry Andric /// Formats an \c AnnotatedLine and returns the penalty. 10030b57cec5SDimitry Andric /// 10040b57cec5SDimitry Andric /// If \p DryRun is \c false, directly applies the changes. 10050b57cec5SDimitry Andric virtual unsigned formatLine(const AnnotatedLine &Line, unsigned FirstIndent, 10060b57cec5SDimitry Andric unsigned FirstStartColumn, bool DryRun) = 0; 10070b57cec5SDimitry Andric 10080b57cec5SDimitry Andric protected: 10090b57cec5SDimitry Andric /// If the \p State's next token is an r_brace closing a nested block, 10100b57cec5SDimitry Andric /// format the nested block before it. 10110b57cec5SDimitry Andric /// 10120b57cec5SDimitry Andric /// Returns \c true if all children could be placed successfully and adapts 10130b57cec5SDimitry Andric /// \p Penalty as well as \p State. If \p DryRun is false, also directly 10140b57cec5SDimitry Andric /// creates changes using \c Whitespaces. 10150b57cec5SDimitry Andric /// 10160b57cec5SDimitry Andric /// The crucial idea here is that children always get formatted upon 10170b57cec5SDimitry Andric /// encountering the closing brace right after the nested block. Now, if we 10180b57cec5SDimitry Andric /// are currently trying to keep the "}" on the same line (i.e. \p NewLine is 10190b57cec5SDimitry Andric /// \c false), the entire block has to be kept on the same line (which is only 10200b57cec5SDimitry Andric /// possible if it fits on the line, only contains a single statement, etc. 10210b57cec5SDimitry Andric /// 10220b57cec5SDimitry Andric /// If \p NewLine is true, we format the nested block on separate lines, i.e. 10230b57cec5SDimitry Andric /// break after the "{", format all lines with correct indentation and the put 10240b57cec5SDimitry Andric /// the closing "}" on yet another new line. 10250b57cec5SDimitry Andric /// 10260b57cec5SDimitry Andric /// This enables us to keep the simple structure of the 10270b57cec5SDimitry Andric /// \c UnwrappedLineFormatter, where we only have two options for each token: 10280b57cec5SDimitry Andric /// break or don't break. 10290b57cec5SDimitry Andric bool formatChildren(LineState &State, bool NewLine, bool DryRun, 10300b57cec5SDimitry Andric unsigned &Penalty) { 10310b57cec5SDimitry Andric const FormatToken *LBrace = State.NextToken->getPreviousNonComment(); 103206c3fb27SDimitry Andric bool HasLBrace = LBrace && LBrace->is(tok::l_brace) && LBrace->is(BK_Block); 10330b57cec5SDimitry Andric FormatToken &Previous = *State.NextToken->Previous; 103406c3fb27SDimitry Andric if (Previous.Children.size() == 0 || (!HasLBrace && !LBrace->MacroParent)) { 10350b57cec5SDimitry Andric // The previous token does not open a block. Nothing to do. We don't 10360b57cec5SDimitry Andric // assert so that we can simply call this function for all tokens. 10370b57cec5SDimitry Andric return true; 103881ad6265SDimitry Andric } 10390b57cec5SDimitry Andric 104006c3fb27SDimitry Andric if (NewLine || Previous.MacroParent) { 1041fe6060f1SDimitry Andric const ParenState &P = State.Stack.back(); 1042fe6060f1SDimitry Andric 1043fe6060f1SDimitry Andric int AdditionalIndent = 1044fe6060f1SDimitry Andric P.Indent - Previous.Children[0]->Level * Style.IndentWidth; 10450b57cec5SDimitry Andric Penalty += 10460b57cec5SDimitry Andric BlockFormatter->format(Previous.Children, DryRun, AdditionalIndent, 10470b57cec5SDimitry Andric /*FixBadIndentation=*/true); 10480b57cec5SDimitry Andric return true; 10490b57cec5SDimitry Andric } 10500b57cec5SDimitry Andric 10510b57cec5SDimitry Andric if (Previous.Children[0]->First->MustBreakBefore) 10520b57cec5SDimitry Andric return false; 10530b57cec5SDimitry Andric 10540b57cec5SDimitry Andric // Cannot merge into one line if this line ends on a comment. 10550b57cec5SDimitry Andric if (Previous.is(tok::comment)) 10560b57cec5SDimitry Andric return false; 10570b57cec5SDimitry Andric 10580b57cec5SDimitry Andric // Cannot merge multiple statements into a single line. 10590b57cec5SDimitry Andric if (Previous.Children.size() > 1) 10600b57cec5SDimitry Andric return false; 10610b57cec5SDimitry Andric 10620b57cec5SDimitry Andric const AnnotatedLine *Child = Previous.Children[0]; 10630b57cec5SDimitry Andric // We can't put the closing "}" on a line with a trailing comment. 10640b57cec5SDimitry Andric if (Child->Last->isTrailingComment()) 10650b57cec5SDimitry Andric return false; 10660b57cec5SDimitry Andric 10670b57cec5SDimitry Andric // If the child line exceeds the column limit, we wouldn't want to merge it. 10680b57cec5SDimitry Andric // We add +2 for the trailing " }". 10690b57cec5SDimitry Andric if (Style.ColumnLimit > 0 && 107081ad6265SDimitry Andric Child->Last->TotalLength + State.Column + 2 > Style.ColumnLimit) { 10710b57cec5SDimitry Andric return false; 107281ad6265SDimitry Andric } 10730b57cec5SDimitry Andric 10740b57cec5SDimitry Andric if (!DryRun) { 10750b57cec5SDimitry Andric Whitespaces->replaceWhitespace( 10760b57cec5SDimitry Andric *Child->First, /*Newlines=*/0, /*Spaces=*/1, 10775ffd83dbSDimitry Andric /*StartOfTokenColumn=*/State.Column, /*IsAligned=*/false, 10785ffd83dbSDimitry Andric State.Line->InPPDirective); 10790b57cec5SDimitry Andric } 10800b57cec5SDimitry Andric Penalty += 10810b57cec5SDimitry Andric formatLine(*Child, State.Column + 1, /*FirstStartColumn=*/0, DryRun); 10825f757f3fSDimitry Andric if (!DryRun) 10835f757f3fSDimitry Andric markFinalized(Child->First); 10840b57cec5SDimitry Andric 10850b57cec5SDimitry Andric State.Column += 1 + Child->Last->TotalLength; 10860b57cec5SDimitry Andric return true; 10870b57cec5SDimitry Andric } 10880b57cec5SDimitry Andric 10890b57cec5SDimitry Andric ContinuationIndenter *Indenter; 10900b57cec5SDimitry Andric 10910b57cec5SDimitry Andric private: 10920b57cec5SDimitry Andric WhitespaceManager *Whitespaces; 10930b57cec5SDimitry Andric const FormatStyle &Style; 10940b57cec5SDimitry Andric UnwrappedLineFormatter *BlockFormatter; 10950b57cec5SDimitry Andric }; 10960b57cec5SDimitry Andric 10970b57cec5SDimitry Andric /// Formatter that keeps the existing line breaks. 10980b57cec5SDimitry Andric class NoColumnLimitLineFormatter : public LineFormatter { 10990b57cec5SDimitry Andric public: 11000b57cec5SDimitry Andric NoColumnLimitLineFormatter(ContinuationIndenter *Indenter, 11010b57cec5SDimitry Andric WhitespaceManager *Whitespaces, 11020b57cec5SDimitry Andric const FormatStyle &Style, 11030b57cec5SDimitry Andric UnwrappedLineFormatter *BlockFormatter) 11040b57cec5SDimitry Andric : LineFormatter(Indenter, Whitespaces, Style, BlockFormatter) {} 11050b57cec5SDimitry Andric 11060b57cec5SDimitry Andric /// Formats the line, simply keeping all of the input's line breaking 11070b57cec5SDimitry Andric /// decisions. 11080b57cec5SDimitry Andric unsigned formatLine(const AnnotatedLine &Line, unsigned FirstIndent, 11090b57cec5SDimitry Andric unsigned FirstStartColumn, bool DryRun) override { 11100b57cec5SDimitry Andric assert(!DryRun); 11110b57cec5SDimitry Andric LineState State = Indenter->getInitialState(FirstIndent, FirstStartColumn, 11120b57cec5SDimitry Andric &Line, /*DryRun=*/false); 11130b57cec5SDimitry Andric while (State.NextToken) { 11140b57cec5SDimitry Andric bool Newline = 11150b57cec5SDimitry Andric Indenter->mustBreak(State) || 11160b57cec5SDimitry Andric (Indenter->canBreak(State) && State.NextToken->NewlinesBefore > 0); 11170b57cec5SDimitry Andric unsigned Penalty = 0; 11180b57cec5SDimitry Andric formatChildren(State, Newline, /*DryRun=*/false, Penalty); 11190b57cec5SDimitry Andric Indenter->addTokenToState(State, Newline, /*DryRun=*/false); 11200b57cec5SDimitry Andric } 11210b57cec5SDimitry Andric return 0; 11220b57cec5SDimitry Andric } 11230b57cec5SDimitry Andric }; 11240b57cec5SDimitry Andric 11250b57cec5SDimitry Andric /// Formatter that puts all tokens into a single line without breaks. 11260b57cec5SDimitry Andric class NoLineBreakFormatter : public LineFormatter { 11270b57cec5SDimitry Andric public: 11280b57cec5SDimitry Andric NoLineBreakFormatter(ContinuationIndenter *Indenter, 11290b57cec5SDimitry Andric WhitespaceManager *Whitespaces, const FormatStyle &Style, 11300b57cec5SDimitry Andric UnwrappedLineFormatter *BlockFormatter) 11310b57cec5SDimitry Andric : LineFormatter(Indenter, Whitespaces, Style, BlockFormatter) {} 11320b57cec5SDimitry Andric 11330b57cec5SDimitry Andric /// Puts all tokens into a single line. 11340b57cec5SDimitry Andric unsigned formatLine(const AnnotatedLine &Line, unsigned FirstIndent, 11350b57cec5SDimitry Andric unsigned FirstStartColumn, bool DryRun) override { 11360b57cec5SDimitry Andric unsigned Penalty = 0; 11370b57cec5SDimitry Andric LineState State = 11380b57cec5SDimitry Andric Indenter->getInitialState(FirstIndent, FirstStartColumn, &Line, DryRun); 11390b57cec5SDimitry Andric while (State.NextToken) { 11400b57cec5SDimitry Andric formatChildren(State, /*NewLine=*/false, DryRun, Penalty); 11410b57cec5SDimitry Andric Indenter->addTokenToState( 11420b57cec5SDimitry Andric State, /*Newline=*/State.NextToken->MustBreakBefore, DryRun); 11430b57cec5SDimitry Andric } 11440b57cec5SDimitry Andric return Penalty; 11450b57cec5SDimitry Andric } 11460b57cec5SDimitry Andric }; 11470b57cec5SDimitry Andric 11480b57cec5SDimitry Andric /// Finds the best way to break lines. 11490b57cec5SDimitry Andric class OptimizingLineFormatter : public LineFormatter { 11500b57cec5SDimitry Andric public: 11510b57cec5SDimitry Andric OptimizingLineFormatter(ContinuationIndenter *Indenter, 11520b57cec5SDimitry Andric WhitespaceManager *Whitespaces, 11530b57cec5SDimitry Andric const FormatStyle &Style, 11540b57cec5SDimitry Andric UnwrappedLineFormatter *BlockFormatter) 11550b57cec5SDimitry Andric : LineFormatter(Indenter, Whitespaces, Style, BlockFormatter) {} 11560b57cec5SDimitry Andric 11570b57cec5SDimitry Andric /// Formats the line by finding the best line breaks with line lengths 11580b57cec5SDimitry Andric /// below the column limit. 11590b57cec5SDimitry Andric unsigned formatLine(const AnnotatedLine &Line, unsigned FirstIndent, 11600b57cec5SDimitry Andric unsigned FirstStartColumn, bool DryRun) override { 11610b57cec5SDimitry Andric LineState State = 11620b57cec5SDimitry Andric Indenter->getInitialState(FirstIndent, FirstStartColumn, &Line, DryRun); 11630b57cec5SDimitry Andric 11640b57cec5SDimitry Andric // If the ObjC method declaration does not fit on a line, we should format 11650b57cec5SDimitry Andric // it with one arg per line. 11660b57cec5SDimitry Andric if (State.Line->Type == LT_ObjCMethodDecl) 11670b57cec5SDimitry Andric State.Stack.back().BreakBeforeParameter = true; 11680b57cec5SDimitry Andric 11690b57cec5SDimitry Andric // Find best solution in solution space. 11700b57cec5SDimitry Andric return analyzeSolutionSpace(State, DryRun); 11710b57cec5SDimitry Andric } 11720b57cec5SDimitry Andric 11730b57cec5SDimitry Andric private: 11740b57cec5SDimitry Andric struct CompareLineStatePointers { 11750b57cec5SDimitry Andric bool operator()(LineState *obj1, LineState *obj2) const { 11760b57cec5SDimitry Andric return *obj1 < *obj2; 11770b57cec5SDimitry Andric } 11780b57cec5SDimitry Andric }; 11790b57cec5SDimitry Andric 11800b57cec5SDimitry Andric /// A pair of <penalty, count> that is used to prioritize the BFS on. 11810b57cec5SDimitry Andric /// 11820b57cec5SDimitry Andric /// In case of equal penalties, we want to prefer states that were inserted 11830b57cec5SDimitry Andric /// first. During state generation we make sure that we insert states first 11840b57cec5SDimitry Andric /// that break the line as late as possible. 11850b57cec5SDimitry Andric typedef std::pair<unsigned, unsigned> OrderedPenalty; 11860b57cec5SDimitry Andric 11870b57cec5SDimitry Andric /// An edge in the solution space from \c Previous->State to \c State, 11880b57cec5SDimitry Andric /// inserting a newline dependent on the \c NewLine. 11890b57cec5SDimitry Andric struct StateNode { 11900b57cec5SDimitry Andric StateNode(const LineState &State, bool NewLine, StateNode *Previous) 11910b57cec5SDimitry Andric : State(State), NewLine(NewLine), Previous(Previous) {} 11920b57cec5SDimitry Andric LineState State; 11930b57cec5SDimitry Andric bool NewLine; 11940b57cec5SDimitry Andric StateNode *Previous; 11950b57cec5SDimitry Andric }; 11960b57cec5SDimitry Andric 11970b57cec5SDimitry Andric /// An item in the prioritized BFS search queue. The \c StateNode's 11980b57cec5SDimitry Andric /// \c State has the given \c OrderedPenalty. 11990b57cec5SDimitry Andric typedef std::pair<OrderedPenalty, StateNode *> QueueItem; 12000b57cec5SDimitry Andric 12010b57cec5SDimitry Andric /// The BFS queue type. 1202753f127fSDimitry Andric typedef std::priority_queue<QueueItem, SmallVector<QueueItem>, 12030b57cec5SDimitry Andric std::greater<QueueItem>> 12040b57cec5SDimitry Andric QueueType; 12050b57cec5SDimitry Andric 12060b57cec5SDimitry Andric /// Analyze the entire solution space starting from \p InitialState. 12070b57cec5SDimitry Andric /// 12080b57cec5SDimitry Andric /// This implements a variant of Dijkstra's algorithm on the graph that spans 12090b57cec5SDimitry Andric /// the solution space (\c LineStates are the nodes). The algorithm tries to 12100b57cec5SDimitry Andric /// find the shortest path (the one with lowest penalty) from \p InitialState 12110b57cec5SDimitry Andric /// to a state where all tokens are placed. Returns the penalty. 12120b57cec5SDimitry Andric /// 12130b57cec5SDimitry Andric /// If \p DryRun is \c false, directly applies the changes. 12140b57cec5SDimitry Andric unsigned analyzeSolutionSpace(LineState &InitialState, bool DryRun) { 12150b57cec5SDimitry Andric std::set<LineState *, CompareLineStatePointers> Seen; 12160b57cec5SDimitry Andric 12170b57cec5SDimitry Andric // Increasing count of \c StateNode items we have created. This is used to 12180b57cec5SDimitry Andric // create a deterministic order independent of the container. 12190b57cec5SDimitry Andric unsigned Count = 0; 12200b57cec5SDimitry Andric QueueType Queue; 12210b57cec5SDimitry Andric 12220b57cec5SDimitry Andric // Insert start element into queue. 12230eae32dcSDimitry Andric StateNode *RootNode = 12240b57cec5SDimitry Andric new (Allocator.Allocate()) StateNode(InitialState, false, nullptr); 12250eae32dcSDimitry Andric Queue.push(QueueItem(OrderedPenalty(0, Count), RootNode)); 12260b57cec5SDimitry Andric ++Count; 12270b57cec5SDimitry Andric 12280b57cec5SDimitry Andric unsigned Penalty = 0; 12290b57cec5SDimitry Andric 12300b57cec5SDimitry Andric // While not empty, take first element and follow edges. 12310b57cec5SDimitry Andric while (!Queue.empty()) { 123281ad6265SDimitry Andric // Quit if we still haven't found a solution by now. 1233*0fca6ea1SDimitry Andric if (Count > 25'000'000) 123481ad6265SDimitry Andric return 0; 123581ad6265SDimitry Andric 12360b57cec5SDimitry Andric Penalty = Queue.top().first.first; 12370b57cec5SDimitry Andric StateNode *Node = Queue.top().second; 12380b57cec5SDimitry Andric if (!Node->State.NextToken) { 12390b57cec5SDimitry Andric LLVM_DEBUG(llvm::dbgs() 12400b57cec5SDimitry Andric << "\n---\nPenalty for line: " << Penalty << "\n"); 12410b57cec5SDimitry Andric break; 12420b57cec5SDimitry Andric } 12430b57cec5SDimitry Andric Queue.pop(); 12440b57cec5SDimitry Andric 12450b57cec5SDimitry Andric // Cut off the analysis of certain solutions if the analysis gets too 12460b57cec5SDimitry Andric // complex. See description of IgnoreStackForComparison. 1247*0fca6ea1SDimitry Andric if (Count > 50'000) 12480b57cec5SDimitry Andric Node->State.IgnoreStackForComparison = true; 12490b57cec5SDimitry Andric 125081ad6265SDimitry Andric if (!Seen.insert(&Node->State).second) { 12510b57cec5SDimitry Andric // State already examined with lower penalty. 12520b57cec5SDimitry Andric continue; 125381ad6265SDimitry Andric } 12540b57cec5SDimitry Andric 1255e8d8bef9SDimitry Andric FormatDecision LastFormat = Node->State.NextToken->getDecision(); 12560b57cec5SDimitry Andric if (LastFormat == FD_Unformatted || LastFormat == FD_Continue) 125704eeddc0SDimitry Andric addNextStateToQueue(Penalty, Node, /*NewLine=*/false, &Count, &Queue); 12580b57cec5SDimitry Andric if (LastFormat == FD_Unformatted || LastFormat == FD_Break) 125904eeddc0SDimitry Andric addNextStateToQueue(Penalty, Node, /*NewLine=*/true, &Count, &Queue); 12600b57cec5SDimitry Andric } 12610b57cec5SDimitry Andric 12620b57cec5SDimitry Andric if (Queue.empty()) { 12630b57cec5SDimitry Andric // We were unable to find a solution, do nothing. 12640b57cec5SDimitry Andric // FIXME: Add diagnostic? 12650b57cec5SDimitry Andric LLVM_DEBUG(llvm::dbgs() << "Could not find a solution.\n"); 12660b57cec5SDimitry Andric return 0; 12670b57cec5SDimitry Andric } 12680b57cec5SDimitry Andric 12690b57cec5SDimitry Andric // Reconstruct the solution. 12700b57cec5SDimitry Andric if (!DryRun) 12710b57cec5SDimitry Andric reconstructPath(InitialState, Queue.top().second); 12720b57cec5SDimitry Andric 12730b57cec5SDimitry Andric LLVM_DEBUG(llvm::dbgs() 12740b57cec5SDimitry Andric << "Total number of analyzed states: " << Count << "\n"); 12750b57cec5SDimitry Andric LLVM_DEBUG(llvm::dbgs() << "---\n"); 12760b57cec5SDimitry Andric 12770b57cec5SDimitry Andric return Penalty; 12780b57cec5SDimitry Andric } 12790b57cec5SDimitry Andric 12800b57cec5SDimitry Andric /// Add the following state to the analysis queue \c Queue. 12810b57cec5SDimitry Andric /// 12820b57cec5SDimitry Andric /// Assume the current state is \p PreviousNode and has been reached with a 12830b57cec5SDimitry Andric /// penalty of \p Penalty. Insert a line break if \p NewLine is \c true. 12840b57cec5SDimitry Andric void addNextStateToQueue(unsigned Penalty, StateNode *PreviousNode, 128504eeddc0SDimitry Andric bool NewLine, unsigned *Count, QueueType *Queue) { 12860b57cec5SDimitry Andric if (NewLine && !Indenter->canBreak(PreviousNode->State)) 12870b57cec5SDimitry Andric return; 12880b57cec5SDimitry Andric if (!NewLine && Indenter->mustBreak(PreviousNode->State)) 12890b57cec5SDimitry Andric return; 12900b57cec5SDimitry Andric 12910b57cec5SDimitry Andric StateNode *Node = new (Allocator.Allocate()) 12920b57cec5SDimitry Andric StateNode(PreviousNode->State, NewLine, PreviousNode); 12930b57cec5SDimitry Andric if (!formatChildren(Node->State, NewLine, /*DryRun=*/true, Penalty)) 12940b57cec5SDimitry Andric return; 12950b57cec5SDimitry Andric 12960b57cec5SDimitry Andric Penalty += Indenter->addTokenToState(Node->State, NewLine, true); 12970b57cec5SDimitry Andric 129804eeddc0SDimitry Andric Queue->push(QueueItem(OrderedPenalty(Penalty, *Count), Node)); 129904eeddc0SDimitry Andric ++(*Count); 13000b57cec5SDimitry Andric } 13010b57cec5SDimitry Andric 13020b57cec5SDimitry Andric /// Applies the best formatting by reconstructing the path in the 13030b57cec5SDimitry Andric /// solution space that leads to \c Best. 13040b57cec5SDimitry Andric void reconstructPath(LineState &State, StateNode *Best) { 130504eeddc0SDimitry Andric llvm::SmallVector<StateNode *> Path; 13060b57cec5SDimitry Andric // We do not need a break before the initial token. 13070b57cec5SDimitry Andric while (Best->Previous) { 130804eeddc0SDimitry Andric Path.push_back(Best); 13090b57cec5SDimitry Andric Best = Best->Previous; 13100b57cec5SDimitry Andric } 131104eeddc0SDimitry Andric for (const auto &Node : llvm::reverse(Path)) { 13120b57cec5SDimitry Andric unsigned Penalty = 0; 131304eeddc0SDimitry Andric formatChildren(State, Node->NewLine, /*DryRun=*/false, Penalty); 131404eeddc0SDimitry Andric Penalty += Indenter->addTokenToState(State, Node->NewLine, false); 13150b57cec5SDimitry Andric 13160b57cec5SDimitry Andric LLVM_DEBUG({ 131704eeddc0SDimitry Andric printLineState(Node->Previous->State); 131804eeddc0SDimitry Andric if (Node->NewLine) { 13190b57cec5SDimitry Andric llvm::dbgs() << "Penalty for placing " 132004eeddc0SDimitry Andric << Node->Previous->State.NextToken->Tok.getName() 13210b57cec5SDimitry Andric << " on a new line: " << Penalty << "\n"; 13220b57cec5SDimitry Andric } 13230b57cec5SDimitry Andric }); 13240b57cec5SDimitry Andric } 13250b57cec5SDimitry Andric } 13260b57cec5SDimitry Andric 13270b57cec5SDimitry Andric llvm::SpecificBumpPtrAllocator<StateNode> Allocator; 13280b57cec5SDimitry Andric }; 13290b57cec5SDimitry Andric 13300b57cec5SDimitry Andric } // anonymous namespace 13310b57cec5SDimitry Andric 13320b57cec5SDimitry Andric unsigned UnwrappedLineFormatter::format( 13330b57cec5SDimitry Andric const SmallVectorImpl<AnnotatedLine *> &Lines, bool DryRun, 13340b57cec5SDimitry Andric int AdditionalIndent, bool FixBadIndentation, unsigned FirstStartColumn, 13350b57cec5SDimitry Andric unsigned NextStartColumn, unsigned LastStartColumn) { 13360b57cec5SDimitry Andric LineJoiner Joiner(Style, Keywords, Lines); 13370b57cec5SDimitry Andric 13380b57cec5SDimitry Andric // Try to look up already computed penalty in DryRun-mode. 13390b57cec5SDimitry Andric std::pair<const SmallVectorImpl<AnnotatedLine *> *, unsigned> CacheKey( 13400b57cec5SDimitry Andric &Lines, AdditionalIndent); 13410b57cec5SDimitry Andric auto CacheIt = PenaltyCache.find(CacheKey); 13420b57cec5SDimitry Andric if (DryRun && CacheIt != PenaltyCache.end()) 13430b57cec5SDimitry Andric return CacheIt->second; 13440b57cec5SDimitry Andric 13450b57cec5SDimitry Andric assert(!Lines.empty()); 13460b57cec5SDimitry Andric unsigned Penalty = 0; 13470b57cec5SDimitry Andric LevelIndentTracker IndentTracker(Style, Keywords, Lines[0]->Level, 13480b57cec5SDimitry Andric AdditionalIndent); 1349fe6060f1SDimitry Andric const AnnotatedLine *PrevPrevLine = nullptr; 13500b57cec5SDimitry Andric const AnnotatedLine *PreviousLine = nullptr; 13510b57cec5SDimitry Andric const AnnotatedLine *NextLine = nullptr; 13520b57cec5SDimitry Andric 13530b57cec5SDimitry Andric // The minimum level of consecutive lines that have been formatted. 13540b57cec5SDimitry Andric unsigned RangeMinLevel = UINT_MAX; 13550b57cec5SDimitry Andric 13560b57cec5SDimitry Andric bool FirstLine = true; 13570b57cec5SDimitry Andric for (const AnnotatedLine *Line = 13580b57cec5SDimitry Andric Joiner.getNextMergedLine(DryRun, IndentTracker); 135904eeddc0SDimitry Andric Line; PrevPrevLine = PreviousLine, PreviousLine = Line, Line = NextLine, 136004eeddc0SDimitry Andric FirstLine = false) { 136104eeddc0SDimitry Andric assert(Line->First); 13620b57cec5SDimitry Andric const AnnotatedLine &TheLine = *Line; 13630b57cec5SDimitry Andric unsigned Indent = IndentTracker.getIndent(); 13640b57cec5SDimitry Andric 13650b57cec5SDimitry Andric // We continue formatting unchanged lines to adjust their indent, e.g. if a 13660b57cec5SDimitry Andric // scope was added. However, we need to carefully stop doing this when we 1367bdd1243dSDimitry Andric // exit the scope of affected lines to prevent indenting the entire 13680b57cec5SDimitry Andric // remaining file if it currently missing a closing brace. 13690b57cec5SDimitry Andric bool PreviousRBrace = 13700b57cec5SDimitry Andric PreviousLine && PreviousLine->startsWith(tok::r_brace); 13710b57cec5SDimitry Andric bool ContinueFormatting = 13720b57cec5SDimitry Andric TheLine.Level > RangeMinLevel || 13730b57cec5SDimitry Andric (TheLine.Level == RangeMinLevel && !PreviousRBrace && 13740b57cec5SDimitry Andric !TheLine.startsWith(tok::r_brace)); 13750b57cec5SDimitry Andric 13760b57cec5SDimitry Andric bool FixIndentation = (FixBadIndentation || ContinueFormatting) && 13770b57cec5SDimitry Andric Indent != TheLine.First->OriginalColumn; 13780b57cec5SDimitry Andric bool ShouldFormat = TheLine.Affected || FixIndentation; 13790b57cec5SDimitry Andric // We cannot format this line; if the reason is that the line had a 13800b57cec5SDimitry Andric // parsing error, remember that. 13810b57cec5SDimitry Andric if (ShouldFormat && TheLine.Type == LT_Invalid && Status) { 13820b57cec5SDimitry Andric Status->FormatComplete = false; 13830b57cec5SDimitry Andric Status->Line = 13840b57cec5SDimitry Andric SourceMgr.getSpellingLineNumber(TheLine.First->Tok.getLocation()); 13850b57cec5SDimitry Andric } 13860b57cec5SDimitry Andric 13870b57cec5SDimitry Andric if (ShouldFormat && TheLine.Type != LT_Invalid) { 13880b57cec5SDimitry Andric if (!DryRun) { 138904eeddc0SDimitry Andric bool LastLine = TheLine.First->is(tok::eof); 1390fe6060f1SDimitry Andric formatFirstToken(TheLine, PreviousLine, PrevPrevLine, Lines, Indent, 13910b57cec5SDimitry Andric LastLine ? LastStartColumn : NextStartColumn + Indent); 13920b57cec5SDimitry Andric } 13930b57cec5SDimitry Andric 13940b57cec5SDimitry Andric NextLine = Joiner.getNextMergedLine(DryRun, IndentTracker); 13950b57cec5SDimitry Andric unsigned ColumnLimit = getColumnLimit(TheLine.InPPDirective, NextLine); 13960b57cec5SDimitry Andric bool FitsIntoOneLine = 139706c3fb27SDimitry Andric !TheLine.ContainsMacroCall && 139806c3fb27SDimitry Andric (TheLine.Last->TotalLength + Indent <= ColumnLimit || 13990b57cec5SDimitry Andric (TheLine.Type == LT_ImportStatement && 14000eae32dcSDimitry Andric (!Style.isJavaScript() || !Style.JavaScriptWrapImports)) || 14010b57cec5SDimitry Andric (Style.isCSharp() && 140206c3fb27SDimitry Andric TheLine.InPPDirective)); // don't split #regions in C# 140381ad6265SDimitry Andric if (Style.ColumnLimit == 0) { 14040b57cec5SDimitry Andric NoColumnLimitLineFormatter(Indenter, Whitespaces, Style, this) 14050b57cec5SDimitry Andric .formatLine(TheLine, NextStartColumn + Indent, 14060b57cec5SDimitry Andric FirstLine ? FirstStartColumn : 0, DryRun); 140781ad6265SDimitry Andric } else if (FitsIntoOneLine) { 14080b57cec5SDimitry Andric Penalty += NoLineBreakFormatter(Indenter, Whitespaces, Style, this) 14090b57cec5SDimitry Andric .formatLine(TheLine, NextStartColumn + Indent, 14100b57cec5SDimitry Andric FirstLine ? FirstStartColumn : 0, DryRun); 141181ad6265SDimitry Andric } else { 14120b57cec5SDimitry Andric Penalty += OptimizingLineFormatter(Indenter, Whitespaces, Style, this) 14130b57cec5SDimitry Andric .formatLine(TheLine, NextStartColumn + Indent, 14140b57cec5SDimitry Andric FirstLine ? FirstStartColumn : 0, DryRun); 141581ad6265SDimitry Andric } 14160b57cec5SDimitry Andric RangeMinLevel = std::min(RangeMinLevel, TheLine.Level); 14170b57cec5SDimitry Andric } else { 14180b57cec5SDimitry Andric // If no token in the current line is affected, we still need to format 14190b57cec5SDimitry Andric // affected children. 142081ad6265SDimitry Andric if (TheLine.ChildrenAffected) { 14210b57cec5SDimitry Andric for (const FormatToken *Tok = TheLine.First; Tok; Tok = Tok->Next) 14220b57cec5SDimitry Andric if (!Tok->Children.empty()) 14230b57cec5SDimitry Andric format(Tok->Children, DryRun); 142481ad6265SDimitry Andric } 14250b57cec5SDimitry Andric 14260b57cec5SDimitry Andric // Adapt following lines on the current indent level to the same level 14270b57cec5SDimitry Andric // unless the current \c AnnotatedLine is not at the beginning of a line. 14280b57cec5SDimitry Andric bool StartsNewLine = 14290b57cec5SDimitry Andric TheLine.First->NewlinesBefore > 0 || TheLine.First->IsFirst; 14300b57cec5SDimitry Andric if (StartsNewLine) 14310b57cec5SDimitry Andric IndentTracker.adjustToUnmodifiedLine(TheLine); 14320b57cec5SDimitry Andric if (!DryRun) { 14330b57cec5SDimitry Andric bool ReformatLeadingWhitespace = 14340b57cec5SDimitry Andric StartsNewLine && ((PreviousLine && PreviousLine->Affected) || 14350b57cec5SDimitry Andric TheLine.LeadingEmptyLinesAffected); 14360b57cec5SDimitry Andric // Format the first token. 143781ad6265SDimitry Andric if (ReformatLeadingWhitespace) { 1438fe6060f1SDimitry Andric formatFirstToken(TheLine, PreviousLine, PrevPrevLine, Lines, 14390b57cec5SDimitry Andric TheLine.First->OriginalColumn, 14400b57cec5SDimitry Andric TheLine.First->OriginalColumn); 144181ad6265SDimitry Andric } else { 14420b57cec5SDimitry Andric Whitespaces->addUntouchableToken(*TheLine.First, 14430b57cec5SDimitry Andric TheLine.InPPDirective); 144481ad6265SDimitry Andric } 14450b57cec5SDimitry Andric 14460b57cec5SDimitry Andric // Notify the WhitespaceManager about the unchanged whitespace. 14470b57cec5SDimitry Andric for (FormatToken *Tok = TheLine.First->Next; Tok; Tok = Tok->Next) 14480b57cec5SDimitry Andric Whitespaces->addUntouchableToken(*Tok, TheLine.InPPDirective); 14490b57cec5SDimitry Andric } 14500b57cec5SDimitry Andric NextLine = Joiner.getNextMergedLine(DryRun, IndentTracker); 14510b57cec5SDimitry Andric RangeMinLevel = UINT_MAX; 14520b57cec5SDimitry Andric } 14535f757f3fSDimitry Andric if (!DryRun) 14545f757f3fSDimitry Andric markFinalized(TheLine.First); 14550b57cec5SDimitry Andric } 14560b57cec5SDimitry Andric PenaltyCache[CacheKey] = Penalty; 14570b57cec5SDimitry Andric return Penalty; 14580b57cec5SDimitry Andric } 14590b57cec5SDimitry Andric 146006c3fb27SDimitry Andric static auto computeNewlines(const AnnotatedLine &Line, 146106c3fb27SDimitry Andric const AnnotatedLine *PreviousLine, 1462fe6060f1SDimitry Andric const AnnotatedLine *PrevPrevLine, 146306c3fb27SDimitry Andric const SmallVectorImpl<AnnotatedLine *> &Lines, 146406c3fb27SDimitry Andric const FormatStyle &Style) { 146506c3fb27SDimitry Andric const auto &RootToken = *Line.First; 146606c3fb27SDimitry Andric auto Newlines = 14670b57cec5SDimitry Andric std::min(RootToken.NewlinesBefore, Style.MaxEmptyLinesToKeep + 1); 14680b57cec5SDimitry Andric // Remove empty lines before "}" where applicable. 14690b57cec5SDimitry Andric if (RootToken.is(tok::r_brace) && 14700b57cec5SDimitry Andric (!RootToken.Next || 14710b57cec5SDimitry Andric (RootToken.Next->is(tok::semi) && !RootToken.Next->Next)) && 14720b57cec5SDimitry Andric // Do not remove empty lines before namespace closing "}". 147381ad6265SDimitry Andric !getNamespaceToken(&Line, Lines)) { 14740b57cec5SDimitry Andric Newlines = std::min(Newlines, 1u); 147581ad6265SDimitry Andric } 14760b57cec5SDimitry Andric // Remove empty lines at the start of nested blocks (lambdas/arrow functions) 147706c3fb27SDimitry Andric if (!PreviousLine && Line.Level > 0) 14780b57cec5SDimitry Andric Newlines = std::min(Newlines, 1u); 14790b57cec5SDimitry Andric if (Newlines == 0 && !RootToken.IsFirst) 14800b57cec5SDimitry Andric Newlines = 1; 1481*0fca6ea1SDimitry Andric if (RootToken.IsFirst && 1482*0fca6ea1SDimitry Andric (!Style.KeepEmptyLines.AtStartOfFile || !RootToken.HasUnescapedNewline)) { 14830b57cec5SDimitry Andric Newlines = 0; 1484*0fca6ea1SDimitry Andric } 14850b57cec5SDimitry Andric 14860b57cec5SDimitry Andric // Remove empty lines after "{". 1487*0fca6ea1SDimitry Andric if (!Style.KeepEmptyLines.AtStartOfBlock && PreviousLine && 14880b57cec5SDimitry Andric PreviousLine->Last->is(tok::l_brace) && 14890b57cec5SDimitry Andric !PreviousLine->startsWithNamespace() && 1490fe6060f1SDimitry Andric !(PrevPrevLine && PrevPrevLine->startsWithNamespace() && 1491fe6060f1SDimitry Andric PreviousLine->startsWith(tok::l_brace)) && 149281ad6265SDimitry Andric !startsExternCBlock(*PreviousLine)) { 14930b57cec5SDimitry Andric Newlines = 1; 149481ad6265SDimitry Andric } 14950b57cec5SDimitry Andric 1496e8d8bef9SDimitry Andric // Insert or remove empty line before access specifiers. 1497e8d8bef9SDimitry Andric if (PreviousLine && RootToken.isAccessSpecifier()) { 1498e8d8bef9SDimitry Andric switch (Style.EmptyLineBeforeAccessModifier) { 1499e8d8bef9SDimitry Andric case FormatStyle::ELBAMS_Never: 1500fe6060f1SDimitry Andric if (Newlines > 1) 1501e8d8bef9SDimitry Andric Newlines = 1; 1502e8d8bef9SDimitry Andric break; 1503e8d8bef9SDimitry Andric case FormatStyle::ELBAMS_Leave: 1504e8d8bef9SDimitry Andric Newlines = std::max(RootToken.NewlinesBefore, 1u); 1505e8d8bef9SDimitry Andric break; 1506e8d8bef9SDimitry Andric case FormatStyle::ELBAMS_LogicalBlock: 1507fe6060f1SDimitry Andric if (PreviousLine->Last->isOneOf(tok::semi, tok::r_brace) && Newlines <= 1) 1508e8d8bef9SDimitry Andric Newlines = 2; 1509fe6060f1SDimitry Andric if (PreviousLine->First->isAccessSpecifier()) 1510fe6060f1SDimitry Andric Newlines = 1; // Previous is an access modifier remove all new lines. 1511e8d8bef9SDimitry Andric break; 1512e8d8bef9SDimitry Andric case FormatStyle::ELBAMS_Always: { 1513e8d8bef9SDimitry Andric const FormatToken *previousToken; 1514e8d8bef9SDimitry Andric if (PreviousLine->Last->is(tok::comment)) 1515e8d8bef9SDimitry Andric previousToken = PreviousLine->Last->getPreviousNonComment(); 1516e8d8bef9SDimitry Andric else 1517e8d8bef9SDimitry Andric previousToken = PreviousLine->Last; 15185f757f3fSDimitry Andric if ((!previousToken || previousToken->isNot(tok::l_brace)) && 15195f757f3fSDimitry Andric Newlines <= 1) { 1520e8d8bef9SDimitry Andric Newlines = 2; 15215f757f3fSDimitry Andric } 1522e8d8bef9SDimitry Andric } break; 1523e8d8bef9SDimitry Andric } 1524e8d8bef9SDimitry Andric } 15250b57cec5SDimitry Andric 1526fe6060f1SDimitry Andric // Insert or remove empty line after access specifiers. 15270b57cec5SDimitry Andric if (PreviousLine && PreviousLine->First->isAccessSpecifier() && 1528fe6060f1SDimitry Andric (!PreviousLine->InPPDirective || !RootToken.HasUnescapedNewline)) { 1529fe6060f1SDimitry Andric // EmptyLineBeforeAccessModifier is handling the case when two access 1530fe6060f1SDimitry Andric // modifiers follow each other. 1531fe6060f1SDimitry Andric if (!RootToken.isAccessSpecifier()) { 1532fe6060f1SDimitry Andric switch (Style.EmptyLineAfterAccessModifier) { 1533fe6060f1SDimitry Andric case FormatStyle::ELAAMS_Never: 1534fe6060f1SDimitry Andric Newlines = 1; 1535fe6060f1SDimitry Andric break; 1536fe6060f1SDimitry Andric case FormatStyle::ELAAMS_Leave: 1537fe6060f1SDimitry Andric Newlines = std::max(Newlines, 1u); 1538fe6060f1SDimitry Andric break; 1539fe6060f1SDimitry Andric case FormatStyle::ELAAMS_Always: 1540fe6060f1SDimitry Andric if (RootToken.is(tok::r_brace)) // Do not add at end of class. 1541fe6060f1SDimitry Andric Newlines = 1u; 1542fe6060f1SDimitry Andric else 1543fe6060f1SDimitry Andric Newlines = std::max(Newlines, 2u); 1544fe6060f1SDimitry Andric break; 1545fe6060f1SDimitry Andric } 1546fe6060f1SDimitry Andric } 1547fe6060f1SDimitry Andric } 15480b57cec5SDimitry Andric 154906c3fb27SDimitry Andric return Newlines; 155006c3fb27SDimitry Andric } 155106c3fb27SDimitry Andric 155206c3fb27SDimitry Andric void UnwrappedLineFormatter::formatFirstToken( 155306c3fb27SDimitry Andric const AnnotatedLine &Line, const AnnotatedLine *PreviousLine, 155406c3fb27SDimitry Andric const AnnotatedLine *PrevPrevLine, 155506c3fb27SDimitry Andric const SmallVectorImpl<AnnotatedLine *> &Lines, unsigned Indent, 155606c3fb27SDimitry Andric unsigned NewlineIndent) { 155706c3fb27SDimitry Andric FormatToken &RootToken = *Line.First; 155806c3fb27SDimitry Andric if (RootToken.is(tok::eof)) { 1559*0fca6ea1SDimitry Andric unsigned Newlines = std::min( 1560*0fca6ea1SDimitry Andric RootToken.NewlinesBefore, 1561*0fca6ea1SDimitry Andric Style.KeepEmptyLines.AtEndOfFile ? Style.MaxEmptyLinesToKeep + 1 : 1); 156206c3fb27SDimitry Andric unsigned TokenIndent = Newlines ? NewlineIndent : 0; 156306c3fb27SDimitry Andric Whitespaces->replaceWhitespace(RootToken, Newlines, TokenIndent, 156406c3fb27SDimitry Andric TokenIndent); 156506c3fb27SDimitry Andric return; 156606c3fb27SDimitry Andric } 156706c3fb27SDimitry Andric 156806c3fb27SDimitry Andric if (RootToken.Newlines < 0) { 156906c3fb27SDimitry Andric RootToken.Newlines = 157006c3fb27SDimitry Andric computeNewlines(Line, PreviousLine, PrevPrevLine, Lines, Style); 157106c3fb27SDimitry Andric assert(RootToken.Newlines >= 0); 157206c3fb27SDimitry Andric } 157306c3fb27SDimitry Andric 157406c3fb27SDimitry Andric if (RootToken.Newlines > 0) 15750b57cec5SDimitry Andric Indent = NewlineIndent; 15760b57cec5SDimitry Andric 157781ad6265SDimitry Andric // Preprocessor directives get indented before the hash only if specified. In 157881ad6265SDimitry Andric // Javascript import statements are indented like normal statements. 157981ad6265SDimitry Andric if (!Style.isJavaScript() && 158081ad6265SDimitry Andric Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash && 15810b57cec5SDimitry Andric (Line.Type == LT_PreprocessorDirective || 158281ad6265SDimitry Andric Line.Type == LT_ImportStatement)) { 15830b57cec5SDimitry Andric Indent = 0; 158481ad6265SDimitry Andric } 15850b57cec5SDimitry Andric 158606c3fb27SDimitry Andric Whitespaces->replaceWhitespace(RootToken, RootToken.Newlines, Indent, Indent, 15875ffd83dbSDimitry Andric /*IsAligned=*/false, 15880b57cec5SDimitry Andric Line.InPPDirective && 15890b57cec5SDimitry Andric !RootToken.HasUnescapedNewline); 15900b57cec5SDimitry Andric } 15910b57cec5SDimitry Andric 15920b57cec5SDimitry Andric unsigned 15930b57cec5SDimitry Andric UnwrappedLineFormatter::getColumnLimit(bool InPPDirective, 15940b57cec5SDimitry Andric const AnnotatedLine *NextLine) const { 15950b57cec5SDimitry Andric // In preprocessor directives reserve two chars for trailing " \" if the 15960b57cec5SDimitry Andric // next line continues the preprocessor directive. 15970b57cec5SDimitry Andric bool ContinuesPPDirective = 15980b57cec5SDimitry Andric InPPDirective && 15990b57cec5SDimitry Andric // If there is no next line, this is likely a child line and the parent 16000b57cec5SDimitry Andric // continues the preprocessor directive. 16010b57cec5SDimitry Andric (!NextLine || 16020b57cec5SDimitry Andric (NextLine->InPPDirective && 16030b57cec5SDimitry Andric // If there is an unescaped newline between this line and the next, the 16040b57cec5SDimitry Andric // next line starts a new preprocessor directive. 16050b57cec5SDimitry Andric !NextLine->First->HasUnescapedNewline)); 16060b57cec5SDimitry Andric return Style.ColumnLimit - (ContinuesPPDirective ? 2 : 0); 16070b57cec5SDimitry Andric } 16080b57cec5SDimitry Andric 16090b57cec5SDimitry Andric } // namespace format 16100b57cec5SDimitry Andric } // namespace clang 1611