@@ -2132,7 +2132,7 @@ static bool isPrintLikeMethod(DeclName name, const DeclContext *dc) {
21322132}
21332133
21342134using MirroredMethodEntry =
2135- std::pair <const clang::ObjCMethodDecl*, ProtocolDecl*>;
2135+ std::tuple <const clang::ObjCMethodDecl*, ProtocolDecl*, bool /* isAsync */ >;
21362136
21372137namespace {
21382138 // / Customized llvm::DenseMapInfo for storing borrowed APSInts.
@@ -7964,19 +7964,14 @@ void SwiftDeclConverter::importMirroredProtocolMembers(
79647964 if (isa<AccessorDecl>(afd))
79657965 return ;
79667966
7967- // Asynch methods are also always imported without async, so don't
7968- // record them here.
7969- if (afd->hasAsync ())
7970- return ;
7971-
79727967 auto objcMethod =
79737968 dyn_cast_or_null<clang::ObjCMethodDecl>(member->getClangDecl ());
79747969 if (!objcMethod)
79757970 return ;
79767971
79777972 // For now, just remember that we saw this method.
79787973 methodsByName[objcMethod->getSelector ()]
7979- .push_back (MirroredMethodEntry{ objcMethod, proto} );
7974+ .push_back (std::make_tuple ( objcMethod, proto, afd-> hasAsync ()) );
79807975 };
79817976
79827977 if (name) {
@@ -8053,18 +8048,20 @@ compareMethodsForMirrorImport(ClangImporter::Implementation &importer,
80538048// / Return true if this method is overridden by any methods in the array.
80548049static bool suppressOverriddenMethods (ClangImporter::Implementation &importer,
80558050 const clang::ObjCMethodDecl *method,
8051+ bool isAsync,
80568052 MutableArrayRef<MirroredMethodEntry> entries) {
80578053 assert (method && " method was already suppressed" );
80588054
80598055 for (auto &entry: entries) {
8060- auto otherMethod = entry. first ;
8056+ auto otherMethod = std::get< 0 >( entry) ;
80618057 if (!otherMethod) continue ;
8058+ if (isAsync != std::get<2 >(entry)) continue ;
80628059
80638060 assert (method != otherMethod && " found same method twice?" );
80648061 switch (compareMethodsForMirrorImport (importer, method, otherMethod)) {
80658062 // If the second method is suppressed, null it out.
80668063 case Suppresses:
8067- entry. first = nullptr ;
8064+ std::get< 0 >( entry) = nullptr ;
80688065 continue ;
80698066
80708067 // If the first method is suppressed, return immediately. We should
@@ -8120,8 +8117,17 @@ void addCompletionHandlerAttribute(Decl *asyncImport,
81208117void SwiftDeclConverter::importNonOverriddenMirroredMethods (DeclContext *dc,
81218118 MutableArrayRef<MirroredMethodEntry> entries,
81228119 SmallVectorImpl<Decl *> &members) {
8120+ // Keep track of the async imports. We'll come back to them.
8121+ llvm::SmallMapVector<const clang::ObjCMethodDecl*, Decl *, 4 > asyncImports;
8122+
8123+ // Keep track of all of the synchronous imports.
8124+ llvm::SmallMapVector<
8125+ const clang::ObjCMethodDecl*, llvm::TinyPtrVector<Decl *>, 4 >
8126+ syncImports;
8127+
81238128 for (size_t i = 0 , e = entries.size (); i != e; ++i) {
8124- auto objcMethod = entries[i].first ;
8129+ auto objcMethod = std::get<0 >(entries[i]);
8130+ bool isAsync = std::get<2 >(entries[i]);
81258131
81268132 // If the method was suppressed by a previous method, ignore it.
81278133 if (!objcMethod)
@@ -8131,7 +8137,8 @@ void SwiftDeclConverter::importNonOverriddenMirroredMethods(DeclContext *dc,
81318137 // that it overrides. If it is overridden by any of them, suppress it
81328138 // instead; but there's no need to mark that in the array, just continue
81338139 // on to the next method.
8134- if (suppressOverriddenMethods (Impl, objcMethod, entries.slice (i + 1 )))
8140+ if (suppressOverriddenMethods (
8141+ Impl, objcMethod, isAsync, entries.slice (i + 1 )))
81358142 continue ;
81368143
81378144 // Okay, the method wasn't suppressed, import it.
@@ -8148,9 +8155,11 @@ void SwiftDeclConverter::importNonOverriddenMirroredMethods(DeclContext *dc,
81488155 }
81498156
81508157 // Import the method.
8151- auto proto = entries[i]. second ;
8158+ auto proto = std::get< 1 >( entries[i]) ;
81528159 if (auto imported =
8153- Impl.importMirroredDecl (objcMethod, dc, getVersion (), proto)) {
8160+ Impl.importMirroredDecl (objcMethod, dc,
8161+ getVersion ().withConcurrency (isAsync),
8162+ proto)) {
81548163 size_t start = members.size ();
81558164
81568165 members.push_back (imported);
@@ -8160,21 +8169,22 @@ void SwiftDeclConverter::importNonOverriddenMirroredMethods(DeclContext *dc,
81608169 members.push_back (alternate);
81618170 }
81628171
8163- if (!getVersion ().supportsConcurrency ()) {
8164- auto asyncVersion = getVersion ().withConcurrency (true );
8165- if (auto asyncImport = Impl.importMirroredDecl (
8166- objcMethod, dc, asyncVersion, proto)) {
8167- if (asyncImport != imported) {
8168- addCompletionHandlerAttribute (
8169- asyncImport,
8170- llvm::makeArrayRef (members).drop_front (start),
8171- Impl.SwiftContext );
8172- members.push_back (asyncImport);
8173- }
8174- }
8172+ if (isAsync) {
8173+ asyncImports[objcMethod] = imported;
8174+ } else {
8175+ syncImports[objcMethod] = llvm::TinyPtrVector<Decl *>(
8176+ llvm::makeArrayRef (members).drop_front (start + 1 ));
81758177 }
81768178 }
81778179 }
8180+
8181+ // Write up sync and async versions.
8182+ for (const auto &asyncImport : asyncImports) {
8183+ addCompletionHandlerAttribute (
8184+ asyncImport.second ,
8185+ syncImports[asyncImport.first ],
8186+ Impl.SwiftContext );
8187+ }
81788188}
81798189
81808190void SwiftDeclConverter::importInheritedConstructors (
0 commit comments