<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/90341>90341</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            Invalid examples in ObjC-Block-ABI specification doc examples
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          TheLouisHong
      </td>
    </tr>
</table>

<pre>
    # Context 
Referring to the following:
- Clang 19.0.0git documentation `BLOCK IMPLEMENTATION SPECIFICATION`
    - `Imported Variables` segment (segment describing objc blocks' behavior when importing variables) https://clang.llvm.org/docs/Block-ABI-Apple.html#imported-const-copy-of-block-reference
 - `Imported const copy of Block reference`  sub-section

There exists an example in the block ABI doc that is of the following:
```C++
void (^existingBlock)(void) = ...;
void (^vv)(void) = ^{ existingBlock(); }
vv();

struct __block_literal_3 {
   ...; // existing block
};

struct __block_literal_4 {
 void *isa;
    int flags;
    int reserved;
    void (*invoke)(struct __block_literal_4 *);
    struct __block_literal_3 *const existingBlock;
};

void __block_invoke_4(struct __block_literal_2 *_block) {
 __block->existingBlock->invoke(__block->existingBlock);
}

void __block_copy_4(struct __block_literal_4 *dst, struct __block_literal_4 *src) {
     //_Block_copy_assign(&dst->existingBlock, src->existingBlock, 0);
     _Block_object_assign(&dst->existingBlock, src->existingBlock, BLOCK_FIELD_IS_BLOCK);
}

void __block_dispose_4(struct __block_literal_4 *src) {
     // was _Block_destroy
 _Block_object_dispose(src->existingBlock, BLOCK_FIELD_IS_BLOCK);
}

static struct __block_descriptor_4 {
 unsigned long int reserved;
    unsigned long int Block_size;
    void (*copy_helper)(struct __block_literal_4 *dst, struct __block_literal_4 *src);
    void (*dispose_helper)(struct __block_literal_4 *);
} __block_descriptor_4 = {
    0,
    sizeof(struct __block_literal_4),
    __block_copy_4,
 __block_dispose_4,
};
```

I want to highlight this particular invoke function within the example
```C++
void __block_invoke_4(struct __block_literal_2 *_block) {
 __block->existingBlock->invoke(__block->existingBlock);
}
```

# Issue

This function does not make sense within the context, appears to be invalid C++ code, and most importantly, the example contradicts the ABI spec it describes.

1. __block_literal_2 is undefined within the example. 
2. the parameter of `__block_invoke_4` is named `_block`, but the function body dereferences `__block` (two underscores)
3. Within the context and my understanding of the block ABI, `__block_invoke_4` should take the parameter of pointer to type `__block_literal_4`, as it is the `invoke` function _of_ `__block_literal_4 `. 
  
  Within the example we can see invoke is a function pointer of type `void (*invoke)(struct __block_literal_4 *);`

  ```C++
  struct __block_literal_4 {
      void *isa;
 int flags;
      int reserved;
      void (*invoke)(struct __block_literal_4 *);
      struct __block_literal_3 *const existingBlock;
  };
  ```
  
  # Verification
`clang -rewrite-objc -o a.c test.m` confirms that the doc is indeed err and typo-ed

`test.m`
```objc
int main (int argc, const char * argv[])
{
    void (^existingBlock)(void) = ^{ char* stub = "existingBlockkkkkkkkkk";};
    void (^vv)(void) = ^{ existingBlock(); char* stub = "vvvvvvvvvvvvvv";};
    vv();
    return 0;
}
```

```C
struct __main_block_impl_0 {
  struct __block_impl impl;
  struct __main_block_desc_0* Desc;
 __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int flags=0) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
 impl.FuncPtr = fp;
    Desc = desc;
  }
};
static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
 char* stub = "existingBlockkkkkkkkkk";}

static struct __main_block_desc_0 {
 size_t reserved;
  size_t Block_size;
} __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0)};

struct __main_block_impl_1 {
 struct __block_impl impl;
  struct __main_block_desc_1* Desc;
  struct __block_impl *existingBlock;
  __main_block_impl_1(void *fp, struct __main_block_desc_1 *desc, void *_existingBlock, int flags=0) : existingBlock((struct __block_impl *)_existingBlock) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};

// LOUIS
// ===========================
//                             correctly declared as pointer to own block struct
static void __main_block_func_1(struct __main_block_impl_1 *__cself) {
// correctly uses __cself
  void (*existingBlock)() = (void (*)())__cself->existingBlock; // bound by copy
 ((void (*)(__block_impl *))((__block_impl *)existingBlock)->FuncPtr)((__block_impl *)existingBlock); char* stub = "vvvvvvvvvvvvvv";
}
// ===========================
static void __main_block_copy_1(struct __main_block_impl_1*dst, struct __main_block_impl_1*src) {_Block_object_assign((void*)&dst->existingBlock, (void*)src->existingBlock, 7/*BLOCK_FIELD_IS_BLOCK*/);}

static void __main_block_dispose_1(struct __main_block_impl_1*src) {_Block_object_dispose((void*)src->existingBlock, 7/*BLOCK_FIELD_IS_BLOCK*/);}

static struct __main_block_desc_1 {
 size_t reserved;
  size_t Block_size;
  void (*copy)(struct __main_block_impl_1*, struct __main_block_impl_1*);
  void (*dispose)(struct __main_block_impl_1*);
} __main_block_desc_1_DATA = { 0, sizeof(struct __main_block_impl_1), __main_block_copy_1, __main_block_dispose_1};
int main (int argc, const char * argv[])
{
 void (*existingBlock)(void) = ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA));
    void (*vv)(void) = ((void (*)())&__main_block_impl_1((void *)__main_block_func_1, &__main_block_desc_1_DATA, (void *)existingBlock, 570425344));
    ((void (*)(__block_impl *))((__block_impl *)vv)->FuncPtr)((__block_impl *)vv);
 return 0;
}
```

# Comment
The error appears to be copy-paste errors and/or typos. 

I noticed similar typos/errors in every example after this one. This particular documentation requires review. https://clang.llvm.org/docs/Block-ABI-Apple.html
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzMWVuT2joS_jWely4oIy4zPPDAZailNidJbWbPeaSE3YASI3klGTLn12-1fMFXwiSTqkNRCSNLre6vW62v29wYcZCIM2-88MarB57Yo9KzlyN-UIkw_1Ly8LBT4evMY0NYKmnxuwXPX3n-_D-4R62FPIBVYI8IexVF6iLkwRvO0yk9WEZcHmAw7ft9_yAshCpITigtt0JJ8Cb-4sOn5b9h88fnD89_PH98mb9sPn2EL5-fl5v1Zun-8iZ-Kg0AoEdrNqdYaYsh_Mm14LsIjTfxweCBJIPHnvKfIZpAix3pqHZfA9hFKvhmPPYIOzzys1AaLkeUIJxAmnYuJLIpHK2NDRnD1h5bB2RKP4rOp77SB4-tQxUYj60XJLQ3X2x68ziOsH-0p8hjQ5Ep2QuUNLYXqPi1p_Y9p0JPE3YoA8wsq5rlVgCtALUHJx-uKyY-gEl2PYMBgZhKSP99OaJGwO_CWANcAn7npzhCENI5yO0N88WG3AD2yC0IQ1u0e4-Ad9-lxxb0daNnJULC2Bs_u42EPDgNPTb12BM9Jei84Qr6_b43bK46n5tTvfGz97iAmsAnmjhcgPe4yqSci8Gy2cbqJLCw3ToDt5GwqHm0HYL3uChCJ9UGUl8WO6WYZMIeV_cJHpUEZ4bNheHFYgpUIS3sI34wjVGNBvUZw8qDAh82F_KsvmGKUbcCbF7GgUR0o8DmaURV4S1MbZjtlMnlpOpsR93aMNohHXP-LLDJJva8YTVUaCC38qlrUsXNeQC06EfH5JZ2DqvQWI8tuyByU4wOqtrTJ42W7eK6U5ownacmobEtai_B6KB13K-7DDLJavcVA_tLsl0e3a43zx9W282XrfvzXghDYWJlbvr4RxDBhZvcmhCN1eo1D4KKidlWtNH7GGLoKgnqnk0Tf2yVrhzWRLrbLoRIyUP3YWxOS20w4m_sOrUuOI4Yxah_fHTvDseu3XKP3bthDcAOnCgRl33re2xZyi_ib1T7Gxs5NUoL6id0WU0L5bBbtqSi_PYpe3sDFy4tEY6jOBwjcThasEdhIObaiiCJuIY0s8A-ke5-hIuwx-wCzO7DH15v_8zc1wYI0bKNMQlWaYAwV_tDhQaksnDi3xAMSoNlTIKU1FE88jhGrg3BuyPScOaRCCGDBwIVopslQzgpYzPWxKWNXmm8BLATqnkoAmvcOHEOE2MAoiBlaPplnQf9FmyFgUSGuBd0GJt-7GdMlPXdaMw1P6FFTZTGm_gNL058kij5CUP3PHXbhMIcdolNaVAOG7FeCLHgXaYkkiR57MlelNNPm0BpRxlTfYZ9-KsBcIrba7bAchk6WrqvMjNSpUN1c1RJFIIlLzbMjZWQ9JOo-GuMZRnX85layg15QaSO8SZ-Fo0T_2r7Vu23rSJoMEcdiv__angGLggBl2AQ8_MoDPDrDrm-ZH-m789ToOqRAGg_2Z0MaVS70do5XTuhu0Hp3oXU_TytAyhn0xIode9RCvkTtdiLgJcKionvCh7oabxoYbHnKqieAt4PwKKx_RPFTKDkXuiTScsJCgGqLYQBIUPEEFBrF_n2NVY9DCu5a-IXcmopjvZKhwjeExeScKTfXB8CiuKsRjpyTUDQ8DktYYtTWHHq_VVLVoqQZBJsbLJLxxmrrCw-HmMEcwXsyoZvL3jaNj9XPh2b1usjGtRoEy3Bv_dGuR6eag1EXsjT0imOtn752NSilCbQ_RCVNGkTRHfB1idTV2iC6-SW3TIAydv7uMKeGvIcxSJ5bFk-tiu_wV5JdF8YnoE82X78slQy0Gjxi-XBt_qRylasSaBbU8sI6dNEBp-tTp_HldVkpRsPK-ZeK9yyRzNqmzGSkpWURR0gt3zD5tttYDDaV43-mbi-QbdbsC-2IsK4bU2O2ZMWVp2S04bU7Wr-Ms8JquOlLXS0JWSmN2r6-vRBWfVfCOdBM5xb5Xls3pW5W5S7P_wH5fDP12wbdVbzYAznLfmoflvlqntsWpf5m89WMeGdjldOoF35-uHTfzdfKiPecPXO37L0W59AaY2BjYh-BhHXGBJnKzE8dZEZY0ydc0-6GNw6KYOudJFpe9UoMWggn5mhW6I5LXdrceMVAfyU8Zz0qmLTTFyzCrq263YqkSHsXl1TNNs3Dc-GzJZAzTdre1bXmLTIIuwty950a9du4d8ab51R4ary21HR0qlom3NtC3W2szLukzqjs7dVmdfVH3p0eM3b20QpmNPOe6sJQ96E-CESXVZeO1q_X_1bOf-Xrt1GK6tWqbQB8sO4qBLRZvfqrj3qfauG5T9FDQZpr6r9RCy7IqR0ebxHWXI7b1aqhfZUl6e2STtdLlEGl2VbGOQS6qtLfCsT39GCbK1q3qzn4A49B516DjI9l1CV0Th140d_xMbD0ajFpve5Rxwcd14eKXSFDm8t0Nyb2NMJpc3bfUhlttK1Bp575RhzY7PHhgpxj62VdtW4yRs5eWtVKisCDMGIk4h4Nslj62yxkIBn1K9Fj4fvHR85CgNKYh9eao3Y6rtejf9LhEYDGs8CL_1feLv6EM6G4XQ45Q84GzwORoz5YzZ8OM5CjtMnNg2n4XAy3vMxH00ngz0bB4_4hGyCD2LGfDbyR-xxwBjzB_29H0xCxofBwJ_sp_snb-TjiYuo0ORBGJPgbOoPR4OHiO8wMu5dOWMSL-Ae0q0-Xj3oGa3p7ZKD8UZ-JIw1VylW2Ahnm6ylmiHoMP20-7rsFVa6LmnRinG9lHzyQ6KjWRW0g7DHZNcP1Mlja9or-68Xa0WXk8fWTkMC0lnw_wAAAP__TG3Kyw">