https://github.com/StoeckOverflow created 
https://github.com/llvm/llvm-project/pull/215266

Address @Xazax-hun's comments about volatile and nullability stripping from 
https://github.com/llvm/llvm-project/pull/213043#pullrequestreview-4830763715.

This strips top-level `volatile` like top-level `const` when building 
`Where.Parameters` selector spellings, and recursively strips nullability 
through pointer-like layers such as `int * _Nullable * _Nullable`.

This is a prequel PR to https://github.com/llvm/llvm-project/pull/213043.

Reviewers: @Xazax-hun @j-hui @egorzhdan

>From 7936ec3b781aaa767a816e0c3e703e134b622f2f Mon Sep 17 00:00:00 2001
From: stoeckoverflow <[email protected]>
Date: Mon, 10 Aug 2026 11:32:55 +0200
Subject: [PATCH] [APINotes] Strip selector volatile and nested nullability

---
 clang/lib/Sema/SemaAPINotes.cpp               | 35 ++++++++++++++++---
 .../Headers/WhereParametersSema.apinotes      | 20 +++++++++++
 .../Inputs/Headers/WhereParametersSema.h      |  4 +++
 clang/test/APINotes/where-parameters-sema.cpp | 16 +++++++++
 4 files changed, 70 insertions(+), 5 deletions(-)

diff --git a/clang/lib/Sema/SemaAPINotes.cpp b/clang/lib/Sema/SemaAPINotes.cpp
index c5560605124c8..f9a2674171d44 100644
--- a/clang/lib/Sema/SemaAPINotes.cpp
+++ b/clang/lib/Sema/SemaAPINotes.cpp
@@ -994,11 +994,35 @@ UnwindTagContext(TagDecl *DC, api_notes::APINotesManager 
&APINotes) {
   return std::nullopt;
 }
 
