[PATCH] D43906: [clang-format] Improve detection of Objective-C block types

Ben Hamilton via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Feb 28 13:46:10 PST 2018


benhamilton created this revision.
benhamilton added reviewers: krasimir, jolesiak.
Herald added a subscriber: cfe-commits.

Previously, clang-format would detect the following as an
Objective-C block type:

  FOO(^);

when it actually must be a C or C++ macro dealing with an XOR
statement or an XOR operator overload.

According to the Clang Block Language Spec:

https://clang.llvm.org/docs/BlockLanguageSpec.html

block types are of the form:

  int (^)(char, float)

and block variables of block type are of the form:

  void (^blockReturningVoidWithVoidArgument)(void);
  int (^blockReturningIntWithIntAndCharArguments)(int, char);
  void (^arrayOfTenBlocksReturningVoidWithIntArgument[10])(int);

This tightens up the detection so we don't unnecessarily detect
C macros which pass in the XOR operator.

Depends On https://reviews.llvm.org/D43904

Test Plan: New tests added. Ran tests with:

  make -j12 FormatTests &&
  ./tools/clang/unittests/Format/FormatTests


Repository:
  rC Clang

https://reviews.llvm.org/D43906

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


Index: unittests/Format/FormatTest.cpp
===================================================================
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -12024,6 +12024,16 @@
           "for (const Foo<Bar>& baz = in.value(); !baz.at_end(); ++baz) {}"));
 }
 
+TEST_F(FormatTest, GuessLanguageWithCaret) {
+  EXPECT_EQ(FormatStyle::LK_Cpp, guessLanguage("foo.h", "FOO(^);"));
+  EXPECT_EQ(FormatStyle::LK_ObjC,
+            guessLanguage("foo.h", "int(^)(char, float);"));
+  EXPECT_EQ(FormatStyle::LK_ObjC,
+            guessLanguage("foo.h", "int(^foo)(char, float);"));
+  EXPECT_EQ(FormatStyle::LK_ObjC,
+            guessLanguage("foo.h", "int(^foo[10])(char, float);"));
+}
+
 } // end namespace
 } // end namespace format
 } // end namespace clang
Index: lib/Format/TokenAnnotator.cpp
===================================================================
--- lib/Format/TokenAnnotator.cpp
+++ lib/Format/TokenAnnotator.cpp
@@ -142,8 +142,20 @@
 
     bool StartsObjCMethodExpr = false;
     if (CurrentToken->is(tok::caret)) {
-      // (^ can start a block type.
-      Left->Type = TT_ObjCBlockLParen;
+      const FormatToken *Next = CurrentToken->getNextNonComment();
+      if (Next &&
+          // int (^)(char, float)
+          (Next->startsSequence(tok::r_paren, tok::l_paren) ||
+           // int (^blockReturningIntWithCharAndFloatArguments)(char, float)
+           Next->startsSequence(tok::identifier, tok::r_paren, tok::l_paren) ||
+           // int
+           // (^arrayOfTenBlocksReturningIntWithCharAndFloatArguments[10])(char,
+           // float)
+           Next->startsSequence(tok::identifier, tok::l_square,
+                                tok::numeric_constant, tok::r_square,
+                                tok::r_paren, tok::l_paren))) {
+        Left->Type = TT_ObjCBlockLParen;
+      }
     } else if (FormatToken *MaybeSel = Left->Previous) {
       // @selector( starts a selector.
       if (MaybeSel->isObjCAtKeyword(tok::objc_selector) && MaybeSel->Previous &&


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D43906.136388.patch
Type: text/x-patch
Size: 2038 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180228/28069888/attachment.bin>


More information about the cfe-commits mailing list