Skip to content

Commit df4ba00

Browse files
[clang-format] Support of TableGen statements in unwrapped line parser (#78846)
Make TableGen's statements to be parsed considering their structure. - Avoid to parse label - Avoid class from being parsed as c++'s class - Support if statement of the form `if <cond> then { ... }` - Support defset statement of the form `defset <type> <name> {}` --------- Co-authored-by: Björn Schäpers <[email protected]>
1 parent 6096327 commit df4ba00

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

clang/lib/Format/UnwrappedLineParser.cpp

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1661,7 +1661,8 @@ void UnwrappedLineParser::parseStructuralElement(
16611661
// In Verilog labels can be any expression, so we don't do them here.
16621662
// JS doesn't have macros, and within classes colons indicate fields, not
16631663
// labels.
1664-
if (!Style.isJavaScript() && !Style.isVerilog() &&
1664+
// TableGen doesn't have labels.
1665+
if (!Style.isJavaScript() && !Style.isVerilog() && !Style.isTableGen() &&
16651666
Tokens->peekNextToken()->is(tok::colon) && !Line->MustBeDeclaration) {
16661667
nextToken();
16671668
Line->Tokens.begin()->Tok->MustBreakBefore = true;
@@ -1790,6 +1791,12 @@ void UnwrappedLineParser::parseStructuralElement(
17901791
addUnwrappedLine();
17911792
return;
17921793
}
1794+
if (Style.isTableGen()) {
1795+
// Do nothing special. In this case the l_brace becomes FunctionLBrace.
1796+
// This is same as def and so on.
1797+
nextToken();
1798+
break;
1799+
}
17931800
[[fallthrough]];
17941801
case tok::kw_struct:
17951802
case tok::kw_union:
@@ -2028,6 +2035,16 @@ void UnwrappedLineParser::parseStructuralElement(
20282035
// initialisers are indented the same way.
20292036
if (Style.isCSharp())
20302037
FormatTok->setBlockKind(BK_BracedInit);
2038+
// TableGen's defset statement has syntax of the form,
2039+
// `defset <type> <name> = { <statement>... }`
2040+
if (Style.isTableGen() &&
2041+
Line->Tokens.begin()->Tok->is(Keywords.kw_defset)) {
2042+
FormatTok->setFinalizedType(TT_FunctionLBrace);
2043+
parseBlock(/*MustBeDeclaration=*/false, /*AddLevels=*/1u,
2044+
/*MunchSemi=*/false);
2045+
addUnwrappedLine();
2046+
break;
2047+
}
20312048
nextToken();
20322049
parseBracedList();
20332050
} else if (Style.Language == FormatStyle::LK_Proto &&
@@ -2743,6 +2760,14 @@ FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind,
27432760
}
27442761
}
27452762

2763+
// TableGen's if statement has the form of `if <cond> then { ... }`.
2764+
if (Style.isTableGen()) {
2765+
while (!eof() && FormatTok->isNot(Keywords.kw_then)) {
2766+
// Simply skip until then. This range only contains a value.
2767+
nextToken();
2768+
}
2769+
}
2770+
27462771
// Handle `if !consteval`.
27472772
if (FormatTok->is(tok::exclaim))
27482773
nextToken();

clang/unittests/Format/TokenAnnotatorTest.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2232,6 +2232,18 @@ TEST_F(TokenAnnotatorTest, UnderstandTableGenTokens) {
22322232
EXPECT_TOKEN(Tokens[0], tok::identifier, TT_Unknown);
22332233
Tokens = Annotate("01234Vector");
22342234
EXPECT_TOKEN(Tokens[0], tok::identifier, TT_Unknown);
2235+
2236+
// Structured statements.
2237+
Tokens = Annotate("class Foo {}");
2238+
EXPECT_TOKEN(Tokens[2], tok::l_brace, TT_FunctionLBrace);
2239+
Tokens = Annotate("def Def: Foo {}");
2240+
EXPECT_TOKEN(Tokens[2], tok::colon, TT_InheritanceColon);
2241+
EXPECT_TOKEN(Tokens[4], tok::l_brace, TT_FunctionLBrace);
2242+
Tokens = Annotate("if cond then {} else {}");
2243+
EXPECT_TOKEN(Tokens[3], tok::l_brace, TT_ControlStatementLBrace);
2244+
EXPECT_TOKEN(Tokens[6], tok::l_brace, TT_ElseLBrace);
2245+
Tokens = Annotate("defset Foo Def2 = {}");
2246+
EXPECT_TOKEN(Tokens[4], tok::l_brace, TT_FunctionLBrace);
22352247
}
22362248

22372249
TEST_F(TokenAnnotatorTest, UnderstandConstructors) {

0 commit comments

Comments
 (0)