@@ -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 ;
@@ -1209,7 +1228,9 @@ NameImporter::considerAsyncImport(
12091228 StringRef baseName,
12101229 SmallVectorImpl<StringRef> ¶mNames,
12111230 ArrayRef<const clang::ParmVarDecl *> params,
1212- bool isInitializer, CustomAsyncName customName,
1231+ bool isInitializer,
1232+ Optional<unsigned > explicitCompletionHandlerParamIndex,
1233+ CustomAsyncName customName,
12131234 Optional<ForeignErrorConvention::Info> errorInfo) {
12141235 // If there are no unclaimed parameters, there's no .
12151236 unsigned errorParamAdjust = errorInfo ? 1 : 0 ;
@@ -1228,43 +1249,50 @@ NameImporter::considerAsyncImport(
12281249 paramNames.size () + errorParamAdjust + customAsyncNameAdjust)
12291250 return None;
12301251
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 ;
12441268
1245- LLVM_FALLTHROUGH;
1269+ LLVM_FALLTHROUGH;
12461270
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+ }
12561280
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 ;
12621286
1263- return None;
1287+ return None;
12641288
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;
12681296 }
12691297
12701298 // Used for returns once we've determined that the method cannot be
@@ -1448,6 +1476,20 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D,
14481476 return ImportedName ();
14491477 result.effectiveContext = effectiveCtx;
14501478
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+
14511493 // FIXME: ugly to check here, instead perform unified check up front in
14521494 // containing struct...
14531495 if (findSwiftNewtype (D, clangSema, version))
@@ -1597,6 +1639,7 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D,
15971639 if (auto asyncInfo = considerAsyncImport (
15981640 method, parsedName.BaseName , parsedName.ArgumentLabels ,
15991641 params, isInitializer,
1642+ completionHandlerParamIndex,
16001643 nameAttr->isAsync ? CustomAsyncName::SwiftAsyncName
16011644 : CustomAsyncName::SwiftName,
16021645 result.getErrorInfo ())) {
@@ -1886,7 +1929,8 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D,
18861929 result.info .accessorKind == ImportedAccessorKind::None) {
18871930 if (auto asyncInfo = considerAsyncImport (
18881931 objcMethod, baseName, argumentNames, params, isInitializer,
1889- CustomAsyncName::None, result.getErrorInfo ())) {
1932+ completionHandlerParamIndex, CustomAsyncName::None,
1933+ result.getErrorInfo ())) {
18901934 result.info .hasAsyncInfo = true ;
18911935 result.info .asyncInfo = *asyncInfo;
18921936 }
@@ -2061,7 +2105,7 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D,
20612105 // If this declaration has the swift_private attribute, prepend "__" to the
20622106 // appropriate place.
20632107 SmallString<16 > swiftPrivateScratch;
2064- if (shouldBeSwiftPrivate (*this , D, version)) {
2108+ if (shouldBeSwiftPrivate (*this , D, version, result. info . hasAsyncInfo )) {
20652109 // Special case: empty arg factory, "for historical reasons", is not private
20662110 if (isInitializer && argumentNames.empty () &&
20672111 (result.getInitKind () == CtorInitializerKind::Factory ||
0 commit comments