[clang] [clang][AST] Fix positioning of preserve cconv attributes in TypePrinter (PR #147285)
https://github.com/th0br0 created https://github.com/llvm/llvm-project/pull/147285 TypePrinter currently generates function pointer declarations 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 :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. >From 2adbac2deeaf3279ef973e68ddffc12d23bf0193 Mon Sep 17 00:00:00 2001 From: "Andreas C. Osowski" Date: Mon, 7 Jul 2025 13:38:30 +0200 Subject: [PATCH] [clang][AST] Fix positioning of preserve cconv attributes in TypePrinter --- clang/lib/AST/TypePrinter.cpp | 33 ++--- clang/test/AST/ast-print-cconv-preserve.cpp | 14 + clang/test/Sema/preserve-call-conv.c| 8 ++--- clang/test/Sema/preserve-none-call-conv.c | 4 +-- clang/test/SemaCXX/lambda-attributes.cpp| 6 ++-- 5 files changed, 46 insertions(+), 19 deletions(-) create mode 100644 clang/test/AST/ast-print-cconv-preserve.cpp diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index d18723d807c6a..a845bca42e374 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -1861,6 +1861,17 @@ void TypePrinter::printAttributedBefore(const AttributedType *T, if (T->getAttrKind() == attr::ObjCKindOf) OS << "__kindof "; + if (T->getAttrKind() == attr::PreserveNone) { +OS << "__attribute__((preserve_none)) "; +spaceBeforePlaceHolder(OS); + } else if (T->getAttrKind() == attr::PreserveMost) { +OS << "__attribute__((preserve_most)) "; +spaceBeforePlaceHolder(OS); + } else if (T->getAttrKind() == attr::PreserveAll) { +OS << "__attribute__((preserve_all)) "; +spaceBeforePlaceHolder(OS); + } + if (T->getAttrKind() == attr::AddressSpace) printBefore(T->getEquivalentType(), OS); else @@ -1972,6 +1983,13 @@ void TypePrinter::printAttributedAfter(const AttributedType *T, return; } + if (T->getAttrKind() == attr::PreserveAll || + T->getAttrKind() == attr::PreserveMost || + T->getAttrKind() == attr::PreserveNone) { +// This has to be printed before the declaration. +return; + } + OS << " __attribute__(("; switch (T->getAttrKind()) { #define TYPE_ATTR(NAME) @@ -2036,6 +2054,9 @@ void TypePrinter::printAttributedAfter(const AttributedType *T, case attr::Blocking: case attr::Allocating: case attr::SwiftAttr: + case attr::PreserveAll: + case attr::PreserveMost: + case attr::PreserveNone: llvm_unreachable("This attribute should have been handled already"); case attr::NSReturnsRetained: @@ -2071,20 +2092,12 @@ void TypePrinter::printAttributedAfter(const AttributedType *T, case attr::DeviceKernel: OS << T->getAttr()->getSpelling(); break; - case attr::IntelOclBicc: OS << "inteloclbicc"; break; - case attr::PreserveMost: -OS << "preserve_most"; -break; - - case attr::PreserveAll: -OS << "preserve_all"; + case attr::IntelOclBicc: +OS << "inteloclbicc"; break; case attr::M68kRTD: OS << "m68k_rtd"; break; - case attr::PreserveNone: -OS << "preserve_none"; -break; case attr::RISCVVectorCC: OS << "riscv_vector_cc"; break; diff --git a/clang/test/AST/ast-print-cconv-preserve.cpp b/clang/test/AST/ast-print-cconv-preserve.cpp new file mode 100644 index 0..af12fe64b2278 --- /dev/null +++ b/clang/test/AST/ast-print-cconv-preserve.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -ast-print %s -o - | FileCheck %s + +void (__attribute__((preserve_none)) *none)(); + +// CHECK: __attribute__((preserve_none)) void (*none)(); + +__attribute__((preserve_all)) void (*all)(); + +// CHECK: __attribute__((preserve_all)) void ((*all))(); + +__attribute__((preserve_most)) void (*most)(); + +// CHECK: __attribute__((preserve_most)) void ((*most))(); + diff --git a/clang/test/Sema/preserve-call-conv.c b/clang/test/Sema/preserve-call-conv.c index adb851960b2e3..01d0872bd6c55 100644 --- a/clang/test/Sema/preserve-call-conv.c +++ b/clang/test/Sema/preserve-call-conv.c @@ -14,8 +14,8 @@ void __attribute__((preserve_most(1))) foo1(void *ptr) { // expected-error {{'pr void (__attribute__((preserve_most)) *pfoo1)(void *) = foo; -void (__attribute__((cdecl)) *pfoo2)(void *) = foo; // expected-error {{incompatible
[clang] Revert "[clang][AST] Fix positioning of preserve cconv attributes in TypePrinter" (PR #147724)
https://github.com/th0br0 created https://github.com/llvm/llvm-project/pull/147724 Reverts llvm/llvm-project#147285 Looks like I need to limit the test's target triple. >From 07dc90502cb1686f904f2f0722567438f088083e Mon Sep 17 00:00:00 2001 From: "Andreas C. Osowski" Date: Wed, 9 Jul 2025 15:17:23 +0200 Subject: [PATCH] =?UTF-8?q?Revert=20"[clang][AST]=20Fix=20positioning=20of?= =?UTF-8?q?=20preserve=20cconv=20attributes=20in=20TypePrin=E2=80=A6"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit ab187bbd3a5c64451846aa3480f271a93dfba760. --- clang/lib/AST/TypePrinter.cpp | 33 +++-- clang/test/AST/ast-print-cconv-preserve.cpp | 14 - clang/test/Sema/preserve-call-conv.c| 8 ++--- clang/test/Sema/preserve-none-call-conv.c | 4 +-- clang/test/SemaCXX/lambda-attributes.cpp| 6 ++-- 5 files changed, 19 insertions(+), 46 deletions(-) delete mode 100644 clang/test/AST/ast-print-cconv-preserve.cpp diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index 818d2139628e3..d18723d807c6a 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -1861,17 +1861,6 @@ void TypePrinter::printAttributedBefore(const AttributedType *T, if (T->getAttrKind() == attr::ObjCKindOf) OS << "__kindof "; - if (T->getAttrKind() == attr::PreserveNone) { -OS << "__attribute__((preserve_none)) "; -spaceBeforePlaceHolder(OS); - } else if (T->getAttrKind() == attr::PreserveMost) { -OS << "__attribute__((preserve_most)) "; -spaceBeforePlaceHolder(OS); - } else if (T->getAttrKind() == attr::PreserveAll) { -OS << "__attribute__((preserve_all)) "; -spaceBeforePlaceHolder(OS); - } - if (T->getAttrKind() == attr::AddressSpace) printBefore(T->getEquivalentType(), OS); else @@ -1983,13 +1972,6 @@ void TypePrinter::printAttributedAfter(const AttributedType *T, return; } - if (T->getAttrKind() == attr::PreserveAll || - T->getAttrKind() == attr::PreserveMost || - T->getAttrKind() == attr::PreserveNone) { -// This has to be printed before the type. -return; - } - OS << " __attribute__(("; switch (T->getAttrKind()) { #define TYPE_ATTR(NAME) @@ -2054,9 +2036,6 @@ void TypePrinter::printAttributedAfter(const AttributedType *T, case attr::Blocking: case attr::Allocating: case attr::SwiftAttr: - case attr::PreserveAll: - case attr::PreserveMost: - case attr::PreserveNone: llvm_unreachable("This attribute should have been handled already"); case attr::NSReturnsRetained: @@ -2092,12 +2071,20 @@ void TypePrinter::printAttributedAfter(const AttributedType *T, case attr::DeviceKernel: OS << T->getAttr()->getSpelling(); break; - case attr::IntelOclBicc: -OS << "inteloclbicc"; + case attr::IntelOclBicc: OS << "inteloclbicc"; break; + case attr::PreserveMost: +OS << "preserve_most"; +break; + + case attr::PreserveAll: +OS << "preserve_all"; break; case attr::M68kRTD: OS << "m68k_rtd"; break; + case attr::PreserveNone: +OS << "preserve_none"; +break; case attr::RISCVVectorCC: OS << "riscv_vector_cc"; break; diff --git a/clang/test/AST/ast-print-cconv-preserve.cpp b/clang/test/AST/ast-print-cconv-preserve.cpp deleted file mode 100644 index af12fe64b2278..0 --- a/clang/test/AST/ast-print-cconv-preserve.cpp +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: %clang_cc1 -ast-print %s -o - | FileCheck %s - -void (__attribute__((preserve_none)) *none)(); - -// CHECK: __attribute__((preserve_none)) void (*none)(); - -__attribute__((preserve_all)) void (*all)(); - -// CHECK: __attribute__((preserve_all)) void ((*all))(); - -__attribute__((preserve_most)) void (*most)(); - -// CHECK: __attribute__((preserve_most)) void ((*most))(); - diff --git a/clang/test/Sema/preserve-call-conv.c b/clang/test/Sema/preserve-call-conv.c index 01d0872bd6c55..adb851960b2e3 100644 --- a/clang/test/Sema/preserve-call-conv.c +++ b/clang/test/Sema/preserve-call-conv.c @@ -14,8 +14,8 @@ void __attribute__((preserve_most(1))) foo1(void *ptr) { // expected-error {{'pr void (__attribute__((preserve_most)) *pfoo1)(void *) = foo; -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 *)'}} -void (*pfoo3)(void *) = foo; // expected-error {{incompatible function pointer types initializing 'void (*)(void *)' with an expression of type '__attribute__((preserve_most)) void (void *)'}} +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))'}} +void (*pfoo3)(void *) = foo; // expected-e
[clang] Revert "[clang][AST] Fix positioning of preserve cconv attributes in TypePrinter" (PR #147724)
https://github.com/th0br0 closed https://github.com/llvm/llvm-project/pull/147724 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Revert "[clang][AST] Fix positioning of preserve cconv attributes in TypePrinter" (PR #147724)
th0br0 wrote: Nevermind, thanks, @erichkeane ! https://github.com/llvm/llvm-project/pull/147724 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits