sstwcw created this revision.
sstwcw added a reviewer: clang-format.
sstwcw added a project: clang-format.
Herald added a project: All.
sstwcw requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
Previously several places had code to determine whether the line is an
if / while / for statement. This commit replaces them with a function
call.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D121756
Files:
clang/lib/Format/ContinuationIndenter.cpp
clang/lib/Format/FormatToken.h
clang/lib/Format/TokenAnnotator.cpp
clang/lib/Format/UnwrappedLineParser.cpp
Index: clang/lib/Format/UnwrappedLineParser.cpp
===================================================================
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -2422,8 +2422,10 @@
} else {
if (FormatTok->isOneOf(tok::kw_constexpr, tok::identifier))
nextToken();
- if (FormatTok->is(tok::l_paren))
+ if (FormatTok->Tok.is(tok::l_paren)) {
+ FormatTok->setType(TT_ConditionLParen);
parseParens();
+ }
}
handleAttributes();
@@ -2714,14 +2716,20 @@
void UnwrappedLineParser::parseForOrWhileLoop() {
assert(FormatTok->isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) &&
"'for', 'while' or foreach macro expected");
+ // Those that begin with a for require special treatment because inside the
+ // parentheses is not an expression.
+ bool IsFor = FormatTok->is(tok::kw_for) || FormatTok->is(TT_ForEachMacro);
nextToken();
// JS' for await ( ...
if (Style.isJavaScript() && FormatTok->is(Keywords.kw_await))
nextToken();
if (Style.isCpp() && FormatTok->is(tok::kw_co_await))
nextToken();
- if (FormatTok->is(tok::l_paren))
+ if (FormatTok->is(tok::l_paren)) {
+ if (!IsFor)
+ FormatTok->setType(TT_ConditionLParen);
parseParens();
+ }
keepAncestorBraces();
@@ -2827,8 +2835,10 @@
void UnwrappedLineParser::parseSwitch() {
assert(FormatTok->is(tok::kw_switch) && "'switch' expected");
nextToken();
- if (FormatTok->is(tok::l_paren))
+ if (FormatTok->is(tok::l_paren)) {
+ FormatTok->setType(TT_ConditionLParen);
parseParens();
+ }
keepAncestorBraces();
Index: clang/lib/Format/TokenAnnotator.cpp
===================================================================
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -63,13 +63,6 @@
Left->Previous->MatchingParen->is(TT_LambdaLSquare);
}
-/// Returns \c true if the token is followed by a boolean condition, \c false
-/// otherwise.
-static bool isKeywordWithCondition(const FormatToken &Tok) {
- return Tok.isOneOf(tok::kw_if, tok::kw_for, tok::kw_while, tok::kw_switch,
- tok::kw_constexpr, tok::kw_catch);
-}
-
/// A parser that gathers additional information about tokens.
///
/// The \c TokenAnnotator tries to match parenthesis and square brakets and
@@ -130,10 +123,9 @@
// parameter cases, but should not alter program semantics.
if (CurrentToken->Next && CurrentToken->Next->is(tok::greater) &&
Left->ParentBracket != tok::less &&
- (isKeywordWithCondition(*Line.First) ||
- CurrentToken->getStartOfNonWhitespace() ==
- CurrentToken->Next->getStartOfNonWhitespace().getLocWithOffset(
- -1)))
+ CurrentToken->getStartOfNonWhitespace() ==
+ CurrentToken->Next->getStartOfNonWhitespace().getLocWithOffset(
+ -1))
return false;
Left->MatchingParen = CurrentToken;
CurrentToken->MatchingParen = Left;
@@ -257,12 +249,11 @@
// type X = (...);
// export type X = (...);
Contexts.back().IsExpression = false;
- } else if (OpeningParen.Previous &&
- (OpeningParen.Previous->isOneOf(tok::kw_static_assert,
- tok::kw_while, tok::l_paren,
- tok::comma) ||
- OpeningParen.Previous->isIf() ||
- OpeningParen.Previous->is(TT_BinaryOperator))) {
+ } else if (OpeningParen.isConditionLParen(/*IncludeSpecial=*/false) ||
+ (OpeningParen.Previous &&
+ OpeningParen.Previous->isOneOf(TT_BinaryOperator, tok::l_paren,
+ tok::comma,
+ tok::kw_static_assert))) {
// static_assert, if and while usually contain expressions.
Contexts.back().IsExpression = true;
} else if (Style.isJavaScript() && OpeningParen.Previous &&
@@ -1437,17 +1428,18 @@
// recovered from an error (e.g. failure to find the matching >).
if (!CurrentToken->isTypeFinalized() &&
!CurrentToken->isOneOf(
- TT_LambdaLSquare, TT_LambdaLBrace, TT_AttributeMacro, TT_IfMacro,
- TT_ForEachMacro, TT_TypenameMacro, TT_FunctionLBrace,
- TT_ImplicitStringLiteral, TT_InlineASMBrace, TT_FatArrow,
- TT_LambdaArrow, TT_NamespaceMacro, TT_OverloadedOperator,
- TT_RegexLiteral, TT_TemplateString, TT_ObjCStringLiteral,
- TT_UntouchableMacroFunc, TT_StatementAttributeLikeMacro,
- TT_FunctionLikeOrFreestandingMacro, TT_ClassLBrace, TT_EnumLBrace,
- TT_RecordLBrace, TT_StructLBrace, TT_UnionLBrace, TT_RequiresClause,
+ TT_AttributeMacro, TT_BracedListLBrace, TT_ClassLBrace,
+ TT_CompoundRequirementLBrace, TT_ConditionLParen, TT_EnumLBrace,
+ TT_FatArrow, TT_ForEachMacro, TT_FunctionLBrace,
+ TT_FunctionLikeOrFreestandingMacro, TT_IfMacro,
+ TT_ImplicitStringLiteral, TT_InlineASMBrace, TT_LambdaArrow,
+ TT_LambdaLBrace, TT_LambdaLSquare, TT_NamespaceMacro,
+ TT_ObjCStringLiteral, TT_OverloadedOperator, TT_RecordLBrace,
+ TT_RegexLiteral, TT_RequiresClause,
TT_RequiresClauseInARequiresExpression, TT_RequiresExpression,
- TT_RequiresExpressionLParen, TT_RequiresExpressionLBrace,
- TT_CompoundRequirementLBrace, TT_BracedListLBrace))
+ TT_RequiresExpressionLBrace, TT_RequiresExpressionLParen,
+ TT_StatementAttributeLikeMacro, TT_StructLBrace, TT_TemplateString,
+ TT_TypenameMacro, TT_UnionLBrace, TT_UntouchableMacroFunc))
CurrentToken->setType(TT_Unknown);
CurrentToken->Role.reset();
CurrentToken->MatchingParen = nullptr;
@@ -2992,8 +2984,7 @@
if (Left.is(tok::l_paren) && InFunctionDecl &&
Style.AlignAfterOpenBracket != FormatStyle::BAS_DontAlign)
return 100;
- if (Left.is(tok::l_paren) && Left.Previous &&
- (Left.Previous->is(tok::kw_for) || Left.Previous->isIf()))
+ if (Left.isConditionLParen(/*IncludeSpecial=*/true))
return 1000;
if (Left.is(tok::equal) && InFunctionDecl)
return 110;
@@ -3489,15 +3480,11 @@
(Left.is(tok::l_brace) && Left.isNot(BK_Block) &&
Right.is(tok::r_brace) && Right.isNot(BK_Block)))
return Style.SpaceInEmptyParentheses;
- if (Style.SpacesInConditionalStatement) {
- if (Left.is(tok::l_paren) && Left.Previous &&
- isKeywordWithCondition(*Left.Previous))
- return true;
- if (Right.is(tok::r_paren) && Right.MatchingParen &&
- Right.MatchingParen->Previous &&
- isKeywordWithCondition(*Right.MatchingParen->Previous))
- return true;
- }
+ if (Style.SpacesInConditionalStatement &&
+ (Left.isConditionLParen(/*IncludeSpecial=*/true) ||
+ (Right.is(tok::r_paren) && Right.MatchingParen &&
+ Right.MatchingParen->isConditionLParen(/*IncludeSpecial=*/true))))
+ return true;
// auto{x} auto(x)
if (Left.is(tok::kw_auto) && Right.isOneOf(tok::l_paren, tok::l_brace))
@@ -3751,11 +3738,8 @@
return true;
if (Left.is(tok::semi))
return true;
- if (Left.isOneOf(tok::pp_elif, tok::kw_for, tok::kw_while, tok::kw_switch,
- tok::kw_case, TT_ForEachMacro, TT_ObjCForIn))
- return Style.SpaceBeforeParensOptions.AfterControlStatements ||
- spaceRequiredBeforeParens(Right);
- if (Left.isIf(Line.Type != LT_PreprocessorDirective))
+ if (Right.isConditionLParen(/*IncludeSpecial=*/true) ||
+ Left.is(tok::pp_elif))
return Style.SpaceBeforeParensOptions.AfterControlStatements ||
spaceRequiredBeforeParens(Right);
@@ -4502,13 +4486,9 @@
// We only break before r_paren if we're in a block indented context.
if (Right.is(tok::r_paren)) {
- if (Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent) {
+ if (Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent)
return Right.MatchingParen &&
- !(Right.MatchingParen->Previous &&
- (Right.MatchingParen->Previous->is(tok::kw_for) ||
- Right.MatchingParen->Previous->isIf()));
- }
-
+ !Right.MatchingParen->isConditionLParen(/*IncludeSpecial=*/true);
return false;
}
Index: clang/lib/Format/FormatToken.h
===================================================================
--- clang/lib/Format/FormatToken.h
+++ clang/lib/Format/FormatToken.h
@@ -39,7 +39,8 @@
TYPE(CastRParen) \
TYPE(ClassLBrace) \
TYPE(CompoundRequirementLBrace) \
- TYPE(ConditionalExpr) \
+ TYPE(ConditionLParen) /* the condition in an if statement */ \
+ TYPE(ConditionalExpr) /* ternary ?: expression */ \
TYPE(ConflictAlternative) \
TYPE(ConflictEnd) \
TYPE(ConflictStart) \
@@ -515,9 +516,21 @@
}
template <typename T> bool isNot(T Kind) const { return !is(Kind); }
- bool isIf(bool AllowConstexprMacro = true) const {
- return is(tok::kw_if) || endsSequence(tok::kw_constexpr, tok::kw_if) ||
- (endsSequence(tok::identifier, tok::kw_if) && AllowConstexprMacro);
+ /// Returns \c true if the token is the open parenthesis of a
+ /// statement's condition like if or while.
+ bool isConditionLParen(bool IncludeSpecial) const {
+ if (!is(tok::l_paren))
+ return false;
+ if (is(TT_ConditionLParen))
+ return true;
+ const FormatToken *Prev = getPreviousNonComment();
+ // `for` and `catch` special handling. Inside the parentheses is not
+ // an expression.
+ return Prev &&
+ ((IncludeSpecial && Prev->isOneOf(TT_ForEachMacro, TT_ObjCForIn,
+ tok::kw_for, tok::kw_catch)) ||
+ Prev->isOneOf(tok::kw_if, tok::kw_while, tok::kw_switch,
+ tok::kw_case, tok::kw_constexpr));
}
bool closesScopeAfterBlock() const {
Index: clang/lib/Format/ContinuationIndenter.cpp
===================================================================
--- clang/lib/Format/ContinuationIndenter.cpp
+++ clang/lib/Format/ContinuationIndenter.cpp
@@ -745,9 +745,8 @@
}
State.Column += Spaces;
- if (Current.isNot(tok::comment) && Previous.is(tok::l_paren) &&
- Previous.Previous &&
- (Previous.Previous->is(tok::kw_for) || Previous.Previous->isIf())) {
+ if (Current.isNot(tok::comment) &&
+ Previous.isConditionLParen(/*IncludeSpecial=*/true)) {
// Treat the condition inside an if as if it was a second function
// parameter, i.e. let nested calls have a continuation indent.
CurrentState.LastSpace = State.Column;
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits