@@ -1252,6 +1252,24 @@ enum class ConventionsKind : uint8_t {
1252
1252
CXXMethod = 8 ,
1253
1253
};
1254
1254
1255
+ template <typename T>
1256
+ std::optional<T>
1257
+ matchSwiftAttr (const clang::Decl *decl,
1258
+ llvm::ArrayRef<std::pair<llvm::StringRef, T>> patterns) {
1259
+ if (!decl || !decl->hasAttrs ())
1260
+ return std::nullopt;
1261
+
1262
+ for (const auto *attr : decl->getAttrs ()) {
1263
+ if (const auto *swiftAttr = llvm::dyn_cast<clang::SwiftAttrAttr>(attr)) {
1264
+ for (const auto &p : patterns) {
1265
+ if (swiftAttr->getAttribute () == p.first )
1266
+ return p.second ;
1267
+ }
1268
+ }
1269
+ }
1270
+ return std::nullopt;
1271
+ }
1272
+
1255
1273
class Conventions {
1256
1274
ConventionsKind kind;
1257
1275
@@ -1353,37 +1371,26 @@ class Conventions {
1353
1371
std::optional<ResultConvention>
1354
1372
getCxxRefConventionWithAttrs (const TypeLowering &tl,
1355
1373
const clang::Decl *decl) const {
1356
- if (tl.getLoweredType ().isForeignReferenceType ()) {
1357
- if (decl->hasAttrs ()) {
1358
- for (const auto *attr : decl->getAttrs ()) {
1359
- if (const auto *swiftAttr = dyn_cast<clang::SwiftAttrAttr>(attr)) {
1360
- if (swiftAttr->getAttribute () == " returns_unretained" ) {
1361
- return ResultConvention::Unowned;
1362
- } else if (swiftAttr->getAttribute () == " returns_retained" ) {
1363
- return ResultConvention::Owned;
1364
- }
1365
- }
1366
- }
1367
- }
1368
- if (auto *classDecl = tl.getLoweredType ()
1369
- .getASTType ()
1370
- .getPointer ()
1371
- ->lookThroughAllOptionalTypes ()
1372
- ->getClassOrBoundGenericClass ()) {
1373
- if (auto clangRecordDecl =
1374
- dyn_cast<clang::RecordDecl>(classDecl->getClangDecl ())) {
1375
- for (const auto *attr : clangRecordDecl->getAttrs ()) {
1376
- if (const auto *swiftAttr = dyn_cast<clang::SwiftAttrAttr>(attr)) {
1377
- if (swiftAttr->getAttribute () ==
1378
- " returns_unretained_by_default" ) {
1379
- return ResultConvention::Unowned;
1380
- } else if (swiftAttr->getAttribute () ==
1381
- " returns_retained_by_default" ) {
1382
- return ResultConvention::Owned;
1383
- }
1384
- }
1385
- }
1386
- }
1374
+ if (!tl.getLoweredType ().isForeignReferenceType ())
1375
+ return std::nullopt;
1376
+
1377
+ if (auto result = matchSwiftAttr<ResultConvention>(
1378
+ decl, {{" returns_unretained" , ResultConvention::Unowned},
1379
+ {" returns_retained" , ResultConvention::Owned}})) {
1380
+ return result;
1381
+ }
1382
+
1383
+ if (auto *classDecl = tl.getLoweredType ()
1384
+ .getASTType ()
1385
+ .getPointer ()
1386
+ ->lookThroughAllOptionalTypes ()
1387
+ ->getClassOrBoundGenericClass ()) {
1388
+ if (auto *clangRecordDecl = llvm::dyn_cast_or_null<clang::RecordDecl>(
1389
+ classDecl->getClangDecl ())) {
1390
+ return matchSwiftAttr<ResultConvention>(
1391
+ clangRecordDecl,
1392
+ {{" returns_unretained_by_default" , ResultConvention::Unowned},
1393
+ {" returns_retained_by_default" , ResultConvention::Owned}});
1387
1394
}
1388
1395
}
1389
1396
return std::nullopt;
0 commit comments