-static void stripAPINotesParameterNullability(QualType &ParamType) {
-  while (true) {
-    if (!AttributedType::stripOuterNullability(ParamType))
-      return;
+static QualType stripAPINotesParameterNullability(QualType ParamType,
+                                                  const ASTContext &Context) {
+  while (AttributedType::stripOuterNullability(ParamType)) {
+  }
+
+  SplitQualType Split = ParamType.split();
+  QualType Unqualified(Split.Ty, 0);
+  QualType Result = Unqualified;
+
+  if (const auto *PT = llvm::dyn_cast<PointerType>(Unqualified.getTypePtr())) {
+    QualType Pointee =
+        stripAPINotesParameterNullability(PT->getPointeeType(), Context);
+    if (Pointee.getAsOpaquePtr() != PT->getPointeeType().getAsOpaquePtr())
+      Result = Context.getPointerType(Pointee);
+  } else if (const auto *BPT =
+                 llvm::dyn_cast<BlockPointerType>(Unqualified.getTypePtr())) {
+    QualType Pointee =
+        stripAPINotesParameterNullability(BPT->getPointeeType(), Context);
+    if (Pointee.getAsOpaquePtr() != BPT->getPointeeType().getAsOpaquePtr())
+      Result = Context.getBlockPointerType(Pointee);
+  } else if (const auto *OPT = llvm::dyn_cast<ObjCObjectPointerType>(
+                 Unqualified.getTypePtr())) {
+    QualType Pointee =
+        stripAPINotesParameterNullability(OPT->getPointeeType(), Context);
+    if (Pointee.getAsOpaquePtr() != OPT->getPointeeType().getAsOpaquePtr())
+      Result = Context.getObjCObjectPointerType(Pointee);
   }
+
+  return Context.getQualifiedType(Result, Split.Quals);
 }
 
 namespace clang {
@@ -1043,7 +1067,8 @@ static std::string getAPINotesParameterSelectorSpelling(
     ParamType = ParamType.getDesugaredType(Context);
 
   ParamType.removeLocalConst();
-  stripAPINotesParameterNullability(ParamType);
+  ParamType.removeLocalVolatile();
+  ParamType = stripAPINotesParameterNullability(ParamType, Context);
 
   return ParamType.getAsString(Policy);
 }
diff --git a/clang/test/APINotes/Inputs/Headers/WhereParametersSema.apinotes 
b/clang/test/APINotes/Inputs/Headers/WhereParametersSema.apinotes
index 7ffee9223f8c3..c161ddc546e4b 100644
--- a/clang/test/APINotes/Inputs/Headers/WhereParametersSema.apinotes
+++ b/clang/test/APINotes/Inputs/Headers/WhereParametersSema.apinotes
@@ -64,6 +64,26 @@ Functions:
     Parameters:
     - int
   SwiftName: constValueGlobal(_:)
+- Name: volatileValueGlobal
+  Where:
+    Parameters:
+    - int
+  SwiftName: volatileValueGlobal(_:)
+- Name: pointerVolatileGlobal
+  Where:
+    Parameters:
+    - 'int *'
+  SwiftName: pointerVolatileGlobal(_:)
+- Name: pointeeVolatileMismatchGlobal
+  Where:
+    Parameters:
+    - 'int *'
+  SwiftName: shouldNotApplyPointeeVolatile(_:)
+- Name: nestedNullableGlobal
+  Where:
+    Parameters:
+    - 'int **'
+  SwiftName: nestedNullableGlobal(_:)
 Namespaces:
 - Name: SelectorNamespace
   Functions:
diff --git a/clang/test/APINotes/Inputs/Headers/WhereParametersSema.h 
b/clang/test/APINotes/Inputs/Headers/WhereParametersSema.h
index 8226fa287b115..3fc0973482485 100644
--- a/clang/test/APINotes/Inputs/Headers/WhereParametersSema.h
+++ b/clang/test/APINotes/Inputs/Headers/WhereParametersSema.h
@@ -22,6 +22,10 @@ void multiAliasGlobal(DeepAliasInt);
 void nullableGlobal(char * _Nonnull);
 void rawIntGlobal(int);
 void constValueGlobal(const int);
+void volatileValueGlobal(volatile int);
+void pointerVolatileGlobal(int *volatile);
+void pointeeVolatileMismatchGlobal(volatile int *);
+void nestedNullableGlobal(int * _Nullable * _Nullable);
 
 namespace SelectorNamespace {
 void makeNamespaced(int);
diff --git a/clang/test/APINotes/where-parameters-sema.cpp 
b/clang/test/APINotes/where-parameters-sema.cpp
index fbb7cb45b9441..526a48d284ee5 100644
--- a/clang/test/APINotes/where-parameters-sema.cpp
+++ b/clang/test/APINotes/where-parameters-sema.cpp
@@ -10,6 +10,10 @@
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps 
-fmodules-cache-path=%t/ModulesCache/WhereParametersSema -fdisable-module-hash 
-fapinotes-modules -I %S/Inputs/Headers %s -ast-dump -ast-dump-filter 
nullableGlobal -x c++ | FileCheck --check-prefix=CHECK-GLOBAL-NULLABILITY %s
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps 
-fmodules-cache-path=%t/ModulesCache/WhereParametersSema -fdisable-module-hash 
-fapinotes-modules -I %S/Inputs/Headers %s -ast-dump -ast-dump-filter 
rawIntGlobal -x c++ | FileCheck --check-prefix=CHECK-GLOBAL-RAW-INT %s
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps 
-fmodules-cache-path=%t/ModulesCache/WhereParametersSema -fdisable-module-hash 
-fapinotes-modules -I %S/Inputs/Headers %s -ast-dump -ast-dump-filter 
constValueGlobal -x c++ | FileCheck --check-prefix=CHECK-GLOBAL-CONST %s
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps 
-fmodules-cache-path=%t/ModulesCache/WhereParametersSema -fdisable-module-hash 
-fapinotes-modules -I %S/Inputs/Headers %s -ast-dump -ast-dump-filter 
volatileValueGlobal -x c++ | FileCheck --check-prefix=CHECK-GLOBAL-VOLATILE %s
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps 
-fmodules-cache-path=%t/ModulesCache/WhereParametersSema -fdisable-module-hash 
-fapinotes-modules -I %S/Inputs/Headers %s -ast-dump -ast-dump-filter 
pointerVolatileGlobal -x c++ | FileCheck 
--check-prefix=CHECK-GLOBAL-POINTER-VOLATILE %s
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps 
-fmodules-cache-path=%t/ModulesCache/WhereParametersSema -fdisable-module-hash 
-fapinotes-modules -I %S/Inputs/Headers %s -ast-dump -ast-dump-filter 
pointeeVolatileMismatchGlobal -x c++ | FileCheck 
--check-prefix=CHECK-GLOBAL-POINTEE-VOLATILE-MISMATCH %s
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps 
-fmodules-cache-path=%t/ModulesCache/WhereParametersSema -fdisable-module-hash 
-fapinotes-modules -I %S/Inputs/Headers %s -ast-dump -ast-dump-filter 
nestedNullableGlobal -x c++ | FileCheck 
--check-prefix=CHECK-GLOBAL-NESTED-NULLABILITY %s
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps 
-fmodules-cache-path=%t/ModulesCache/WhereParametersSema -fdisable-module-hash 
-fapinotes-modules -I %S/Inputs/Headers %s -ast-dump -ast-dump-filter 
SelectorNamespace::makeNamespaced -x c++ | FileCheck 
--check-prefix=CHECK-GLOBAL-NAMESPACE %s
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps 
-fmodules-cache-path=%t/ModulesCache/WhereParametersSema -fdisable-module-hash 
-fapinotes-modules -I %S/Inputs/Headers %s -ast-dump -ast-dump-filter 
SelectorWidget::setValue -x c++ | FileCheck 
--check-prefix=CHECK-METHOD-OVERLOADS %s
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps 
-fmodules-cache-path=%t/ModulesCache/WhereParametersSema -fdisable-module-hash 
-fapinotes-modules -I %S/Inputs/Headers %s -ast-dump -ast-dump-filter 
SelectorWidget::broad -x c++ | FileCheck --check-prefix=CHECK-METHOD-BROAD %s
@@ -27,6 +31,18 @@
 
 #include "WhereParametersSema.h"
 
+// CHECK-GLOBAL-VOLATILE: FunctionDecl {{.+}} volatileValueGlobal 'void 
(volatile int)'
+// CHECK-GLOBAL-VOLATILE: SwiftNameAttr {{.+}} "volatileValueGlobal(_:)"
+
+// CHECK-GLOBAL-POINTER-VOLATILE: FunctionDecl {{.+}} pointerVolatileGlobal 
'void (int *volatile)'
+// CHECK-GLOBAL-POINTER-VOLATILE: SwiftNameAttr {{.+}} 
"pointerVolatileGlobal(_:)"
+
+// CHECK-GLOBAL-POINTEE-VOLATILE-MISMATCH: FunctionDecl {{.+}} 
pointeeVolatileMismatchGlobal 'void (volatile int *)'
+// CHECK-GLOBAL-POINTEE-VOLATILE-MISMATCH-NOT: SwiftNameAttr
+
+// CHECK-GLOBAL-NESTED-NULLABILITY: FunctionDecl {{.+}} nestedNullableGlobal 
'void (int * _Nullable * _Nullable)'
+// CHECK-GLOBAL-NESTED-NULLABILITY: SwiftNameAttr {{.+}} 
"nestedNullableGlobal(_:)"
+
 // CHECK-GLOBAL-OVERLOADS: FunctionDecl {{.+}} makeWidget 'void (int)'
 // CHECK-GLOBAL-OVERLOADS-NEXT: ParmVarDecl {{.+}} 'int'
 // CHECK-GLOBAL-OVERLOADS-NEXT: SwiftNameAttr {{.+}} "makeIntWidget(_:)"

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to