BreakableToken.h revision 919398bb40d5d643f38b6595f5e8eac641e89d50
170ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko//===--- BreakableToken.h - Format C++ code -------------------------------===//
270ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko//
370ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko//                     The LLVM Compiler Infrastructure
470ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko//
570ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko// This file is distributed under the University of Illinois Open Source
670ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko// License. See LICENSE.TXT for details.
770ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko//
870ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko//===----------------------------------------------------------------------===//
970ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko///
1070ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko/// \file
1170ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko/// \brief Declares BreakableToken, BreakableStringLiteral, and
1270ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko/// BreakableBlockComment classes, that contain token type-specific logic to
1370ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko/// break long lines in tokens.
1470ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko///
1570ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko//===----------------------------------------------------------------------===//
1670ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
1770ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko#ifndef LLVM_CLANG_FORMAT_BREAKABLETOKEN_H
1870ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko#define LLVM_CLANG_FORMAT_BREAKABLETOKEN_H
1970ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
2070ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko#include "TokenAnnotator.h"
2170ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko#include "WhitespaceManager.h"
2270ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko#include <utility>
2370ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
2470ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienkonamespace clang {
2570ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienkonamespace format {
2670ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
2770ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienkoclass BreakableToken {
2870ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienkopublic:
29919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko  BreakableToken(const SourceManager &SourceMgr, const FormatToken &Tok,
30919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko                 unsigned StartColumn)
31919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko      : Tok(Tok), StartColumn(StartColumn),
32919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko        TokenText(SourceMgr.getCharacterData(Tok.getStartOfNonWhitespace()),
33919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko                  Tok.TokenLength) {}
3470ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  virtual ~BreakableToken() {}
3570ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  virtual unsigned getLineCount() const = 0;
36919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko  virtual unsigned getLineSize(unsigned Index) const = 0;
3770ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  virtual unsigned getLineLengthAfterSplit(unsigned LineIndex,
38919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko                                           unsigned TailOffset) const = 0;
3970ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
4070ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  // Contains starting character index and length of split.
4170ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  typedef std::pair<StringRef::size_type, unsigned> Split;
4270ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  virtual Split getSplit(unsigned LineIndex, unsigned TailOffset,
43919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko                         unsigned ColumnLimit) const = 0;
4470ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  virtual void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split,
4570ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko                           bool InPPDirective,
4670ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko                           WhitespaceManager &Whitespaces) = 0;
4770ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  virtual void trimLine(unsigned LineIndex, unsigned TailOffset,
4870ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko                        unsigned InPPDirective,
49919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko                        WhitespaceManager &Whitespaces) {}
50919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienkoprotected:
51919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko  const FormatToken &Tok;
52919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko  unsigned StartColumn;
53919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko  StringRef TokenText;
5470ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko};
5570ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
5670ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienkoclass BreakableStringLiteral : public BreakableToken {
5770ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienkopublic:
58919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko  BreakableStringLiteral(const SourceManager &SourceMgr, const FormatToken &Tok,
59919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko                         unsigned StartColumn)
60919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko      : BreakableToken(SourceMgr, Tok, StartColumn) {
61919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko    assert(TokenText.startswith("\"") && TokenText.endswith("\""));
62919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko  }
6370ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
6470ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  virtual unsigned getLineCount() const { return 1; }
6570ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
66919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko  virtual unsigned getLineSize(unsigned Index) const {
6770ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko    return Tok.TokenLength - 2; // Should be in sync with getLine
6870ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  }
6970ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
7070ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  virtual unsigned getLineLengthAfterSplit(unsigned LineIndex,
71919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko                                           unsigned TailOffset) const {
72919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko    return getDecorationLength() + getLine().size() - TailOffset;
7370ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  }
7470ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
7570ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  virtual Split getSplit(unsigned LineIndex, unsigned TailOffset,
76919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko                         unsigned ColumnLimit) const {
77919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko    StringRef Text = getLine().substr(TailOffset);
78919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko    if (ColumnLimit <= getDecorationLength())
7970ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko      return Split(StringRef::npos, 0);
80919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko    unsigned MaxSplit = ColumnLimit - getDecorationLength();
8170ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko    assert(MaxSplit < Text.size());
8270ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko    StringRef::size_type SpaceOffset = Text.rfind(' ', MaxSplit);
8370ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko    if (SpaceOffset != StringRef::npos && SpaceOffset != 0)
8470ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko      return Split(SpaceOffset + 1, 0);
8570ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko    StringRef::size_type SlashOffset = Text.rfind('/', MaxSplit);
8670ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko    if (SlashOffset != StringRef::npos && SlashOffset != 0)
8770ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko      return Split(SlashOffset + 1, 0);
8870ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko    StringRef::size_type SplitPoint = getStartOfCharacter(Text, MaxSplit);
8970ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko    if (SplitPoint != StringRef::npos && SplitPoint > 1)
9070ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko      // Do not split at 0.
9170ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko      return Split(SplitPoint, 0);
9270ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko    return Split(StringRef::npos, 0);
9370ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  }
9470ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
9570ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  virtual void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split,
9670ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko                           bool InPPDirective, WhitespaceManager &Whitespaces) {
9770ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko    unsigned WhitespaceStartColumn = StartColumn + Split.first + 2;
98919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko    Whitespaces.breakToken(Tok, 1 + TailOffset + Split.first, Split.second,
9970ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko                           "\"", "\"", InPPDirective, StartColumn,
10070ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko                           WhitespaceStartColumn);
10170ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  }
10270ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
10370ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienkoprivate:
104919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko  StringRef getLine() const {
10570ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko    // Get string without quotes.
10670ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko    // FIXME: Handle string prefixes.
107919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko    return TokenText.substr(1, TokenText.size() - 2);
10870ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  }
10970ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
110919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko  unsigned getDecorationLength() const { return StartColumn + 2; }
111919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko
11270ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  static StringRef::size_type getStartOfCharacter(StringRef Text,
11370ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko                                                  StringRef::size_type Offset) {
11470ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko    StringRef::size_type NextEscape = Text.find('\\');
11570ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko    while (NextEscape != StringRef::npos && NextEscape < Offset) {
11670ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko      StringRef::size_type SequenceLength =
11770ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko          getEscapeSequenceLength(Text.substr(NextEscape));
11870ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko      if (Offset < NextEscape + SequenceLength)
11970ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko        return NextEscape;
12070ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko      NextEscape = Text.find('\\', NextEscape + SequenceLength);
12170ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko    }
12270ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko    return Offset;
12370ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  }
12470ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
12570ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  static unsigned getEscapeSequenceLength(StringRef Text) {
12670ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko    assert(Text[0] == '\\');
12770ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko    if (Text.size() < 2)
12870ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko      return 1;
12970ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
13070ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko    switch (Text[1]) {
13170ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko    case 'u':
13270ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko      return 6;
13370ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko    case 'U':
13470ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko      return 10;
13570ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko    case 'x':
13670ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko      return getHexLength(Text);
13770ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko    default:
13870ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko      if (Text[1] >= '0' && Text[1] <= '7')
13970ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko        return getOctalLength(Text);
14070ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko      return 2;
14170ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko    }
14270ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  }
14370ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
14470ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  static unsigned getHexLength(StringRef Text) {
14570ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko    unsigned I = 2; // Point after '\x'.
14670ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko    while (I < Text.size() && ((Text[I] >= '0' && Text[I] <= '9') ||
14770ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko                               (Text[I] >= 'a' && Text[I] <= 'f') ||
14870ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko                               (Text[I] >= 'A' && Text[I] <= 'F'))) {
14970ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko      ++I;
15070ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko    }
15170ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko    return I;
15270ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  }
15370ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
15470ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  static unsigned getOctalLength(StringRef Text) {
15570ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko    unsigned I = 1;
15670ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko    while (I < Text.size() && I < 4 && (Text[I] >= '0' && Text[I] <= '7')) {
15770ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko      ++I;
15870ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko    }
15970ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko    return I;
16070ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  }
16170ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
16270ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko};
16370ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
164919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienkoclass BreakableComment : public BreakableToken {
16570ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienkopublic:
166919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko  virtual unsigned getLineSize(unsigned Index) const {
16770ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko    return getLine(Index).size();
16870ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  }
16970ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
170919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko  virtual unsigned getLineCount() const { return Lines.size(); }
17170ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
172919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko  virtual unsigned getLineLengthAfterSplit(unsigned LineIndex,
173919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko                                           unsigned TailOffset) const {
174919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko    return getContentStartColumn(LineIndex, TailOffset) +
175919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko           getLine(LineIndex).size() - TailOffset;
17670ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  }
17770ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
17870ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  virtual Split getSplit(unsigned LineIndex, unsigned TailOffset,
179919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko                         unsigned ColumnLimit) const;
18070ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  virtual void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split,
18170ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko                           bool InPPDirective, WhitespaceManager &Whitespaces);
18270ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
183919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienkoprotected:
184919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko  BreakableComment(const SourceManager &SourceMgr, const FormatToken &Tok,
185919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko                   unsigned StartColumn)
186919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko      : BreakableToken(SourceMgr, Tok, StartColumn) {}
18770ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
18870ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  // Get comment lines without /* */, common prefix and trailing whitespace.
18970ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  // Last line is not trimmed, as it is terminated by */, so its trailing
19070ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  // whitespace is not really trailing.
191919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko  StringRef getLine(unsigned Index) const {
19270ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko    return Index < Lines.size() - 1 ? Lines[Index].rtrim() : Lines[Index];
19370ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  }
19470ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
195919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko  unsigned getContentStartColumn(unsigned LineIndex,
196919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko                                 unsigned TailOffset) const {
197919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko    return (TailOffset == 0 && LineIndex == 0)
198919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko               ? StartColumn
199919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko               : IndentAtLineBreak + Decoration.size();
200919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko  }
201919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko
20270ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  unsigned IndentAtLineBreak;
203919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko  StringRef Decoration;
20470ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  SmallVector<StringRef, 16> Lines;
20570ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko};
20670ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
207919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienkoclass BreakableBlockComment : public BreakableComment {
208919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienkopublic:
209919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko  BreakableBlockComment(const SourceManager &SourceMgr,
210919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko                        const AnnotatedToken &Token, unsigned StartColumn);
211919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko
212919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko  void alignLines(WhitespaceManager &Whitespaces);
213919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko
214919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko  virtual unsigned getLineLengthAfterSplit(unsigned LineIndex,
215919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko                                           unsigned TailOffset) const {
216919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko    return BreakableComment::getLineLengthAfterSplit(LineIndex, TailOffset) +
217919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko           (LineIndex + 1 < Lines.size() ? 0 : 2);
218919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko  }
219919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko
220919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko  virtual void trimLine(unsigned LineIndex, unsigned TailOffset,
221919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko                        unsigned InPPDirective, WhitespaceManager &Whitespaces);
222919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko
223919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienkoprivate:
224919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko  unsigned OriginalStartColumn;
225919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko  unsigned CommonPrefixLength;
226919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko};
227919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko
228919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienkoclass BreakableLineComment : public BreakableComment {
229919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienkopublic:
230919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko  BreakableLineComment(const SourceManager &SourceMgr,
231919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko                       const AnnotatedToken &Token, unsigned StartColumn);
232919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko
233919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienkoprivate:
234919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko  static StringRef getLineCommentPrefix(StringRef Comment);
235919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko};
236919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko
23770ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko} // namespace format
23870ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko} // namespace clang
23970ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
24070ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko#endif // LLVM_CLANG_FORMAT_BREAKABLETOKEN_H
241