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

Maxime Beaulieu via cfe-commits cfe-commits at lists.llvm.org
Wed Apr 13 07:17:59 PDT 2016


mxbOctasic created this revision.
mxbOctasic added a reviewer: djasper.
mxbOctasic added subscribers: cameron314, cfe-commits.
Herald added a subscriber: klimek.

The `*` was treated as multiplication operator in complex pointer type casts.

e.g. 
(type *const)bar
(type *restrict)bar

Patch by cameron314

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,15 @@
                "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 *x = (type *foo)bar");
+  verifyFormat("type *const x = (type *const)bar");
+  verifyFormat("type *x = (type *foo)(bar)");
 }
 
 TEST_F(FormatTest, UnderstandsAttributes) {
Index: lib/Format/TokenAnnotator.cpp
===================================================================
--- lib/Format/TokenAnnotator.cpp
+++ lib/Format/TokenAnnotator.cpp
@@ -1167,6 +1167,14 @@
     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->is(tok::identifier) && Tok.Previous &&
+        Tok.Previous->isOneOf(tok::kw_const, tok::identifier) &&
+        Tok.Previous->Previous &&
+        Tok.Previous->Previous->is(TT_PointerOrReference))
+      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;".
@@ -1260,6 +1268,17 @@
     if (NextNextToken && NextNextToken->is(tok::arrow))
       return TT_BinaryOperator;
 
+    // Casts are never binary operators, regardless of IsExpression
+    if (NextToken->isOneOf(tok::r_paren, tok::greater))
+      return TT_PointerOrReference;
+    if (NextToken->isOneOf(tok::identifier, tok::kw_const) && NextNextToken &&
+        NextNextToken->is(tok::r_paren) && NextNextToken->Next &&
+        NextNextToken->Next->isOneOf(tok::identifier, tok::l_paren) &&
+        (!PrevToken->Previous || !PrevToken->Previous->is(tok::l_paren) ||
+         !PrevToken->Previous->Previous ||
+         !PrevToken->Previous->Previous->is(tok::kw_decltype)))
+      return TT_PointerOrReference;
+
     // It is very unlikely that we are going to find a pointer or reference type
     // definition on the RHS of an assignment.
     if (IsExpression && !Contexts.back().CaretFound)


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D19058.53550.patch
Type: text/x-patch
Size: 2492 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160413/8c07a43b/attachment.bin>


More information about the cfe-commits mailing list