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 <zyn7...@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 <zyn7...@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@-1 {{no matching function}}
+  // expected-note@#foo {{substitution failure [with T = report_fn]: type 
'report_fn' (aka 'void (*)(const char *) __attribute__((noreturn))')}}
+}
+
+}

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to