Skip to content

Commit d076735

Browse files
author
hnakamura5
committed
[clang-format] TableGen multi line string support.
1 parent 8d817f6 commit d076735

File tree

6 files changed

+70
-1
lines changed

6 files changed

+70
-1
lines changed

clang/lib/Format/ContinuationIndenter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1591,6 +1591,9 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
15911591
State.StartOfStringLiteral = State.Column + 1;
15921592
if (Current.is(TT_CSharpStringLiteral) && State.StartOfStringLiteral == 0) {
15931593
State.StartOfStringLiteral = State.Column + 1;
1594+
} else if (Current.is(TT_TableGenMultiLineString) &&
1595+
State.StartOfStringLiteral == 0) {
1596+
State.StartOfStringLiteral = State.Column + 1;
15941597
} else if (Current.isStringLiteral() && State.StartOfStringLiteral == 0) {
15951598
State.StartOfStringLiteral = State.Column;
15961599
} else if (!Current.isOneOf(tok::comment, tok::identifier, tok::hash) &&

clang/lib/Format/FormatToken.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ namespace format {
148148
TYPE(StructLBrace) \
149149
TYPE(StructRBrace) \
150150
TYPE(StructuredBindingLSquare) \
151+
TYPE(TableGenMultiLineString) \
151152
TYPE(TemplateCloser) \
152153
TYPE(TemplateOpener) \
153154
TYPE(TemplateString) \

clang/lib/Format/FormatTokenLexer.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ ArrayRef<FormatToken *> FormatTokenLexer::lex() {
9393
// string literals are correctly identified.
9494
handleCSharpVerbatimAndInterpolatedStrings();
9595
}
96+
if (Style.isTableGen())
97+
handleTableGenMultilineString();
9698
if (Tokens.back()->NewlinesBefore > 0 || Tokens.back()->IsMultiline)
9799
FirstInLineIndex = Tokens.size() - 1;
98100
} while (Tokens.back()->isNot(tok::eof));
@@ -272,6 +274,14 @@ void FormatTokenLexer::tryMergePreviousTokens() {
272274
return;
273275
}
274276
}
277+
if (Style.isTableGen()) {
278+
if (tryMergeTokens({tok::l_square, tok::l_brace},
279+
TT_TableGenMultiLineString)) {
280+
// Multi line string starts with [{
281+
Tokens.back()->Tok.setKind(tok::string_literal);
282+
return;
283+
}
284+
}
275285
}
276286

277287
bool FormatTokenLexer::tryMergeNSStringLiteral() {
@@ -763,6 +773,53 @@ void FormatTokenLexer::handleCSharpVerbatimAndInterpolatedStrings() {
763773
resetLexer(SourceMgr.getFileOffset(Lex->getSourceLocation(Offset + 1)));
764774
}
765775

776+
void FormatTokenLexer::handleTableGenMultilineString() {
777+
FormatToken *MultiLineString = Tokens.back();
778+
if (MultiLineString->isNot(TT_TableGenMultiLineString))
779+
return;
780+
781+
bool PrevIsRBrace = false;
782+
const char *FirstBreak = nullptr;
783+
const char *LastBreak = nullptr;
784+
const char *Begin = MultiLineString->TokenText.begin();
785+
// Skip until }], the closer of multi line string found.
786+
for (const char *Current = Begin, *End = Lex->getBuffer().end();
787+
Current != End; ++Current) {
788+
if (PrevIsRBrace && *Current == ']') {
789+
// }] is the end of multi line string.
790+
if (!FirstBreak)
791+
FirstBreak = Current;
792+
MultiLineString->TokenText = StringRef(Begin, Current - Begin + 1);
793+
// ColumnWidth is only the width of the first line.
794+
MultiLineString->ColumnWidth = encoding::columnWidthWithTabs(
795+
StringRef(Begin, FirstBreak - Begin + 1),
796+
MultiLineString->OriginalColumn, Style.TabWidth, Encoding);
797+
if (LastBreak) {
798+
// Set LastLineColumnWidth if multi line string has multiple lines.
799+
MultiLineString->LastLineColumnWidth = encoding::columnWidthWithTabs(
800+
StringRef(LastBreak + 1, Current - LastBreak),
801+
MultiLineString->OriginalColumn, Style.TabWidth, Encoding);
802+
}
803+
resetLexer(SourceMgr.getFileOffset(Lex->getSourceLocation(Current + 1)));
804+
return;
805+
}
806+
PrevIsRBrace = false;
807+
if (*Current == '\n') {
808+
MultiLineString->IsMultiline = true;
809+
// Assure LastBreak is not equal to FirstBreak.
810+
if (!FirstBreak)
811+
FirstBreak = Current;
812+
LastBreak = Current;
813+
continue;
814+
}
815+
if (*Current == '}') {
816+
// Memorize '}'. If next character is ']', they are the closer.
817+
PrevIsRBrace = true;
818+
continue;
819+
}
820+
}
821+
}
822+
766823
void FormatTokenLexer::handleTemplateStrings() {
767824
FormatToken *BacktickToken = Tokens.back();
768825

clang/lib/Format/FormatTokenLexer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ class FormatTokenLexer {
9595

9696
void handleCSharpVerbatimAndInterpolatedStrings();
9797

98+
// Handles TableGen multiline strings. It has the form [{ ... }].
99+
void handleTableGenMultilineString();
100+
98101
void tryParsePythonComment();
99102

100103
bool tryMerge_TMacro();

clang/lib/Format/TokenAnnotator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1710,7 +1710,7 @@ class AnnotatingParser {
17101710
TT_UnionLBrace, TT_RequiresClause,
17111711
TT_RequiresClauseInARequiresExpression, TT_RequiresExpression,
17121712
TT_RequiresExpressionLParen, TT_RequiresExpressionLBrace,
1713-
TT_BracedListLBrace)) {
1713+
TT_BracedListLBrace, TT_TableGenMultiLineString)) {
17141714
CurrentToken->setType(TT_Unknown);
17151715
}
17161716
CurrentToken->Role.reset();

clang/unittests/Format/TokenAnnotatorTest.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2193,6 +2193,11 @@ TEST_F(TokenAnnotatorTest, UnderstandTableGenTokens) {
21932193
ASSERT_TRUE(Keywords.isTableGenDefinition(*Tokens[0]));
21942194
ASSERT_TRUE(Tokens[0]->is(Keywords.kw_def));
21952195
ASSERT_TRUE(Tokens[1]->is(TT_StartOfName));
2196+
2197+
// Code, the multiline string token.
2198+
Tokens = Annotate("[{ code is multiline string }]");
2199+
ASSERT_EQ(Tokens.size(), 2u) << Tokens;
2200+
EXPECT_TOKEN(Tokens[0], tok::string_literal, TT_TableGenMultiLineString);
21962201
}
21972202

21982203
TEST_F(TokenAnnotatorTest, UnderstandConstructors) {

0 commit comments

Comments
 (0)