1d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper//===--- FormatToken.cpp - Format C++ code --------------------------------===//
2d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper//
3d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper//                     The LLVM Compiler Infrastructure
4d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper//
5d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper// This file is distributed under the University of Illinois Open Source
6d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper// License. See LICENSE.TXT for details.
7d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper//
8d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper//===----------------------------------------------------------------------===//
9d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper///
10d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper/// \file
11d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper/// \brief This file implements specific functions of \c FormatTokens and their
12d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper/// roles.
13d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper///
14d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper//===----------------------------------------------------------------------===//
15d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper
16d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper#include "ContinuationIndenter.h"
17a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar#include "FormatToken.h"
18d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper#include "clang/Format/Format.h"
19d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper#include "llvm/ADT/SmallVector.h"
20d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper#include "llvm/Support/Debug.h"
21b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar#include <climits>
22d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper
23d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jaspernamespace clang {
24d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jaspernamespace format {
25d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper
26a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainarconst char *getTokenTypeName(TokenType Type) {
27a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  static const char *const TokNames[] = {
28a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar#define TYPE(X) #X,
29a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarLIST_TOKEN_TYPES
30a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar#undef TYPE
31a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar    nullptr
32a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  };
33a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar
34a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  if (Type < NUM_TOKEN_TYPES)
35a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar    return TokNames[Type];
36a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  llvm_unreachable("unknown TokenType");
37a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  return nullptr;
38a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar}
39a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar
40651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// FIXME: This is copy&pasted from Sema. Put it in a common place and remove
41651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// duplication.
42651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesbool FormatToken::isSimpleTypeSpecifier() const {
43651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  switch (Tok.getKind()) {
44651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  case tok::kw_short:
45651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  case tok::kw_long:
46651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  case tok::kw___int64:
47651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  case tok::kw___int128:
48651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  case tok::kw_signed:
49651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  case tok::kw_unsigned:
50651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  case tok::kw_void:
51651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  case tok::kw_char:
52651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  case tok::kw_int:
53651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  case tok::kw_half:
54651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  case tok::kw_float:
55651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  case tok::kw_double:
56651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  case tok::kw_wchar_t:
57651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  case tok::kw_bool:
58651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  case tok::kw___underlying_type:
59651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  case tok::annot_typename:
60651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  case tok::kw_char16_t:
61651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  case tok::kw_char32_t:
62651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  case tok::kw_typeof:
63651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  case tok::kw_decltype:
64651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return true;
65651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  default:
66651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return false;
67651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
68651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
69651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
70d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel JasperTokenRole::~TokenRole() {}
71d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper
72d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jaspervoid TokenRole::precomputeFormattingInfos(const FormatToken *Token) {}
73d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper
74651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesunsigned CommaSeparatedList::formatAfterToken(LineState &State,
75651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                              ContinuationIndenter *Indenter,
76651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                              bool DryRun) {
77b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  if (State.NextToken == nullptr || !State.NextToken->Previous)
78d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper    return 0;
79d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper
80d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper  // Ensure that we start on the opening brace.
81b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  const FormatToken *LBrace =
82b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      State.NextToken->Previous->getPreviousNonComment();
83b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  if (!LBrace || LBrace->isNot(tok::l_brace) || LBrace->BlockKind == BK_Block ||
843c6aea7ac63265c769b5fe09e213ab1c4cee111eDaniel Jasper      LBrace->Type == TT_DictLiteral ||
85d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper      LBrace->Next->Type == TT_DesignatedInitializerPeriod)
86d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper    return 0;
87d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper
88451f1e0e5040db6a114217e7bd9767bf751d5bd3Daniel Jasper  // Calculate the number of code points we have to format this list. As the
89451f1e0e5040db6a114217e7bd9767bf751d5bd3Daniel Jasper  // first token is already placed, we have to subtract it.
906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  unsigned RemainingCodePoints =
916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      Style.ColumnLimit - State.Column + State.NextToken->Previous->ColumnWidth;
92451f1e0e5040db6a114217e7bd9767bf751d5bd3Daniel Jasper
93d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper  // Find the best ColumnFormat, i.e. the best number of columns to use.
94451f1e0e5040db6a114217e7bd9767bf751d5bd3Daniel Jasper  const ColumnFormat *Format = getColumnFormat(RemainingCodePoints);
95651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // If no ColumnFormat can be used, the braced list would generally be
96651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // bin-packed. Add a severe penalty to this so that column layouts are
97651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // preferred if possible.
98d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper  if (!Format)
99651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return 10000;
100d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper
101d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper  // Format the entire list.
102d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper  unsigned Penalty = 0;
103d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper  unsigned Column = 0;
104d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper  unsigned Item = 0;
105d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper  while (State.NextToken != LBrace->MatchingParen) {
106d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper    bool NewLine = false;
107d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper    unsigned ExtraSpaces = 0;
108d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper
109d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper    // If the previous token was one of our commas, we are now on the next item.
110d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper    if (Item < Commas.size() && State.NextToken->Previous == Commas[Item]) {
111d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper      if (!State.NextToken->isTrailingComment()) {
112d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper        ExtraSpaces += Format->ColumnSizes[Column] - ItemLengths[Item];
113d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper        ++Column;
114d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper      }
115d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper      ++Item;
116d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper    }
117d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper
118d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper    if (Column == Format->Columns || State.NextToken->MustBreakBefore) {
119d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper      Column = 0;
120d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper      NewLine = true;
121d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper    }
122d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper
123d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper    // Place token using the continuation indenter and store the penalty.
124d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper    Penalty += Indenter->addTokenToState(State, NewLine, DryRun, ExtraSpaces);
125d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper  }
126d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper  return Penalty;
127d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper}
128d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper
129651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesunsigned CommaSeparatedList::formatFromToken(LineState &State,
130651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                             ContinuationIndenter *Indenter,
131651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                             bool DryRun) {
132651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (HasNestedBracedList)
133651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    State.Stack.back().AvoidBinPacking = true;
134651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return 0;
135651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
136651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
137d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper// Returns the lengths in code points between Begin and End (both included),
138d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper// assuming that the entire sequence is put on a single line.
139d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasperstatic unsigned CodePointsBetween(const FormatToken *Begin,
140d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper                                  const FormatToken *End) {
141332c67703f63fafd26cf88fc31faeb80c1523725Daniel Jasper  assert(End->TotalLength >= Begin->TotalLength);
14283a7dcdf5fce1bdf74ce985419d77a41a51abfa2Alexander Kornienko  return End->TotalLength - Begin->TotalLength + Begin->ColumnWidth;
143d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper}
144d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper
145d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jaspervoid CommaSeparatedList::precomputeFormattingInfos(const FormatToken *Token) {
146332c67703f63fafd26cf88fc31faeb80c1523725Daniel Jasper  // FIXME: At some point we might want to do this for other lists, too.
147332c67703f63fafd26cf88fc31faeb80c1523725Daniel Jasper  if (!Token->MatchingParen || Token->isNot(tok::l_brace))
148d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper    return;
149d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper
150176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // In C++11 braced list style, we should not format in columns unless they
151b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  // have many items (20 or more) or we allow bin-packing of function call
152b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  // arguments.
153b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  if (Style.Cpp11BracedListStyle && !Style.BinPackArguments &&
154176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      Commas.size() < 19)
1556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return;
1566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1570e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // Column format doesn't really make sense if we don't align after brackets.
158a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  if (Style.AlignAfterOpenBracket == FormatStyle::BAS_DontAlign)
1590e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    return;
1600e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
161d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper  FormatToken *ItemBegin = Token->Next;
162b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  while (ItemBegin->isTrailingComment())
163b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    ItemBegin = ItemBegin->Next;
164d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper  SmallVector<bool, 8> MustBreakBeforeItem;
165d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper
166d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper  // The lengths of an item if it is put at the end of the line. This includes
167d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper  // trailing comments which are otherwise ignored for column alignment.
168d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper  SmallVector<unsigned, 8> EndOfLineItemLength;
169d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper
170b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  bool HasSeparatingComment = false;
171d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper  for (unsigned i = 0, e = Commas.size() + 1; i != e; ++i) {
172d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper    // Skip comments on their own line.
173b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    while (ItemBegin->HasUnescapedNewline && ItemBegin->isTrailingComment()) {
174d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper      ItemBegin = ItemBegin->Next;
175b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      HasSeparatingComment = i > 0;
176b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    }
177d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper
178d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper    MustBreakBeforeItem.push_back(ItemBegin->MustBreakBefore);
17974317e4d3a6e662412cdd971df57da326229fedbDaniel Jasper    if (ItemBegin->is(tok::l_brace))
18074317e4d3a6e662412cdd971df57da326229fedbDaniel Jasper      HasNestedBracedList = true;
1816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    const FormatToken *ItemEnd = nullptr;
182d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper    if (i == Commas.size()) {
183d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper      ItemEnd = Token->MatchingParen;
184d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper      const FormatToken *NonCommentEnd = ItemEnd->getPreviousNonComment();
185d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper      ItemLengths.push_back(CodePointsBetween(ItemBegin, NonCommentEnd));
186a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar      if (Style.Cpp11BracedListStyle &&
187a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar          !ItemEnd->Previous->isTrailingComment()) {
188d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper        // In Cpp11 braced list style, the } and possibly other subsequent
189d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper        // tokens will need to stay on a line with the last element.
190d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper        while (ItemEnd->Next && !ItemEnd->Next->CanBreakBefore)
191d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper          ItemEnd = ItemEnd->Next;
192d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper      } else {
193d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper        // In other braced lists styles, the "}" can be wrapped to the new line.
194d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper        ItemEnd = Token->MatchingParen->Previous;
195d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper      }
196d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper    } else {
197d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper      ItemEnd = Commas[i];
198d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper      // The comma is counted as part of the item when calculating the length.
199332c67703f63fafd26cf88fc31faeb80c1523725Daniel Jasper      ItemLengths.push_back(CodePointsBetween(ItemBegin, ItemEnd));
200176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
201d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper      // Consume trailing comments so the are included in EndOfLineItemLength.
202d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper      if (ItemEnd->Next && !ItemEnd->Next->HasUnescapedNewline &&
203d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper          ItemEnd->Next->isTrailingComment())
204d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper        ItemEnd = ItemEnd->Next;
205d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper    }
206d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper    EndOfLineItemLength.push_back(CodePointsBetween(ItemBegin, ItemEnd));
207332c67703f63fafd26cf88fc31faeb80c1523725Daniel Jasper    // If there is a trailing comma in the list, the next item will start at the
208332c67703f63fafd26cf88fc31faeb80c1523725Daniel Jasper    // closing brace. Don't create an extra item for this.
209332c67703f63fafd26cf88fc31faeb80c1523725Daniel Jasper    if (ItemEnd->getNextNonComment() == Token->MatchingParen)
210332c67703f63fafd26cf88fc31faeb80c1523725Daniel Jasper      break;
211d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper    ItemBegin = ItemEnd->Next;
212d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper  }
213d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper
214b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  // Don't use column layout for nested lists, lists with few elements and in
215b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  // presence of separating comments.
216b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  if (Token->NestingLevel != 0 || Commas.size() < 5 || HasSeparatingComment)
217651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return;
218651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
219d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper  // We can never place more than ColumnLimit / 3 items in a row (because of the
220d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper  // spaces and the comma).
221b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  unsigned MaxItems = Style.ColumnLimit / 3;
222b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  std::vector<unsigned> MinSizeInColumn;
223b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  MinSizeInColumn.reserve(MaxItems);
224b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  for (unsigned Columns = 1; Columns <= MaxItems; ++Columns) {
225d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper    ColumnFormat Format;
226d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper    Format.Columns = Columns;
227d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper    Format.ColumnSizes.resize(Columns);
228b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    MinSizeInColumn.assign(Columns, UINT_MAX);
22974317e4d3a6e662412cdd971df57da326229fedbDaniel Jasper    Format.LineCount = 1;
230d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper    bool HasRowWithSufficientColumns = false;
231d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper    unsigned Column = 0;
232d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper    for (unsigned i = 0, e = ItemLengths.size(); i != e; ++i) {
233ae76f7f850a9101a20191b10241ca72c23dc40ddManuel Klimek      assert(i < MustBreakBeforeItem.size());
234d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper      if (MustBreakBeforeItem[i] || Column == Columns) {
235d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper        ++Format.LineCount;
236d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper        Column = 0;
237d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper      }
238d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper      if (Column == Columns - 1)
239d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper        HasRowWithSufficientColumns = true;
240b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      unsigned Length =
241d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper          (Column == Columns - 1) ? EndOfLineItemLength[i] : ItemLengths[i];
242b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      Format.ColumnSizes[Column] = std::max(Format.ColumnSizes[Column], Length);
243b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      MinSizeInColumn[Column] = std::min(MinSizeInColumn[Column], Length);
244d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper      ++Column;
245d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper    }
246d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper    // If all rows are terminated early (e.g. by trailing comments), we don't
247d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper    // need to look further.
248d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper    if (!HasRowWithSufficientColumns)
249d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper      break;
250d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper    Format.TotalWidth = Columns - 1; // Width of the N-1 spaces.
251b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar
252b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    for (unsigned i = 0; i < Columns; ++i)
253d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper      Format.TotalWidth += Format.ColumnSizes[i];
254b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar
255b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    // Don't use this Format, if the difference between the longest and shortest
256b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    // element in a column exceeds a threshold to avoid excessive spaces.
257b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    if ([&] {
258b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar          for (unsigned i = 0; i < Columns - 1; ++i)
259b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar            if (Format.ColumnSizes[i] - MinSizeInColumn[i] > 10)
260b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar              return true;
261b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar          return false;
262b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar        }())
263b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      continue;
264d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper
265d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper    // Ignore layouts that are bound to violate the column limit.
266d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper    if (Format.TotalWidth > Style.ColumnLimit)
267d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper      continue;
268d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper
269d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper    Formats.push_back(Format);
270d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper  }
271d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper}
272d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper
273d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasperconst CommaSeparatedList::ColumnFormat *
274d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel JasperCommaSeparatedList::getColumnFormat(unsigned RemainingCharacters) const {
2756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  const ColumnFormat *BestFormat = nullptr;
276d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper  for (SmallVector<ColumnFormat, 4>::const_reverse_iterator
277d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper           I = Formats.rbegin(),
278d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper           E = Formats.rend();
279d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper       I != E; ++I) {
280d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper    if (I->TotalWidth <= RemainingCharacters) {
281d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper      if (BestFormat && I->LineCount > BestFormat->LineCount)
282d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper        break;
283d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper      BestFormat = &*I;
284d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper    }
285d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper  }
286d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper  return BestFormat;
287d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper}
288d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper
289d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper} // namespace format
290d4a03dbb0bdbd4908375306283cb61813bd8f454Daniel Jasper} // namespace clang
291