<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/60866>60866</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[clang-format] QualifierOrder should support All of C++'s declaration specifiers.
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
Doggermelon
</td>
</tr>
</table>
<pre>
Clang format supports a limited number of [C++'s *decl-specifier*s (and children)](https://eel.is/c++draft/dcl.spec.general) in its [QualifierOrder](https://github.com/llvm/llvm-project/blob/main/clang/docs/ClangFormatStyleOptions.rst#id231) option. It should support all of them and, optionally, alias the ones which are similar to each other when not explicitly included in QualifierOrder.
Here's a list of qualifiers that could be added:
- typedef
- consteval
- constinit
- thread_local
- extern
- mutable
- signed
- unsigned
- long
- short
- decltype
- auto
Sticking the aliasing behind a new flag will keep backwards compatibility, or forgo it completely and require each qualifier be included if the user wants to reorder it (e.g. "static, extern, mutable, thread_local, constexpr, constinit, consteval, signed, unsigned, short, long, type, decltype, auto").
The way I envision the aliasing working is:
```cpp
// With a QualifierOrder: "inline, constexpr, static, type"
// Current behavior:
int inline static consteval long example0();
// becomes (`consteval` is unrecognized)
inline static int consteval long example0();
// New proposed behavior:
// `consteval` and `constinit` will be treated as `constexpr`
// `mutable`, `extern`, and `thread_local` will be treated as `static`
// Note: `extern "C"` and `extern "C++"` are linkage-specifications
// and can't be freely reordered in a decl-specifier-seq
// `decltype` and `auto` will be treated as `type`
static inline decltype(12) constinit example1 = 12;
// becomes
inline constinit static decltype(12) example1 = 12;
// With a QualifierOrder: "static, const, type"
// Current behavior:
int static volatile const example2;
// becomes (it gives up if a qualifier that isn't in QualifierOrder is encountered)
static int volatile const example2;
// New proposed behavior:
// `volatile` will be treated as `const` if not in QualifierOrder
int volatile const example3;
// becomes
const volatile int example3;
// With a QualifierOrder: "short, signed, type"
// New proposed behavior:
// `short` and `long` can match to each other before `type`.
// `signed` and `unsigned` can match to each other before `type`.
unsigned long int long example4;
// becomes
long long unsigned int example4;
// With a QualifierOrder: "thread_local, signed, short, type, static, long"
// New proposed behavior:
// if a qualifier and its alias are both present, prefer the place it's explicitly named.
extern thread_local unsigned long example5;
// becomes
thread_local unsigned extern long example5;
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJykV01vIykT_jX4UorVxnbHPviQOIreuczo1ay0xxUN5W42NPQAHSf761dFf_kjycxkpcgRDVQVz1NPFYgQdGkRd2x9z9YPM9HGyvndgytL9DUaZ2eFU6-7vRG2hIPztYgQ2qZxPgYQYHStIyqwbV2gB3cAtr7fM36f_m4DMH6nUJqb0KDUB42e8Tv6uhFWgay0UR4t41u2fmB8U8XYBLa8Y_yR8UdEM9eB8UfZGVReHCLjj0qaOdmbl2jRC8P4FrQFHQN5_38rTPL0zSv0b9ktdazaYi5dzfijMc_Dv5vGu79RkovCuILxx1poS_7p9OTYSQongfGYsPgeXw1-a6J2Nsx9iIwvteLLBYXk0uc5fIkQKtcaNQAHwhiCKlZYg7CK8X2_WBjzSiNhtAg0D85igGOlZQXCIwRdayM8RAcoZAUuVujhWKEF6yLgS2O01NG8grbStAoVIXMOyZxlDyy7637_hx4TUcRliBTWj2E1RSAiyBR7gSCUQkUopp03EF8bVHgYhtLZEPFZmLMP2uo4bqg8CvWXcXJahC8RvR1GdRtFYXAYpuRUw6i152PjbDmurJwf_VDGUXDDWLTRnR76e9TySdsyIZywpkGBlbYKBFg8wsGIEo7aGHhCbKAQ8ukovAogXd2IqAttdExcOU-6KB3omCYNRjSvxCt4_NFqjx1VI6wE5cROSgNoA9EobAxErUdHRJFFxjc4L-fAOA9RRC3JZY8Z34948f05uHzf0_HS-HGQqBhnnrtlPaR8P8FLXxOcfN9hTNYJTr6foKUsJVg5Z3x7llJ_VAhH8QpfAO2zDtrZc5yPzifwdRhzieVZ9yebpv-SlAp_6liBuEhgtrwjPLQ12uLVUSeYujj5aWy92X3rPdpIlItn7fwYiLYROru9nQmsBAXgiyCKM8Y3VLWW92d2C5SuxlTf6DAjznkGOkBrPUpXWv0PgbwdPJ56I_-_6PHU71c8QuNd4wKq60P1iy4jogwdvqXUyLMu4wuE6FFQXRdh2kb45tmlySED84wgZ3nWJ2c37n2c5ea7bnrmLnwAfHURE-eDcWJ_T8xOpzib6LpPN-0RjLZPosShB0mRyjVceEkNSVjGbykv4OCRZNxLsaujAs572U3AH5d4jAKZYks6effU_eLOzpgGKSkmsW0WJLNJxkNWLIAtH2DB30nEsxSbNvdersy_a_Q64z4S5qTA5PI_SLEP9NkZEbXpjzCE-d6hSX06QqmfMUDbUIkVJ9U39TQdOqKvmiPpFK10rY3E-ijTE33-NJrPKHMw-hMRpkpySL3-KvQJtrcjXH6YJN3ScSeZud73m3kwNJGpr7yfB78KVGd0EldqUHlG0oVaRFld3I0KPDiPJ0KbX1nsoptMjo3wE2aHvV3tJhRPi_jqQwrSyvQzWjmhYfVZGi4vBm90-aGjT8rt-v6nibrQHAFL1_PuXks1uXCxgsZjQJsiaDwekjgRGiMkAl1VbsPpjdaKGlUPc1_uT48G59D3qK0_RPzt_b3xd8wMVxWYqd1SbZdbMcPdIr_NN_k2W29m1S47FPlqyVdyrYptzreLRXYrNopjJvJVkd3O9I5nfJlxnmWr9e1yM1dcrLDgasG5WCm5YKsMa6HNnJ4lc-fLmQ6hxV2ebfJ8ZkSBJqQnG-d0WU2TxNb6YeZ36SlTtGVgq4zu9GGyEnU06a2XXjQ33XuOrR8ui-DFe-Wue6-cvuuodwifOimM_TDMZ603u99-baX46WWVzvdvAAAA__9G8aSD">