@@ -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 ;
@@ -1209,7 +1228,9 @@ NameImporter::considerAsyncImport(
1209
1228
StringRef baseName,
1210
1229
SmallVectorImpl<StringRef> ¶mNames,
1211
1230
ArrayRef<const clang::ParmVarDecl *> params,
1212
- bool isInitializer, CustomAsyncName customName,
1231
+ bool isInitializer,
1232
+ Optional<unsigned > explicitCompletionHandlerParamIndex,
1233
+ CustomAsyncName customName,
1213
1234
Optional<ForeignErrorConvention::Info> errorInfo) {
1214
1235
// If there are no unclaimed parameters, there's no .
1215
1236
unsigned errorParamAdjust = errorInfo ? 1 : 0 ;
@@ -1228,43 +1249,50 @@ NameImporter::considerAsyncImport(
1228
1249
paramNames.size () + errorParamAdjust + customAsyncNameAdjust)
1229
1250
return None;
1230
1251
1231
- // The last parameter will be the completion handler for an async function.
1232
- unsigned completionHandlerParamIndex = params.size () - 1 ;
1233
- unsigned completionHandlerParamNameIndex = paramNames.size () - 1 ;
1234
-
1235
- // Determine whether the naming indicates that this is a completion
1236
- // handler.
1237
- switch (customName) {
1238
- case CustomAsyncName::None:
1239
- // Check whether the first parameter is the completion handler and the
1240
- // base name has a suitable completion-handler suffix.
1241
- if (completionHandlerParamIndex == 0 &&
1242
- stripWithCompletionHandlerSuffix (baseName))
1243
- break ;
1252
+ // If we don't already know the completion handler parameter index, go
1253
+ // try to figure it out.
1254
+ unsigned completionHandlerParamIndex;
1255
+ unsigned completionHandlerParamNameIndex;
1256
+ if (!explicitCompletionHandlerParamIndex) {
1257
+ // Determine whether the naming indicates that this is a completion
1258
+ // handler.
1259
+ completionHandlerParamIndex = params.size () - 1 ;
1260
+ completionHandlerParamNameIndex = paramNames.size () - 1 ;
1261
+ switch (customName) {
1262
+ case CustomAsyncName::None:
1263
+ // Check whether the first parameter is the completion handler and the
1264
+ // base name has a suitable completion-handler suffix.
1265
+ if (completionHandlerParamIndex == 0 &&
1266
+ stripWithCompletionHandlerSuffix (baseName))
1267
+ break ;
1244
1268
1245
- LLVM_FALLTHROUGH;
1269
+ LLVM_FALLTHROUGH;
1246
1270
1247
- case CustomAsyncName::SwiftName:
1248
- // Check whether the argument label itself has an appropriate name.
1249
- if (isCompletionHandlerParamName (
1250
- paramNames[completionHandlerParamNameIndex]) ||
1251
- (completionHandlerParamNameIndex > 0 &&
1252
- stripWithCompletionHandlerSuffix (
1253
- paramNames[completionHandlerParamNameIndex]))) {
1254
- break ;
1255
- }
1271
+ case CustomAsyncName::SwiftName:
1272
+ // Check whether the argument label itself has an appropriate name.
1273
+ if (isCompletionHandlerParamName (
1274
+ paramNames[completionHandlerParamNameIndex]) ||
1275
+ (completionHandlerParamNameIndex > 0 &&
1276
+ stripWithCompletionHandlerSuffix (
1277
+ paramNames[completionHandlerParamNameIndex]))) {
1278
+ break ;
1279
+ }
1256
1280
1257
- // Check whether the parameter itself has a name that indicates that
1258
- // it is a completion handelr.
1259
- if (isCompletionHandlerParamName (
1260
- params[completionHandlerParamIndex]->getName ()))
1261
- break ;
1281
+ // Check whether the parameter itself has a name that indicates that
1282
+ // it is a completion handelr.
1283
+ if (isCompletionHandlerParamName (
1284
+ params[completionHandlerParamIndex]->getName ()))
1285
+ break ;
1262
1286
1263
- return None;
1287
+ return None;
1264
1288
1265
- case CustomAsyncName::SwiftAsyncName:
1266
- // Having a custom async name implies that this is a completion handler.
1267
- break ;
1289
+ case CustomAsyncName::SwiftAsyncName:
1290
+ // Having a custom async name implies that this is a completion handler.
1291
+ break ;
1292
+ }
1293
+ } else {
1294
+ completionHandlerParamIndex = *explicitCompletionHandlerParamIndex;
1295
+ completionHandlerParamNameIndex = *explicitCompletionHandlerParamIndex;
1268
1296
}
1269
1297
1270
1298
// Used for returns once we've determined that the method cannot be
@@ -1448,6 +1476,20 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D,
1448
1476
return ImportedName ();
1449
1477
result.effectiveContext = effectiveCtx;
1450
1478
1479
+ // Gather information from the swift_async attribute, if there is one.
1480
+ Optional<unsigned > completionHandlerParamIndex;
1481
+ if (version.supportsConcurrency ()) {
1482
+ if (const auto *swiftAsyncAttr = D->getAttr <clang::SwiftAsyncAttr>()) {
1483
+ // If this is swift_async(none), don't import as async at all.
1484
+ if (swiftAsyncAttr->getKind () == clang::SwiftAsyncAttr::None)
1485
+ return ImportedName ();
1486
+
1487
+ // Get the completion handler parameter index, if there is one.
1488
+ completionHandlerParamIndex =
1489
+ swiftAsyncAttr->getCompletionHandlerIndex ().getASTIndex ();
1490
+ }
1491
+ }
1492
+
1451
1493
// FIXME: ugly to check here, instead perform unified check up front in
1452
1494
// containing struct...
1453
1495
if (findSwiftNewtype (D, clangSema, version))
@@ -1597,6 +1639,7 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D,
1597
1639
if (auto asyncInfo = considerAsyncImport (
1598
1640
method, parsedName.BaseName , parsedName.ArgumentLabels ,
1599
1641
params, isInitializer,
1642
+ completionHandlerParamIndex,
1600
1643
nameAttr->isAsync ? CustomAsyncName::SwiftAsyncName
1601
1644
: CustomAsyncName::SwiftName,
1602
1645
result.getErrorInfo ())) {
@@ -1886,7 +1929,8 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D,
1886
1929
result.info .accessorKind == ImportedAccessorKind::None) {
1887
1930
if (auto asyncInfo = considerAsyncImport (
1888
1931
objcMethod, baseName, argumentNames, params, isInitializer,
1889
- CustomAsyncName::None, result.getErrorInfo ())) {
1932
+ completionHandlerParamIndex, CustomAsyncName::None,
1933
+ result.getErrorInfo ())) {
1890
1934
result.info .hasAsyncInfo = true ;
1891
1935
result.info .asyncInfo = *asyncInfo;
1892
1936
}
@@ -2061,7 +2105,7 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D,
2061
2105
// If this declaration has the swift_private attribute, prepend "__" to the
2062
2106
// appropriate place.
2063
2107
SmallString<16 > swiftPrivateScratch;
2064
- if (shouldBeSwiftPrivate (*this , D, version)) {
2108
+ if (shouldBeSwiftPrivate (*this , D, version, result. info . hasAsyncInfo )) {
2065
2109
// Special case: empty arg factory, "for historical reasons", is not private
2066
2110
if (isInitializer && argumentNames.empty () &&
2067
2111
(result.getInitKind () == CtorInitializerKind::Factory ||
0 commit comments