@@ -1298,6 +1298,25 @@ class Conventions {
1298
1298
}
1299
1299
llvm_unreachable (" unhandled ownership" );
1300
1300
}
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
+ }
1301
1320
};
1302
1321
1303
1322
// / A visitor for breaking down formal result types into a SILResultInfo
@@ -3341,7 +3360,8 @@ class ObjCMethodConventions : public Conventions {
3341
3360
return ResultConvention::Owned;
3342
3361
3343
3362
if (tl.getLoweredType ().isForeignReferenceType ())
3344
- return ResultConvention::Unowned;
3363
+ return getCxxRefConventionWithAttrs (tl, Method)
3364
+ .value_or (ResultConvention::Unowned);
3345
3365
3346
3366
return ResultConvention::Autoreleased;
3347
3367
}
@@ -3381,25 +3401,6 @@ class CFunctionTypeConventions : public Conventions {
3381
3401
const clang::FunctionType *type)
3382
3402
: Conventions(kind), FnType(type) {}
3383
3403
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
-
3403
3404
public:
3404
3405
CFunctionTypeConventions (const clang::FunctionType *type)
3405
3406
: Conventions(ConventionsKind::CFunctionType), FnType(type) {}
@@ -3517,11 +3518,7 @@ class CFunctionConventions : public CFunctionTypeConventions {
3517
3518
return ResultConvention::Indirect;
3518
3519
}
3519
3520
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))
3525
3522
return *resultConventionOpt;
3526
3523
3527
3524
if (isCFTypedef (tl, TheDecl->getReturnType ())) {
@@ -3603,11 +3600,8 @@ class CXXMethodConventions : public CFunctionTypeConventions {
3603
3600
return ResultConvention::Indirect;
3604
3601
}
3605
3602
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.
3609
3603
if (auto resultConventionOpt =
3610
- getForeignReferenceTypeResultConventionWithAttributes (resultTL, TheDecl))
3604
+ getCxxRefConventionWithAttrs (resultTL, TheDecl))
3611
3605
return *resultConventionOpt;
3612
3606
3613
3607
if (TheDecl->hasAttr <clang::CFReturnsRetainedAttr>() &&
0 commit comments