@@ -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
@@ -3335,7 +3354,8 @@ class ObjCMethodConventions : public Conventions {
33353354 return ResultConvention::Owned;
33363355
33373356 if (tl.getLoweredType ().isForeignReferenceType ())
3338- return ResultConvention::Unowned;
3357+ return getCxxRefConventionWithAttrs (tl, Method)
3358+ .value_or (ResultConvention::Unowned);
33393359
33403360 return ResultConvention::Autoreleased;
33413361 }
@@ -3375,25 +3395,6 @@ class CFunctionTypeConventions : public Conventions {
33753395 const clang::FunctionType *type)
33763396 : Conventions(kind), FnType(type) {}
33773397
3378- // Determines owned/unowned ResultConvention of the returned value based on
3379- // returns_retained/returns_unretained attribute.
3380- std::optional<ResultConvention>
3381- getForeignReferenceTypeResultConventionWithAttributes (
3382- const TypeLowering &tl, const clang::FunctionDecl *decl) const {
3383- if (tl.getLoweredType ().isForeignReferenceType () && decl->hasAttrs ()) {
3384- for (const auto *attr : decl->getAttrs ()) {
3385- if (const auto *swiftAttr = dyn_cast<clang::SwiftAttrAttr>(attr)) {
3386- if (swiftAttr->getAttribute () == " returns_unretained" ) {
3387- return ResultConvention::Unowned;
3388- } else if (swiftAttr->getAttribute () == " returns_retained" ) {
3389- return ResultConvention::Owned;
3390- }
3391- }
3392- }
3393- }
3394- return std::nullopt ;
3395- }
3396-
33973398public:
33983399 CFunctionTypeConventions (const clang::FunctionType *type)
33993400 : Conventions(ConventionsKind::CFunctionType), FnType(type) {}
@@ -3511,11 +3512,7 @@ class CFunctionConventions : public CFunctionTypeConventions {
35113512 return ResultConvention::Indirect;
35123513 }
35133514
3514- // Explicitly setting the ownership of the returned FRT if the C++
3515- // global/free function has either swift_attr("returns_retained") or
3516- // ("returns_unretained") attribute.
3517- if (auto resultConventionOpt =
3518- getForeignReferenceTypeResultConventionWithAttributes (tl, TheDecl))
3515+ if (auto resultConventionOpt = getCxxRefConventionWithAttrs (tl, TheDecl))
35193516 return *resultConventionOpt;
35203517
35213518 if (isCFTypedef (tl, TheDecl->getReturnType ())) {
@@ -3597,11 +3594,8 @@ class CXXMethodConventions : public CFunctionTypeConventions {
35973594 return ResultConvention::Indirect;
35983595 }
35993596
3600- // Explicitly setting the ownership of the returned FRT if the C++ member
3601- // method has either swift_attr("returns_retained") or
3602- // ("returns_unretained") attribute.
36033597 if (auto resultConventionOpt =
3604- getForeignReferenceTypeResultConventionWithAttributes (resultTL, TheDecl))
3598+ getCxxRefConventionWithAttrs (resultTL, TheDecl))
36053599 return *resultConventionOpt;
36063600
36073601 if (TheDecl->hasAttr <clang::CFReturnsRetainedAttr>() &&
0 commit comments