aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Format/UnwrappedLineParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Format/UnwrappedLineParser.cpp')
-rw-r--r--clang/lib/Format/UnwrappedLineParser.cpp66
1 files changed, 51 insertions, 15 deletions
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index 50d41c9f57a6..b904e0e56d9e 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -1170,6 +1170,15 @@ void UnwrappedLineParser::parsePPDefine() {
assert((int)Line->PPLevel >= 0);
Line->InMacroBody = true;
+ if (Style.SkipMacroDefinitionBody) {
+ do {
+ FormatTok->Finalized = true;
+ nextToken();
+ } while (!eof());
+ addUnwrappedLine();
+ return;
+ }
+
if (FormatTok->is(tok::identifier) &&
Tokens->peekNextToken()->is(tok::colon)) {
nextToken();
@@ -1652,7 +1661,8 @@ void UnwrappedLineParser::parseStructuralElement(
// In Verilog labels can be any expression, so we don't do them here.
// JS doesn't have macros, and within classes colons indicate fields, not
// labels.
- if (!Style.isJavaScript() && !Style.isVerilog() &&
+ // TableGen doesn't have labels.
+ if (!Style.isJavaScript() && !Style.isVerilog() && !Style.isTableGen() &&
Tokens->peekNextToken()->is(tok::colon) && !Line->MustBeDeclaration) {
nextToken();
Line->Tokens.begin()->Tok->MustBreakBefore = true;
@@ -1781,6 +1791,12 @@ void UnwrappedLineParser::parseStructuralElement(
addUnwrappedLine();
return;
}
+ if (Style.isTableGen()) {
+ // Do nothing special. In this case the l_brace becomes FunctionLBrace.
+ // This is same as def and so on.
+ nextToken();
+ break;
+ }
[[fallthrough]];
case tok::kw_struct:
case tok::kw_union:
@@ -2019,6 +2035,16 @@ void UnwrappedLineParser::parseStructuralElement(
// initialisers are indented the same way.
if (Style.isCSharp())
FormatTok->setBlockKind(BK_BracedInit);
+ // TableGen's defset statement has syntax of the form,
+ // `defset <type> <name> = { <statement>... }`
+ if (Style.isTableGen() &&
+ Line->Tokens.begin()->Tok->is(Keywords.kw_defset)) {
+ FormatTok->setFinalizedType(TT_FunctionLBrace);
+ parseBlock(/*MustBeDeclaration=*/false, /*AddLevels=*/1u,
+ /*MunchSemi=*/false);
+ addUnwrappedLine();
+ break;
+ }
nextToken();
parseBracedList();
} else if (Style.Language == FormatStyle::LK_Proto &&
@@ -2734,6 +2760,14 @@ FormatToken *UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind,
}
}
+ // TableGen's if statement has the form of `if <cond> then { ... }`.
+ if (Style.isTableGen()) {
+ while (!eof() && FormatTok->isNot(Keywords.kw_then)) {
+ // Simply skip until then. This range only contains a value.
+ nextToken();
+ }
+ }
+
// Handle `if !consteval`.
if (FormatTok->is(tok::exclaim))
nextToken();
@@ -3873,6 +3907,9 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) {
const FormatToken &InitialToken = *FormatTok;
nextToken();
+ auto IsNonMacroIdentifier = [](const FormatToken *Tok) {
+ return Tok->is(tok::identifier) && Tok->TokenText != Tok->TokenText.upper();
+ };
// The actual identifier can be a nested name specifier, and in macros
// it is often token-pasted.
// An [[attribute]] can be before the identifier.
@@ -3894,27 +3931,26 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) {
}
if (FormatTok->is(tok::l_square) && handleCppAttributes())
continue;
- bool IsNonMacroIdentifier =
- FormatTok->is(tok::identifier) &&
- FormatTok->TokenText != FormatTok->TokenText.upper();
nextToken();
// We can have macros in between 'class' and the class name.
- if (!IsNonMacroIdentifier && FormatTok->is(tok::l_paren))
+ if (!IsNonMacroIdentifier(FormatTok->Previous) &&
+ FormatTok->is(tok::l_paren)) {
parseParens();
+ }
}
- // Note that parsing away template declarations here leads to incorrectly
- // accepting function declarations as record declarations.
- // In general, we cannot solve this problem. Consider:
- // class A<int> B() {}
- // which can be a function definition or a class definition when B() is a
- // macro. If we find enough real-world cases where this is a problem, we
- // can parse for the 'template' keyword in the beginning of the statement,
- // and thus rule out the record production in case there is no template
- // (this would still leave us with an ambiguity between template function
- // and class declarations).
if (FormatTok->isOneOf(tok::colon, tok::less)) {
+ int AngleNestingLevel = 0;
do {
+ if (FormatTok->is(tok::less))
+ ++AngleNestingLevel;
+ else if (FormatTok->is(tok::greater))
+ --AngleNestingLevel;
+
+ if (AngleNestingLevel == 0 && FormatTok->is(tok::l_paren) &&
+ IsNonMacroIdentifier(FormatTok->Previous)) {
+ break;
+ }
if (FormatTok->is(tok::l_brace)) {
calculateBraceTypes(/*ExpectClassBody=*/true);
if (!tryToParseBracedList())