[clang] [Clang][RFC] Resugar attributed type alias (PR #143143)
Younan Zhang via cfe-commits
cfe-commits at lists.llvm.org
Fri Jun 6 06:57:30 PDT 2025
https://github.com/zyn0217 created https://github.com/llvm/llvm-project/pull/143143
https://github.com/llvm/llvm-project/issues/142608 reflects a case where the type sugar on the attributed type alias is lost.
It might be possible to add the sugar back at the cost of duplicating the type alias decl, along with a modified type source info.
Though I'm not sure if the solution is feasible, and since there's no test regression I'll just elaborate the difference through a diagnostic.
>From 7a418dddf46e580b32d874d84f26f88a8d483151 Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7109 at gmail.com>
Date: Fri, 6 Jun 2025 21:23:09 +0800
Subject: [PATCH 1/2] [Clang] Retain type sugar on attributed type declarations
---
clang/lib/Sema/SemaType.cpp | 34 ++++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 338b81fe89748..e5f7f4bdc98dc 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -6856,6 +6856,8 @@ namespace {
Reference,
MemberPointer,
MacroQualified,
+ Elaborated,
+ TypeAlias,
};
QualType Original;
@@ -6893,6 +6895,12 @@ namespace {
} else if (isa<MacroQualifiedType>(Ty)) {
T = cast<MacroQualifiedType>(Ty)->getUnderlyingType();
Stack.push_back(MacroQualified);
+ } else if (isa<ElaboratedType>(Ty)) {
+ T = cast<ElaboratedType>(Ty)->desugar();
+ Stack.push_back(Elaborated);
+ } else if (isa<TypedefType>(Ty)) {
+ T = cast<TypedefType>(Ty)->desugar();
+ Stack.push_back(TypeAlias);
} else {
const Type *DTy = Ty->getUnqualifiedDesugaredType();
if (Ty == DTy) {
@@ -6939,6 +6947,7 @@ namespace {
case Desugar:
// This is the point at which we potentially lose source
// information.
+ // FIXME: Preserve more sugar
return wrap(C, Old->getUnqualifiedDesugaredType(), I);
case Attributed:
@@ -6998,6 +7007,31 @@ namespace {
else
return C.getRValueReferenceType(New);
}
+ case Elaborated: {
+ auto *ET = cast<ElaboratedType>(Old);
+ return C.getElaboratedType(ET->getKeyword(), ET->getQualifier(),
+ wrap(C, ET->getNamedType(), I));
+ }
+ case TypeAlias: {
+ auto *ET = cast<TypedefType>(Old);
+ QualType Underlying = wrap(C, ET->desugar(), I);
+ TypedefNameDecl *Typedef;
+ if (auto *TD = dyn_cast<TypedefDecl>(ET->getDecl())) {
+ Typedef = TypedefDecl::Create(C, TD->getDeclContext(),
+ TD->getBeginLoc(), TD->getLocation(),
+ TD->getIdentifier(), nullptr);
+ Typedef->setModedTypeSourceInfo(TD->getTypeSourceInfo(), Underlying);
+ } else {
+ auto *Alias = cast<TypeAliasDecl>(ET->getDecl());
+ Typedef = TypedefDecl::Create(
+ C, Alias->getDeclContext(), Alias->getBeginLoc(),
+ Alias->getLocation(), Alias->getIdentifier(), nullptr);
+ Typedef->setModedTypeSourceInfo(Alias->getTypeSourceInfo(),
+ Underlying);
+ }
+ Typedef->setPreviousDecl(ET->getDecl());
+ return C.getTypedefType(Typedef, Underlying);
+ }
}
llvm_unreachable("unknown wrapping kind");
>From 081acf9e6753cb01ff37e999137419d8fbec2da8 Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7109 at gmail.com>
Date: Fri, 6 Jun 2025 21:48:29 +0800
Subject: [PATCH 2/2] Test?
---
.../test/SemaCXX/function-type-attributes.cpp | 21 +++++++++++++++++++
1 file changed, 21 insertions(+)
create mode 100644 clang/test/SemaCXX/function-type-attributes.cpp
diff --git a/clang/test/SemaCXX/function-type-attributes.cpp b/clang/test/SemaCXX/function-type-attributes.cpp
new file mode 100644
index 0000000000000..38b8d12f2eea0
--- /dev/null
+++ b/clang/test/SemaCXX/function-type-attributes.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace GH142608 {
+
+typedef void (*report_fn)(const char *err);
+
+void die_builtin(const char *err);
+
+__attribute__((noreturn))
+report_fn die_routine;
+
+template <class T>
+void foo(T, typename T::size = 0); // #foo
+
+void bar() {
+ foo<__attribute__((noreturn)) report_fn>(die_routine);
+ // expected-error at -1 {{no matching function}}
+ // expected-note@#foo {{substitution failure [with T = report_fn]: type 'report_fn' (aka 'void (*)(const char *) __attribute__((noreturn))')}}
+}
+
+}
More information about the cfe-commits
mailing list