From 08c62b4b97f7067acba7540a73948ac3c8c9e4df Mon Sep 17 00:00:00 2001 From: Fahad Nayyar Date: Tue, 10 Jun 2025 06:49:46 -0700 Subject: [PATCH 1/5] [cxx-interop] Add SWIFT_RETUNRS_(UN)RETAINED discussions to C++ interop docs --- documentation/cxx-interop/index.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/documentation/cxx-interop/index.md b/documentation/cxx-interop/index.md index a1f06a9e8..8c1cd41af 100644 --- a/documentation/cxx-interop/index.md +++ b/documentation/cxx-interop/index.md @@ -1255,6 +1255,30 @@ object.doSomething() // `object` will be released here. ``` +To specify the ownership of returned `SWIFT_SHARED_REFERENCE` types, use the `SWIFT_RETURNS_RETAINED` and `SWIFT_RETURNS_UNRETAINED` annotations on C++ functions and methods. These annotations tell the Swift compiler whether the type is returned as `+1` (retained) or `+0` (unretained). This is necessary to ensure that appropriate `retain`/`release` operations are inserted at the boundary: + +```c++ +// Returns +1 ownership; Swift will take responsibility for releasing it. +SharedObject* makeOwnedObject() SWIFT_RETURNS_RETAINED; + +// Returns +0 ownership; the caller must ensure the object stays alive. +SharedObject* makeUnownedObject() SWIFT_RETURNS_UNRETAINED; +``` + +These ownership conventions are reflected naturally in Swift: +```swift +let owned = makeOwnedObject() +owned.doSomething() +// `owned` is automatically released when it goes out of scope + +let unowned = makeUnownedObject() +unowned.doSomething() +// make sure `unowned` remains valid while in use +``` + +These ownership annotations are also supported in Objective-C or Objective-C++ functions that return C++ `SWIFT_SHARED_REFERENCE` types. + + ### Inheritance and Virtual Member Functions Similar to value types, casting an instance of a derived reference type to a From e534fe062010895048de7d15537a76c379f3bb70 Mon Sep 17 00:00:00 2001 From: Fahad Nayyar Date: Tue, 1 Jul 2025 22:26:51 -0700 Subject: [PATCH 2/5] changed some comments --- documentation/cxx-interop/index.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/documentation/cxx-interop/index.md b/documentation/cxx-interop/index.md index 8c1cd41af..b78ab7396 100644 --- a/documentation/cxx-interop/index.md +++ b/documentation/cxx-interop/index.md @@ -1261,7 +1261,7 @@ To specify the ownership of returned `SWIFT_SHARED_REFERENCE` types, use the `SW // Returns +1 ownership; Swift will take responsibility for releasing it. SharedObject* makeOwnedObject() SWIFT_RETURNS_RETAINED; -// Returns +0 ownership; the caller must ensure the object stays alive. +// Returns +0 ownership; the caller must ensure the object stays alive by retaining it before use. SharedObject* makeUnownedObject() SWIFT_RETURNS_UNRETAINED; ``` @@ -1271,12 +1271,12 @@ let owned = makeOwnedObject() owned.doSomething() // `owned` is automatically released when it goes out of scope -let unowned = makeUnownedObject() -unowned.doSomething() -// make sure `unowned` remains valid while in use +let unOwned = makeUnownedObject() +unOwned.doSomething() +// Swift makes sure `unOwned` remains valid while in use by calling an explicit retain operation. ``` -These ownership annotations are also supported in Objective-C or Objective-C++ functions that return C++ `SWIFT_SHARED_REFERENCE` types. +These ownership annotations are also supported in Objective-C++ functions that return C++ `SWIFT_SHARED_REFERENCE` types. ### Inheritance and Virtual Member Functions From 69e12e08187417b0d99200498487952ce1db2dd1 Mon Sep 17 00:00:00 2001 From: Fahad Nayyar Date: Wed, 2 Jul 2025 15:36:59 -0700 Subject: [PATCH 3/5] edits --- documentation/cxx-interop/index.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/documentation/cxx-interop/index.md b/documentation/cxx-interop/index.md index b78ab7396..a06041006 100644 --- a/documentation/cxx-interop/index.md +++ b/documentation/cxx-interop/index.md @@ -1255,29 +1255,32 @@ object.doSomething() // `object` will be released here. ``` -To specify the ownership of returned `SWIFT_SHARED_REFERENCE` types, use the `SWIFT_RETURNS_RETAINED` and `SWIFT_RETURNS_UNRETAINED` annotations on C++ functions and methods. These annotations tell the Swift compiler whether the type is returned as `+1` (retained) or `+0` (unretained). This is necessary to ensure that appropriate `retain`/`release` operations are inserted at the boundary: +#### Calling convention for returning shared reference types + +When C++ functions and methods return `SWIFT_SHARED_REFERENCE` types, it is necessary to specify the ownership of the returned value. For this you can use the `SWIFT_RETURNS_RETAINED` and `SWIFT_RETURNS_UNRETAINED` annotations on C++ functions and methods. These annotations tell the Swift compiler whether the type is returned as `+1` (retained) or `+0` (unretained). This is necessary to ensure that appropriate `retain`/`release` operations are inserted at the boundary: ```c++ // Returns +1 ownership; Swift will take responsibility for releasing it. SharedObject* makeOwnedObject() SWIFT_RETURNS_RETAINED; // Returns +0 ownership; the caller must ensure the object stays alive by retaining it before use. -SharedObject* makeUnownedObject() SWIFT_RETURNS_UNRETAINED; +SharedObject* getUnownedObject() SWIFT_RETURNS_UNRETAINED; ``` These ownership conventions are reflected naturally in Swift: ```swift let owned = makeOwnedObject() owned.doSomething() -// `owned` is automatically released when it goes out of scope +// `owned` is automatically released when it goes out of scope. -let unOwned = makeUnownedObject() +let unOwned = getUnownedObject() unOwned.doSomething() -// Swift makes sure `unOwned` remains valid while in use by calling an explicit retain operation. +// Swift makes sure `unOwned` remains valid while in use by calling a retain operation. ``` These ownership annotations are also supported in Objective-C++ functions that return C++ `SWIFT_SHARED_REFERENCE` types. +Note that the Swift compiler will automatically infer the ownership conventons for Swift functions returning `SWIFT_SHARED_REFERENCE` types. See [Exposing C++ Shared Reference Types back from Swift](#exposing-c-shared-reference-types-back-from-swift) for calling Swift functions returning `SWIFT_SHARED_REFERENCE` types from C++. ### Inheritance and Virtual Member Functions From ee608905bf7629e9b19daf9022ca0799f62495fc Mon Sep 17 00:00:00 2001 From: Fahad Nayyar Date: Thu, 3 Jul 2025 16:39:32 -0700 Subject: [PATCH 4/5] Addressed some comments from j-hui --- documentation/cxx-interop/index.md | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/documentation/cxx-interop/index.md b/documentation/cxx-interop/index.md index a06041006..12cffadd2 100644 --- a/documentation/cxx-interop/index.md +++ b/documentation/cxx-interop/index.md @@ -1255,32 +1255,34 @@ object.doSomething() // `object` will be released here. ``` -#### Calling convention for returning shared reference types +#### Calling conventions for returning Shared Reference Types -When C++ functions and methods return `SWIFT_SHARED_REFERENCE` types, it is necessary to specify the ownership of the returned value. For this you can use the `SWIFT_RETURNS_RETAINED` and `SWIFT_RETURNS_UNRETAINED` annotations on C++ functions and methods. These annotations tell the Swift compiler whether the type is returned as `+1` (retained) or `+0` (unretained). This is necessary to ensure that appropriate `retain`/`release` operations are inserted at the boundary: +When C++ functions and methods return `SWIFT_SHARED_REFERENCE` types, it is necessary to specify the ownership of the returned value. +For this you should use the `SWIFT_RETURNS_RETAINED` and `SWIFT_RETURNS_UNRETAINED` annotations on functions and methods. +These annotations tell the Swift compiler whether the type is returned as `+1` (retained) or `+0` (unretained). ```c++ -// Returns +1 ownership; Swift will take responsibility for releasing it. +// Returns +1 ownership. SharedObject* makeOwnedObject() SWIFT_RETURNS_RETAINED; -// Returns +0 ownership; the caller must ensure the object stays alive by retaining it before use. -SharedObject* getUnownedObject() SWIFT_RETURNS_UNRETAINED; +// Returns +0 ownership. +SharedObject* getUnOwnedObject() SWIFT_RETURNS_UNRETAINED; ``` -These ownership conventions are reflected naturally in Swift: +These annotations are necessary to ensure that appropriate `retain`/`release` operations are inserted at the boundary: + ```swift let owned = makeOwnedObject() owned.doSomething() -// `owned` is automatically released when it goes out of scope. +// `owned` is already at +1, so no further retain is needed here -let unOwned = getUnownedObject() +let unOwned = getUnOwnedObject() +// Swift inserts a retain operation on `unowned` here to bring it to +1. unOwned.doSomething() -// Swift makes sure `unOwned` remains valid while in use by calling a retain operation. ``` -These ownership annotations are also supported in Objective-C++ functions that return C++ `SWIFT_SHARED_REFERENCE` types. - -Note that the Swift compiler will automatically infer the ownership conventons for Swift functions returning `SWIFT_SHARED_REFERENCE` types. See [Exposing C++ Shared Reference Types back from Swift](#exposing-c-shared-reference-types-back-from-swift) for calling Swift functions returning `SWIFT_SHARED_REFERENCE` types from C++. +Note that the Swift compiler will automatically infer the ownership conventons for Swift functions returning `SWIFT_SHARED_REFERENCE` types. +See [Exposing C++ Shared Reference Types back from Swift](#exposing-c-shared-reference-types-back-from-swift) for calling Swift functions returning `SWIFT_SHARED_REFERENCE` types from C++. ### Inheritance and Virtual Member Functions From faa1e37b3d0ef03f5663c266890b4950eab003df Mon Sep 17 00:00:00 2001 From: Fahad Nayyar Date: Thu, 3 Jul 2025 18:00:08 -0700 Subject: [PATCH 5/5] Changed title --- documentation/cxx-interop/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/cxx-interop/index.md b/documentation/cxx-interop/index.md index 12cffadd2..74ca22823 100644 --- a/documentation/cxx-interop/index.md +++ b/documentation/cxx-interop/index.md @@ -1255,7 +1255,7 @@ object.doSomething() // `object` will be released here. ``` -#### Calling conventions for returning Shared Reference Types +#### Calling conventions when returning Shared Reference Types from C++ to Swift When C++ functions and methods return `SWIFT_SHARED_REFERENCE` types, it is necessary to specify the ownership of the returned value. For this you should use the `SWIFT_RETURNS_RETAINED` and `SWIFT_RETURNS_UNRETAINED` annotations on functions and methods.