@@ -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
@@ -3335,7 +3354,8 @@ class ObjCMethodConventions : public Conventions {
3335
3354
return ResultConvention::Owned;
3336
3355
3337
3356
if (tl.getLoweredType ().isForeignReferenceType ())
3338
- return ResultConvention::Unowned;
3357
+ return getCxxRefConventionWithAttrs (tl, Method)
3358
+ .value_or (ResultConvention::Unowned);
3339
3359
3340
3360
return ResultConvention::Autoreleased;
3341
3361
}
@@ -3375,25 +3395,6 @@ class CFunctionTypeConventions : public Conventions {
3375
3395
const clang::FunctionType *type)
3376
3396
: Conventions(kind), FnType(type) {}
3377
3397
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
-
3397
3398
public:
3398
3399
CFunctionTypeConventions (const clang::FunctionType *type)
3399
3400
: Conventions(ConventionsKind::CFunctionType), FnType(type) {}
@@ -3511,11 +3512,7 @@ class CFunctionConventions : public CFunctionTypeConventions {
3511
3512
return ResultConvention::Indirect;
3512
3513
}
3513
3514
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))
3519
3516
return *resultConventionOpt;
3520
3517
3521
3518
if (isCFTypedef (tl, TheDecl->getReturnType ())) {
@@ -3597,11 +3594,8 @@ class CXXMethodConventions : public CFunctionTypeConventions {
3597
3594
return ResultConvention::Indirect;
3598
3595
}
3599
3596
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.
3603
3597
if (auto resultConventionOpt =
3604
- getForeignReferenceTypeResultConventionWithAttributes (resultTL, TheDecl))
3598
+ getCxxRefConventionWithAttrs (resultTL, TheDecl))
3605
3599
return *resultConventionOpt;
3606
3600
3607
3601
if (TheDecl->hasAttr <clang::CFReturnsRetainedAttr>() &&
0 commit comments