@@ -3593,6 +3593,26 @@ namespace {
3593
3593
// by changing the name of one. That changed method needs to be added
3594
3594
// to the lookup table since it cannot be found lazily.
3595
3595
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
+
3596
3616
if (cxxMethod->getDeclName ().isIdentifier ()) {
3597
3617
auto &mutableFuncPtrs = Impl.cxxMethods [cxxMethod->getName ()].second ;
3598
3618
if (mutableFuncPtrs.contains (cxxMethod)) {
@@ -4133,11 +4153,6 @@ namespace {
4133
4153
if (!dc)
4134
4154
return nullptr ;
4135
4155
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
-
4141
4156
// Handle cases where 2 CXX methods differ strictly in "constness"
4142
4157
// In such a case append a suffix ("Mutating") to the mutable version
4143
4158
// of the method when importing to swift
@@ -4285,16 +4300,7 @@ namespace {
4285
4300
templateParams);
4286
4301
4287
4302
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 ()) {
4298
4304
selfIdx = None;
4299
4305
} else {
4300
4306
// Swift imports the "self" param last, even for clang functions.
@@ -5393,9 +5399,13 @@ namespace {
5393
5399
// / \param setter function returning `UnsafeMutablePointer<T>`
5394
5400
// / \return subscript declaration
5395
5401
SubscriptDecl *makeSubscript (FuncDecl *getter, FuncDecl *setter);
5402
+ FuncDecl *makeOperator (FuncDecl *operatorMethod,
5403
+ clang::CXXMethodDecl *clangOperator);
5404
+
5396
5405
VarDecl *makeComputedPropertyFromCXXMethods (FuncDecl *getter,
5397
5406
FuncDecl *setter);
5398
5407
5408
+
5399
5409
// / Import the accessor and its attributes.
5400
5410
AccessorDecl *importAccessor (const clang::ObjCMethodDecl *clangAccessor,
5401
5411
AbstractStorageDecl *storage,
@@ -8080,6 +8090,133 @@ SwiftDeclConverter::makeSubscript(FuncDecl *getter, FuncDecl *setter) {
8080
8090
return subscript;
8081
8091
}
8082
8092
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
+
8083
8220
void SwiftDeclConverter::addProtocols (
8084
8221
ProtocolDecl *protocol, SmallVectorImpl<ProtocolDecl *> &protocols,
8085
8222
llvm::SmallPtrSetImpl<ProtocolDecl *> &known) {
0 commit comments