https://github.com/tshakalekholoane updated https://github.com/llvm/llvm-project/pull/183484
>From 4d74f585cd4496ad3007b749dc2272ae0d2d0e21 Mon Sep 17 00:00:00 2001 From: Tshaka Lekholoane <[email protected]> Date: Wed, 15 Apr 2026 18:46:04 +0200 Subject: [PATCH 1/2] [Clang] Add C++11/C23-style spellings for Swift import attributes Swift interop attributes such as swift_name, swift_attr, and swift_private previously only supported GNU-style spelling. Add the missing [[]] attribute spellings for C++11 and C23 compatibility, bringing them in line with other Clang attributes. --- clang/docs/ReleaseNotes.rst | 7 +++ clang/include/clang/Basic/Attr.td | 10 ++-- clang/test/Sema/attr-swift-import.c | 77 +++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 5 deletions(-) create mode 100644 clang/test/Sema/attr-swift-import.c diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index dc1192bbbd3d7..a9634587874b8 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -242,6 +242,13 @@ Removed Compiler Flags Attribute Changes in Clang -------------------------- +- Added C++11/C23 style spellings for Swift import attributes. The + ``swift_async_name``, ``swift_attr``, ``swift_name``, ``swift_newtype``, + ``swift_wrapper``, and ``swift_private`` attributes now support the + ``[[clang::...]]`` syntax in addition to the GNU ``__attribute__`` style, + bringing them in line with other Clang attributes and improving compatibility + with C++11/C23 codebases. + - Added new attribute ``stack_protector_ignore`` to opt specific local variables out of the analysis which determines if a function should get a stack protector. A function will still generate a stack protector if other local variables or command line flags diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 328e70b3ed900..df7acf752827a 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -3168,14 +3168,14 @@ def SwiftNullability : Attr { } def SwiftAsyncName : InheritableAttr { - let Spellings = [GNU<"swift_async_name">]; + let Spellings = [Clang<"swift_async_name">]; let Args = [StringArgument<"Name">]; let Subjects = SubjectList<[ObjCMethod, Function], ErrorDiag>; let Documentation = [SwiftAsyncNameDocs]; } def SwiftAttr : DeclOrTypeAttr { - let Spellings = [GNU<"swift_attr">]; + let Spellings = [Clang<"swift_attr">]; let Args = [StringArgument<"Attribute">]; let Documentation = [SwiftAttrDocs]; let PragmaAttributeSupport = 1; @@ -3231,13 +3231,13 @@ def SwiftImportPropertyAsAccessors : InheritableAttr { } def SwiftName : InheritableAttr { - let Spellings = [GNU<"swift_name">]; + let Spellings = [Clang<"swift_name">]; let Args = [StringArgument<"Name">]; let Documentation = [SwiftNameDocs]; } def SwiftNewType : InheritableAttr { - let Spellings = [GNU<"swift_newtype">, GNU<"swift_wrapper">]; + let Spellings = [Clang<"swift_newtype">, Clang<"swift_wrapper">]; let Args = [EnumArgument<"NewtypeKind", "NewtypeKind", /*is_string=*/false, ["struct", "enum"], ["NK_Struct", "NK_Enum"]>]; let Subjects = SubjectList<[TypedefName], ErrorDiag>; @@ -3246,7 +3246,7 @@ def SwiftNewType : InheritableAttr { } def SwiftPrivate : InheritableAttr { - let Spellings = [GNU<"swift_private">]; + let Spellings = [Clang<"swift_private">]; let Documentation = [SwiftPrivateDocs]; let SimpleHandler = 1; } diff --git a/clang/test/Sema/attr-swift-import.c b/clang/test/Sema/attr-swift-import.c new file mode 100644 index 0000000000000..9ce58e5487f36 --- /dev/null +++ b/clang/test/Sema/attr-swift-import.c @@ -0,0 +1,77 @@ +// RUN: %clang_cc1 -fblocks -fsyntax-only -std=c23 -verify -Wunknown-attributes %s + +#pragma mark - swift_async_name + +[[clang::swift_async_name("testAsyncNameFunc()")]] +void test_async_name_func(void (^completion)(void)); + +// expected-warning@+1 {{too many parameters in the signature specified by the 'clang::swift_async_name' attribute (expected 0; got 1)}} +[[clang::swift_async_name("testAsyncNameFuncWithNoCompletionHandler(x:)")]] +void test_async_name_func_with_no_completion_handler(int x); + +// expected-warning@+1 {{'clang::swift_async_name' attribute cannot be applied to a function with no parameters}} +[[clang::swift_async_name("testAsyncNameFuncWithNoParameters()")]] +void test_async_name_func_with_no_parameters(void); + +[[clang::swift_async_name("testAsyncNameFuncWithParameter(x:)")]] +void test_async_name_func_with_parameter(int x, void (^completion)(void)); + +// expected-warning@+1 {{too many parameters in the signature specified by the 'clang::swift_async_name' attribute (expected 1; got 2)}} +[[clang::swift_async_name("testAsyncNameFuncWithTooManyParameters(x:completion:)")]] +void test_async_name_func_with_too_many_parameters(int x, void (^completion)(void)); + +#pragma mark - swift_attr + +[[clang::swift_attr("Escapable")]] +typedef struct test_attr_t test_attr_t; + +#pragma mark - swift_name + +[[clang::swift_name("TestName")]] +typedef struct test_name_s *test_name_t; + +[[clang::swift_name("TestName.init()")]] +test_name_t test_name_init(void); + +[[clang::swift_name("TestName.mutatingMethod(self:)")]] +void test_name_mutating_method(test_name_t test_name); + +[[clang::swift_name("getter:TestName.property(self:)")]] +int test_name_get_property(const test_name_t test_name); + +[[clang::swift_name("setter:TestName.property(self:newValue:)")]] +void test_name_set_property(test_name_t test_name, int x); + +enum [[clang::swift_name("TestNameEnum")]] test_name_e { + test_name_a [[clang::swift_name("a")]] = 1, + test_name_b +}; + +// expected-error@+1 {{'clang::swift_name' attribute cannot be applied to types}} +void test_name_func_applied_to_type(int x) [[clang::swift_name("testNameFuncAppliedToType(_:)")]]; + +#pragma mark - swift_newtype, swift_wrapper + +[[clang::swift_newtype(enum)]] +typedef struct test_newtype_e test_newtype_t; + +// expected-error@+1 {{'clang::swift_newtype' attribute only applies to typedefs}} +struct [[clang::swift_newtype(struct)]] test_newtype_s; + +[[clang::swift_wrapper(struct)]] +typedef struct test_wrapper_s test_wrapper_t; + +#pragma mark - swift_private + +enum [[clang::swift_private]] test_private_e { + test_private_a, + test_private_b +}; + +struct [[clang::swift_private]] test_private_s; + +[[clang::swift_private]] +typedef struct test_private_s test_private_t; + +[[clang::swift_private]] +void test_private_func(void); >From 40848839a7e18eea3bd564a41f3d0aa60ca24c7f Mon Sep 17 00:00:00 2001 From: Tshaka Lekholoane <[email protected]> Date: Mon, 18 May 2026 20:57:23 +0200 Subject: [PATCH 2/2] [Clang] Document Swift interop attributes in Attr.td Added comments regarding Swift interop attributes and vendor namespace considerations. --- clang/include/clang/Basic/Attr.td | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index df7acf752827a..1c17ca9e9c68b 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -3147,6 +3147,17 @@ def Regparm : TypeAttr { let ASTNode = 0; } +// FIXME: The following Swift interop attributes currently use the Clang +// vendor namespace for their CXX11/C23 spellings, consistent with other +// Swift-related attributes e.g., clang::swift_async. +// +// A Swift vendor namespace was considered e.g., swift::name rather than +// clang::swift_name, but it was decided not to claim that prematurely. +// Doing so deserves more attention -- among other things, one would +// want to avoid stuttering e.g., swift::swift_name. +// +// See https://github.com/llvm/llvm-project/pull/183484 + def SwiftType : Attr { // This attribute has no spellings as it is only ever created implicitly // from API notes. _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
