Skip to content

Commit 0c423af

Browse files
authored
[clang-format] Add Options to break inside the TableGen DAGArg. (#83149)
Add two options to control the line break inside TableGen DAGArg. - TableGenBreakInsideDAGArg - TableGenBreakingDAGArgOperators
1 parent 73381a8 commit 0c423af

File tree

8 files changed

+371
-6
lines changed

8 files changed

+371
-6
lines changed

clang/docs/ClangFormatStyleOptions.rst

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6158,6 +6158,70 @@ the configuration (without a prefix: ``Auto``).
61586158
**TabWidth** (``Unsigned``) :versionbadge:`clang-format 3.7` :ref:`<TabWidth>`
61596159
The number of columns used for tab stops.
61606160

6161+
.. _TableGenBreakInsideDAGArg:
6162+
6163+
**TableGenBreakInsideDAGArg** (``DAGArgStyle``) :versionbadge:`clang-format 19` :ref:`<TableGenBreakInsideDAGArg>`
6164+
The styles of the line break inside the DAGArg in TableGen.
6165+
6166+
Possible values:
6167+
6168+
* ``DAS_DontBreak`` (in configuration: ``DontBreak``)
6169+
Never break inside DAGArg.
6170+
6171+
.. code-block:: c++
6172+
6173+
let DAGArgIns = (ins i32:$src1, i32:$src2);
6174+
6175+
* ``DAS_BreakElements`` (in configuration: ``BreakElements``)
6176+
Break inside DAGArg after each list element but for the last.
6177+
This aligns to the first element.
6178+
6179+
.. code-block:: c++
6180+
6181+
let DAGArgIns = (ins i32:$src1,
6182+
i32:$src2);
6183+
6184+
* ``DAS_BreakAll`` (in configuration: ``BreakAll``)
6185+
Break inside DAGArg after the operator and the all elements.
6186+
6187+
.. code-block:: c++
6188+
6189+
let DAGArgIns = (ins
6190+
i32:$src1,
6191+
i32:$src2
6192+
);
6193+
6194+
6195+
6196+
.. _TableGenBreakingDAGArgOperators:
6197+
6198+
**TableGenBreakingDAGArgOperators** (``List of Strings``) :versionbadge:`clang-format 19` :ref:`<TableGenBreakingDAGArgOperators>`
6199+
Works only when TableGenBreakInsideDAGArg is not DontBreak.
6200+
The string list needs to consist of identifiers in TableGen.
6201+
If any identifier is specified, this limits the line breaks by
6202+
TableGenBreakInsideDAGArg option only on DAGArg values beginning with
6203+
the specified identifiers.
6204+
6205+
For example the configuration,
6206+
6207+
.. code-block:: c++
6208+
6209+
TableGenBreakInsideDAGArg: BreakAll
6210+
TableGenBreakingDAGArgOperators: ['ins', 'outs']
6211+
6212+
makes the line break only occurs inside DAGArgs beginning with the
6213+
specified identifiers 'ins' and 'outs'.
6214+
6215+
6216+
.. code-block:: c++
6217+
6218+
let DAGArgIns = (ins
6219+
i32:$src1,
6220+
i32:$src2
6221+
);
6222+
let DAGArgOtherID = (other i32:$other1, i32:$other2);
6223+
let DAGArgBang = (!cast<SomeType>("Some") i32:$src1, i32:$src2)
6224+
61616225
.. _TypeNames:
61626226

61636227
**TypeNames** (``List of Strings``) :versionbadge:`clang-format 17` :ref:`<TypeNames>`

clang/include/clang/Format/Format.h

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4728,6 +4728,60 @@ struct FormatStyle {
47284728
/// \version 8
47294729
std::vector<std::string> StatementMacros;
47304730

4731+
/// Works only when TableGenBreakInsideDAGArg is not DontBreak.
4732+
/// The string list needs to consist of identifiers in TableGen.
4733+
/// If any identifier is specified, this limits the line breaks by
4734+
/// TableGenBreakInsideDAGArg option only on DAGArg values beginning with
4735+
/// the specified identifiers.
4736+
///
4737+
/// For example the configuration,
4738+
/// \code
4739+
/// TableGenBreakInsideDAGArg: BreakAll
4740+
/// TableGenBreakingDAGArgOperators: ['ins', 'outs']
4741+
/// \endcode
4742+
///
4743+
/// makes the line break only occurs inside DAGArgs beginning with the
4744+
/// specified identifiers 'ins' and 'outs'.
4745+
///
4746+
/// \code
4747+
/// let DAGArgIns = (ins
4748+
/// i32:$src1,
4749+
/// i32:$src2
4750+
/// );
4751+
/// let DAGArgOtherID = (other i32:$other1, i32:$other2);
4752+
/// let DAGArgBang = (!cast<SomeType>("Some") i32:$src1, i32:$src2)
4753+
/// \endcode
4754+
/// \version 19
4755+
std::vector<std::string> TableGenBreakingDAGArgOperators;
4756+
4757+
/// Different ways to control the format inside TableGen DAGArg.
4758+
enum DAGArgStyle : int8_t {
4759+
/// Never break inside DAGArg.
4760+
/// \code
4761+
/// let DAGArgIns = (ins i32:$src1, i32:$src2);
4762+
/// \endcode
4763+
DAS_DontBreak,
4764+
/// Break inside DAGArg after each list element but for the last.
4765+
/// This aligns to the first element.
4766+
/// \code
4767+
/// let DAGArgIns = (ins i32:$src1,
4768+
/// i32:$src2);
4769+
/// \endcode
4770+
DAS_BreakElements,
4771+
/// Break inside DAGArg after the operator and the all elements.
4772+
/// \code
4773+
/// let DAGArgIns = (ins
4774+
/// i32:$src1,
4775+
/// i32:$src2
4776+
/// );
4777+
/// \endcode
4778+
DAS_BreakAll,
4779+
};
4780+
4781+
/// The styles of the line break inside the DAGArg in TableGen.
4782+
/// \version 19
4783+
DAGArgStyle TableGenBreakInsideDAGArg;
4784+
47314785
/// The number of columns used for tab stops.
47324786
/// \version 3.7
47334787
unsigned TabWidth;
@@ -4980,9 +5034,12 @@ struct FormatStyle {
49805034
SpacesInSquareBrackets == R.SpacesInSquareBrackets &&
49815035
Standard == R.Standard &&
49825036
StatementAttributeLikeMacros == R.StatementAttributeLikeMacros &&
4983-
StatementMacros == R.StatementMacros && TabWidth == R.TabWidth &&
4984-
TypeNames == R.TypeNames && TypenameMacros == R.TypenameMacros &&
4985-
UseTab == R.UseTab &&
5037+
StatementMacros == R.StatementMacros &&
5038+
TableGenBreakingDAGArgOperators ==
5039+
R.TableGenBreakingDAGArgOperators &&
5040+
TableGenBreakInsideDAGArg == R.TableGenBreakInsideDAGArg &&
5041+
TabWidth == R.TabWidth && TypeNames == R.TypeNames &&
5042+
TypenameMacros == R.TypenameMacros && UseTab == R.UseTab &&
49865043
VerilogBreakBetweenInstancePorts ==
49875044
R.VerilogBreakBetweenInstancePorts &&
49885045
WhitespaceSensitiveMacros == R.WhitespaceSensitiveMacros;

clang/lib/Format/ContinuationIndenter.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -815,6 +815,7 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
815815
!CurrentState.IsCSharpGenericTypeConstraint && Previous.opensScope() &&
816816
Previous.isNot(TT_ObjCMethodExpr) && Previous.isNot(TT_RequiresClause) &&
817817
Previous.isNot(TT_TableGenDAGArgOpener) &&
818+
Previous.isNot(TT_TableGenDAGArgOpenerToBreak) &&
818819
!(Current.MacroParent && Previous.MacroParent) &&
819820
(Current.isNot(TT_LineComment) ||
820821
Previous.isOneOf(BK_BracedInit, TT_VerilogMultiLineListLParen))) {
@@ -1437,7 +1438,9 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) {
14371438
Style.BreakInheritanceList == FormatStyle::BILS_AfterColon) {
14381439
return CurrentState.Indent;
14391440
}
1440-
if (Previous.is(tok::r_paren) && !Current.isBinaryOperator() &&
1441+
if (Previous.is(tok::r_paren) &&
1442+
Previous.isNot(TT_TableGenDAGArgOperatorToBreak) &&
1443+
!Current.isBinaryOperator() &&
14411444
!Current.isOneOf(tok::colon, tok::comment)) {
14421445
return ContinuationIndent;
14431446
}
@@ -1698,7 +1701,8 @@ void ContinuationIndenter::moveStatePastFakeLParens(LineState &State,
16981701
(Style.AlignAfterOpenBracket != FormatStyle::BAS_DontAlign ||
16991702
PrecedenceLevel != prec::Comma || Current.NestingLevel == 0) &&
17001703
(!Style.isTableGen() ||
1701-
(Previous && Previous->is(TT_TableGenDAGArgListComma)))) {
1704+
(Previous && Previous->isOneOf(TT_TableGenDAGArgListComma,
1705+
TT_TableGenDAGArgListCommaToBreak)))) {
17021706
NewParenState.Indent = std::max(
17031707
std::max(State.Column, NewParenState.Indent), CurrentState.LastSpace);
17041708
}
@@ -1835,6 +1839,17 @@ void ContinuationIndenter::moveStatePastScopeOpener(LineState &State,
18351839
Style.ContinuationIndentWidth +
18361840
std::max(CurrentState.LastSpace, CurrentState.StartOfFunctionCall);
18371841

1842+
if (Style.isTableGen() && Current.is(TT_TableGenDAGArgOpenerToBreak) &&
1843+
Style.TableGenBreakInsideDAGArg == FormatStyle::DAS_BreakElements) {
1844+
// For the case the next token is a TableGen DAGArg operator identifier
1845+
// that is not marked to have a line break after it.
1846+
// In this case the option DAS_BreakElements requires to align the
1847+
// DAGArg elements to the operator.
1848+
const FormatToken *Next = Current.Next;
1849+
if (Next && Next->is(TT_TableGenDAGArgOperatorID))
1850+
NewIndent = State.Column + Next->TokenText.size() + 2;
1851+
}
1852+
18381853
// Ensure that different different brackets force relative alignment, e.g.:
18391854
// void SomeFunction(vector< // break
18401855
// int> v);

clang/lib/Format/Format.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,14 @@ struct ScalarEnumerationTraits<FormatStyle::BreakTemplateDeclarationsStyle> {
279279
}
280280
};
281281

282+
template <> struct ScalarEnumerationTraits<FormatStyle::DAGArgStyle> {
283+
static void enumeration(IO &IO, FormatStyle::DAGArgStyle &Value) {
284+
IO.enumCase(Value, "DontBreak", FormatStyle::DAS_DontBreak);
285+
IO.enumCase(Value, "BreakElements", FormatStyle::DAS_BreakElements);
286+
IO.enumCase(Value, "BreakAll", FormatStyle::DAS_BreakAll);
287+
}
288+
};
289+
282290
template <>
283291
struct ScalarEnumerationTraits<FormatStyle::DefinitionReturnTypeBreakingStyle> {
284292
static void
@@ -1092,6 +1100,10 @@ template <> struct MappingTraits<FormatStyle> {
10921100
IO.mapOptional("StatementAttributeLikeMacros",
10931101
Style.StatementAttributeLikeMacros);
10941102
IO.mapOptional("StatementMacros", Style.StatementMacros);
1103+
IO.mapOptional("TableGenBreakingDAGArgOperators",
1104+
Style.TableGenBreakingDAGArgOperators);
1105+
IO.mapOptional("TableGenBreakInsideDAGArg",
1106+
Style.TableGenBreakInsideDAGArg);
10951107
IO.mapOptional("TabWidth", Style.TabWidth);
10961108
IO.mapOptional("TypeNames", Style.TypeNames);
10971109
IO.mapOptional("TypenameMacros", Style.TypenameMacros);
@@ -1552,6 +1564,8 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
15521564
LLVMStyle.StatementAttributeLikeMacros.push_back("Q_EMIT");
15531565
LLVMStyle.StatementMacros.push_back("Q_UNUSED");
15541566
LLVMStyle.StatementMacros.push_back("QT_REQUIRE_VERSION");
1567+
LLVMStyle.TableGenBreakingDAGArgOperators = {};
1568+
LLVMStyle.TableGenBreakInsideDAGArg = FormatStyle::DAS_DontBreak;
15551569
LLVMStyle.TabWidth = 8;
15561570
LLVMStyle.UseTab = FormatStyle::UT_Never;
15571571
LLVMStyle.VerilogBreakBetweenInstancePorts = true;

clang/lib/Format/FormatToken.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,11 @@ extern bool IsCpp;
156156
TYPE(TableGenDAGArgCloser) \
157157
TYPE(TableGenDAGArgListColon) \
158158
TYPE(TableGenDAGArgListComma) \
159+
TYPE(TableGenDAGArgListCommaToBreak) \
159160
TYPE(TableGenDAGArgOpener) \
161+
TYPE(TableGenDAGArgOpenerToBreak) \
162+
TYPE(TableGenDAGArgOperatorID) \
163+
TYPE(TableGenDAGArgOperatorToBreak) \
160164
TYPE(TableGenListCloser) \
161165
TYPE(TableGenListOpener) \
162166
TYPE(TableGenMultiLineString) \

clang/lib/Format/TokenAnnotator.cpp

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -986,16 +986,59 @@ class AnnotatingParser {
986986
return false;
987987
}
988988

989+
// Judge if the token is a operator ID to insert line break in DAGArg.
990+
// That is, TableGenBreakingDAGArgOperators is empty (by the definition of the
991+
// option) or the token is in the list.
992+
bool isTableGenDAGArgBreakingOperator(const FormatToken &Tok) {
993+
auto &Opes = Style.TableGenBreakingDAGArgOperators;
994+
// If the list is empty, all operators are breaking operators.
995+
if (Opes.empty())
996+
return true;
997+
// Otherwise, the operator is limited to normal identifiers.
998+
if (Tok.isNot(tok::identifier) ||
999+
Tok.isOneOf(TT_TableGenBangOperator, TT_TableGenCondOperator)) {
1000+
return false;
1001+
}
1002+
// The case next is colon, it is not a operator of identifier.
1003+
if (!Tok.Next || Tok.Next->is(tok::colon))
1004+
return false;
1005+
return std::find(Opes.begin(), Opes.end(), Tok.TokenText.str()) !=
1006+
Opes.end();
1007+
}
1008+
9891009
// SimpleValue6 ::= "(" DagArg [DagArgList] ")"
9901010
// This parses SimpleValue 6's inside part of "(" ")"
9911011
bool parseTableGenDAGArgAndList(FormatToken *Opener) {
1012+
FormatToken *FirstTok = CurrentToken;
9921013
if (!parseTableGenDAGArg())
9931014
return false;
1015+
bool BreakInside = false;
1016+
if (Style.TableGenBreakInsideDAGArg != FormatStyle::DAS_DontBreak) {
1017+
// Specialized detection for DAGArgOperator, that determines the way of
1018+
// line break for this DAGArg elements.
1019+
if (isTableGenDAGArgBreakingOperator(*FirstTok)) {
1020+
// Special case for identifier DAGArg operator.
1021+
BreakInside = true;
1022+
Opener->setType(TT_TableGenDAGArgOpenerToBreak);
1023+
if (FirstTok->isOneOf(TT_TableGenBangOperator,
1024+
TT_TableGenCondOperator)) {
1025+
// Special case for bang/cond operators. Set the whole operator as
1026+
// the DAGArg operator. Always break after it.
1027+
CurrentToken->Previous->setType(TT_TableGenDAGArgOperatorToBreak);
1028+
} else if (FirstTok->is(tok::identifier)) {
1029+
if (Style.TableGenBreakInsideDAGArg == FormatStyle::DAS_BreakAll)
1030+
FirstTok->setType(TT_TableGenDAGArgOperatorToBreak);
1031+
else
1032+
FirstTok->setType(TT_TableGenDAGArgOperatorID);
1033+
}
1034+
}
1035+
}
9941036
// Parse the [DagArgList] part
9951037
bool FirstDAGArgListElm = true;
9961038
while (CurrentToken) {
9971039
if (!FirstDAGArgListElm && CurrentToken->is(tok::comma)) {
998-
CurrentToken->setType(TT_TableGenDAGArgListComma);
1040+
CurrentToken->setType(BreakInside ? TT_TableGenDAGArgListCommaToBreak
1041+
: TT_TableGenDAGArgListComma);
9991042
skipToNextNonComment();
10001043
}
10011044
if (CurrentToken && CurrentToken->is(tok::r_paren)) {
@@ -5086,6 +5129,11 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
50865129
}
50875130
if (Right.is(TT_TableGenCondOperatorColon))
50885131
return false;
5132+
if (Left.isOneOf(TT_TableGenDAGArgOperatorID,
5133+
TT_TableGenDAGArgOperatorToBreak) &&
5134+
Right.isNot(TT_TableGenDAGArgCloser)) {
5135+
return true;
5136+
}
50895137
// Do not insert bang operators and consequent openers.
50905138
if (Right.isOneOf(tok::l_paren, tok::less) &&
50915139
Left.isOneOf(TT_TableGenBangOperator, TT_TableGenCondOperator)) {
@@ -5462,6 +5510,18 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
54625510
// case2:0);
54635511
if (Left.is(TT_TableGenCondOperatorComma))
54645512
return true;
5513+
if (Left.is(TT_TableGenDAGArgOperatorToBreak) &&
5514+
Right.isNot(TT_TableGenDAGArgCloser)) {
5515+
return true;
5516+
}
5517+
if (Left.is(TT_TableGenDAGArgListCommaToBreak))
5518+
return true;
5519+
if (Right.is(TT_TableGenDAGArgCloser) && Right.MatchingParen &&
5520+
Right.MatchingParen->is(TT_TableGenDAGArgOpenerToBreak) &&
5521+
&Left != Right.MatchingParen->Next) {
5522+
// Check to avoid empty DAGArg such as (ins).
5523+
return Style.TableGenBreakInsideDAGArg == FormatStyle::DAS_BreakAll;
5524+
}
54655525
}
54665526

54675527
if (Line.startsWith(tok::kw_asm) && Right.is(TT_InlineASMColon) &&
@@ -5876,6 +5936,8 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
58765936
// Avoid to break around paste operator.
58775937
if (Left.is(tok::hash) || Right.is(tok::hash))
58785938
return false;
5939+
if (Left.isOneOf(TT_TableGenBangOperator, TT_TableGenCondOperator))
5940+
return false;
58795941
}
58805942

58815943
if (Left.is(tok::at))

0 commit comments

Comments
 (0)