[PATCH] D19058: clang-format: Pointer `*` is seen as multiplication in C-style casts

Maxime Beaulieu via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 14 10:48:24 PDT 2016


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;".


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D19058.53755.patch
Type: text/x-patch
Size: 2653 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160414/7b5ac718/attachment.bin>


More information about the cfe-commits mailing list