<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/119688>119688</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Misaligned formatting of array of objects with designated initializers
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
GlebMorgan
</td>
</tr>
</table>
<pre>
Looks like Clang-format fails to properly format arrays of objects (tables) with long rows which don't fit onto a single line (according to set `ColumnLimit`).
```c
type_t table[] = {
{ .name = "foo", .description = "...", .value = 37, .type = TYPE_SOME, .arg = NULL },
{ .name = "bar", .description = "...", .value = 42, .type = TYPE_ANOTHER, .arg = NULL },
...
};
```
It works for simple cases, but starts to fail when line wrapping is required.
Below are some examples I discovered after playing around a bit.
## Example 1
### Current behavior
- Closing bracket of the 1st inner object is incorrectly indented
- 1st initializer of the 2nd inner object is over-indented
```c
some_struct_t test_1[] = {
{ .field_1 = some_long_expression(1),
.field_2 = some_long_expression(2),
.field_3 = some_long_expression(3),
.field_4 = some_long_expression(4) },
{ .field_1 = 1, .field_2 = 2, .field_3 = 3, .field_4 = 4 },
};
```
### Expected result
```
some_struct_t test_1[] = {
{ .field_1 = some_long_expression(1),
.field_2 = some_long_expression(2),
.field_3 = some_long_expression(3),
.field_4 = some_long_expression(4) },
{ .field_1 = 1, .field_2 = 2, .field_3 = 3, .field_4 = 4 },
};
```
## Example 2
### Current behavior
- Closing bracket of the 1st inner object is incorrectly indented
- Last initializer of the 2nd inner object is over-indented
```c
some_struct_t test_2[] = {
{ .field_1 = 1,
.field_2 = 2,
.field_3 = 3,
.field_4 = some_long_expression(4) },
{ .field_1 = 1, .field_2 = 2, .field_3 = 3, .field_4 = 4 },
};
```
### Expected result
```
some_struct_t test_2[] = {
{ .field_1 = 1,
.field_2 = 2,
.field_3 = 3,
.field_4 = some_long_expression(4) },
{ .field_1 = 1, .field_2 = 2, .field_3 = 3, .field_4 = 4 },
};
```
## Example 3
### Current behavior
- All initializers after the 1st one are under-indented by 1 space
> Note: no trailing comma after `some_long_expression(4)`
```c
some_struct_t test_3[] = {
{ .field_1 = some_long_expression(1),
.field_2 = some_long_expression(2),
.field_3 = some_long_expression(3),
.field_4 = some_long_expression(4) },
{ .field_1 = some_long_expression(1),
.field_2 = some_long_expression(2),
.field_3 = some_long_expression(3),
.field_4 = some_long_expression(4) },
};
```
### Expected result
```
some_struct_t test_3[] = {
{ .field_1 = some_long_expression(1),
.field_2 = some_long_expression(2),
.field_3 = some_long_expression(3),
.field_4 = some_long_expression(4) },
{ .field_1 = some_long_expression(1),
.field_2 = some_long_expression(2),
.field_3 = some_long_expression(3),
.field_4 = some_long_expression(4) },
};
```
## Example 4
### Current behavior
- Closing brackets of both inner objects are over-indented by 1 space
- Neither `BracedInitializerIndentWidth` or `ContinuationIndentWidth` are respected
> Note: trailing comma added after `some_long_expression(4)`
```c
some_struct_t test_4[] = {
{
.field_1 = some_long_expression(1),
.field_2 = some_long_expression(2),
.field_3 = some_long_expression(3),
.field_4 = some_long_expression(4),
},
{
.field_1 = some_long_expression(1),
.field_2 = some_long_expression(2),
.field_3 = some_long_expression(3),
.field_4 = some_long_expression(4),
},
};
```
### Expected result
```
some_struct_t test_4[] = {
{
.field_1 = some_long_expression(1),
.field_2 = some_long_expression(2),
.field_3 = some_long_expression(3),
.field_4 = some_long_expression(4),
},
{
.field_1 = some_long_expression(1),
.field_2 = some_long_expression(2),
.field_3 = some_long_expression(3),
.field_4 = some_long_expression(4),
},
};
```
---
It is possible that our `.clang-format` file is misconfigured somehow, please let me know if that is the case
The command used to format files:
```bash
clang-format -i --style=file test.c
```
Used `.clang-format` configuration:
```yaml
BasedOnStyle: LLVM
Language: Cpp
IndentWidth: 4
AlignAfterOpenBracket: Align
ColumnLimit: 80
AlignConsecutiveAssignments: None
AlignConsecutiveBitFields: Consecutive
AlignConsecutiveDeclarations: None
AlignConsecutiveMacros: Consecutive
AlignEscapedNewlines: Left
AlignOperands: Align
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Empty
AllowShortCaseLabelsOnASingleLine: false
AllowShortEnumsOnASingleLine: true
AllowShortFunctionsOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: Never
BinPackArguments: false
BinPackParameters: false
BreakBeforeBraces: Custom
BraceWrapping:
AfterCaseLabel: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: false
AfterStruct: false
AfterUnion: false
BeforeElse: false
BeforeWhile: false
BreakBeforeTernaryOperators: false
ContinuationIndentWidth: 4
PointerAlignment: Right
IndentCaseBlocks: false
IndentCaseLabels: true
IndentPPDirectives: AfterHash
KeepEmptyLinesAtTheStartOfBlocks: false
ReflowComments: true
SortIncludes: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceBeforeParens: ControlStatementsExceptControlMacros
SpacesBeforeTrailingComments: 4
Cpp11BracedListStyle: false
UseTab: Never
IndentWrappedFunctionNames: false
AlwaysBreakAfterDefinitionReturnType: None
PenaltyReturnTypeOnItsOwnLine: 160
```
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzkWV1v6j7S_zTmZgRKHErLBReB0udfPRSq05492qvKJBPirWNnbaeU_fQrOwFCgZ4XnR5td6tKgOfNM_ObGcdhxvCVRByRizG5uO6wyuZKj_5P4PJO6RWTnaVKN6OZUs8GBH9GmAgmV91M6YJZyBgXBqyCUqsStdhAQ2Bas40BlYFa_gMTa4DQK8uWAg2hQ1hzm4NQcgVarQ2sc57kkCpJ6KWFjFtQ0ipgYLhcCQTBJToFLEmUTrlcOZMGLZBBMFGiKuSMF9ySQUDosEeC2H3z_wkJYrsp8cmCt167CSS6BnI5JkHsPqAnWYH1IqWZUoRSQifQS9EkmpeWK7ml9nq9LfWFiaqWii79gjPkfz_-_X769LC4m_plpld-df51NgNyeU3oxBkGOLa9ZPpnbffpCdvxfPH41_TLd8w7fUHslqJxO2juexDfWlgr_WxcSsHwohQICTMugRNYVhaMZdr67DsYwDpHWWdqrVlZuixxAxr_WXGNqbM0RqHWwDSCUQUCvjKn1MAtpNwk6gU1psAyixpKwTZOA9OqkikwWHLbq_dFaERoBNNaGsL2qiNMKq1RWlhizl640iSIuzARymEJlpolz2gdMG2OEBoLXErUDUzdjrlMlNaYWLEBLlOUFlOvo2bmljPB_-VEah1Upkc6nC_dlvABHp3zT8bqKrEOlmjsU3iMyy08Mo4ifQo9yUu6snnC11KjMdyVzFVI6HCf1a0IfU-E7kUa9ug99uikhf57In1X58dob7sTeny2d0tbK_WGotZKba-_13oOunswTF9LTCymoNFUwr5h_ehM_IFUfJJc7MqV_rFynbGPq1f6YygJz1UlPSbsQ_zTVfbe32_K-vbvD1biL8T4fJDPR_mzFVD0QwUUC9HGvmnG6raIlEQ_hyuZtoAPyw2EYEqWYGMkmsJcWSRRDFKB1YwLV5aJKgrWqCSD4J2gNV58p5yi_8nx9yHuHGH9-y79vDsfUO2_FQKfaO5-jEP_CTDYdaz-r4x8_-y4VDY_mNXGd62DaX3YtLowR27zui-NNUswvd23wVsv842nNieDAJSuHyCl5bJi7knrDYMzptHUUD5uiW_7YZrunl9-R1fsnyuJVrY-ZydpWXhbHW8sf87Gf8q_D-iZ7wLk8MD2U83mj_TPX4nmObD81_p5DjTdbnd3ScMNlMoYvhQINmcWVOX7Ty9p3dS5bpZxgY674CZRMuOrSmPqN5SrtTuZlgKZQRBooUB4lmoNPKt1cuPPjgkzzdHw0f1ybU-mUBlM_TVQcynIBRoSxe1tL5nJSRC3twRdDt2usRuBJLr2m3Oo7iXH7n51Bk65tPXDN-83JjesECSIx8xgupAPtZ0YZrO_3ZEgnjG5qtjKL03K0oWy1fuj2E-tWPCVjF1DX5Qox_VkckRPIEHcvnyMYrgKtkITJQ0mleUvGPsr1gKldUGBuZJ4gmvM7Y2DiedprZ9gvcZEsNrl9zTesUSrc-qmJmElpnNcCy59tmCGmd2SFyVqJuvNbH31n4_NyJuoYueR1VWtV6h1LESsV5WnLeQcX-2MSx_kjAnTZrtnmhVoUZtF1vLoHaGHXGk7Fip5NgsZP_ir4S3jtCjt5oBxwgzO2BLFMfOx1qmsimO-tmOe7aaSiQ_7D9i_zR4ss9hE4g37HF_QHXvGXN6z5HkXsvbuGto-TgdEjex5jJnS6E85dZ4rY1XhqSzBb80tbF0W4GG8C0pbFzQ0Ja1WYrfr9j4bFhemA0m_uo3KCZ0Pfl6dIHyVbwVqZ6bu1wF7vf4t5wLPBOARtWR64zFr1WGczh3umgK_V1xa1B7aW5-_8FVud_3ARazGXFvtnlZDrIWWmnR_f801Jq7k6iJyTv9VN8H_Ryw9XhwaTGwfc3ywTNtFdmzoC2ZCrU9U24ODmExEleLBsjsH1-n0HW_CzEH49_SZWvGEibk6ptdhvWca5bZ_HCDDTF8TLG2z3PSZRtY0OTnRJ1zAJ2UZhvW5fMaN3XXlrf2vBh_Zsg29JmsOzJhuoTZnBZrDUl6zjfGg8N5dY-avP5T8grbS8nFTYqtX3qNkwm72tIW8tWaxltsCDQ9P6PUY6qSjKB1GQ9bBUXgZRcPh1ZAOOvmIBRj2-xfsIuoPB8Nh2E-H4RWmg0ukIS4Hgw4f0YD2QxrSMKA0GPSuri4zDFkwzC4ullFIST_AgnHRE-Kl6Cm96nBjKhyF4XBwddURHmX-JR2lEtfgqYRScnHd0SMn1F1WK0P6geDGmr0ay63A0R03zGEc02ZIW_fYorL6PV37NZ1_M5eiG1nMnUXbl0idSotRbm3ppzu9IfRmxW1eLXuJKgi9cUabj26plVNI6I3fqiH0pvHlZUT_HQAA__87PMOL">