[clang] [Clang] Add C++11/C23-style spellings for Swift import attributes (PR #183484)

Tshaka Lekholoane via cfe-commits cfe-commits at lists.llvm.org
Sun Mar 8 13:45:25 PDT 2026


https://github.com/tshakalekholoane updated https://github.com/llvm/llvm-project/pull/183484

>From 2902e874ad2e6a06e17b34027fc6eadc8aa3d2a9 Mon Sep 17 00:00:00 2001
From: Tshaka Lekholoane <mail+git at tshaka.dev>
Date: Fri, 27 Feb 2026 21:12:44 +0200
Subject: [PATCH] [Clang] Add C++11/C23-style spellings for Swift import
 attributes

Swift import attributes such as swift_async_name, swift_attr,
swift_name, swift_newtype, swift_wrapper, 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 be570630406ef..769b10a7fb6e8 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -200,6 +200,13 @@ Attribute Changes in Clang
   type-level control over overflow behavior. There is also an accompanying type
   specifier for each behavior kind via `__ob_wrap` and `__ob_trap`.
 
+- 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.
+
 Improvements to Clang's diagnostics
 -----------------------------------
 - Added ``-Wlifetime-safety`` to enable lifetime safety analysis,
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index a5641e2e008cd..02b07ea7815a7 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -3149,14 +3149,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;
@@ -3212,13 +3212,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>;
@@ -3227,7 +3227,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 at +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 at +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 at +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 at +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 at +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);



More information about the cfe-commits mailing list