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

    <tr>
        <th>Summary</th>
        <td>
            clang-format: macros within struct initialization formatting issues
        </td>
    </tr>

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

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

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

<pre>
    In Zephyr RTOS we have added a [.clang-format](https://github.com/zephyrproject-rtos/zephyr/blob/main/.clang-format) that matches our style guide (similar to the Linux Kernel one). We make extensive use of macros to statically allocate resources. It is often the case that certain structs contain fields that are conditional to a build option, e.g.

```c
struct foo {
        uint8_t bar1;
        uint8_t bar2;
        uint8_t bar3;
#ifdef CONFIG_BAZ1
        uint8_t baz1;
#endif
#ifdef CONFIG_BAZ2
        uint8_t baz2;
#endif
}
```

In some cases, we have that such struct is defined and initialized within another macro, like:

```c
#define FOO_DEFINE(x, y)                                                       \
        struct foo foo = {                                                     \
                .bar1 = 1,                                                     \
                .bar2 = 2,                                                     \
                .bar3 = 3,                                                     \
                IF_ENABLED(CONFIG_BAZ1, (.baz1 = x, ))                         \
                IF_ENABLED(CONFIG_BAZ2, (.baz2 = y, ))                         \
        }
```

or:

```c
#ifdef CONFIG_BAZ1
#define BAZ1_INIT(x) .baz1 = x,
#else
#define BAZ1_INIT(x)
#endif

#ifdef CONFIG_BAZ2
#define BAZ2_INIT(y) .baz2 = y,
#else
#define BAZ2_INIT(y)
#endif

#define FOO_DEFINE(x, y)                                                       \
        struct foo foo = {                                                     \
                .bar1 = 1,                                                     \
                .bar2 = 2,                                                     \
                .bar3 = 3,                                                     \
                BAZ1_INIT(x)                                                   \
                BAZ2_INIT(y)                                                   \
        }
```

In such cases, because we can't add a comma after e.g. `IF_ENABLED` or `BAZ_INIT`, formatting looks wrong when we run clang-format:

```c
#define FOO_DEFINE(x, y)                                                       \
        struct foo foo = {.bar1 = 1,                                           \
                          .bar2 = 2,                                           \
                          .bar3 = 3,                                           \
                          IF_ENABLED(CONFIG_BAZ1, (.baz1 = x, ))               \
                                  IF_ENABLED(CONFIG_BAZ2, (.baz2 = y, ))}
```

```c
#define FOO_DEFINE(x) struct foo foo = {
        .bar1 = 1,
       .bar2 = 2, .bar3 = 3, BAZ1_INIT(x) BAZ2_INIT(x)
}
```

There's one trick to force a line break, that is, to add a trailing comment:

```c
#define FOO_DEFINE(x, y)                                                       \
        struct foo foo = {                                                     \
                .bar1 = 1,                                                     \
                .bar2 = 2,                                                     \
                .bar3 = 3,                                                     \
                IF_ENABLED(CONFIG_BAZ1, (.baz1 = x, )) /**/                    \
                IF_ENABLED(CONFIG_BAZ2, (.baz2 = y, )) /**/                    \
        }
```

```c
#define FOO_DEFINE(x, y)                                                       \
        struct foo foo = {                                                     \
                .bar1 = 1,                                                     \
                .bar2 = 2,                                                     \
                .bar3 = 3,                                                     \
                BAZ1_INIT(x) /**/                                              \
                BAZ2_INIT(y) /**/                                              \
        }
```

I'm not sure if there's any better option other than adding the trailing comment, but it would be nice if `clang-format` had a way to automatically handle such cases.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJztWN9v4jgQ_mvCy6hRSAqUBx7aUk7oVq10V2mlfUFOMiG-GruynaX0r7-xAzS0NGwpDz3doogkA_5mPL_82anKV6OphB_4WK40_HV_9zcsEUr2E4HlOebAIOhdhZlgcn5WKL1gNuiNg_iitPbRBMllEE_omnNbVmmYqQW9PHuwR63-wcyeaavMVkgPqVAp3RaMS7rtIsdDsCWzQM9ZiQZUpcHYlUCYVzxHIL2GL7hgGqyivyJ847J6gj9RSxSgJBJECN-REB4Q8MmiNJzmUhkEVZA008q4scYyyzMmxAroS2XMImg0pDBDE8LUAif1BY33ajJGAN60DLUl0wlAV5k1kCnp3wuOIjf1f5hGJ8-55Uoy4fQxSCsuclCPThbE14DhPAyicRBdrr_7UX1l9XutAAqlIBhcbf45rLi0FzMLKdPdINkrj9-RJy_yOOFFjgVc391Opn_Mri5_dPeMeO42RyBNqHh3fLxvfPze-MH41aSbnqB8NGpRO904V20y0jvXVFm59r6LEVnBpctTmQOX5HEm-DO9LykjKSxMKoqfriPvsAR_QJe2LZ4nW2tUmNzdzcY3k-ntDWXekxu-cjl63CfoXW991AiuD3AydkH-NCxdoUsMD9h19p4IMfaI8QkRE4-YnAhxOpnd3F5efbtxramZ1ARPktDlslf4VEuGbWH8Ney4gV27Z_VR7NYqUPpwmr5XxNsEdrLZ9HZ6X-fvEHY98VKbwuChsXsL-VA7aKLFG7TVxpIXvx2yZGdsqyW_S_e_VbpvUvQUiLup9knEg4uVW5G2i1WKGXN0Y-kWMFrpB9YxKSIARI4WDBhxCu0XfyCkRm_pR6C0k5H5tfWkiPBqamS5nINQ6sHAUit6XpZETUiHriTscKgvurYdndyvgksXwNF5_R7YUSm9D-wEC9Fb2Dbk1mWoPXV_PTeGsD-oWzt3o1uL19N5FatX3n5T_c3ibaw6rRO5J4ZHzH9g3A4ArObZg-PcVBAZbWOI8pE01cgenEZPIrkvVcfLfWlazbhwFeZqFOWXLaJPw_5vV5mj6tLvbS_9NTleRztR_JCOE5Xz7yz9oln6phseyo6PIO9yohMht3Mj6skLoB04USSNwAt3lrLu1EyuiCpZR4bqMxGoN-rUnqXryq4bu5OXN63ZUayKOriFpapETiAgeebRXe43qRBRqpK5_r5kK9_sK6sW23MfUpQLbLC3sJOPknyYDFnHcitw9IpXbY6P1kcLmzOIzaED87No0DVuTIWmU2kxajktE-Ln5na2PjOj13osPfT60UXSKUfpOea9bsGG2Iu7BeZp2sV-Gg3TqJsjG_Q6gqW0dxoFvasgjiUua_X0HPTGHT6KoziO-t1BN4r6yXmYZPEgPj8vWMYGSdaLgvMIF-Tp0NkRKj3v6JE3Ka3mhn4U3Fjz8iMzhs8loldH-OTZUunRfMF0JUTHqx550_8FjALt4g">