Skip to content

Commit b0080a4

Browse files
author
hnakamura5
committed
[clang-format] Support of TableGen formatting.
Currently, TableGen has its language style but the it does not works well. This patch adds total support of TableGen formatting including the support for the code (multi line string), DAG args, bang operators, the cond operator, and the paste operators.
1 parent f5ab0bb commit b0080a4

12 files changed

+1197
-25
lines changed

clang/include/clang/Format/Format.h

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,36 @@ struct FormatStyle {
396396
/// \version 17
397397
ShortCaseStatementsAlignmentStyle AlignConsecutiveShortCaseStatements;
398398

399+
/// Style of aligning consecutive TableGen cond operator colons.
400+
/// \code
401+
/// !cond(!eq(size, 1) : 1,
402+
/// !eq(size, 16): 1,
403+
/// true : 0)
404+
/// \endcode
405+
/// \version 18
406+
AlignConsecutiveStyle AlignConsecutiveTableGenCondOperatorColons;
407+
408+
/// Style of aligning consecutive TableGen DAGArg operator colons.
409+
/// Intended to be used with TableGenBreakInsideDAGArgList
410+
/// \code
411+
/// let dagarg = (ins
412+
/// a :$src1,
413+
/// aa :$src2,
414+
/// aaa:$src3
415+
/// )
416+
/// \endcode
417+
/// \version 18
418+
AlignConsecutiveStyle AlignConsecutiveTableGenBreakingDAGArgColons;
419+
420+
/// Style of aligning consecutive TableGen def colons.
421+
/// \code
422+
/// def Def : Parent {}
423+
/// def DefDef : Parent {}
424+
/// def DefDefDef : Parent {}
425+
/// \endcode
426+
/// \version 18
427+
AlignConsecutiveStyle AlignConsecutiveTableGenDefinitions;
428+
399429
/// Different styles for aligning escaped newlines.
400430
enum EscapedNewlineAlignmentStyle : int8_t {
401431
/// Don't align escaped newlines.
@@ -3037,6 +3067,7 @@ struct FormatStyle {
30373067
bool isProto() const {
30383068
return Language == LK_Proto || Language == LK_TextProto;
30393069
}
3070+
bool isTableGen() const { return Language == LK_TableGen; }
30403071

30413072
/// Language, this format style is targeted at.
30423073
/// \version 3.5
@@ -4656,6 +4687,15 @@ struct FormatStyle {
46564687
/// \version 8
46574688
std::vector<std::string> StatementMacros;
46584689

4690+
/// Tablegen
4691+
bool TableGenAllowBreakBeforeInheritColon;
4692+
bool TableGenAllowBreakAfterInheritColon;
4693+
bool TableGenBreakInsideCondOperator;
4694+
bool TableGenBreakInsideDAGArgList;
4695+
bool TableGenPreferBreakInsideSquareBracket;
4696+
bool TableGenSpaceAroundDAGArgColon;
4697+
std::vector<std::string> TableGenBreakingDAGArgOperators;
4698+
46594699
/// The number of columns used for tab stops.
46604700
/// \version 3.7
46614701
unsigned TabWidth;
@@ -4753,6 +4793,13 @@ struct FormatStyle {
47534793
AlignConsecutiveMacros == R.AlignConsecutiveMacros &&
47544794
AlignConsecutiveShortCaseStatements ==
47554795
R.AlignConsecutiveShortCaseStatements &&
4796+
AlignConsecutiveTableGenCondOperatorColons ==
4797+
R.AlignConsecutiveTableGenCondOperatorColons &&
4798+
AlignConsecutiveTableGenBreakingDAGArgColons ==
4799+
R.AlignConsecutiveTableGenBreakingDAGArgColons &&
4800+
AlignConsecutiveTableGenDefinitions ==
4801+
R.AlignConsecutiveTableGenDefinitions &&
4802+
AlignConsecutiveMacros == R.AlignConsecutiveMacros &&
47564803
AlignEscapedNewlines == R.AlignEscapedNewlines &&
47574804
AlignOperands == R.AlignOperands &&
47584805
AlignTrailingComments == R.AlignTrailingComments &&

clang/lib/Format/ContinuationIndenter.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,7 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
800800
if (Style.AlignAfterOpenBracket != FormatStyle::BAS_DontAlign &&
801801
!CurrentState.IsCSharpGenericTypeConstraint && Previous.opensScope() &&
802802
Previous.isNot(TT_ObjCMethodExpr) && Previous.isNot(TT_RequiresClause) &&
803+
Previous.isNot(TT_TableGenDAGArgOpener) &&
803804
!(Current.MacroParent && Previous.MacroParent) &&
804805
(Current.isNot(TT_LineComment) ||
805806
Previous.isOneOf(BK_BracedInit, TT_VerilogMultiLineListLParen))) {
@@ -1229,7 +1230,7 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) {
12291230
return CurrentState.Indent;
12301231
}
12311232
if ((Current.isOneOf(tok::r_brace, tok::r_square) ||
1232-
(Current.is(tok::greater) && Style.isProto())) &&
1233+
(Current.is(tok::greater) && (Style.isProto() || Style.isTableGen()))) &&
12331234
State.Stack.size() > 1) {
12341235
if (Current.closesBlockOrBlockTypeList(Style))
12351236
return State.Stack[State.Stack.size() - 2].NestedBlockIndent;
@@ -1257,6 +1258,12 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) {
12571258
Current.Next->isOneOf(tok::semi, tok::kw_const, tok::l_brace))) {
12581259
return State.Stack[State.Stack.size() - 2].LastSpace;
12591260
}
1261+
// When DAGArg closer exists top of line, it must be aligned in the similar
1262+
// way as function call above.
1263+
if (Current.is(tok::r_paren) && State.Stack.size() > 1 &&
1264+
(Current.isOneOf(TT_TableGenDAGArgCloser, TT_TableGenParamAngleCloser))) {
1265+
return State.Stack[State.Stack.size() - 2].LastSpace;
1266+
}
12601267
if (Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent &&
12611268
(Current.is(tok::r_paren) ||
12621269
(Current.is(tok::r_brace) && Current.MatchingParen &&
@@ -1593,6 +1600,9 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
15931600
State.StartOfStringLiteral = State.Column + 1;
15941601
if (Current.is(TT_CSharpStringLiteral) && State.StartOfStringLiteral == 0) {
15951602
State.StartOfStringLiteral = State.Column + 1;
1603+
} else if (Current.is(TT_TableGenMultiLineString) &&
1604+
State.StartOfStringLiteral == 0) {
1605+
State.StartOfStringLiteral = State.Column + 1;
15961606
} else if (Current.isStringLiteral() && State.StartOfStringLiteral == 0) {
15971607
State.StartOfStringLiteral = State.Column;
15981608
} else if (!Current.isOneOf(tok::comment, tok::identifier, tok::hash) &&
@@ -1672,7 +1682,9 @@ void ContinuationIndenter::moveStatePastFakeLParens(LineState &State,
16721682
(!Previous || Previous->isNot(tok::kw_return) ||
16731683
(Style.Language != FormatStyle::LK_Java && PrecedenceLevel > 0)) &&
16741684
(Style.AlignAfterOpenBracket != FormatStyle::BAS_DontAlign ||
1675-
PrecedenceLevel != prec::Comma || Current.NestingLevel == 0)) {
1685+
PrecedenceLevel != prec::Comma || Current.NestingLevel == 0) &&
1686+
(!Style.isTableGen() || !Previous ||
1687+
!Previous->isNot(TT_TableGenDAGArgListComma))) {
16761688
NewParenState.Indent = std::max(
16771689
std::max(State.Column, NewParenState.Indent), CurrentState.LastSpace);
16781690
}
@@ -1915,6 +1927,8 @@ void ContinuationIndenter::moveStatePastScopeCloser(LineState &State) {
19151927
(Current.isOneOf(tok::r_paren, tok::r_square, TT_TemplateString) ||
19161928
(Current.is(tok::r_brace) && State.NextToken != State.Line->First) ||
19171929
State.NextToken->is(TT_TemplateCloser) ||
1930+
State.NextToken->is(TT_TableGenParamAngleCloser) ||
1931+
State.NextToken->is(TT_TableGenListCloser) ||
19181932
(Current.is(tok::greater) && Current.is(TT_DictLiteral)))) {
19191933
State.Stack.pop_back();
19201934
}

clang/lib/Format/Format.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -926,6 +926,12 @@ template <> struct MappingTraits<FormatStyle> {
926926
IO.mapOptional("AlignConsecutiveMacros", Style.AlignConsecutiveMacros);
927927
IO.mapOptional("AlignConsecutiveShortCaseStatements",
928928
Style.AlignConsecutiveShortCaseStatements);
929+
IO.mapOptional("AlignConsecutiveTableGenCondOperatorColons",
930+
Style.AlignConsecutiveTableGenCondOperatorColons);
931+
IO.mapOptional("AlignConsecutiveTableGenBreakingDAGArgColons",
932+
Style.AlignConsecutiveTableGenBreakingDAGArgColons);
933+
IO.mapOptional("AlignConsecutiveTableGenDefinitions",
934+
Style.AlignConsecutiveTableGenDefinitions);
929935
IO.mapOptional("AlignEscapedNewlines", Style.AlignEscapedNewlines);
930936
IO.mapOptional("AlignOperands", Style.AlignOperands);
931937
IO.mapOptional("AlignTrailingComments", Style.AlignTrailingComments);
@@ -1124,6 +1130,20 @@ template <> struct MappingTraits<FormatStyle> {
11241130
IO.mapOptional("StatementAttributeLikeMacros",
11251131
Style.StatementAttributeLikeMacros);
11261132
IO.mapOptional("StatementMacros", Style.StatementMacros);
1133+
IO.mapOptional("TableGenAllowBreakAfterInheritColon",
1134+
Style.TableGenAllowBreakAfterInheritColon);
1135+
IO.mapOptional("TableGenAllowBreakBeforeInheritColon",
1136+
Style.TableGenAllowBreakBeforeInheritColon);
1137+
IO.mapOptional("TableGenBreakInsideCondOperator",
1138+
Style.TableGenBreakInsideCondOperator);
1139+
IO.mapOptional("TableGenBreakInsideDAGArgList",
1140+
Style.TableGenBreakInsideDAGArgList);
1141+
IO.mapOptional("TableGenPreferBreakInsideSquareBracket",
1142+
Style.TableGenPreferBreakInsideSquareBracket);
1143+
IO.mapOptional("TableGenSpaceAroundDAGArgColon",
1144+
Style.TableGenSpaceAroundDAGArgColon);
1145+
IO.mapOptional("TableGenBreakingDAGArgOperators",
1146+
Style.TableGenBreakingDAGArgOperators);
11271147
IO.mapOptional("TabWidth", Style.TabWidth);
11281148
IO.mapOptional("TypeNames", Style.TypeNames);
11291149
IO.mapOptional("TypenameMacros", Style.TypenameMacros);
@@ -1437,6 +1457,9 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
14371457
LLVMStyle.AlignConsecutiveDeclarations = {};
14381458
LLVMStyle.AlignConsecutiveMacros = {};
14391459
LLVMStyle.AlignConsecutiveShortCaseStatements = {};
1460+
LLVMStyle.AlignConsecutiveTableGenBreakingDAGArgColons = {};
1461+
LLVMStyle.AlignConsecutiveTableGenCondOperatorColons = {};
1462+
LLVMStyle.AlignConsecutiveTableGenDefinitions = {};
14401463
LLVMStyle.AlignTrailingComments = {};
14411464
LLVMStyle.AlignTrailingComments.Kind = FormatStyle::TCAS_Always;
14421465
LLVMStyle.AlignTrailingComments.OverEmptyLines = 0;
@@ -1585,6 +1608,12 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
15851608
LLVMStyle.StatementAttributeLikeMacros.push_back("Q_EMIT");
15861609
LLVMStyle.StatementMacros.push_back("Q_UNUSED");
15871610
LLVMStyle.StatementMacros.push_back("QT_REQUIRE_VERSION");
1611+
LLVMStyle.TableGenAllowBreakAfterInheritColon = true;
1612+
LLVMStyle.TableGenAllowBreakBeforeInheritColon = false;
1613+
LLVMStyle.TableGenBreakInsideCondOperator = true;
1614+
LLVMStyle.TableGenBreakInsideDAGArgList = false;
1615+
LLVMStyle.TableGenPreferBreakInsideSquareBracket = false;
1616+
LLVMStyle.TableGenSpaceAroundDAGArgColon = false;
15881617
LLVMStyle.TabWidth = 8;
15891618
LLVMStyle.UseTab = FormatStyle::UT_Never;
15901619
LLVMStyle.VerilogBreakBetweenInstancePorts = true;

clang/lib/Format/FormatToken.h

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,23 @@ namespace format {
148148
TYPE(StructLBrace) \
149149
TYPE(StructRBrace) \
150150
TYPE(StructuredBindingLSquare) \
151+
TYPE(TableGenBangOperator) \
152+
TYPE(TableGenCondOperator) \
153+
TYPE(TableGenCondOperatorColon) \
154+
TYPE(TableGenCondOperatorComma) \
155+
TYPE(TableGenDAGArgCloser) \
156+
TYPE(TableGenDAGArgListColon) \
157+
TYPE(TableGenDAGArgListColonToAlign) \
158+
TYPE(TableGenDAGArgListComma) \
159+
TYPE(TableGenDAGArgOpener) \
160+
TYPE(TableGenDAGArgOperatorID) \
161+
TYPE(TableGenListCloser) \
162+
TYPE(TableGenListOpener) \
163+
TYPE(TableGenMultiLineString) \
164+
TYPE(TableGenParamAngleOpener) \
165+
TYPE(TableGenParamAngleCloser) \
166+
TYPE(TableGenTrailingPasteOperator) \
167+
TYPE(TableGenValueSuffix) \
151168
TYPE(TemplateCloser) \
152169
TYPE(TemplateOpener) \
153170
TYPE(TemplateString) \
@@ -671,6 +688,8 @@ struct FormatToken {
671688
return true;
672689
if (is(TT_DictLiteral) && is(tok::less))
673690
return true;
691+
if (is(TT_TableGenParamAngleOpener))
692+
return true;
674693
return isOneOf(tok::l_paren, tok::l_brace, tok::l_square,
675694
TT_TemplateOpener);
676695
}
@@ -681,6 +700,10 @@ struct FormatToken {
681700
return true;
682701
if (is(TT_DictLiteral) && is(tok::greater))
683702
return true;
703+
if (is(TT_TableGenParamAngleCloser))
704+
return true;
705+
if (is(TT_TableGenListCloser))
706+
return true;
684707
return isOneOf(tok::r_paren, tok::r_brace, tok::r_square,
685708
TT_TemplateCloser);
686709
}
@@ -1202,6 +1225,21 @@ struct AdditionalKeywords {
12021225
kw_verilogHashHash = &IdentTable.get("##");
12031226
kw_apostrophe = &IdentTable.get("\'");
12041227

1228+
// TableGen keywords
1229+
kw_bit = &IdentTable.get("bit");
1230+
kw_bits = &IdentTable.get("bits");
1231+
kw_code = &IdentTable.get("code");
1232+
kw_dag = &IdentTable.get("dag");
1233+
kw_def = &IdentTable.get("def");
1234+
kw_defm = &IdentTable.get("defm");
1235+
kw_defset = &IdentTable.get("defset");
1236+
kw_defvar = &IdentTable.get("defvar");
1237+
kw_dump = &IdentTable.get("dump");
1238+
kw_include = &IdentTable.get("include");
1239+
kw_list = &IdentTable.get("list");
1240+
kw_multiclass = &IdentTable.get("multiclass");
1241+
kw_then = &IdentTable.get("then");
1242+
12051243
// Keep this at the end of the constructor to make sure everything here
12061244
// is
12071245
// already initialized.
@@ -1294,6 +1332,27 @@ struct AdditionalKeywords {
12941332
kw_wildcard, kw_wire,
12951333
kw_with, kw_wor,
12961334
kw_verilogHash, kw_verilogHashHash});
1335+
1336+
TableGenExtraKeywords = std::unordered_set<IdentifierInfo *>({
1337+
kw_assert,
1338+
kw_bit,
1339+
kw_bits,
1340+
kw_code,
1341+
kw_dag,
1342+
kw_def,
1343+
kw_defm,
1344+
kw_defset,
1345+
kw_defvar,
1346+
kw_dump,
1347+
kw_foreach,
1348+
kw_in,
1349+
kw_include,
1350+
kw_let,
1351+
kw_list,
1352+
kw_multiclass,
1353+
kw_string,
1354+
kw_then,
1355+
});
12971356
}
12981357

12991358
// Context sensitive keywords.
@@ -1539,6 +1598,21 @@ struct AdditionalKeywords {
15391598
// Symbols in Verilog that don't exist in C++.
15401599
IdentifierInfo *kw_apostrophe;
15411600

1601+
// TableGen keywords
1602+
IdentifierInfo *kw_bit;
1603+
IdentifierInfo *kw_bits;
1604+
IdentifierInfo *kw_code;
1605+
IdentifierInfo *kw_dag;
1606+
IdentifierInfo *kw_def;
1607+
IdentifierInfo *kw_defm;
1608+
IdentifierInfo *kw_defset;
1609+
IdentifierInfo *kw_defvar;
1610+
IdentifierInfo *kw_dump;
1611+
IdentifierInfo *kw_include;
1612+
IdentifierInfo *kw_list;
1613+
IdentifierInfo *kw_multiclass;
1614+
IdentifierInfo *kw_then;
1615+
15421616
/// Returns \c true if \p Tok is a keyword or an identifier.
15431617
bool isWordLike(const FormatToken &Tok) const {
15441618
// getIdentifierinfo returns non-null for keywords as well as identifiers.
@@ -1811,6 +1885,27 @@ struct AdditionalKeywords {
18111885
}
18121886
}
18131887

1888+
bool isTableGenDefinition(const FormatToken &Tok) const {
1889+
return Tok.isOneOf(kw_def, kw_defm, kw_defset, kw_defvar, kw_multiclass,
1890+
kw_let, tok::kw_class);
1891+
}
1892+
1893+
bool isTableGenKeyword(const FormatToken &Tok) const {
1894+
switch (Tok.Tok.getKind()) {
1895+
case tok::kw_class:
1896+
case tok::kw_else:
1897+
case tok::kw_false:
1898+
case tok::kw_if:
1899+
case tok::kw_int:
1900+
case tok::kw_true:
1901+
return true;
1902+
default:
1903+
return Tok.is(tok::identifier) &&
1904+
TableGenExtraKeywords.find(Tok.Tok.getIdentifierInfo()) !=
1905+
TableGenExtraKeywords.end();
1906+
}
1907+
}
1908+
18141909
private:
18151910
/// The JavaScript keywords beyond the C++ keyword set.
18161911
std::unordered_set<IdentifierInfo *> JsExtraKeywords;
@@ -1820,6 +1915,9 @@ struct AdditionalKeywords {
18201915

18211916
/// The Verilog keywords beyond the C++ keyword set.
18221917
std::unordered_set<IdentifierInfo *> VerilogExtraKeywords;
1918+
1919+
/// The TableGen keywords beyond the C++ keyword set.
1920+
std::unordered_set<IdentifierInfo *> TableGenExtraKeywords;
18231921
};
18241922

18251923
inline bool isLineComment(const FormatToken &FormatTok) {

0 commit comments

Comments
 (0)