@@ -2294,53 +2294,6 @@ namespace {
22942294 }
22952295
22962296 if (auto MD = dyn_cast<FuncDecl>(member)) {
2297- if (auto cxxMethod = dyn_cast<clang::CXXMethodDecl>(m)) {
2298- ImportedName methodImportedName =
2299- Impl.importFullName (cxxMethod, getActiveSwiftVersion ());
2300- auto cxxOperatorKind = cxxMethod->getOverloadedOperator ();
2301-
2302- if (cxxOperatorKind == clang::OverloadedOperatorKind::OO_PlusPlus) {
2303- // Make sure the type is not a foreign reference type.
2304- // We cannot handle `operator++` for those types, since the
2305- // current implementation creates a new instance of the type.
2306- if (cxxMethod->param_empty () && !isa<ClassDecl>(result)) {
2307- // This is a pre-increment operator. We synthesize a
2308- // non-mutating function called `successor() -> Self`.
2309- FuncDecl *successorFunc = synthesizer.makeSuccessorFunc (MD);
2310- result->addMember (successorFunc);
2311-
2312- Impl.markUnavailable (MD, " use .successor()" );
2313- } else {
2314- Impl.markUnavailable (MD, " unable to create .successor() func" );
2315- }
2316- MD->overwriteAccess (AccessLevel::Private);
2317- }
2318- // Check if this method _is_ an overloaded operator but is not a
2319- // call / subscript / dereference / increment. Those
2320- // operators do not need static versions.
2321- else if (cxxOperatorKind !=
2322- clang::OverloadedOperatorKind::OO_None &&
2323- cxxOperatorKind !=
2324- clang::OverloadedOperatorKind::OO_PlusPlus &&
2325- cxxOperatorKind !=
2326- clang::OverloadedOperatorKind::OO_Call &&
2327- !methodImportedName.isSubscriptAccessor () &&
2328- !methodImportedName.isDereferenceAccessor ()) {
2329-
2330- auto opFuncDecl = synthesizer.makeOperator (MD, cxxMethod);
2331-
2332- Impl.addAlternateDecl (MD, opFuncDecl);
2333-
2334- auto msg = " use " + std::string{clang::getOperatorSpelling (cxxOperatorKind)} + " instead" ;
2335- Impl.markUnavailable (MD,msg);
2336-
2337- // Make the actual member operator private.
2338- MD->overwriteAccess (AccessLevel::Private);
2339-
2340- // Make sure the synthesized decl can be found by lookupDirect.
2341- result->addMemberToLookupTable (opFuncDecl);
2342- }
2343- }
23442297 methods.push_back (MD);
23452298 continue ;
23462299 }
@@ -3275,12 +3228,19 @@ namespace {
32753228 }
32763229
32773230 // / Handles special functions such as subscripts and dereference operators.
3278- bool processSpecialImportedFunc (FuncDecl *func, ImportedName importedName) {
3231+ bool
3232+ processSpecialImportedFunc (FuncDecl *func, ImportedName importedName,
3233+ clang::OverloadedOperatorKind cxxOperatorKind) {
3234+ if (cxxOperatorKind == clang::OverloadedOperatorKind::OO_None)
3235+ return true ;
3236+
32793237 auto dc = func->getDeclContext ();
3238+ auto typeDecl = dc->getSelfNominalTypeDecl ();
3239+ if (!typeDecl)
3240+ return true ;
32803241
32813242 if (importedName.isSubscriptAccessor ()) {
32823243 assert (func->getParameters ()->size () == 1 );
3283- auto typeDecl = dc->getSelfNominalTypeDecl ();
32843244 auto parameter = func->getParameters ()->get (0 );
32853245 auto parameterType = parameter->getTypeInContext ();
32863246 if (!typeDecl || !parameterType)
@@ -3310,10 +3270,10 @@ namespace {
33103270 }
33113271
33123272 Impl.markUnavailable (func, " use subscript" );
3273+ return true ;
33133274 }
33143275
33153276 if (importedName.isDereferenceAccessor ()) {
3316- auto typeDecl = dc->getSelfNominalTypeDecl ();
33173277 auto &getterAndSetter = Impl.cxxDereferenceOperators [typeDecl];
33183278
33193279 switch (importedName.getAccessorKind ()) {
@@ -3328,6 +3288,42 @@ namespace {
33283288 }
33293289
33303290 Impl.markUnavailable (func, " use .pointee property" );
3291+ return true ;
3292+ }
3293+
3294+ if (cxxOperatorKind == clang::OverloadedOperatorKind::OO_PlusPlus) {
3295+ // Make sure the type is not a foreign reference type.
3296+ // We cannot handle `operator++` for those types, since the
3297+ // current implementation creates a new instance of the type.
3298+ if (func->getParameters ()->size () == 0 && !isa<ClassDecl>(typeDecl)) {
3299+ // This is a pre-increment operator. We synthesize a
3300+ // non-mutating function called `successor() -> Self`.
3301+ FuncDecl *successorFunc = synthesizer.makeSuccessorFunc (func);
3302+ typeDecl->addMember (successorFunc);
3303+
3304+ Impl.markUnavailable (func, " use .successor()" );
3305+ } else {
3306+ Impl.markUnavailable (func, " unable to create .successor() func" );
3307+ }
3308+ func->overwriteAccess (AccessLevel::Private);
3309+ return true ;
3310+ }
3311+
3312+ // Check if this method _is_ an overloaded operator but is not a
3313+ // call / subscript / dereference / increment. Those
3314+ // operators do not need static versions.
3315+ if (cxxOperatorKind != clang::OverloadedOperatorKind::OO_Call) {
3316+ auto opFuncDecl = synthesizer.makeOperator (func, cxxOperatorKind);
3317+ Impl.addAlternateDecl (func, opFuncDecl);
3318+
3319+ Impl.markUnavailable (
3320+ func, (Twine (" use " ) + clang::getOperatorSpelling (cxxOperatorKind) +
3321+ " instead" )
3322+ .str ());
3323+
3324+ // Make sure the synthesized decl can be found by lookupDirect.
3325+ typeDecl->addMemberToLookupTable (opFuncDecl);
3326+ return true ;
33313327 }
33323328
33333329 return true ;
@@ -3656,7 +3652,8 @@ namespace {
36563652 func->setAccess (AccessLevel::Public);
36573653
36583654 if (!importFuncWithoutSignature) {
3659- bool success = processSpecialImportedFunc (func, importedName);
3655+ bool success = processSpecialImportedFunc (
3656+ func, importedName, decl->getOverloadedOperator ());
36603657 if (!success)
36613658 return nullptr ;
36623659 }
@@ -4012,6 +4009,12 @@ namespace {
40124009 if (!importedDC)
40134010 return nullptr ;
40144011
4012+ // While importing the DeclContext, we might have imported the decl
4013+ // itself.
4014+ auto known = Impl.importDeclCached (decl, getVersion ());
4015+ if (known.has_value ())
4016+ return known.value ();
4017+
40154018 if (isa<clang::TypeDecl>(decl->getTargetDecl ())) {
40164019 Decl *SwiftDecl = Impl.importDecl (decl->getUnderlyingDecl (), getActiveSwiftVersion ());
40174020 if (!SwiftDecl)
@@ -4060,7 +4063,8 @@ namespace {
40604063 if (!clonedMethod)
40614064 return nullptr ;
40624065
4063- bool success = processSpecialImportedFunc (clonedMethod, importedName);
4066+ bool success = processSpecialImportedFunc (
4067+ clonedMethod, importedName, targetMethod->getOverloadedOperator ());
40644068 if (!success)
40654069 return nullptr ;
40664070
0 commit comments