@@ -1282,9 +1282,8 @@ static bool canBridgeTypes(ImportTypeKind importKind) {
1282
1282
case ImportTypeKind::Result:
1283
1283
case ImportTypeKind::AuditedResult:
1284
1284
case ImportTypeKind::Parameter:
1285
+ case ImportTypeKind::CompletionHandlerParameter:
1285
1286
case ImportTypeKind::CompletionHandlerResultParameter:
1286
- case ImportTypeKind::CFRetainedOutParameter:
1287
- case ImportTypeKind::CFUnretainedOutParameter:
1288
1287
case ImportTypeKind::Property:
1289
1288
case ImportTypeKind::PropertyWithReferenceSemantics:
1290
1289
case ImportTypeKind::ObjCCollectionElement:
@@ -1310,9 +1309,8 @@ static bool isCFAudited(ImportTypeKind importKind) {
1310
1309
case ImportTypeKind::AuditedVariable:
1311
1310
case ImportTypeKind::AuditedResult:
1312
1311
case ImportTypeKind::Parameter:
1312
+ case ImportTypeKind::CompletionHandlerParameter:
1313
1313
case ImportTypeKind::CompletionHandlerResultParameter:
1314
- case ImportTypeKind::CFRetainedOutParameter:
1315
- case ImportTypeKind::CFUnretainedOutParameter:
1316
1314
case ImportTypeKind::Property:
1317
1315
case ImportTypeKind::PropertyWithReferenceSemantics:
1318
1316
return true ;
@@ -1388,7 +1386,7 @@ static Type maybeImportNSErrorOutParameter(ClangImporter::Implementation &impl,
1388
1386
1389
1387
static Type maybeImportCFOutParameter (ClangImporter::Implementation &impl,
1390
1388
Type importedType,
1391
- ImportTypeKind importKind ) {
1389
+ ImportTypeAttrs attrs ) {
1392
1390
PointerTypeKind PTK;
1393
1391
auto elementType = importedType->getAnyPointerElementType (PTK);
1394
1392
if (!elementType || PTK != PTK_UnsafeMutablePointer)
@@ -1414,7 +1412,7 @@ static Type maybeImportCFOutParameter(ClangImporter::Implementation &impl,
1414
1412
resultTy = OptionalType::get (resultTy);
1415
1413
1416
1414
PointerTypeKind pointerKind;
1417
- if (importKind == ImportTypeKind ::CFRetainedOutParameter)
1415
+ if (attrs. contains (ImportTypeAttr ::CFRetainedOutParameter) )
1418
1416
pointerKind = PTK_UnsafeMutablePointer;
1419
1417
else
1420
1418
pointerKind = PTK_AutoreleasingUnsafeMutablePointer;
@@ -1569,8 +1567,16 @@ static ImportedType adjustTypeForConcreteImport(
1569
1567
break ;
1570
1568
1571
1569
case ImportHint::OtherPointer:
1572
- // Special-case AutoreleasingUnsafeMutablePointer<NSError?> parameters.
1573
- if (importKind == ImportTypeKind::Parameter) {
1570
+ // Remove 'Unmanaged' from audited CF out-parameters.
1571
+ if (attrs.contains (ImportTypeAttr::CFRetainedOutParameter) ||
1572
+ attrs.contains (ImportTypeAttr::CFUnretainedOutParameter)) {
1573
+ if (Type outParamTy =
1574
+ maybeImportCFOutParameter (impl, importedType, attrs)) {
1575
+ importedType = outParamTy;
1576
+ break ;
1577
+ }
1578
+ } else if (importKind == ImportTypeKind::Parameter) {
1579
+ // Special-case AutoreleasingUnsafeMutablePointer<NSError?> parameters.
1574
1580
if (Type result = maybeImportNSErrorOutParameter (impl, importedType,
1575
1581
resugarNSErrorPointer)) {
1576
1582
importedType = result;
@@ -1579,16 +1585,6 @@ static ImportedType adjustTypeForConcreteImport(
1579
1585
}
1580
1586
}
1581
1587
1582
- // Remove 'Unmanaged' from audited CF out-parameters.
1583
- if (importKind == ImportTypeKind::CFRetainedOutParameter ||
1584
- importKind == ImportTypeKind::CFUnretainedOutParameter) {
1585
- if (Type outParamTy = maybeImportCFOutParameter (impl, importedType,
1586
- importKind)) {
1587
- importedType = outParamTy;
1588
- break ;
1589
- }
1590
- }
1591
-
1592
1588
break ;
1593
1589
}
1594
1590
@@ -1637,6 +1633,63 @@ static ImportedType adjustTypeForConcreteImport(
1637
1633
return {importedType, isIUO};
1638
1634
}
1639
1635
1636
+ void swift::findSwiftAttributes (
1637
+ clang::QualType type,
1638
+ llvm::function_ref<void (const clang::SwiftAttrAttr *)> callback) {
1639
+ std::function<clang::QualType (clang::QualType)> skipUnrelatedSugar =
1640
+ [&](clang::QualType type) -> clang::QualType {
1641
+ if (auto *MQT = dyn_cast<clang::MacroQualifiedType>(type))
1642
+ return MQT->isSugared () ? skipUnrelatedSugar (MQT->desugar ()) : type;
1643
+
1644
+ if (auto *ET = dyn_cast<clang::ElaboratedType>(type))
1645
+ return ET->isSugared () ? skipUnrelatedSugar (ET->desugar ()) : type;
1646
+
1647
+ return type;
1648
+ };
1649
+
1650
+ type = skipUnrelatedSugar (type);
1651
+
1652
+ // Consider only immediate attributes, don't look through the typerefs
1653
+ // because they are imported separately.
1654
+ while (const auto *AT = dyn_cast<clang::AttributedType>(type)) {
1655
+ if (auto swiftAttr =
1656
+ dyn_cast_or_null<clang::SwiftAttrAttr>(AT->getAttr ())) {
1657
+ callback (swiftAttr);
1658
+ }
1659
+ type = skipUnrelatedSugar (AT->getEquivalentType ());
1660
+ }
1661
+ }
1662
+
1663
+ void swift::getConcurrencyAttrs (ASTContext &SwiftContext,
1664
+ ImportTypeKind importKind,
1665
+ ImportTypeAttrs &attrs, clang::QualType type) {
1666
+ bool isMainActor = false ;
1667
+ bool isSendable =
1668
+ SwiftContext.LangOpts .hasFeature (Feature::SendableCompletionHandlers) &&
1669
+ importKind == ImportTypeKind::CompletionHandlerParameter;
1670
+ bool isNonSendable = false ;
1671
+
1672
+ // Consider only immediate attributes, don't look through the typerefs
1673
+ // because they are imported separately.
1674
+ findSwiftAttributes (type, [&](const clang::SwiftAttrAttr *attr) {
1675
+ if (isMainActorAttr (attr)) {
1676
+ isMainActor = true ;
1677
+ isNonSendable = importKind == ImportTypeKind::Parameter ||
1678
+ importKind == ImportTypeKind::CompletionHandlerParameter;
1679
+ } else if (attr->getAttribute () == " @Sendable" )
1680
+ isSendable = true ;
1681
+ else if (attr->getAttribute () == " @_nonSendable" )
1682
+ isNonSendable = true ;
1683
+ });
1684
+
1685
+ if (isMainActor)
1686
+ attrs |= ImportTypeAttr::MainActor;
1687
+ if (isSendable)
1688
+ attrs |= ImportTypeAttr::Sendable;
1689
+ if (isNonSendable)
1690
+ attrs -= ImportTypeAttr::Sendable;
1691
+ }
1692
+
1640
1693
ImportedType ClangImporter::Implementation::importType (
1641
1694
clang::QualType type, ImportTypeKind importKind,
1642
1695
llvm::function_ref<void (Diagnostic &&)> addImportDiagnosticFn,
@@ -1683,6 +1736,8 @@ ImportedType ClangImporter::Implementation::importType(
1683
1736
optionality = translateNullability (*nullability, stripNonResultOptionality);
1684
1737
}
1685
1738
1739
+ getConcurrencyAttrs (SwiftContext, importKind, attrs, type);
1740
+
1686
1741
// If this is a completion handler parameter, record the function type whose
1687
1742
// parameters will act as the results of the completion handler.
1688
1743
const clang::FunctionType *completionHandlerType = nullptr ;
@@ -1944,7 +1999,9 @@ class GetSendableType :
1944
1999
VISIT (ModuleType, pass)
1945
2000
VISIT (DynamicSelfType, pass)
1946
2001
1947
- NEVER_VISIT (SubstitutableType)
2002
+ // Ignore attributes placed on generic parameter references and
2003
+ // other substitutable types.
2004
+ VISIT (SubstitutableType, pass)
1948
2005
NEVER_VISIT (DependentMemberType)
1949
2006
1950
2007
Result visitAnyFunctionType (AnyFunctionType *ty) {
@@ -2004,14 +2061,10 @@ class GetSendableType :
2004
2061
2005
2062
} // anonymous namespace
2006
2063
2007
- ImportTypeAttrs swift::getImportTypeAttrs (const clang::Decl *D, bool isParam,
2008
- bool sendableByDefault) {
2064
+ ImportTypeAttrs swift::getImportTypeAttrs (const clang::Decl *D, bool isParam) {
2009
2065
ImportTypeAttrs attrs;
2010
2066
2011
- if (sendableByDefault)
2012
- attrs |= ImportTypeAttr::DefaultsToSendable;
2013
-
2014
- bool sendableRequested = sendableByDefault;
2067
+ bool sendableRequested = false ;
2015
2068
bool sendableDisqualified = false ;
2016
2069
2017
2070
if (D->hasAttrs ()) {
@@ -2022,6 +2075,16 @@ ImportTypeAttrs swift::getImportTypeAttrs(const clang::Decl *D, bool isParam,
2022
2075
continue ;
2023
2076
}
2024
2077
2078
+ if (isa<clang::CFReturnsRetainedAttr>(attr)) {
2079
+ attrs |= ImportTypeAttr::CFRetainedOutParameter;
2080
+ continue ;
2081
+ }
2082
+
2083
+ if (isa<clang::CFReturnsNotRetainedAttr>(attr)) {
2084
+ attrs |= ImportTypeAttr::CFUnretainedOutParameter;
2085
+ continue ;
2086
+ }
2087
+
2025
2088
auto swiftAttr = dyn_cast<clang::SwiftAttrAttr>(attr);
2026
2089
if (!swiftAttr)
2027
2090
continue ;
@@ -2295,17 +2358,6 @@ ImportedType ClangImporter::Implementation::importFunctionParamsAndReturnType(
2295
2358
return {swiftResultTy, importedType.isImplicitlyUnwrapped ()};
2296
2359
}
2297
2360
2298
- static ImportTypeKind
2299
- getImportTypeKindForParam (const clang::ParmVarDecl *param) {
2300
- ImportTypeKind importKind = ImportTypeKind::Parameter;
2301
- if (param->hasAttr <clang::CFReturnsRetainedAttr>())
2302
- importKind = ImportTypeKind::CFRetainedOutParameter;
2303
- else if (param->hasAttr <clang::CFReturnsNotRetainedAttr>())
2304
- importKind = ImportTypeKind::CFUnretainedOutParameter;
2305
-
2306
- return importKind;
2307
- }
2308
-
2309
2361
llvm::Optional<ClangImporter::Implementation::ImportParameterTypeResult>
2310
2362
ClangImporter::Implementation::importParameterType (
2311
2363
const clang::ParmVarDecl *param, OptionalTypeKind optionalityOfParam,
@@ -2318,7 +2370,9 @@ ClangImporter::Implementation::importParameterType(
2318
2370
if (auto elaborated = dyn_cast<clang::ElaboratedType>(paramTy))
2319
2371
paramTy = elaborated->desugar ();
2320
2372
2321
- ImportTypeKind importKind = getImportTypeKindForParam (param);
2373
+ ImportTypeKind importKind = paramIsCompletionHandler
2374
+ ? ImportTypeKind::CompletionHandlerParameter
2375
+ : ImportTypeKind::Parameter;
2322
2376
2323
2377
// Import the parameter type into Swift.
2324
2378
auto attrs = getImportTypeAttrs (param, /* isParam=*/ true );
@@ -2432,12 +2486,6 @@ ClangImporter::Implementation::importParameterType(
2432
2486
}
2433
2487
2434
2488
if (!swiftParamTy) {
2435
- bool sendableByDefault =
2436
- paramIsCompletionHandler &&
2437
- SwiftContext.LangOpts .hasFeature (Feature::SendableCompletionHandlers);
2438
-
2439
- auto attrs = getImportTypeAttrs (param, /* isParam=*/ true , sendableByDefault);
2440
-
2441
2489
// If this is the throws error parameter, we don't need to convert any
2442
2490
// NSError** arguments to the sugared NSErrorPointer typealias form,
2443
2491
// because all that is done with it is retrieving the canonical
@@ -3206,17 +3254,16 @@ ImportedType ClangImporter::Implementation::importMethodParamsAndReturnType(
3206
3254
decomposeCompletionHandlerType (swiftParamTy, *asyncInfo)) {
3207
3255
swiftResultTy = replacedSwiftResultTy;
3208
3256
3209
- ImportTypeKind importKind = getImportTypeKindForParam (param);
3210
-
3211
3257
// Import the original completion handler type without adjustments.
3212
3258
Type origSwiftParamTy =
3213
- importType (paramTy, importKind, paramAddDiag,
3214
- allowNSUIntegerAsIntInParam, Bridgeability::Full,
3215
- ImportTypeAttrs (), optionalityOfParam,
3259
+ importType (paramTy, ImportTypeKind::CompletionHandlerParameter,
3260
+ paramAddDiag, allowNSUIntegerAsIntInParam,
3261
+ Bridgeability::Full, ImportTypeAttrs (),
3262
+ optionalityOfParam,
3216
3263
/* resugarNSErrorPointer=*/ !paramIsError, llvm::None)
3217
3264
.getType ();
3218
- completionHandlerType = mapGenericArgs (origDC, dc, origSwiftParamTy)
3219
- ->getCanonicalType ();
3265
+ completionHandlerType =
3266
+ mapGenericArgs (origDC, dc, origSwiftParamTy) ->getCanonicalType ();
3220
3267
continue ;
3221
3268
}
3222
3269
0 commit comments