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
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to