@@ -1298,6 +1298,25 @@ class Conventions {
12981298 }
12991299 llvm_unreachable (" unhandled ownership" );
13001300 }
1301+
1302+ // Determines owned/unowned ResultConvention of the returned value based on
1303+ // returns_retained/returns_unretained attribute.
1304+ std::optional<ResultConvention>
1305+ getCxxRefConventionWithAttrs (const TypeLowering &tl,
1306+ const clang::Decl *decl) const {
1307+ if (tl.getLoweredType ().isForeignReferenceType () && decl->hasAttrs ()) {
1308+ for (const auto *attr : decl->getAttrs ()) {
1309+ if (const auto *swiftAttr = dyn_cast<clang::SwiftAttrAttr>(attr)) {
1310+ if (swiftAttr->getAttribute () == " returns_unretained" ) {
1311+ return ResultConvention::Unowned;
1312+ } else if (swiftAttr->getAttribute () == " returns_retained" ) {
1313+ return ResultConvention::Owned;
1314+ }
1315+ }
1316+ }
1317+ }
1318+ return std::nullopt ;
1319+ }
13011320};
13021321
13031322// / A visitor for breaking down formal result types into a SILResultInfo
@@ -3341,7 +3360,8 @@ class ObjCMethodConventions : public Conventions {
33413360 return ResultConvention::Owned;
33423361
33433362 if (tl.getLoweredType ().isForeignReferenceType ())
3344- return ResultConvention::Unowned;
3363+ return getCxxRefConventionWithAttrs (tl, Method)
3364+ .value_or (ResultConvention::Unowned);
33453365
33463366 return ResultConvention::Autoreleased;
33473367 }
@@ -3381,25 +3401,6 @@ class CFunctionTypeConventions : public Conventions {
33813401 const clang::FunctionType *type)
33823402 : Conventions(kind), FnType(type) {}
33833403
3384- // Determines owned/unowned ResultConvention of the returned value based on
3385- // returns_retained/returns_unretained attribute.
3386- std::optional<ResultConvention>
3387- getForeignReferenceTypeResultConventionWithAttributes (
3388- const TypeLowering &tl, const clang::FunctionDecl *decl) const {
3389- if (tl.getLoweredType ().isForeignReferenceType () && decl->hasAttrs ()) {
3390- for (const auto *attr : decl->getAttrs ()) {
3391- if (const auto *swiftAttr = dyn_cast<clang::SwiftAttrAttr>(attr)) {
3392- if (swiftAttr->getAttribute () == " returns_unretained" ) {
3393- return ResultConvention::Unowned;
3394- } else if (swiftAttr->getAttribute () == " returns_retained" ) {
3395- return ResultConvention::Owned;
3396- }
3397- }
3398- }
3399- }
3400- return std::nullopt ;
3401- }
3402-
34033404public:
34043405 CFunctionTypeConventions (const clang::FunctionType *type)
34053406 : Conventions(ConventionsKind::CFunctionType), FnType(type) {}
@@ -3517,11 +3518,7 @@ class CFunctionConventions : public CFunctionTypeConventions {
35173518 return ResultConvention::Indirect;
35183519 }
35193520
3520- // Explicitly setting the ownership of the returned FRT if the C++
3521- // global/free function has either swift_attr("returns_retained") or
3522- // ("returns_unretained") attribute.
3523- if (auto resultConventionOpt =
3524- getForeignReferenceTypeResultConventionWithAttributes (tl, TheDecl))
3521+ if (auto resultConventionOpt = getCxxRefConventionWithAttrs (tl, TheDecl))
35253522 return *resultConventionOpt;
35263523
35273524 if (isCFTypedef (tl, TheDecl->getReturnType ())) {
@@ -3603,11 +3600,8 @@ class CXXMethodConventions : public CFunctionTypeConventions {
36033600 return ResultConvention::Indirect;
36043601 }
36053602
3606- // Explicitly setting the ownership of the returned FRT if the C++ member
3607- // method has either swift_attr("returns_retained") or
3608- // ("returns_unretained") attribute.
36093603 if (auto resultConventionOpt =
3610- getForeignReferenceTypeResultConventionWithAttributes (resultTL, TheDecl))
3604+ getCxxRefConventionWithAttrs (resultTL, TheDecl))
36113605 return *resultConventionOpt;
36123606
36133607 if (TheDecl->hasAttr <clang::CFReturnsRetainedAttr>() &&
0 commit comments