[clang] 63d6659 - [clang-format] Fix support for ObjC blocks with pointer return types

Egor Zhdan via cfe-commits cfe-commits at lists.llvm.org
Mon Jul 17 06:47:57 PDT 2023


Author: Jared Grubb
Date: 2023-07-17T14:47:49+01:00
New Revision: 63d6659a045d2e014d53ae890eec8b3cd96e5805

URL: https://github.com/llvm/llvm-project/commit/63d6659a045d2e014d53ae890eec8b3cd96e5805
DIFF: https://github.com/llvm/llvm-project/commit/63d6659a045d2e014d53ae890eec8b3cd96e5805.diff

LOG: [clang-format] Fix support for ObjC blocks with pointer return types

The ObjC-block detection code only supports a single token as the return type. Add support to detect pointers, too (ObjC has lots of object-pointers).

For example, using `BasedOnStyle: WebKit`, the following is stable output:

```
int* p = ^int*(void)
{ //
    return nullptr;
}
();
```

After the patch, this is stable:

```
int* p = ^int*(void) { //
    return nullptr;
}();
```

Differential Review: https://reviews.llvm.org/D146434

Added: 
    

Modified: 
    clang/lib/Format/UnwrappedLineParser.cpp
    clang/unittests/Format/FormatTest.cpp
    clang/unittests/Format/FormatTestObjC.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index 0ef2b1c3a46293..32619bc56f7a3f 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -1798,12 +1798,18 @@ void UnwrappedLineParser::parseStructuralElement(
       break;
     case tok::caret:
       nextToken();
+      // Block return type.
       if (FormatTok->Tok.isAnyIdentifier() ||
           FormatTok->isSimpleTypeSpecifier()) {
         nextToken();
+        // Return types: pointers are ok too.
+        while (FormatTok->is(tok::star))
+          nextToken();
       }
+      // Block argument list.
       if (FormatTok->is(tok::l_paren))
         parseParens();
+      // Block body.
       if (FormatTok->is(tok::l_brace))
         parseChildBlock();
       break;

diff  --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index e01db1501e2d39..3e24a996595678 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -22619,7 +22619,8 @@ TEST_F(FormatTest, FormatsBlocks) {
                "    }\n"
                "  }\n"
                "});");
-  verifyFormat("Block b = ^int *(A *a, B *b) {}");
+  verifyFormat("Block b = ^int *(A *a, B *b) {\n"
+               "};");
   verifyFormat("BOOL (^aaa)(void) = ^BOOL {\n"
                "};");
 

diff  --git a/clang/unittests/Format/FormatTestObjC.cpp b/clang/unittests/Format/FormatTestObjC.cpp
index 0cae6e2950fe66..a9e5434dfabfbb 100644
--- a/clang/unittests/Format/FormatTestObjC.cpp
+++ b/clang/unittests/Format/FormatTestObjC.cpp
@@ -1019,6 +1019,20 @@ TEST_F(FormatTestObjC, ObjCBlockTypesAndVariables) {
   verifyFormat("int (^foo[kNumEntries])(char, float);");
   verifyFormat("int (^foo[kNumEntries + 10])(char, float);");
   verifyFormat("int (^foo[(kNumEntries + 10)])(char, float);");
+
+  verifyFormat("int *p = ^int *() { //\n"
+               "  return nullptr;\n"
+               "}();");
+
+  verifyFormat("int * (^p)(void) = ^int *(void) { //\n"
+               "  return nullptr;\n"
+               "};");
+
+  // WebKit forces function braces onto a newline, but blocks should not.
+  verifyFormat("int* p = ^int*() { //\n"
+               "    return nullptr;\n"
+               "}();",
+               getWebKitStyle());
 }
 
 TEST_F(FormatTestObjC, ObjCSnippets) {


        


More information about the cfe-commits mailing list