mxbOctasic updated this revision to Diff 53755.
mxbOctasic added a comment.

Moved cast detection logic to `rParenEndsCast`.


http://reviews.llvm.org/D19058

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

Index: unittests/Format/FormatTest.cpp
===================================================================
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -5882,6 +5882,24 @@
                "operator()() && {}");
   verifyGoogleFormat("template <typename T>\n"
                      "auto x() & -> int {}");
+
+  // Some casts look like they might be multiplications, but they are 
definitely
+  // not!
+  // Here, foo could be a macro containing e.g. `const`
+  verifyFormat("(type *foo)bar");
+  verifyFormat("(type *const)bar");
+  verifyFormat("(type *restrict)bar");
+  verifyFormat("(type *foo)(bar)");
+  verifyFormat("(type *const)(bar)");
+  verifyFormat("(type *restrict)(bar)");
+  verifyFormat("type *x = (type *foo)bar");
+  verifyFormat("type *const x = (type *const)bar");
+  verifyFormat("type *x = (type *foo)(bar)");
+
+  FormatStyle LeftPointer = getLLVMStyle();
+  LeftPointer.PointerAlignment = FormatStyle::PAS_Left;
+  verifyFormat("int x = a[(sint16*)pIn - j]", LeftPointer);
+  verifyFormat("int x = a[(int*)pIn - j]", LeftPointer);
 }
 
 TEST_F(FormatTest, UnderstandsAttributes) {
Index: lib/Format/TokenAnnotator.cpp
===================================================================
--- lib/Format/TokenAnnotator.cpp
+++ lib/Format/TokenAnnotator.cpp
@@ -998,8 +998,14 @@
         Current.Type = TT_LineComment;
       }
     } else if (Current.is(tok::r_paren)) {
-      if (rParenEndsCast(Current))
+      if (rParenEndsCast(Current)) {
         Current.Type = TT_CastRParen;
+        for (FormatToken *tok = Current.MatchingParen; tok && tok != &Current;
+             tok = tok->Next)
+          // `*` in casts are never binary operators
+          if (tok->is(tok::star) && tok->is(TT_BinaryOperator))
+            tok->Type = TT_PointerOrReference;
+      }
       if (Current.MatchingParen && Current.Next &&
           !Current.Next->isBinaryOperator() &&
           !Current.Next->isOneOf(tok::semi, tok::colon, tok::l_brace,
@@ -1167,6 +1173,13 @@
     if (ParensAreType && !ParensCouldEndDecl)
       return true;
 
+    // Some more obscure casts can leak through the above heuristic, like
+    // (type* const)bar or (type* MACRO)(bar)
+    if (Tok.Next->isOneOf(tok::identifier, tok::l_paren) && Tok.Previous &&
+        Tok.Previous->isOneOf(tok::kw_const, tok::identifier) &&
+        Tok.Previous->Previous && Tok.Previous->Previous->is(tok::star))
+      return true;
+
     // At this point, we heuristically assume that there are no casts at the
     // start of the line. We assume that we have found most cases where there
     // are by the logic above, e.g. "(void)x;".


Index: unittests/Format/FormatTest.cpp
===================================================================
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -5882,6 +5882,24 @@
                "operator()() && {}");
   verifyGoogleFormat("template <typename T>\n"
                      "auto x() & -> int {}");
+
+  // Some casts look like they might be multiplications, but they are definitely
+  // not!
+  // Here, foo could be a macro containing e.g. `const`
+  verifyFormat("(type *foo)bar");
+  verifyFormat("(type *const)bar");
+  verifyFormat("(type *restrict)bar");
+  verifyFormat("(type *foo)(bar)");
+  verifyFormat("(type *const)(bar)");
+  verifyFormat("(type *restrict)(bar)");
+  verifyFormat("type *x = (type *foo)bar");
+  verifyFormat("type *const x = (type *const)bar");
+  verifyFormat("type *x = (type *foo)(bar)");
+
+  FormatStyle LeftPointer = getLLVMStyle();
+  LeftPointer.PointerAlignment = FormatStyle::PAS_Left;
+  verifyFormat("int x = a[(sint16*)pIn - j]", LeftPointer);
+  verifyFormat("int x = a[(int*)pIn - j]", LeftPointer);
 }
 
 TEST_F(FormatTest, UnderstandsAttributes) {
Index: lib/Format/TokenAnnotator.cpp
===================================================================
--- lib/Format/TokenAnnotator.cpp
+++ lib/Format/TokenAnnotator.cpp
@@ -998,8 +998,14 @@
         Current.Type = TT_LineComment;
       }
     } else if (Current.is(tok::r_paren)) {
-      if (rParenEndsCast(Current))
+      if (rParenEndsCast(Current)) {
         Current.Type = TT_CastRParen;
+        for (FormatToken *tok = Current.MatchingParen; tok && tok != &Current;
+             tok = tok->Next)
+          // `*` in casts are never binary operators
+          if (tok->is(tok::star) && tok->is(TT_BinaryOperator))
+            tok->Type = TT_PointerOrReference;
+      }
       if (Current.MatchingParen && Current.Next &&
           !Current.Next->isBinaryOperator() &&
           !Current.Next->isOneOf(tok::semi, tok::colon, tok::l_brace,
@@ -1167,6 +1173,13 @@
     if (ParensAreType && !ParensCouldEndDecl)
       return true;
 
+    // Some more obscure casts can leak through the above heuristic, like
+    // (type* const)bar or (type* MACRO)(bar)
+    if (Tok.Next->isOneOf(tok::identifier, tok::l_paren) && Tok.Previous &&
+        Tok.Previous->isOneOf(tok::kw_const, tok::identifier) &&
+        Tok.Previous->Previous && Tok.Previous->Previous->is(tok::star))
+      return true;
+
     // At this point, we heuristically assume that there are no casts at the
     // start of the line. We assume that we have found most cases where there
     // are by the logic above, e.g. "(void)x;".
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to