@@ -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
@@ -3340,8 +3359,11 @@ class ObjCMethodConventions : public Conventions {
3340
3359
if (isImplicitPlusOneCFResult ())
3341
3360
return ResultConvention::Owned;
3342
3361
3343
- if (tl.getLoweredType ().isForeignReferenceType ())
3362
+ if (tl.getLoweredType ().isForeignReferenceType ()) {
3363
+ if (auto resultConventionOpt = getCxxRefConventionWithAttrs (tl, Method))
3364
+ return *resultConventionOpt;
3344
3365
return ResultConvention::Unowned;
3366
+ }
3345
3367
3346
3368
return ResultConvention::Autoreleased;
3347
3369
}
@@ -3381,25 +3403,6 @@ class CFunctionTypeConventions : public Conventions {
3381
3403
const clang::FunctionType *type)
3382
3404
: Conventions(kind), FnType(type) {}
3383
3405
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
3406
public:
3404
3407
CFunctionTypeConventions (const clang::FunctionType *type)
3405
3408
: Conventions(ConventionsKind::CFunctionType), FnType(type) {}
@@ -3517,11 +3520,7 @@ class CFunctionConventions : public CFunctionTypeConventions {
3517
3520
return ResultConvention::Indirect;
3518
3521
}
3519
3522
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))
3523
+ if (auto resultConventionOpt = getCxxRefConventionWithAttrs (tl, TheDecl))
3525
3524
return *resultConventionOpt;
3526
3525
3527
3526
if (isCFTypedef (tl, TheDecl->getReturnType ())) {
@@ -3603,11 +3602,8 @@ class CXXMethodConventions : public CFunctionTypeConventions {
3603
3602
return ResultConvention::Indirect;
3604
3603
}
3605
3604
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
3605
if (auto resultConventionOpt =
3610
- getForeignReferenceTypeResultConventionWithAttributes (resultTL, TheDecl))
3606
+ getCxxRefConventionWithAttrs (resultTL, TheDecl))
3611
3607
return *resultConventionOpt;
3612
3608
3613
3609
if (TheDecl->hasAttr <clang::CFReturnsRetainedAttr>() &&
0 commit comments