@@ -1041,7 +1041,26 @@ bool NameImporter::hasNamingConflict(const clang::NamedDecl *decl,
10411041
10421042static bool shouldBeSwiftPrivate (NameImporter &nameImporter,
10431043 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+
10451064 // Decl with the attribute are obviously private
10461065 if (decl->hasAttr <clang::SwiftPrivateAttr>())
10471066 return true ;
@@ -1213,7 +1232,9 @@ NameImporter::considerAsyncImport(
12131232 StringRef baseName,
12141233 SmallVectorImpl<StringRef> ¶mNames,
12151234 ArrayRef<const clang::ParmVarDecl *> params,
1216- bool isInitializer, CustomAsyncName customName,
1235+ bool isInitializer,
1236+ Optional<unsigned > explicitCompletionHandlerParamIndex,
1237+ CustomAsyncName customName,
12171238 Optional<ForeignErrorConvention::Info> errorInfo) {
12181239 // If there are no unclaimed parameters, there's no .
12191240 unsigned errorParamAdjust = errorInfo ? 1 : 0 ;
@@ -1232,43 +1253,50 @@ NameImporter::considerAsyncImport(
12321253 paramNames.size () + errorParamAdjust + customAsyncNameAdjust)
12331254 return None;
12341255
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 ;
12481272
1249- LLVM_FALLTHROUGH;
1273+ LLVM_FALLTHROUGH;
12501274
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+ }
12601284
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 ;
12661290
1267- return None;
1291+ return None;
12681292
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;
12721300 }
12731301
12741302 // Used for returns once we've determined that the method cannot be
@@ -1452,6 +1480,20 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D,
14521480 return ImportedName ();
14531481 result.effectiveContext = effectiveCtx;
14541482
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+
14551497 // FIXME: ugly to check here, instead perform unified check up front in
14561498 // containing struct...
14571499 if (findSwiftNewtype (D, clangSema, version))
@@ -1601,6 +1643,7 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D,
16011643 if (auto asyncInfo = considerAsyncImport (
16021644 method, parsedName.BaseName , parsedName.ArgumentLabels ,
16031645 params, isInitializer,
1646+ completionHandlerParamIndex,
16041647 nameAttr->isAsync ? CustomAsyncName::SwiftAsyncName
16051648 : CustomAsyncName::SwiftName,
16061649 result.getErrorInfo ())) {
@@ -1890,7 +1933,8 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D,
18901933 result.info .accessorKind == ImportedAccessorKind::None) {
18911934 if (auto asyncInfo = considerAsyncImport (
18921935 objcMethod, baseName, argumentNames, params, isInitializer,
1893- CustomAsyncName::None, result.getErrorInfo ())) {
1936+ completionHandlerParamIndex, CustomAsyncName::None,
1937+ result.getErrorInfo ())) {
18941938 result.info .hasAsyncInfo = true ;
18951939 result.info .asyncInfo = *asyncInfo;
18961940 }
@@ -2065,7 +2109,7 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D,
20652109 // If this declaration has the swift_private attribute, prepend "__" to the
20662110 // appropriate place.
20672111 SmallString<16 > swiftPrivateScratch;
2068- if (shouldBeSwiftPrivate (*this , D, version)) {
2112+ if (shouldBeSwiftPrivate (*this , D, version, result. info . hasAsyncInfo )) {
20692113 // Special case: empty arg factory, "for historical reasons", is not private
20702114 if (isInitializer && argumentNames.empty () &&
20712115 (result.getInitKind () == CtorInitializerKind::Factory ||
0 commit comments