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
