You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[clang][AST] Fix positioning of preserve cconv attributes in TypePrinter (#147285)
TypePrinter currently generates function pointer types that do not
compile when using the `preserve_.*` calling conventions as per
https://clang.llvm.org/docs/AttributeReference.html#preserve-all ff.
Running clang with `-Xclang -ast-print` on the following:
```cc
using IN1 = void (__attribute__((preserve_most)) *)();
using IN2 = __attribute__((preserve_most)) void (*) ();
```
outputs:
```cc
using IN1 = void (*)() __attribute__((preserve_most));
using IN2 = void ((*))() __attribute__((preserve_most));
```
However, this does not compile:
```cc
<source>:3:23: error: expected ';' after alias declaration
3 | using IN1 = void (*)() __attribute__((preserve_most));
```
This PR updates TypePrinter such that output is correct and compiles:
```cc
using IN1 = __attribute__((preserve_most)) void (*)();
using IN2 = __attribute__((preserve_most)) void ((*))();
```
I've verified via `-ast-dump` that the AST looks equivalent.
void (__attribute__((cdecl)) *pfoo2)(void*) =foo; // expected-error {{incompatible function pointer types initializing 'void (*)(void *) __attribute__((cdecl))' with an expression of type 'void (void *) __attribute__((preserve_most))'}}
18
-
void (*pfoo3)(void*) =foo; // expected-error {{incompatible function pointer types initializing 'void (*)(void *)' with an expression of type 'void (void *) __attribute__((preserve_most))'}}
17
+
void (__attribute__((cdecl)) *pfoo2)(void*) =foo; // expected-error {{incompatible function pointer types initializing 'void (*)(void *) __attribute__((cdecl))' with an expression of type '__attribute__((preserve_most)) void (void *)'}}
18
+
void (*pfoo3)(void*) =foo; // expected-error {{incompatible function pointer types initializing 'void (*)(void *)' with an expression of type '__attribute__((preserve_most)) void (void *)'}}
19
19
20
20
typedef_fun_ttypedef_fun_foo; // expected-note {{previous declaration is here}}
21
21
void __attribute__((preserve_most)) typedef_fun_foo(intx) { } // expected-error {{function declared 'preserve_most' here was previously declared without calling convention}}
void (__attribute__((cdecl)) *pboo2)(void*) =boo; // expected-error {{incompatible function pointer types initializing 'void (*)(void *) __attribute__((cdecl))' with an expression of type 'void (void *) __attribute__((preserve_all))'}}
34
-
void (*pboo3)(void*) =boo; // expected-error {{incompatible function pointer types initializing 'void (*)(void *)' with an expression of type 'void (void *) __attribute__((preserve_all))'}}
33
+
void (__attribute__((cdecl)) *pboo2)(void*) =boo; // expected-error {{incompatible function pointer types initializing 'void (*)(void *) __attribute__((cdecl))' with an expression of type '__attribute__((preserve_all)) void (void *)'}}
34
+
void (*pboo3)(void*) =boo; // expected-error {{incompatible function pointer types initializing 'void (*)(void *)' with an expression of type '__attribute__((preserve_all)) void (void *)'}}
35
35
36
36
typedef_fun_ttypedef_fun_boo; // expected-note {{previous declaration is here}}
37
37
void __attribute__((preserve_all)) typedef_fun_boo(intx) { } // expected-error {{function declared 'preserve_all' here was previously declared without calling convention}}
void (__attribute__((cdecl)) *pboo2)(void*) =boo; // expected-error {{incompatible function pointer types initializing 'void (*)(void *) __attribute__((cdecl))' with an expression of type 'void (void *) __attribute__((preserve_none))'}}
15
-
void (*pboo3)(void*) =boo; // expected-error {{incompatible function pointer types initializing 'void (*)(void *)' with an expression of type 'void (void *) __attribute__((preserve_none))'}}
14
+
void (__attribute__((cdecl)) *pboo2)(void*) =boo; // expected-error {{incompatible function pointer types initializing 'void (*)(void *) __attribute__((cdecl))' with an expression of type '__attribute__((preserve_none)) void (void *)'}}
15
+
void (*pboo3)(void*) =boo; // expected-error {{incompatible function pointer types initializing 'void (*)(void *)' with an expression of type '__attribute__((preserve_none)) void (void *)'}}
16
16
17
17
typedef_fun_ttypedef_fun_boo; // expected-note {{previous declaration is here}}
18
18
void __attribute__((preserve_none)) typedef_fun_boo(intx) { } // expected-error {{function declared 'preserve_none' here was previously declared without calling convention}}
0 commit comments