@@ -2132,7 +2132,7 @@ static bool isPrintLikeMethod(DeclName name, const DeclContext *dc) {
2132
2132
}
2133
2133
2134
2134
using MirroredMethodEntry =
2135
- std::pair <const clang::ObjCMethodDecl*, ProtocolDecl*>;
2135
+ std::tuple <const clang::ObjCMethodDecl*, ProtocolDecl*, bool /* isAsync */ >;
2136
2136
2137
2137
namespace {
2138
2138
// / Customized llvm::DenseMapInfo for storing borrowed APSInts.
@@ -7964,19 +7964,14 @@ void SwiftDeclConverter::importMirroredProtocolMembers(
7964
7964
if (isa<AccessorDecl>(afd))
7965
7965
return ;
7966
7966
7967
- // Asynch methods are also always imported without async, so don't
7968
- // record them here.
7969
- if (afd->hasAsync ())
7970
- return ;
7971
-
7972
7967
auto objcMethod =
7973
7968
dyn_cast_or_null<clang::ObjCMethodDecl>(member->getClangDecl ());
7974
7969
if (!objcMethod)
7975
7970
return ;
7976
7971
7977
7972
// For now, just remember that we saw this method.
7978
7973
methodsByName[objcMethod->getSelector ()]
7979
- .push_back (MirroredMethodEntry{ objcMethod, proto} );
7974
+ .push_back (std::make_tuple ( objcMethod, proto, afd-> hasAsync ()) );
7980
7975
};
7981
7976
7982
7977
if (name) {
@@ -8053,18 +8048,20 @@ compareMethodsForMirrorImport(ClangImporter::Implementation &importer,
8053
8048
// / Return true if this method is overridden by any methods in the array.
8054
8049
static bool suppressOverriddenMethods (ClangImporter::Implementation &importer,
8055
8050
const clang::ObjCMethodDecl *method,
8051
+ bool isAsync,
8056
8052
MutableArrayRef<MirroredMethodEntry> entries) {
8057
8053
assert (method && " method was already suppressed" );
8058
8054
8059
8055
for (auto &entry: entries) {
8060
- auto otherMethod = entry. first ;
8056
+ auto otherMethod = std::get< 0 >( entry) ;
8061
8057
if (!otherMethod) continue ;
8058
+ if (isAsync != std::get<2 >(entry)) continue ;
8062
8059
8063
8060
assert (method != otherMethod && " found same method twice?" );
8064
8061
switch (compareMethodsForMirrorImport (importer, method, otherMethod)) {
8065
8062
// If the second method is suppressed, null it out.
8066
8063
case Suppresses:
8067
- entry. first = nullptr ;
8064
+ std::get< 0 >( entry) = nullptr ;
8068
8065
continue ;
8069
8066
8070
8067
// If the first method is suppressed, return immediately. We should
@@ -8120,8 +8117,17 @@ void addCompletionHandlerAttribute(Decl *asyncImport,
8120
8117
void SwiftDeclConverter::importNonOverriddenMirroredMethods (DeclContext *dc,
8121
8118
MutableArrayRef<MirroredMethodEntry> entries,
8122
8119
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
+
8123
8128
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]);
8125
8131
8126
8132
// If the method was suppressed by a previous method, ignore it.
8127
8133
if (!objcMethod)
@@ -8131,7 +8137,8 @@ void SwiftDeclConverter::importNonOverriddenMirroredMethods(DeclContext *dc,
8131
8137
// that it overrides. If it is overridden by any of them, suppress it
8132
8138
// instead; but there's no need to mark that in the array, just continue
8133
8139
// 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 )))
8135
8142
continue ;
8136
8143
8137
8144
// Okay, the method wasn't suppressed, import it.
@@ -8148,9 +8155,11 @@ void SwiftDeclConverter::importNonOverriddenMirroredMethods(DeclContext *dc,
8148
8155
}
8149
8156
8150
8157
// Import the method.
8151
- auto proto = entries[i]. second ;
8158
+ auto proto = std::get< 1 >( entries[i]) ;
8152
8159
if (auto imported =
8153
- Impl.importMirroredDecl (objcMethod, dc, getVersion (), proto)) {
8160
+ Impl.importMirroredDecl (objcMethod, dc,
8161
+ getVersion ().withConcurrency (isAsync),
8162
+ proto)) {
8154
8163
size_t start = members.size ();
8155
8164
8156
8165
members.push_back (imported);
@@ -8160,21 +8169,22 @@ void SwiftDeclConverter::importNonOverriddenMirroredMethods(DeclContext *dc,
8160
8169
members.push_back (alternate);
8161
8170
}
8162
8171
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 ));
8175
8177
}
8176
8178
}
8177
8179
}
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
+ }
8178
8188
}
8179
8189
8180
8190
void SwiftDeclConverter::importInheritedConstructors (
0 commit comments