aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp525
1 files changed, 276 insertions, 249 deletions
diff --git a/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp b/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp
index e3fb976ee1cc..91b8fdc8a3c3 100644
--- a/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp
@@ -14,7 +14,6 @@
#include "UnwrappedLineParser.h"
#include "FormatToken.h"
-#include "FormatTokenLexer.h"
#include "FormatTokenSource.h"
#include "Macros.h"
#include "TokenAnnotator.h"
@@ -25,7 +24,6 @@
#include "llvm/Support/raw_os_ostream.h"
#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
#include <utility>
#define DEBUG_TYPE "format-parser"
@@ -51,9 +49,7 @@ void printLine(llvm::raw_ostream &OS, const UnwrappedLine &Line,
<< "T=" << (unsigned)I->Tok->getType()
<< ", OC=" << I->Tok->OriginalColumn << ", \"" << I->Tok->TokenText
<< "\"] ";
- for (SmallVectorImpl<UnwrappedLine>::const_iterator
- CI = I->Children.begin(),
- CE = I->Children.end();
+ for (const auto *CI = I->Children.begin(), *CE = I->Children.end();
CI != CE; ++CI) {
OS << "\n";
printLine(OS, *CI, (Prefix + " ").str());
@@ -121,7 +117,7 @@ public:
assert(Parser.Line->Tokens.empty());
Parser.Line = std::move(PreBlockLine);
if (Parser.CurrentLines == &Parser.PreprocessorDirectives)
- Parser.MustBreakBeforeNextToken = true;
+ Parser.AtEndOfPPLine = true;
Parser.CurrentLines = OriginalLines;
}
@@ -137,7 +133,8 @@ public:
CompoundStatementIndenter(UnwrappedLineParser *Parser,
const FormatStyle &Style, unsigned &LineLevel)
: CompoundStatementIndenter(Parser, LineLevel,
- Style.BraceWrapping.AfterControlStatement,
+ Style.BraceWrapping.AfterControlStatement ==
+ FormatStyle::BWACS_Always,
Style.BraceWrapping.IndentBraces) {}
CompoundStatementIndenter(UnwrappedLineParser *Parser, unsigned &LineLevel,
bool WrapBrace, bool IndentBrace)
@@ -160,8 +157,8 @@ UnwrappedLineParser::UnwrappedLineParser(
ArrayRef<FormatToken *> Tokens, UnwrappedLineConsumer &Callback,
llvm::SpecificBumpPtrAllocator<FormatToken> &Allocator,
IdentifierTable &IdentTable)
- : Line(new UnwrappedLine), MustBreakBeforeNextToken(false),
- CurrentLines(&Lines), Style(Style), IsCpp(Style.isCpp()),
+ : Line(new UnwrappedLine), AtEndOfPPLine(false), CurrentLines(&Lines),
+ Style(Style), IsCpp(Style.isCpp()),
LangOpts(getFormattingLangOpts(Style)), Keywords(Keywords),
CommentPragmasRegex(Style.CommentPragmas), Tokens(nullptr),
Callback(Callback), AllTokens(Tokens), PPBranchLevel(-1),
@@ -169,9 +166,7 @@ UnwrappedLineParser::UnwrappedLineParser(
? IG_Rejected
: IG_Inited),
IncludeGuardToken(nullptr), FirstStartColumn(FirstStartColumn),
- Macros(Style.Macros, SourceMgr, Style, Allocator, IdentTable) {
- assert(IsCpp == LangOpts.CXXOperatorNames);
-}
+ Macros(Style.Macros, SourceMgr, Style, Allocator, IdentTable) {}
void UnwrappedLineParser::reset() {
PPBranchLevel = -1;
@@ -182,7 +177,7 @@ void UnwrappedLineParser::reset() {
Line.reset(new UnwrappedLine);
CommentsBeforeNextToken.clear();
FormatTok = nullptr;
- MustBreakBeforeNextToken = false;
+ AtEndOfPPLine = false;
IsDecltypeAutoFunction = false;
PreprocessorDirectives.clear();
CurrentLines = &Lines;
@@ -274,7 +269,7 @@ void UnwrappedLineParser::parseFile() {
bool MustBeDeclaration = !Line->InPPDirective && !Style.isJavaScript();
ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
MustBeDeclaration);
- if (Style.Language == FormatStyle::LK_TextProto)
+ if (Style.isTextProto() || (Style.isJson() && FormatTok->IsFirst))
parseBracedList();
else
parseLevel();
@@ -288,10 +283,8 @@ void UnwrappedLineParser::parseFile() {
// // endfile comment
// do not have a chance to be put on a line of their own until this point.
// Here we add this newline before end-of-file comments.
- if (Style.Language == FormatStyle::LK_TextProto &&
- !CommentsBeforeNextToken.empty()) {
+ if (Style.isTextProto() && !CommentsBeforeNextToken.empty())
addUnwrappedLine();
- }
flushComments(true);
addUnwrappedLine();
}
@@ -300,6 +293,7 @@ void UnwrappedLineParser::parseCSharpGenericTypeConstraint() {
do {
switch (FormatTok->Tok.getKind()) {
case tok::l_brace:
+ case tok::semi:
return;
default:
if (FormatTok->is(Keywords.kw_where)) {
@@ -346,7 +340,7 @@ bool UnwrappedLineParser::precededByCommentOrPPDirective() const {
(Previous->IsMultiline || Previous->NewlinesBefore > 0);
}
-/// \brief Parses a level, that is ???.
+/// Parses a level, that is ???.
/// \param OpeningBrace Opening brace (\p nullptr if absent) of that level.
/// \param IfKind The \p if statement kind in the level.
/// \param IfLeftBrace The left brace of the \p if block in the level.
@@ -394,7 +388,7 @@ bool UnwrappedLineParser::parseLevel(const FormatToken *OpeningBrace,
break;
case tok::l_brace:
if (InRequiresExpression) {
- FormatTok->setFinalizedType(TT_RequiresExpressionLBrace);
+ FormatTok->setFinalizedType(TT_CompoundRequirementLBrace);
} else if (FormatTok->Previous &&
FormatTok->Previous->ClosesRequiresClause) {
// We need the 'default' case here to correctly parse a function
@@ -505,10 +499,10 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {
auto *NextTok = Tokens->getNextNonComment();
if (!Line->InMacroBody && !Style.isTableGen()) {
- // Skip PPDirective lines and comments.
+ // Skip PPDirective lines (except macro definitions) and comments.
while (NextTok->is(tok::hash)) {
NextTok = Tokens->getNextToken();
- if (NextTok->is(tok::pp_not_keyword))
+ if (NextTok->isOneOf(tok::pp_not_keyword, tok::pp_define))
break;
do {
NextTok = Tokens->getNextToken();
@@ -570,8 +564,9 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {
NextTok->isOneOf(Keywords.kw_of, Keywords.kw_in,
Keywords.kw_as));
ProbablyBracedList =
- ProbablyBracedList || (IsCpp && (PrevTok->Tok.isLiteral() ||
- NextTok->is(tok::l_paren)));
+ ProbablyBracedList ||
+ (IsCpp && (PrevTok->Tok.isLiteral() ||
+ NextTok->isOneOf(tok::l_paren, tok::arrow)));
// If there is a comma, semicolon or right paren after the closing
// brace, we assume this is a braced initializer list.
@@ -1031,6 +1026,12 @@ void UnwrappedLineParser::parsePPDirective() {
case tok::pp_pragma:
parsePPPragma();
break;
+ case tok::pp_error:
+ case tok::pp_warning:
+ nextToken();
+ if (!eof() && Style.isCpp())
+ FormatTok->setFinalizedType(TT_AfterPPDirective);
+ [[fallthrough]];
default:
parsePPUnknown();
break;
@@ -1154,6 +1155,7 @@ void UnwrappedLineParser::parsePPDefine() {
return;
}
+ bool MaybeIncludeGuard = false;
if (IncludeGuard == IG_IfNdefed &&
IncludeGuardToken->TokenText == FormatTok->TokenText) {
IncludeGuard = IG_Defined;
@@ -1164,6 +1166,7 @@ void UnwrappedLineParser::parsePPDefine() {
break;
}
}
+ MaybeIncludeGuard = IncludeGuard == IG_Defined;
}
// In the context of a define, even keywords should be treated as normal
@@ -1174,6 +1177,11 @@ void UnwrappedLineParser::parsePPDefine() {
FormatTok->Tok.setKind(tok::identifier);
FormatTok->Tok.setIdentifierInfo(Keywords.kw_internal_ident_after_define);
nextToken();
+
+ // IncludeGuard can't have a non-empty macro definition.
+ if (MaybeIncludeGuard && !eof())
+ IncludeGuard = IG_Rejected;
+
if (FormatTok->Tok.getKind() == tok::l_paren &&
!FormatTok->hasWhitespaceBefore()) {
parseParens();
@@ -1210,9 +1218,8 @@ void UnwrappedLineParser::parsePPPragma() {
}
void UnwrappedLineParser::parsePPUnknown() {
- do {
+ while (!eof())
nextToken();
- } while (!eof());
if (Style.IndentPPDirectives != FormatStyle::PPDIS_None)
Line->Level += PPBranchLevel + 1;
addUnwrappedLine();
@@ -1348,7 +1355,7 @@ bool UnwrappedLineParser::parseModuleImport() {
// Handle import <foo/bar.h> as we would an include statement.
else if (FormatTok->is(tok::less)) {
nextToken();
- while (!FormatTok->isOneOf(tok::semi, tok::greater, tok::eof)) {
+ while (!FormatTok->isOneOf(tok::semi, tok::greater) && !eof()) {
// Mark tokens up to the trailing line comments as implicit string
// literals.
if (FormatTok->isNot(tok::comment) &&
@@ -1420,8 +1427,7 @@ void UnwrappedLineParser::readTokenWithJavaScriptASI() {
void UnwrappedLineParser::parseStructuralElement(
const FormatToken *OpeningBrace, IfStmtKind *IfKind,
FormatToken **IfLeftBrace, bool *HasDoWhile, bool *HasLabel) {
- if (Style.Language == FormatStyle::LK_TableGen &&
- FormatTok->is(tok::pp_include)) {
+ if (Style.isTableGen() && FormatTok->is(tok::pp_include)) {
nextToken();
if (FormatTok->is(tok::string_literal))
nextToken();
@@ -1463,12 +1469,10 @@ void UnwrappedLineParser::parseStructuralElement(
// Tokens that only make sense at the beginning of a line.
if (FormatTok->isAccessSpecifierKeyword()) {
- if (Style.Language == FormatStyle::LK_Java || Style.isJavaScript() ||
- Style.isCSharp()) {
+ if (Style.isJava() || Style.isJavaScript() || Style.isCSharp())
nextToken();
- } else {
+ else
parseAccessSpecifier();
- }
return;
}
switch (FormatTok->Tok.getKind()) {
@@ -1568,6 +1572,11 @@ void UnwrappedLineParser::parseStructuralElement(
}
parseCaseLabel();
return;
+ case tok::kw_goto:
+ nextToken();
+ if (FormatTok->is(tok::kw_case))
+ nextToken();
+ break;
case tok::kw_try:
case tok::kw___try:
if (Style.isJavaScript() && Line->MustBeDeclaration) {
@@ -1616,6 +1625,10 @@ void UnwrappedLineParser::parseStructuralElement(
parseNamespace();
return;
}
+ if (FormatTok->is(tok::l_brace)) {
+ parseCppExportBlock();
+ return;
+ }
if (FormatTok->is(Keywords.kw_import) && parseModuleImport())
return;
}
@@ -1689,21 +1702,22 @@ void UnwrappedLineParser::parseStructuralElement(
*HasLabel = true;
return;
}
+ if (Style.isJava() && FormatTok->is(Keywords.kw_record)) {
+ parseRecord(/*ParseAsExpr=*/false, /*IsJavaRecord=*/true);
+ addUnwrappedLine();
+ return;
+ }
// In all other cases, parse the declaration.
break;
default:
break;
}
+ bool SeenEqual = false;
for (const bool InRequiresExpression =
- OpeningBrace && OpeningBrace->is(TT_RequiresExpressionLBrace);
+ OpeningBrace && OpeningBrace->isOneOf(TT_RequiresExpressionLBrace,
+ TT_CompoundRequirementLBrace);
!eof();) {
- if (IsCpp && FormatTok->isCppAlternativeOperatorKeyword()) {
- if (auto *Next = Tokens->peekNextToken(/*SkipComment=*/true);
- Next && Next->isBinaryOperator()) {
- FormatTok->Tok.setKind(tok::identifier);
- }
- }
const FormatToken *Previous = FormatTok->Previous;
switch (FormatTok->Tok.getKind()) {
case tok::at:
@@ -1712,12 +1726,12 @@ void UnwrappedLineParser::parseStructuralElement(
nextToken();
parseBracedList();
break;
- } else if (Style.Language == FormatStyle::LK_Java &&
- FormatTok->is(Keywords.kw_interface)) {
+ }
+ if (Style.isJava() && FormatTok->is(Keywords.kw_interface)) {
nextToken();
break;
}
- switch (FormatTok->Tok.getObjCKeywordID()) {
+ switch (bool IsAutoRelease = false; FormatTok->Tok.getObjCKeywordID()) {
case tok::objc_public:
case tok::objc_protected:
case tok::objc_package:
@@ -1738,19 +1752,11 @@ void UnwrappedLineParser::parseStructuralElement(
addUnwrappedLine();
return;
case tok::objc_autoreleasepool:
- nextToken();
- if (FormatTok->is(tok::l_brace)) {
- if (Style.BraceWrapping.AfterControlStatement ==
- FormatStyle::BWACS_Always) {
- addUnwrappedLine();
- }
- parseBlock();
- }
- addUnwrappedLine();
- return;
+ IsAutoRelease = true;
+ [[fallthrough]];
case tok::objc_synchronized:
nextToken();
- if (FormatTok->is(tok::l_paren)) {
+ if (!IsAutoRelease && FormatTok->is(tok::l_paren)) {
// Skip synchronization object
parseParens();
}
@@ -1774,7 +1780,7 @@ void UnwrappedLineParser::parseStructuralElement(
break;
case tok::kw_requires: {
if (IsCpp) {
- bool ParsedClause = parseRequires();
+ bool ParsedClause = parseRequires(SeenEqual);
if (ParsedClause)
return;
} else {
@@ -1831,8 +1837,8 @@ void UnwrappedLineParser::parseStructuralElement(
nextToken();
if (FormatTok->is(tok::l_paren)) {
parseParens();
- assert(FormatTok->Previous);
- if (FormatTok->Previous->endsSequence(tok::r_paren, tok::kw_auto,
+ if (FormatTok->Previous &&
+ FormatTok->Previous->endsSequence(tok::r_paren, tok::kw_auto,
tok::l_paren)) {
Line->SeenDecltypeAuto = true;
}
@@ -1841,10 +1847,8 @@ void UnwrappedLineParser::parseStructuralElement(
case tok::period:
nextToken();
// In Java, classes have an implicit static member "class".
- if (Style.Language == FormatStyle::LK_Java && FormatTok &&
- FormatTok->is(tok::kw_class)) {
+ if (Style.isJava() && FormatTok && FormatTok->is(tok::kw_class))
nextToken();
- }
if (Style.isJavaScript() && FormatTok &&
FormatTok->Tok.getIdentifierInfo()) {
// JavaScript only has pseudo keywords, all keywords are allowed to
@@ -1878,8 +1882,11 @@ void UnwrappedLineParser::parseStructuralElement(
if (FormatTok->isBinaryOperator())
nextToken();
break;
- case tok::caret:
+ case tok::caret: {
+ const auto *Prev = FormatTok->getPreviousNonComment();
nextToken();
+ if (Prev && Prev->is(tok::identifier))
+ break;
// Block return type.
if (FormatTok->Tok.isAnyIdentifier() || FormatTok->isTypeName(LangOpts)) {
nextToken();
@@ -1894,6 +1901,7 @@ void UnwrappedLineParser::parseStructuralElement(
if (FormatTok->is(tok::l_brace))
parseChildBlock();
break;
+ }
case tok::l_brace:
if (InRequiresExpression)
FormatTok->setFinalizedType(TT_BracedListLBrace);
@@ -1903,7 +1911,7 @@ void UnwrappedLineParser::parseStructuralElement(
// structural element.
// FIXME: Figure out cases where this is not true, and add projections
// for them (the one we know is missing are lambdas).
- if (Style.Language == FormatStyle::LK_Java &&
+ if (Style.isJava() &&
Line->Tokens.front().Tok->is(Keywords.kw_synchronized)) {
// If necessary, we could set the type to something different than
// TT_FunctionLBrace.
@@ -1959,7 +1967,7 @@ void UnwrappedLineParser::parseStructuralElement(
tryToParseJSFunction();
break;
}
- if ((Style.isJavaScript() || Style.Language == FormatStyle::LK_Java) &&
+ if ((Style.isJavaScript() || Style.isJava()) &&
FormatTok->is(Keywords.kw_interface)) {
if (Style.isJavaScript()) {
// In JavaScript/TypeScript, "interface" can be used as a standalone
@@ -2035,7 +2043,9 @@ void UnwrappedLineParser::parseStructuralElement(
? FormatTok->NewlinesBefore > 0
: CommentsBeforeNextToken.front()->NewlinesBefore > 0;
- if (FollowedByNewline && (Text.size() >= 5 || FunctionLike) &&
+ if (FollowedByNewline &&
+ (Text.size() >= 5 ||
+ (FunctionLike && FormatTok->isNot(tok::l_paren))) &&
tokenCanStartNewLine(*FormatTok) && Text == Text.upper()) {
if (PreviousToken->isNot(TT_UntouchableMacroFunc))
PreviousToken->setFinalizedType(TT_FunctionLikeOrFreestandingMacro);
@@ -2052,6 +2062,7 @@ void UnwrappedLineParser::parseStructuralElement(
break;
}
+ SeenEqual = true;
nextToken();
if (FormatTok->is(tok::l_brace)) {
// Block kind should probably be set to BK_BracedInit for any language.
@@ -2081,10 +2092,16 @@ void UnwrappedLineParser::parseStructuralElement(
parseSquare();
break;
case tok::kw_new:
- parseNew();
+ if (Style.isCSharp() &&
+ (Tokens->peekNextToken()->isAccessSpecifierKeyword() ||
+ (Previous && Previous->isAccessSpecifierKeyword()))) {
+ nextToken();
+ } else {
+ parseNew();
+ }
break;
case tok::kw_switch:
- if (Style.Language == FormatStyle::LK_Java)
+ if (Style.isJava())
parseSwitch(/*IsExpr=*/true);
else
nextToken();
@@ -2149,7 +2166,7 @@ bool UnwrappedLineParser::tryToParsePropertyAccessor() {
if (!Style.isCSharp())
return false;
// See if it's a property accessor.
- if (FormatTok->Previous->isNot(tok::identifier))
+ if (!FormatTok->Previous || FormatTok->Previous->isNot(tok::identifier))
return false;
// See if we are inside a property accessor.
@@ -2165,12 +2182,16 @@ bool UnwrappedLineParser::tryToParsePropertyAccessor() {
// Track these as they do not require line breaks to be introduced.
bool HasSpecialAccessor = false;
bool IsTrivialPropertyAccessor = true;
+ bool HasAttribute = false;
while (!eof()) {
- if (Tok->isAccessSpecifierKeyword() ||
- Tok->isOneOf(tok::semi, Keywords.kw_internal, Keywords.kw_get,
- Keywords.kw_init, Keywords.kw_set)) {
- if (Tok->isOneOf(Keywords.kw_get, Keywords.kw_init, Keywords.kw_set))
+ if (const bool IsAccessorKeyword =
+ Tok->isOneOf(Keywords.kw_get, Keywords.kw_init, Keywords.kw_set);
+ IsAccessorKeyword || Tok->isAccessSpecifierKeyword() ||
+ Tok->isOneOf(tok::l_square, tok::semi, Keywords.kw_internal)) {
+ if (IsAccessorKeyword)
HasSpecialAccessor = true;
+ else if (Tok->is(tok::l_square))
+ HasAttribute = true;
Tok = Tokens->getNextToken();
continue;
}
@@ -2179,7 +2200,7 @@ bool UnwrappedLineParser::tryToParsePropertyAccessor() {
break;
}
- if (!HasSpecialAccessor) {
+ if (!HasSpecialAccessor || HasAttribute) {
Tokens->setPosition(StoredPosition);
return false;
}
@@ -2364,13 +2385,25 @@ bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
const FormatToken *Previous = FormatTok->Previous;
const FormatToken *LeftSquare = FormatTok;
nextToken();
- if ((Previous && ((Previous->Tok.getIdentifierInfo() &&
- !Previous->isOneOf(tok::kw_return, tok::kw_co_await,
- tok::kw_co_yield, tok::kw_co_return)) ||
- Previous->closesScope())) ||
- LeftSquare->isCppStructuredBinding(IsCpp)) {
- return false;
+ if (Previous) {
+ if (Previous->Tok.getIdentifierInfo() &&
+ !Previous->isOneOf(tok::kw_return, tok::kw_co_await, tok::kw_co_yield,
+ tok::kw_co_return)) {
+ return false;
+ }
+ if (Previous->closesScope()) {
+ // Not a potential C-style cast.
+ if (Previous->isNot(tok::r_paren))
+ return false;
+ const auto *BeforeRParen = Previous->getPreviousNonComment();
+ // Lambdas can be cast to function types only, e.g. `std::function<int()>`
+ // and `int (*)()`.
+ if (!BeforeRParen || !BeforeRParen->isOneOf(tok::greater, tok::r_paren))
+ return false;
+ }
}
+ if (LeftSquare->isCppStructuredBinding(IsCpp))
+ return false;
if (FormatTok->is(tok::l_square) || tok::isLiteral(FormatTok->Tok.getKind()))
return false;
if (FormatTok->is(tok::r_square)) {
@@ -2541,60 +2574,87 @@ bool UnwrappedLineParser::parseBracedList(bool IsAngleBracket, bool IsEnum) {
return false;
}
-/// \brief Parses a pair of parentheses (and everything between them).
+/// Parses a pair of parentheses (and everything between them).
/// \param AmpAmpTokenType If different than TT_Unknown sets this type for all
/// double ampersands. This applies for all nested scopes as well.
///
/// Returns whether there is a `=` token between the parentheses.
-bool UnwrappedLineParser::parseParens(TokenType AmpAmpTokenType) {
+bool UnwrappedLineParser::parseParens(TokenType AmpAmpTokenType,
+ bool InMacroCall) {
assert(FormatTok->is(tok::l_paren) && "'(' expected.");
- auto *LeftParen = FormatTok;
+ auto *LParen = FormatTok;
+ auto *Prev = FormatTok->Previous;
+ bool SeenComma = false;
bool SeenEqual = false;
bool MightBeFoldExpr = false;
- const bool MightBeStmtExpr = Tokens->peekNextToken()->is(tok::l_brace);
nextToken();
+ const bool MightBeStmtExpr = FormatTok->is(tok::l_brace);
+ if (!InMacroCall && Prev && Prev->is(TT_FunctionLikeMacro))
+ InMacroCall = true;
do {
switch (FormatTok->Tok.getKind()) {
case tok::l_paren:
- if (parseParens(AmpAmpTokenType))
+ if (parseParens(AmpAmpTokenType, InMacroCall))
SeenEqual = true;
- if (Style.Language == FormatStyle::LK_Java && FormatTok->is(tok::l_brace))
+ if (Style.isJava() && FormatTok->is(tok::l_brace))
parseChildBlock();
break;
case tok::r_paren: {
- auto *Prev = LeftParen->Previous;
- if (!MightBeStmtExpr && !MightBeFoldExpr && !Line->InMacroBody &&
- Style.RemoveParentheses > FormatStyle::RPS_Leave) {
- const auto *Next = Tokens->peekNextToken();
- const bool DoubleParens =
- Prev && Prev->is(tok::l_paren) && Next && Next->is(tok::r_paren);
- const auto *PrevPrev = Prev ? Prev->getPreviousNonComment() : nullptr;
- const bool Blacklisted =
- PrevPrev &&
- (PrevPrev->isOneOf(tok::kw___attribute, tok::kw_decltype) ||
- (SeenEqual &&
- (PrevPrev->isOneOf(tok::kw_if, tok::kw_while) ||
- PrevPrev->endsSequence(tok::kw_constexpr, tok::kw_if))));
- const bool ReturnParens =
- Style.RemoveParentheses == FormatStyle::RPS_ReturnStatement &&
- ((NestedLambdas.empty() && !IsDecltypeAutoFunction) ||
- (!NestedLambdas.empty() && !NestedLambdas.back())) &&
- Prev && Prev->isOneOf(tok::kw_return, tok::kw_co_return) && Next &&
- Next->is(tok::semi);
- if ((DoubleParens && !Blacklisted) || ReturnParens) {
- LeftParen->Optional = true;
- FormatTok->Optional = true;
- }
- }
+ auto *RParen = FormatTok;
+ nextToken();
if (Prev) {
+ auto OptionalParens = [&] {
+ if (MightBeStmtExpr || MightBeFoldExpr || SeenComma || InMacroCall ||
+ Line->InMacroBody ||
+ Style.RemoveParentheses == FormatStyle::RPS_Leave ||
+ RParen->getPreviousNonComment() == LParen) {
+ return false;
+ }
+ const bool DoubleParens =
+ Prev->is(tok::l_paren) && FormatTok->is(tok::r_paren);
+ if (DoubleParens) {
+ const auto *PrevPrev = Prev->getPreviousNonComment();
+ const bool Excluded =
+ PrevPrev &&
+ (PrevPrev->isOneOf(tok::kw___attribute, tok::kw_decltype) ||
+ (SeenEqual &&
+ (PrevPrev->isOneOf(tok::kw_if, tok::kw_while) ||
+ PrevPrev->endsSequence(tok::kw_constexpr, tok::kw_if))));
+ if (!Excluded)
+ return true;
+ } else {
+ const bool CommaSeparated =
+ Prev->isOneOf(tok::l_paren, tok::comma) &&
+ FormatTok->isOneOf(tok::comma, tok::r_paren);
+ if (CommaSeparated &&
+ // LParen is not preceded by ellipsis, comma.
+ !Prev->endsSequence(tok::comma, tok::ellipsis) &&
+ // RParen is not followed by comma, ellipsis.
+ !(FormatTok->is(tok::comma) &&
+ Tokens->peekNextToken()->is(tok::ellipsis))) {
+ return true;
+ }
+ const bool ReturnParens =
+ Style.RemoveParentheses == FormatStyle::RPS_ReturnStatement &&
+ ((NestedLambdas.empty() && !IsDecltypeAutoFunction) ||
+ (!NestedLambdas.empty() && !NestedLambdas.back())) &&
+ Prev->isOneOf(tok::kw_return, tok::kw_co_return) &&
+ FormatTok->is(tok::semi);
+ if (ReturnParens)
+ return true;
+ }
+ return false;
+ };
if (Prev->is(TT_TypenameMacro)) {
- LeftParen->setFinalizedType(TT_TypeDeclarationParen);
- FormatTok->setFinalizedType(TT_TypeDeclarationParen);
- } else if (Prev->is(tok::greater) && FormatTok->Previous == LeftParen) {
+ LParen->setFinalizedType(TT_TypeDeclarationParen);
+ RParen->setFinalizedType(TT_TypeDeclarationParen);
+ } else if (Prev->is(tok::greater) && RParen->Previous == LParen) {
Prev->setFinalizedType(TT_TemplateCloser);
+ } else if (OptionalParens()) {
+ LParen->Optional = true;
+ RParen->Optional = true;
}
}
- nextToken();
return SeenEqual;
}
case tok::r_brace:
@@ -2614,6 +2674,10 @@ bool UnwrappedLineParser::parseParens(TokenType AmpAmpTokenType) {
parseBracedList();
}
break;
+ case tok::comma:
+ SeenComma = true;
+ nextToken();
+ break;
case tok::ellipsis:
MightBeFoldExpr = true;
nextToken();
@@ -2638,7 +2702,7 @@ bool UnwrappedLineParser::parseParens(TokenType AmpAmpTokenType) {
nextToken();
break;
case tok::kw_switch:
- if (Style.Language == FormatStyle::LK_Java)
+ if (Style.isJava())
parseSwitch(/*IsExpr=*/true);
else
nextToken();
@@ -3015,7 +3079,7 @@ void UnwrappedLineParser::parseTryCatch() {
}
}
// Parse try with resource.
- if (Style.Language == FormatStyle::LK_Java && FormatTok->is(tok::l_paren))
+ if (Style.isJava() && FormatTok->is(tok::l_paren))
parseParens();
keepAncestorBraces();
@@ -3038,30 +3102,35 @@ void UnwrappedLineParser::parseTryCatch() {
parseStructuralElement();
--Line->Level;
}
- while (true) {
+ for (bool SeenCatch = false;;) {
if (FormatTok->is(tok::at))
nextToken();
if (!(FormatTok->isOneOf(tok::kw_catch, Keywords.kw___except,
- tok::kw___finally) ||
- ((Style.Language == FormatStyle::LK_Java || Style.isJavaScript()) &&
- FormatTok->is(Keywords.kw_finally)) ||
- (FormatTok->isObjCAtKeyword(tok::objc_catch) ||
- FormatTok->isObjCAtKeyword(tok::objc_finally)))) {
+ tok::kw___finally, tok::objc_catch,
+ tok::objc_finally) ||
+ ((Style.isJava() || Style.isJavaScript()) &&
+ FormatTok->is(Keywords.kw_finally)))) {
break;
}
+ if (FormatTok->is(tok::kw_catch))
+ SeenCatch = true;
nextToken();
while (FormatTok->isNot(tok::l_brace)) {
if (FormatTok->is(tok::l_paren)) {
parseParens();
continue;
}
- if (FormatTok->isOneOf(tok::semi, tok::r_brace, tok::eof)) {
+ if (FormatTok->isOneOf(tok::semi, tok::r_brace) || eof()) {
if (Style.RemoveBracesLLVM)
NestedTooDeep.pop_back();
return;
}
nextToken();
}
+ if (SeenCatch) {
+ FormatTok->setFinalizedType(TT_ControlStatementLBrace);
+ SeenCatch = false;
+ }
NeedsUnwrappedLine = false;
Line->MustBeDeclaration = false;
CompoundStatementIndenter Indenter(this, Style, Line->Level);
@@ -3079,6 +3148,26 @@ void UnwrappedLineParser::parseTryCatch() {
addUnwrappedLine();
}
+void UnwrappedLineParser::parseNamespaceOrExportBlock(unsigned AddLevels) {
+ bool ManageWhitesmithsBraces =
+ AddLevels == 0u && Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths;
+
+ // If we're in Whitesmiths mode, indent the brace if we're not indenting
+ // the whole block.
+ if (ManageWhitesmithsBraces)
+ ++Line->Level;
+
+ // Munch the semicolon after the block. This is more common than one would
+ // think. Putting the semicolon into its own line is very ugly.
+ parseBlock(/*MustBeDeclaration=*/true, AddLevels, /*MunchSemi=*/true,
+ /*KeepBraces=*/true, /*IfKind=*/nullptr, ManageWhitesmithsBraces);
+
+ addUnwrappedLine(AddLevels > 0 ? LineLevel::Remove : LineLevel::Keep);
+
+ if (ManageWhitesmithsBraces)
+ --Line->Level;
+}
+
void UnwrappedLineParser::parseNamespace() {
assert(FormatTok->isOneOf(tok::kw_namespace, TT_NamespaceMacro) &&
"'namespace' expected");
@@ -3111,29 +3200,15 @@ void UnwrappedLineParser::parseNamespace() {
DeclarationScopeStack.size() > 1)
? 1u
: 0u;
- bool ManageWhitesmithsBraces =
- AddLevels == 0u &&
- Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths;
-
- // If we're in Whitesmiths mode, indent the brace if we're not indenting
- // the whole block.
- if (ManageWhitesmithsBraces)
- ++Line->Level;
-
- // Munch the semicolon after a namespace. This is more common than one would
- // think. Putting the semicolon into its own line is very ugly.
- parseBlock(/*MustBeDeclaration=*/true, AddLevels, /*MunchSemi=*/true,
- /*KeepBraces=*/true, /*IfKind=*/nullptr,
- ManageWhitesmithsBraces);
-
- addUnwrappedLine(AddLevels > 0 ? LineLevel::Remove : LineLevel::Keep);
-
- if (ManageWhitesmithsBraces)
- --Line->Level;
+ parseNamespaceOrExportBlock(AddLevels);
}
// FIXME: Add error handling.
}
+void UnwrappedLineParser::parseCppExportBlock() {
+ parseNamespaceOrExportBlock(/*AddLevels=*/Style.IndentExportBlock ? 1 : 0);
+}
+
void UnwrappedLineParser::parseNew() {
assert(FormatTok->is(tok::kw_new) && "'new' expected");
nextToken();
@@ -3155,7 +3230,7 @@ void UnwrappedLineParser::parseNew() {
} while (!eof());
}
- if (Style.Language != FormatStyle::LK_Java)
+ if (!Style.isJava())
return;
// In Java, we can parse everything up to the parens, which aren't optional.
@@ -3317,7 +3392,7 @@ void UnwrappedLineParser::parseCaseLabel() {
FormatTok->setFinalizedType(TT_CaseLabelColon);
break;
}
- if (Style.Language == FormatStyle::LK_Java && FormatTok->is(tok::arrow)) {
+ if (Style.isJava() && FormatTok->is(tok::arrow)) {
FormatTok->setFinalizedType(TT_CaseLabelArrow);
Case->setFinalizedType(TT_SwitchExpressionLabel);
break;
@@ -3356,81 +3431,21 @@ void UnwrappedLineParser::parseSwitch(bool IsExpr) {
NestedTooDeep.pop_back();
}
-// Operators that can follow a C variable.
-static bool isCOperatorFollowingVar(tok::TokenKind Kind) {
- switch (Kind) {
- case tok::ampamp:
- case tok::ampequal:
- case tok::arrow:
- case tok::caret:
- case tok::caretequal:
- case tok::comma:
- case tok::ellipsis:
- case tok::equal:
- case tok::equalequal:
- case tok::exclaim:
- case tok::exclaimequal:
- case tok::greater:
- case tok::greaterequal:
- case tok::greatergreater:
- case tok::greatergreaterequal:
- case tok::l_paren:
- case tok::l_square:
- case tok::less:
- case tok::lessequal:
- case tok::lessless:
- case tok::lesslessequal:
- case tok::minus:
- case tok::minusequal:
- case tok::minusminus:
- case tok::percent:
- case tok::percentequal:
- case tok::period:
- case tok::pipe:
- case tok::pipeequal:
- case tok::pipepipe:
- case tok::plus:
- case tok::plusequal:
- case tok::plusplus:
- case tok::question:
- case tok::r_brace:
- case tok::r_paren:
- case tok::r_square:
- case tok::semi:
- case tok::slash:
- case tok::slashequal:
- case tok::star:
- case tok::starequal:
- return true;
- default:
- return false;
- }
-}
-
void UnwrappedLineParser::parseAccessSpecifier() {
- FormatToken *AccessSpecifierCandidate = FormatTok;
nextToken();
// Understand Qt's slots.
if (FormatTok->isOneOf(Keywords.kw_slots, Keywords.kw_qslots))
nextToken();
// Otherwise, we don't know what it is, and we'd better keep the next token.
- if (FormatTok->is(tok::colon)) {
+ if (FormatTok->is(tok::colon))
nextToken();
- addUnwrappedLine();
- } else if (FormatTok->isNot(tok::coloncolon) &&
- !isCOperatorFollowingVar(FormatTok->Tok.getKind())) {
- // Not a variable name nor namespace name.
- addUnwrappedLine();
- } else if (AccessSpecifierCandidate) {
- // Consider the access specifier to be a C identifier.
- AccessSpecifierCandidate->Tok.setKind(tok::identifier);
- }
+ addUnwrappedLine();
}
-/// \brief Parses a requires, decides if it is a clause or an expression.
+/// Parses a requires, decides if it is a clause or an expression.
/// \pre The current token has to be the requires keyword.
/// \returns true if it parsed a clause.
-bool UnwrappedLineParser::parseRequires() {
+bool UnwrappedLineParser::parseRequires(bool SeenEqual) {
assert(FormatTok->is(tok::kw_requires) && "'requires' expected");
auto RequiresToken = FormatTok;
@@ -3474,10 +3489,11 @@ bool UnwrappedLineParser::parseRequires() {
case tok::r_paren:
case tok::kw_noexcept:
case tok::kw_const:
+ case tok::star:
+ case tok::amp:
// This is a requires clause.
parseRequiresClause(RequiresToken);
return true;
- case tok::amp:
case tok::ampamp: {
// This can be either:
// if (... && requires (T t) ...)
@@ -3486,7 +3502,7 @@ bool UnwrappedLineParser::parseRequires() {
// We check the one token before that for a const:
// void member(...) const && requires (C<T> ...
auto PrevPrev = PreviousNonComment->getPreviousNonComment();
- if (PrevPrev && PrevPrev->is(tok::kw_const)) {
+ if ((PrevPrev && PrevPrev->is(tok::kw_const)) || !SeenEqual) {
parseRequiresClause(RequiresToken);
return true;
}
@@ -3570,7 +3586,7 @@ bool UnwrappedLineParser::parseRequires() {
return true;
}
-/// \brief Parses a requires clause.
+/// Parses a requires clause.
/// \param RequiresToken The requires keyword token, which starts this clause.
/// \pre We need to be on the next token after the requires keyword.
/// \sa parseRequiresExpression
@@ -3596,11 +3612,11 @@ void UnwrappedLineParser::parseRequiresClause(FormatToken *RequiresToken) {
// It could be inlined into here.
parseConstraintExpression();
- if (!InRequiresExpression)
+ if (!InRequiresExpression && FormatTok->Previous)
FormatTok->Previous->ClosesRequiresClause = true;
}
-/// \brief Parses a requires expression.
+/// Parses a requires expression.
/// \param RequiresToken The requires keyword token, which starts this clause.
/// \pre We need to be on the next token after the requires keyword.
/// \sa parseRequiresClause
@@ -3624,7 +3640,7 @@ void UnwrappedLineParser::parseRequiresExpression(FormatToken *RequiresToken) {
}
}
-/// \brief Parses a constraint expression.
+/// Parses a constraint expression.
///
/// This is the body of a requires clause. It returns, when the parsing is
/// complete, or the expression is incorrect.
@@ -3829,7 +3845,7 @@ bool UnwrappedLineParser::parseEnum() {
FormatTok->setFinalizedType(TT_EnumLBrace);
FormatTok->setBlockKind(BK_Block);
- if (Style.Language == FormatStyle::LK_Java) {
+ if (Style.isJava()) {
// Java enums are different.
parseJavaEnumBody();
return true;
@@ -3870,8 +3886,7 @@ bool UnwrappedLineParser::parseStructLike() {
// record declaration or definition can start a structural element.
parseRecord();
// This does not apply to Java, JavaScript and C#.
- if (Style.Language == FormatStyle::LK_Java || Style.isJavaScript() ||
- Style.isCSharp()) {
+ if (Style.isJava() || Style.isJavaScript() || Style.isCSharp()) {
if (FormatTok->is(tok::semi))
nextToken();
addUnwrappedLine();
@@ -3989,11 +4004,13 @@ void UnwrappedLineParser::parseJavaEnumBody() {
addUnwrappedLine();
}
-void UnwrappedLineParser::parseRecord(bool ParseAsExpr) {
+void UnwrappedLineParser::parseRecord(bool ParseAsExpr, bool IsJavaRecord) {
+ assert(!IsJavaRecord || FormatTok->is(Keywords.kw_record));
const FormatToken &InitialToken = *FormatTok;
nextToken();
- const FormatToken *ClassName = nullptr;
+ FormatToken *ClassName =
+ IsJavaRecord && FormatTok->is(tok::identifier) ? FormatTok : nullptr;
bool IsDerived = false;
auto IsNonMacroIdentifier = [](const FormatToken *Tok) {
return Tok->is(tok::identifier) && Tok->TokenText != Tok->TokenText.upper();
@@ -4007,7 +4024,7 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) {
while (FormatTok->isOneOf(tok::identifier, tok::coloncolon, tok::hashhash,
tok::kw_alignas, tok::l_square) ||
FormatTok->isAttribute() ||
- ((Style.Language == FormatStyle::LK_Java || Style.isJavaScript()) &&
+ ((Style.isJava() || Style.isJavaScript()) &&
FormatTok->isOneOf(tok::period, tok::comma))) {
if (Style.isJavaScript() &&
FormatTok->isOneOf(Keywords.kw_extends, Keywords.kw_implements)) {
@@ -4023,12 +4040,12 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) {
}
if (FormatTok->is(tok::l_square) && handleCppAttributes())
continue;
- const auto *Previous = FormatTok;
+ auto *Previous = FormatTok;
nextToken();
switch (FormatTok->Tok.getKind()) {
case tok::l_paren:
// We can have macros in between 'class' and the class name.
- if (!IsNonMacroIdentifier(Previous) ||
+ if (IsJavaRecord || !IsNonMacroIdentifier(Previous) ||
// e.g. `struct macro(a) S { int i; };`
Previous->Previous == &InitialToken) {
parseParens();
@@ -4038,15 +4055,19 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) {
case tok::hashhash:
break;
default:
- if (!JSPastExtendsOrImplements && !ClassName &&
- Previous->is(tok::identifier) && Previous->isNot(TT_AttributeMacro)) {
+ if (JSPastExtendsOrImplements || ClassName ||
+ Previous->isNot(tok::identifier) || Previous->is(TT_AttributeMacro)) {
+ break;
+ }
+ if (const auto Text = Previous->TokenText;
+ Text.size() == 1 || Text != Text.upper()) {
ClassName = Previous;
}
}
}
auto IsListInitialization = [&] {
- if (!ClassName || IsDerived)
+ if (!ClassName || IsDerived || JSPastExtendsOrImplements)
return false;
assert(FormatTok->is(tok::l_brace));
const auto *Prev = FormatTok->getPreviousNonComment();
@@ -4066,7 +4087,7 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) {
if (AngleNestingLevel == 0) {
if (FormatTok->is(tok::colon)) {
IsDerived = true;
- } else if (FormatTok->is(tok::identifier) &&
+ } else if (!IsDerived && FormatTok->is(tok::identifier) &&
FormatTok->Previous->is(tok::coloncolon)) {
ClassName = FormatTok;
} else if (FormatTok->is(tok::l_paren) &&
@@ -4123,6 +4144,8 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) {
if (FormatTok->is(tok::l_brace)) {
if (IsListInitialization())
return;
+ if (ClassName)
+ ClassName->setFinalizedType(TT_ClassHeadName);
auto [OpenBraceType, ClosingBraceType] = GetBraceTypes(InitialToken);
FormatTok->setFinalizedType(OpenBraceType);
if (ParseAsExpr) {
@@ -4166,17 +4189,15 @@ void UnwrappedLineParser::parseObjCProtocolList() {
do {
nextToken();
// Early exit in case someone forgot a close angle.
- if (FormatTok->isOneOf(tok::semi, tok::l_brace) ||
- FormatTok->isObjCAtKeyword(tok::objc_end)) {
+ if (FormatTok->isOneOf(tok::semi, tok::l_brace, tok::objc_end))
return;
- }
} while (!eof() && FormatTok->isNot(tok::greater));
nextToken(); // Skip '>'.
}
void UnwrappedLineParser::parseObjCUntilAtEnd() {
do {
- if (FormatTok->isObjCAtKeyword(tok::objc_end)) {
+ if (FormatTok->is(tok::objc_end)) {
nextToken();
addUnwrappedLine();
break;
@@ -4199,8 +4220,7 @@ void UnwrappedLineParser::parseObjCUntilAtEnd() {
}
void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
- assert(FormatTok->Tok.getObjCKeywordID() == tok::objc_interface ||
- FormatTok->Tok.getObjCKeywordID() == tok::objc_implementation);
+ assert(FormatTok->isOneOf(tok::objc_interface, tok::objc_implementation));
nextToken();
nextToken(); // interface name
@@ -4248,10 +4268,8 @@ void UnwrappedLineParser::parseObjCLightweightGenerics() {
do {
nextToken();
// Early exit in case someone forgot a close angle.
- if (FormatTok->isOneOf(tok::semi, tok::l_brace) ||
- FormatTok->isObjCAtKeyword(tok::objc_end)) {
+ if (FormatTok->isOneOf(tok::semi, tok::l_brace, tok::objc_end))
break;
- }
if (FormatTok->is(tok::less)) {
++NumOpenAngles;
} else if (FormatTok->is(tok::greater)) {
@@ -4265,7 +4283,7 @@ void UnwrappedLineParser::parseObjCLightweightGenerics() {
// Returns true for the declaration/definition form of @protocol,
// false for the expression form.
bool UnwrappedLineParser::parseObjCProtocol() {
- assert(FormatTok->Tok.getObjCKeywordID() == tok::objc_protocol);
+ assert(FormatTok->is(tok::objc_protocol));
nextToken();
if (FormatTok->is(tok::l_paren)) {
@@ -4422,7 +4440,8 @@ unsigned UnwrappedLineParser::parseVerilogHierarchyHeader() {
Prev->setFinalizedType(TT_VerilogDimensionedTypeName);
parseSquare();
} else if (Keywords.isVerilogIdentifier(*FormatTok) ||
- FormatTok->isOneOf(Keywords.kw_automatic, tok::kw_static)) {
+ FormatTok->isOneOf(tok::hash, tok::hashhash, tok::coloncolon,
+ Keywords.kw_automatic, tok::kw_static)) {
nextToken();
} else {
break;
@@ -4586,7 +4605,7 @@ void UnwrappedLineParser::addUnwrappedLine(LineLevel AdjustLevel) {
} else {
// At the top level we only get here when no unexpansion is going on, or
// when conditional formatting led to unfinished macro reconstructions.
- assert(!Reconstruct || (CurrentLines != &Lines) || PPStack.size() > 0);
+ assert(!Reconstruct || (CurrentLines != &Lines) || !PPStack.empty());
CurrentLines->push_back(std::move(*Line));
}
Line->Tokens.clear();
@@ -4618,9 +4637,9 @@ bool UnwrappedLineParser::isOnNewLine(const FormatToken &FormatTok) {
// section on \p Line.
static bool
continuesLineCommentSection(const FormatToken &FormatTok,
- const UnwrappedLine &Line,
+ const UnwrappedLine &Line, const FormatStyle &Style,
const llvm::Regex &CommentPragmasRegex) {
- if (Line.Tokens.empty())
+ if (Line.Tokens.empty() || Style.ReflowComments != FormatStyle::RCS_Always)
return false;
StringRef IndentContent = FormatTok.TokenText;
@@ -4733,7 +4752,7 @@ void UnwrappedLineParser::flushComments(bool NewlineBeforeNext) {
// FIXME: Consider putting separate line comment sections as children to the
// unwrapped line instead.
Tok->ContinuesLineCommentSection =
- continuesLineCommentSection(*Tok, *Line, CommentPragmasRegex);
+ continuesLineCommentSection(*Tok, *Line, Style, CommentPragmasRegex);
if (isOnNewLine(*Tok) && JustComments && !Tok->ContinuesLineCommentSection)
addUnwrappedLine();
pushToken(Tok);
@@ -4767,8 +4786,7 @@ void UnwrappedLineParser::nextToken(int LevelDifference) {
}
void UnwrappedLineParser::distributeComments(
- const SmallVectorImpl<FormatToken *> &Comments,
- const FormatToken *NextTok) {
+ const ArrayRef<FormatToken *> &Comments, const FormatToken *NextTok) {
// Whether or not a line comment token continues a line is controlled by
// the method continuesLineCommentSection, with the following caveat:
//
@@ -4806,8 +4824,8 @@ void UnwrappedLineParser::distributeComments(
if (HasTrailAlignedWithNextToken && i == StartOfTrailAlignedWithNextToken) {
FormatTok->ContinuesLineCommentSection = false;
} else {
- FormatTok->ContinuesLineCommentSection =
- continuesLineCommentSection(*FormatTok, *Line, CommentPragmasRegex);
+ FormatTok->ContinuesLineCommentSection = continuesLineCommentSection(
+ *FormatTok, *Line, Style, CommentPragmasRegex);
}
if (!FormatTok->ContinuesLineCommentSection &&
(isOnNewLine(*FormatTok) || FormatTok->IsFirst)) {
@@ -4859,9 +4877,16 @@ void UnwrappedLineParser::readToken(int LevelDifference) {
PreviousWasComment = FormatTok->is(tok::comment);
while (!Line->InPPDirective && FormatTok->is(tok::hash) &&
- (!Style.isVerilog() ||
- Keywords.isVerilogPPDirective(*Tokens->peekNextToken())) &&
FirstNonCommentOnLine) {
+ // In Verilog, the backtick is used for macro invocations. In TableGen,
+ // the single hash is used for the paste operator.
+ const auto *Next = Tokens->peekNextToken();
+ if ((Style.isVerilog() && !Keywords.isVerilogPPDirective(*Next)) ||
+ (Style.isTableGen() &&
+ !Next->isOneOf(tok::kw_else, tok::pp_define, tok::pp_ifdef,
+ tok::pp_ifndef, tok::pp_endif))) {
+ break;
+ }
distributeComments(Comments, FormatTok);
Comments.clear();
// If there is an unfinished unwrapped line, we flush the preprocessor
@@ -4990,7 +5015,7 @@ void UnwrappedLineParser::readToken(int LevelDifference) {
namespace {
template <typename Iterator>
void pushTokens(Iterator Begin, Iterator End,
- llvm::SmallVectorImpl<FormatToken *> &Into) {
+ SmallVectorImpl<FormatToken *> &Into) {
for (auto I = Begin; I != End; ++I) {
Into.push_back(I->Tok);
for (const auto &Child : I->Children)
@@ -5054,10 +5079,12 @@ UnwrappedLineParser::parseMacroCall() {
void UnwrappedLineParser::pushToken(FormatToken *Tok) {
Line->Tokens.push_back(UnwrappedLineNode(Tok));
- if (MustBreakBeforeNextToken) {
- Line->Tokens.back().Tok->MustBreakBefore = true;
- Line->Tokens.back().Tok->MustBreakBeforeFinalized = true;
- MustBreakBeforeNextToken = false;
+ if (AtEndOfPPLine) {
+ auto &Tok = *Line->Tokens.back().Tok;
+ Tok.MustBreakBefore = true;
+ Tok.MustBreakBeforeFinalized = true;
+ Tok.FirstAfterPPLine = true;
+ AtEndOfPPLine = false;
}
}