@@ -3593,6 +3593,26 @@ namespace {
35933593 // by changing the name of one. That changed method needs to be added
35943594 // to the lookup table since it cannot be found lazily.
35953595 if (auto cxxMethod = dyn_cast<clang::CXXMethodDecl>(m)) {
3596+ auto cxxOperatorKind = cxxMethod->getOverloadedOperator ();
3597+
3598+ // Check if this method _is_ an overloaded operator but is not a
3599+ // call / subscript. Those 2 operators do not need static versions
3600+ if (cxxOperatorKind != clang::OverloadedOperatorKind::OO_None &&
3601+ cxxOperatorKind != clang::OverloadedOperatorKind::OO_Call &&
3602+ cxxOperatorKind !=
3603+ clang::OverloadedOperatorKind::OO_Subscript) {
3604+
3605+ auto opFuncDecl = makeOperator (MD, cxxMethod);
3606+
3607+ Impl.addAlternateDecl (MD, opFuncDecl);
3608+
3609+ auto msg = " use " + std::string{clang::getOperatorSpelling (cxxOperatorKind)} + " instead" ;
3610+ Impl.markUnavailable (MD,msg);
3611+
3612+ // Make the actual member operator private.
3613+ MD->overwriteAccess (AccessLevel::Private);
3614+ }
3615+
35963616 if (cxxMethod->getDeclName ().isIdentifier ()) {
35973617 auto &mutableFuncPtrs = Impl.cxxMethods [cxxMethod->getName ()].second ;
35983618 if (mutableFuncPtrs.contains (cxxMethod)) {
@@ -4133,11 +4153,6 @@ namespace {
41334153 if (!dc)
41344154 return nullptr ;
41354155
4136- // Support for importing operators is temporarily disabled: rdar://91070109
4137- if (decl->getDeclName ().getNameKind () == clang::DeclarationName::CXXOperatorName &&
4138- decl->getDeclName ().getCXXOverloadedOperator () != clang::OO_Subscript)
4139- return nullptr ;
4140-
41414156 // Handle cases where 2 CXX methods differ strictly in "constness"
41424157 // In such a case append a suffix ("Mutating") to the mutable version
41434158 // of the method when importing to swift
@@ -4285,16 +4300,7 @@ namespace {
42854300 templateParams);
42864301
42874302 if (auto *mdecl = dyn_cast<clang::CXXMethodDecl>(decl)) {
4288- // Subscripts and call operators are imported as normal methods.
4289- bool staticOperator = mdecl->isOverloadedOperator () &&
4290- mdecl->getOverloadedOperator () != clang::OO_Call &&
4291- mdecl->getOverloadedOperator () != clang::OO_Subscript;
4292- if (mdecl->isStatic () ||
4293- // C++ operators that are implemented as non-static member
4294- // functions get imported into Swift as static member functions
4295- // that use an additional parameter for the left-hand side operand
4296- // instead of the receiver object.
4297- staticOperator) {
4303+ if (mdecl->isStatic ()) {
42984304 selfIdx = None;
42994305 } else {
43004306 // Swift imports the "self" param last, even for clang functions.
@@ -5393,9 +5399,13 @@ namespace {
53935399 // / \param setter function returning `UnsafeMutablePointer<T>`
53945400 // / \return subscript declaration
53955401 SubscriptDecl *makeSubscript (FuncDecl *getter, FuncDecl *setter);
5402+ FuncDecl *makeOperator (FuncDecl *operatorMethod,
5403+ clang::CXXMethodDecl *clangOperator);
5404+
53965405 VarDecl *makeComputedPropertyFromCXXMethods (FuncDecl *getter,
53975406 FuncDecl *setter);
53985407
5408+
53995409 // / Import the accessor and its attributes.
54005410 AccessorDecl *importAccessor (const clang::ObjCMethodDecl *clangAccessor,
54015411 AbstractStorageDecl *storage,
@@ -8080,6 +8090,133 @@ SwiftDeclConverter::makeSubscript(FuncDecl *getter, FuncDecl *setter) {
80808090 return subscript;
80818091}
80828092
8093+ static std::pair<BraceStmt *, bool >
8094+ synthesizeOperatorMethodBody (AbstractFunctionDecl *afd, void *context) {
8095+ ASTContext &ctx = afd->getASTContext ();
8096+
8097+ auto funcDecl = cast<FuncDecl>(afd);
8098+ auto methodDecl =
8099+ static_cast <FuncDecl *>(context); /* Swift version of CXXMethod */
8100+
8101+ SmallVector<Expr *, 8 > forwardingParams;
8102+
8103+ // We start from +1 since the first param is our lhs. All other params are
8104+ // forwarded
8105+ for (auto itr = funcDecl->getParameters ()->begin () + 1 ;
8106+ itr != funcDecl->getParameters ()->end (); itr++) {
8107+ auto param = *itr;
8108+ Expr *paramRefExpr =
8109+ new (ctx) DeclRefExpr (param, DeclNameLoc (), /* Implicit=*/ true );
8110+ paramRefExpr->setType (param->getType ());
8111+
8112+ if (param->isInOut ()) {
8113+ paramRefExpr->setType (LValueType::get (param->getType ()));
8114+
8115+ paramRefExpr = new (ctx) InOutExpr (SourceLoc (), paramRefExpr,
8116+ param->getType (), /* isImplicit*/ true );
8117+ paramRefExpr->setType (InOutType::get (param->getType ()));
8118+ }
8119+
8120+ forwardingParams.push_back (paramRefExpr);
8121+ }
8122+
8123+ auto methodExpr =
8124+ new (ctx) DeclRefExpr (methodDecl, DeclNameLoc (), /* implicit*/ true );
8125+ methodExpr->setType (methodDecl->getInterfaceType ());
8126+
8127+ // Lhs parameter
8128+ auto baseParam = funcDecl->getParameters ()->front ();
8129+ Expr *baseExpr =
8130+ new (ctx) DeclRefExpr (baseParam, DeclNameLoc (), /* implicit*/ true );
8131+ baseExpr->setType (baseParam->getType ());
8132+ if (baseParam->isInOut ()) {
8133+ baseExpr->setType (LValueType::get (baseParam->getType ()));
8134+
8135+ baseExpr = new (ctx) InOutExpr (SourceLoc (), baseExpr, baseParam->getType (),
8136+ /* isImplicit*/ true );
8137+ baseExpr->setType (InOutType::get (baseParam->getType ()));
8138+ }
8139+
8140+ auto dotCallExpr =
8141+ DotSyntaxCallExpr::create (ctx, methodExpr, SourceLoc (), baseExpr);
8142+ dotCallExpr->setType (methodDecl->getMethodInterfaceType ());
8143+ dotCallExpr->setThrows (false );
8144+
8145+ auto *argList = ArgumentList::forImplicitUnlabeled (ctx, forwardingParams);
8146+ auto callExpr = CallExpr::createImplicit (ctx, dotCallExpr, argList);
8147+ callExpr->setType (funcDecl->getResultInterfaceType ());
8148+ callExpr->setThrows (false );
8149+
8150+ auto returnStmt = new (ctx) ReturnStmt (SourceLoc (), callExpr,
8151+ /* implicit=*/ true );
8152+
8153+ auto body = BraceStmt::create (ctx, SourceLoc (), {returnStmt}, SourceLoc (),
8154+ /* implicit=*/ true );
8155+ return {body, /* isTypeChecked=*/ true };
8156+ }
8157+
8158+ FuncDecl *
8159+ SwiftDeclConverter::makeOperator (FuncDecl *operatorMethod,
8160+ clang::CXXMethodDecl *clangOperator) {
8161+ auto &ctx = Impl.SwiftContext ;
8162+ auto opName =
8163+ clang::getOperatorSpelling (clangOperator->getOverloadedOperator ());
8164+ auto paramList = operatorMethod->getParameters ();
8165+ auto genericParamList = operatorMethod->getGenericParams ();
8166+
8167+ auto opId = ctx.getIdentifier (opName);
8168+
8169+ auto parentCtx = operatorMethod->getDeclContext ();
8170+
8171+ auto lhsParam = new (ctx) ParamDecl (
8172+ SourceLoc (),
8173+ SourceLoc (),Identifier (),
8174+ SourceLoc (),ctx.getIdentifier (" lhs" ),
8175+ parentCtx);
8176+
8177+ lhsParam->setInterfaceType (operatorMethod->getDeclContext ()->getSelfInterfaceType ());
8178+
8179+ if (operatorMethod->isMutating ()) {
8180+ // This implicitly makes the parameter indirect.
8181+ lhsParam->setSpecifier (ParamSpecifier::InOut);
8182+ } else {
8183+ lhsParam->setSpecifier (ParamSpecifier::Default);
8184+ }
8185+
8186+ SmallVector<ParamDecl *, 4 > newParams;
8187+ newParams.push_back (lhsParam);
8188+
8189+ for (auto param : *paramList) {
8190+ newParams.push_back (param);
8191+ }
8192+
8193+ auto oldArgNames = operatorMethod->getName ().getArgumentNames ();
8194+ SmallVector<Identifier, 4 > newArgNames;
8195+ newArgNames.push_back (Identifier ());
8196+
8197+ for (auto id : oldArgNames) {
8198+ newArgNames.push_back (id);
8199+ }
8200+
8201+ auto opDeclName = DeclName (
8202+ ctx,opId,
8203+ {newArgNames.begin (), newArgNames.end ()});
8204+
8205+ auto topLevelStaticFuncDecl = FuncDecl::createImplicit (
8206+ ctx, StaticSpellingKind::None, opDeclName, SourceLoc (),
8207+ /* Async*/ false , /* Throws*/ false , genericParamList,
8208+ ParameterList::create (ctx, newParams),
8209+ operatorMethod->getResultInterfaceType (), parentCtx);
8210+
8211+ topLevelStaticFuncDecl->setAccess (AccessLevel::Public);
8212+ topLevelStaticFuncDecl->setIsDynamic (false );
8213+ topLevelStaticFuncDecl->setStatic ();
8214+ topLevelStaticFuncDecl->setBodySynthesizer (synthesizeOperatorMethodBody,
8215+ operatorMethod);
8216+
8217+ return topLevelStaticFuncDecl;
8218+ }
8219+
80838220void SwiftDeclConverter::addProtocols (
80848221 ProtocolDecl *protocol, SmallVectorImpl<ProtocolDecl *> &protocols,
80858222 llvm::SmallPtrSetImpl<ProtocolDecl *> &known) {
0 commit comments