@@ -1041,7 +1041,26 @@ bool NameImporter::hasNamingConflict(const clang::NamedDecl *decl,
1041
1041
1042
1042
static bool shouldBeSwiftPrivate (NameImporter &nameImporter,
1043
1043
const clang::NamedDecl *decl,
1044
- ImportNameVersion version) {
1044
+ ImportNameVersion version,
1045
+ bool isAsyncImport) {
1046
+ // For an async import, check whether there is a swift_async attribute
1047
+ // that specifies whether this should be considered swift_private or not.
1048
+ if (isAsyncImport) {
1049
+ if (auto *asyncAttr = decl->getAttr <clang::SwiftAsyncAttr>()) {
1050
+ switch (asyncAttr->getKind ()) {
1051
+ case clang::SwiftAsyncAttr::None:
1052
+ // Fall through to let us decide based on swift_private.
1053
+ break ;
1054
+
1055
+ case clang::SwiftAsyncAttr::SwiftPrivate:
1056
+ return true ;
1057
+
1058
+ case clang::SwiftAsyncAttr::NotSwiftPrivate:
1059
+ return false ;
1060
+ }
1061
+ }
1062
+ }
1063
+
1045
1064
// Decl with the attribute are obviously private
1046
1065
if (decl->hasAttr <clang::SwiftPrivateAttr>())
1047
1066
return true ;
@@ -1213,7 +1232,9 @@ NameImporter::considerAsyncImport(
1213
1232
StringRef baseName,
1214
1233
SmallVectorImpl<StringRef> ¶mNames,
1215
1234
ArrayRef<const clang::ParmVarDecl *> params,
1216
- bool isInitializer, CustomAsyncName customName,
1235
+ bool isInitializer,
1236
+ Optional<unsigned > explicitCompletionHandlerParamIndex,
1237
+ CustomAsyncName customName,
1217
1238
Optional<ForeignErrorConvention::Info> errorInfo) {
1218
1239
// If there are no unclaimed parameters, there's no .
1219
1240
unsigned errorParamAdjust = errorInfo ? 1 : 0 ;
@@ -1232,43 +1253,50 @@ NameImporter::considerAsyncImport(
1232
1253
paramNames.size () + errorParamAdjust + customAsyncNameAdjust)
1233
1254
return None;
1234
1255
1235
- // The last parameter will be the completion handler for an async function.
1236
- unsigned completionHandlerParamIndex = params.size () - 1 ;
1237
- unsigned completionHandlerParamNameIndex = paramNames.size () - 1 ;
1238
-
1239
- // Determine whether the naming indicates that this is a completion
1240
- // handler.
1241
- switch (customName) {
1242
- case CustomAsyncName::None:
1243
- // Check whether the first parameter is the completion handler and the
1244
- // base name has a suitable completion-handler suffix.
1245
- if (completionHandlerParamIndex == 0 &&
1246
- stripWithCompletionHandlerSuffix (baseName))
1247
- break ;
1256
+ // If we don't already know the completion handler parameter index, go
1257
+ // try to figure it out.
1258
+ unsigned completionHandlerParamIndex;
1259
+ unsigned completionHandlerParamNameIndex;
1260
+ if (!explicitCompletionHandlerParamIndex) {
1261
+ // Determine whether the naming indicates that this is a completion
1262
+ // handler.
1263
+ completionHandlerParamIndex = params.size () - 1 ;
1264
+ completionHandlerParamNameIndex = paramNames.size () - 1 ;
1265
+ switch (customName) {
1266
+ case CustomAsyncName::None:
1267
+ // Check whether the first parameter is the completion handler and the
1268
+ // base name has a suitable completion-handler suffix.
1269
+ if (completionHandlerParamIndex == 0 &&
1270
+ stripWithCompletionHandlerSuffix (baseName))
1271
+ break ;
1248
1272
1249
- LLVM_FALLTHROUGH;
1273
+ LLVM_FALLTHROUGH;
1250
1274
1251
- case CustomAsyncName::SwiftName:
1252
- // Check whether the argument label itself has an appropriate name.
1253
- if (isCompletionHandlerParamName (
1254
- paramNames[completionHandlerParamNameIndex]) ||
1255
- (completionHandlerParamNameIndex > 0 &&
1256
- stripWithCompletionHandlerSuffix (
1257
- paramNames[completionHandlerParamNameIndex]))) {
1258
- break ;
1259
- }
1275
+ case CustomAsyncName::SwiftName:
1276
+ // Check whether the argument label itself has an appropriate name.
1277
+ if (isCompletionHandlerParamName (
1278
+ paramNames[completionHandlerParamNameIndex]) ||
1279
+ (completionHandlerParamNameIndex > 0 &&
1280
+ stripWithCompletionHandlerSuffix (
1281
+ paramNames[completionHandlerParamNameIndex]))) {
1282
+ break ;
1283
+ }
1260
1284
1261
- // Check whether the parameter itself has a name that indicates that
1262
- // it is a completion handelr.
1263
- if (isCompletionHandlerParamName (
1264
- params[completionHandlerParamIndex]->getName ()))
1265
- break ;
1285
+ // Check whether the parameter itself has a name that indicates that
1286
+ // it is a completion handelr.
1287
+ if (isCompletionHandlerParamName (
1288
+ params[completionHandlerParamIndex]->getName ()))
1289
+ break ;
1266
1290
1267
- return None;
1291
+ return None;
1268
1292
1269
- case CustomAsyncName::SwiftAsyncName:
1270
- // Having a custom async name implies that this is a completion handler.
1271
- break ;
1293
+ case CustomAsyncName::SwiftAsyncName:
1294
+ // Having a custom async name implies that this is a completion handler.
1295
+ break ;
1296
+ }
1297
+ } else {
1298
+ completionHandlerParamIndex = *explicitCompletionHandlerParamIndex;
1299
+ completionHandlerParamNameIndex = *explicitCompletionHandlerParamIndex;
1272
1300
}
1273
1301
1274
1302
// Used for returns once we've determined that the method cannot be
@@ -1452,6 +1480,20 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D,
1452
1480
return ImportedName ();
1453
1481
result.effectiveContext = effectiveCtx;
1454
1482
1483
+ // Gather information from the swift_async attribute, if there is one.
1484
+ Optional<unsigned > completionHandlerParamIndex;
1485
+ if (version.supportsConcurrency ()) {
1486
+ if (const auto *swiftAsyncAttr = D->getAttr <clang::SwiftAsyncAttr>()) {
1487
+ // If this is swift_async(none), don't import as async at all.
1488
+ if (swiftAsyncAttr->getKind () == clang::SwiftAsyncAttr::None)
1489
+ return ImportedName ();
1490
+
1491
+ // Get the completion handler parameter index, if there is one.
1492
+ completionHandlerParamIndex =
1493
+ swiftAsyncAttr->getCompletionHandlerIndex ().getASTIndex ();
1494
+ }
1495
+ }
1496
+
1455
1497
// FIXME: ugly to check here, instead perform unified check up front in
1456
1498
// containing struct...
1457
1499
if (findSwiftNewtype (D, clangSema, version))
@@ -1601,6 +1643,7 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D,
1601
1643
if (auto asyncInfo = considerAsyncImport (
1602
1644
method, parsedName.BaseName , parsedName.ArgumentLabels ,
1603
1645
params, isInitializer,
1646
+ completionHandlerParamIndex,
1604
1647
nameAttr->isAsync ? CustomAsyncName::SwiftAsyncName
1605
1648
: CustomAsyncName::SwiftName,
1606
1649
result.getErrorInfo ())) {
@@ -1890,7 +1933,8 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D,
1890
1933
result.info .accessorKind == ImportedAccessorKind::None) {
1891
1934
if (auto asyncInfo = considerAsyncImport (
1892
1935
objcMethod, baseName, argumentNames, params, isInitializer,
1893
- CustomAsyncName::None, result.getErrorInfo ())) {
1936
+ completionHandlerParamIndex, CustomAsyncName::None,
1937
+ result.getErrorInfo ())) {
1894
1938
result.info .hasAsyncInfo = true ;
1895
1939
result.info .asyncInfo = *asyncInfo;
1896
1940
}
@@ -2065,7 +2109,7 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D,
2065
2109
// If this declaration has the swift_private attribute, prepend "__" to the
2066
2110
// appropriate place.
2067
2111
SmallString<16 > swiftPrivateScratch;
2068
- if (shouldBeSwiftPrivate (*this , D, version)) {
2112
+ if (shouldBeSwiftPrivate (*this , D, version, result. info . hasAsyncInfo )) {
2069
2113
// Special case: empty arg factory, "for historical reasons", is not private
2070
2114
if (isInitializer && argumentNames.empty () &&
2071
2115
(result.getInitKind () == CtorInitializerKind::Factory ||
0 commit comments