[PATCH] D79293: [clang-format] [PR45218] Fix an issue where < and > and >> in a for loop gets incorrectly interpreted at a TemplateOpener/Closer

MyDeveloperDay via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Sun May 3 10:37:36 PDT 2020


MyDeveloperDay updated this revision to Diff 261705.
MyDeveloperDay added a comment.

Add more test cases to try to ensure TemplateOpener/Closer type isn't assigned incorrectly.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79293/new/

https://reviews.llvm.org/D79293

Files:
  clang/lib/Format/TokenAnnotator.cpp
  clang/unittests/Format/FormatTest.cpp


Index: clang/unittests/Format/FormatTest.cpp
===================================================================
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -7067,6 +7067,19 @@
   verifyFormat("< < < < < < < < < < < < < < < < < < < < < < < < < < < < < <");
 }
 
+TEST_F(FormatTest, UnderstandsShiftOperators) {
+  verifyFormat("if (i < x >> 1)");
+  verifyFormat("while (i < x >> 1)");
+  verifyFormat("for (unsigned i = 0; i < i; ++i, v = v >> 1)");
+  verifyFormat("for (unsigned i = 0; i < x >> 1; ++i, v = v >> 1)");
+  verifyFormat(
+      "for (std::vector<int>::iterator i = 0; i < x >> 1; ++i, v = v >> 1)");
+  verifyFormat("Foo.call<Bar<Function>>()");
+  verifyFormat("if (Foo.call<Bar<Function>>() == 0)");
+  verifyFormat("for (std::vector<std::pair<int>>::iterator i = 0; i < x >> 1; "
+               "++i, v = v >> 1)");
+}
+
 TEST_F(FormatTest, BitshiftOperatorWidth) {
   EXPECT_EQ("int a = 1 << 2; /* foo\n"
             "                   bar */",
Index: clang/lib/Format/TokenAnnotator.cpp
===================================================================
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -119,7 +119,16 @@
             (Style.Language == FormatStyle::LK_Proto && Left->Previous &&
              Left->Previous->isOneOf(TT_SelectorName, TT_DictLiteral)))
           CurrentToken->Type = TT_DictLiteral;
-        else
+        // In if/for/while  (i < x >> 1) ensure we don't see the <> as
+        // TemplateOpener/Closer
+        else if (CurrentToken->Next && CurrentToken->Next->is(tok::greater) &&
+                 CurrentToken->Next->Next &&
+                 !CurrentToken->Next->Next->isOneOf(tok::l_paren,
+                                                    tok::coloncolon) &&
+                 Line.First->isOneOf(tok::kw_if, tok::kw_for, tok::kw_while)) {
+          Left->Type = TT_BinaryOperator;
+          return false;
+        } else
           CurrentToken->Type = TT_TemplateCloser;
         next();
         return true;
@@ -145,6 +154,10 @@
           Contexts[Contexts.size() - 2].IsExpression &&
           !Line.startsWith(tok::kw_template))
         return false;
+      // If we see a ; then likely this is a for loop and not the template
+      if (CurrentToken->is(tok::semi))
+        return false;
+
       updateParameterCount(Left, CurrentToken);
       if (Style.Language == FormatStyle::LK_Proto) {
         if (FormatToken *Previous = CurrentToken->getPreviousNonComment()) {
@@ -1523,7 +1536,8 @@
       if (Current.is(tok::exclaim)) {
         if (Current.Previous &&
             (Keywords.IsJavaScriptIdentifier(
-                 *Current.Previous, /* AcceptIdentifierName= */ true) ||
+                 *Current.Previous,
+                 /* AcceptIdentifierName= */ true) ||
              Current.Previous->isOneOf(
                  tok::kw_namespace, tok::r_paren, tok::r_square, tok::r_brace,
                  Keywords.kw_type, Keywords.kw_get, Keywords.kw_set) ||
@@ -1970,7 +1984,7 @@
   // same decision irrespective of the decisions for tokens leading up to it.
   // Store this information to prevent this from causing exponential runtime.
   llvm::SmallPtrSet<FormatToken *, 16> NonTemplateLess;
-};
+}; // namespace
 
 static const int PrecedenceUnaryOperator = prec::PointerToMember + 1;
 static const int PrecedenceArrowAndPeriod = prec::PointerToMember + 2;
@@ -2174,7 +2188,7 @@
   FormatToken *Current;
 };
 
-} // end anonymous namespace
+} // namespace
 
 void TokenAnnotator::setCommentLineLevels(
     SmallVectorImpl<AnnotatedLine *> &Lines) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D79293.261705.patch
Type: text/x-patch
Size: 3628 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200503/cf08fb4a/attachment-0001.bin>


More information about the cfe-commits mailing list