Clang has several cases where attribute dumpings gets into
undesired places, or even is completely incorrect.
Therefore, this commit improves many cases, as listed below:
1- Variable with attributes have its attribute dumped before its value.
input:
int var __attribute__((unused)) = 0;
output before this commit:
int var = 0 __attribute__((unused)); // Compilation error.
after this patch:
int var __attribute__((unused)) = 0;
2- __declspec attributes are dumped on the left side of the declaration,
as recommended by MSVC docs:
input:
__declspec(thread) int var = 0;
output before this commit:
int var __declspec(thread) = 0;
output after this commit:
__declspec(thread) int var = 0;
3- Functions with body has its attributes dumped on the right side of
the declaration instead of left side when possible. The point of this is to (1) avoid attribute placement confusion in K&R C functions and (2) keep compatibility with GCC.
input
int f(void) __attribute__((unused)) {}
output before this commit:
int f(void) __attribute__((unused)) {}
output after this commit:
__attribute__((unused)) int f(void) {}
The interesting case is with input:
int f(i) int i __attribute__((unused)); {}
output before this commit (incorrect):
int f(i) __attribute__((unused)) int i; {}
output after this commit (correct)
int f(i) int i __attribute__((unused));
And in cases where the attribute is not accepted on the left side of
the declaration is output on the right side of the declaration:
intput:
int f(int i) __attribute__((diagnose_if(i < 0, "oh no", "warning"))) {}
output before and after this commit:
int f(int i) __attribute__((diagnose_if(i < 0, "oh no", "warning"))) {}
The reason behind thius is because GCC does not accept diagnose_if and
i must be declared in order to be referenced in this attribute.
Fixes: https://github.com/llvm/llvm-project/issues/59973
Signed-off-by: Giuliano Belinassi <gbelinassi@suse.de>