Skip to content

Commit 11730e8

Browse files
committed
Remap class operator function names (-/+/*....) to imported operator names __operator(Minus, Plus,...) and fix test cases
1 parent 4267958 commit 11730e8

File tree

10 files changed

+88
-77
lines changed

10 files changed

+88
-77
lines changed

lib/AST/DeclContext.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -870,6 +870,7 @@ void IterableDeclContext::addMember(Decl *member, Decl *hint, bool insertAtHead)
870870
}
871871
}
872872

873+
873874
void IterableDeclContext::addMemberSilently(Decl *member, Decl *hint,
874875
bool insertAtHead) const {
875876
assert(!isa<AccessorDecl>(member) && "Accessors should not be added here");
@@ -1385,4 +1386,4 @@ bool DeclContext::isAlwaysAvailableConformanceContext() const {
13851386
AvailabilityContext::forDeploymentTarget(ctx);
13861387

13871388
return deploymentTarget.isContainedIn(conformanceAvailability);
1388-
}
1389+
}

lib/ClangImporter/ClangImporter.cpp

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
#include "llvm/Support/YAMLTraits.h"
7676
#include "llvm/Support/VirtualFileSystem.h"
7777
#include <algorithm>
78+
#include <string>
7879
#include <memory>
7980

8081
using namespace swift;
@@ -86,6 +87,17 @@ using clang::CompilerInvocation;
8687

8788
#pragma mark Internal data structures
8889

90+
namespace {
91+
static std::string getOperatorNameForToken(std::string OperatorToken) {
92+
#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
93+
if(OperatorToken == Spelling) { \
94+
return #Name; \
95+
};
96+
#include "clang/Basic/OperatorKinds.def"
97+
return "None";
98+
}
99+
}
100+
89101
namespace {
90102
class HeaderImportCallbacks : public clang::PPCallbacks {
91103
ClangImporter::Implementation &Impl;
@@ -4104,25 +4116,47 @@ bool ClangImporter::Implementation::forEachLookupTable(
41044116
bool ClangImporter::Implementation::lookupValue(SwiftLookupTable &table,
41054117
DeclName name,
41064118
VisibleDeclConsumer &consumer) {
4119+
41074120
auto &clangCtx = getClangASTContext();
41084121
auto clangTU = clangCtx.getTranslationUnitDecl();
41094122

41104123
bool declFound = false;
4111-
41124124
// For operators we have to look up static member functions in addition to the
41134125
// top-level function lookup below.
4126+
auto declBaseName = (SwiftContext.LangOpts.EnableCXXInterop && name.isOperator())
4127+
? DeclBaseName(SwiftContext.getIdentifier("__operator" + getOperatorNameForToken(std::string{name.getBaseName().getIdentifier()})))
4128+
: name.getBaseName();
4129+
41144130
if (name.isOperator()) {
4115-
auto declBaseName = SwiftContext.LangOpts.EnableCXXInterop
4116-
? name.getBaseName()
4117-
: DeclBaseName(SwiftContext.getIdentifier("__operatorMinus"));
4118-
for (auto entry : table.lookupMemberOperators( declBaseName)) {
4119-
if (isVisibleClangEntry(entry)) {
4120-
if (auto decl = dyn_cast_or_null<ValueDecl>(
4121-
importDeclReal(entry->getMostRecentDecl(), CurrentVersion))) {
4122-
consumer.foundDecl(decl, DeclVisibilityKind::VisibleAtTopLevel);
4123-
declFound = true;
4131+
for (auto entry : table.lookupMemberOperators(declBaseName)) {
4132+
if (isVisibleClangEntry(entry)) {
4133+
if (auto decl = dyn_cast_or_null<ValueDecl>(
4134+
importDeclReal(entry->getMostRecentDecl(), CurrentVersion))) {
4135+
consumer.foundDecl(decl, DeclVisibilityKind::VisibleAtTopLevel);
4136+
declFound = true;
4137+
for (auto alternate: getAlternateDecls(decl)) {
4138+
if (alternate->getName().matchesRef(name)) {
4139+
consumer.foundDecl(alternate, DeclVisibilityKind::DynamicLookup,
4140+
DynamicLookupInfo::AnyObject);
4141+
}
4142+
}
4143+
}
41244144
}
4125-
}
4145+
}
4146+
for (auto entry : table.lookupMemberOperators(name.getBaseName())) {
4147+
if (isVisibleClangEntry(entry)) {
4148+
if (auto decl = dyn_cast_or_null<ValueDecl>(
4149+
importDeclReal(entry->getMostRecentDecl(), CurrentVersion))) {
4150+
consumer.foundDecl(decl, DeclVisibilityKind::VisibleAtTopLevel);
4151+
declFound = true;
4152+
for (auto alternate : getAlternateDecls(decl)) {
4153+
if (alternate->getName().matchesRef(name)) {
4154+
consumer.foundDecl(alternate, DeclVisibilityKind::DynamicLookup,
4155+
DynamicLookupInfo::AnyObject);
4156+
}
4157+
}
4158+
}
4159+
}
41264160
}
41274161
}
41284162

lib/ClangImporter/ImportDecl.cpp

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3602,14 +3602,6 @@ namespace {
36023602
cxxOperatorKind != clang::OverloadedOperatorKind::OO_Subscript) {
36033603

36043604
auto d = makeOperator(MD, cxxMethod);
3605-
result->addMember(d);
3606-
result->addMemberToLookupTable(d);
3607-
3608-
result->addMemberToLookupTable(member);
3609-
3610-
// Make a note that we've imported this method into this context.
3611-
recordMemberInContext(d, result);
3612-
36133605
Impl.addAlternateDecl(MD, d);
36143606

36153607
Impl.markUnavailable(MD, "use - operator");
@@ -8116,8 +8108,17 @@ synthesizeOperatorMethodBody(AbstractFunctionDecl *afd, void *context) {
81168108
// We start from +1 since the first param is our lhs. All other params are forwarded
81178109
for(auto itr = funcDecl->getParameters()->begin() + 1; itr != funcDecl->getParameters()->end(); itr++) {
81188110
auto param = *itr;
8119-
auto paramRefExpr = new (ctx) DeclRefExpr(param, DeclNameLoc(), /*Implicit=*/true);
8111+
Expr *paramRefExpr = new (ctx) DeclRefExpr(param, DeclNameLoc(), /*Implicit=*/true);
81208112
paramRefExpr->setType(param->getType());
8113+
8114+
if (param->isInOut()) {
8115+
paramRefExpr->setType(LValueType::get(param->getType()));
8116+
8117+
paramRefExpr = new (ctx) InOutExpr(
8118+
SourceLoc(), paramRefExpr, param->getType(), /*isImplicit*/ true);
8119+
paramRefExpr->setType(InOutType::get(param->getType()));
8120+
}
8121+
81218122
forwardingParams.push_back(paramRefExpr);
81228123
}
81238124

@@ -8126,8 +8127,15 @@ synthesizeOperatorMethodBody(AbstractFunctionDecl *afd, void *context) {
81268127

81278128
// Lhs parameter
81288129
auto baseParam = funcDecl->getParameters()->front();
8129-
auto baseExpr = new (ctx) DeclRefExpr(baseParam, DeclNameLoc(), /*implicit*/ true);
8130+
Expr *baseExpr = new (ctx) DeclRefExpr(baseParam, DeclNameLoc(), /*implicit*/ true);
81308131
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(), /*isImplicit*/ true);
8136+
baseExpr->setType(InOutType::get(baseParam->getType()));
8137+
}
8138+
81318139
auto dotCallExpr = DotSyntaxCallExpr::create(ctx, methodExpr, SourceLoc(), baseExpr);
81328140
dotCallExpr->setType(methodDecl->getMethodInterfaceType());
81338141
dotCallExpr->setThrows(false);

lib/ClangImporter/ImportName.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1514,14 +1514,14 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D,
15141514
completionHandlerParamIndex =
15151515
swiftAsyncAttr->getCompletionHandlerIndex().getASTIndex();
15161516
}
1517-
1517+
15181518
if (const auto *asyncErrorAttr = D->getAttr<clang::SwiftAsyncErrorAttr>()) {
15191519
switch (auto convention = asyncErrorAttr->getConvention()) {
15201520
// No flag parameter in these cases.
15211521
case clang::SwiftAsyncErrorAttr::NonNullError:
15221522
case clang::SwiftAsyncErrorAttr::None:
15231523
break;
1524-
1524+
15251525
// Get the flag argument index and polarity from the attribute.
15261526
case clang::SwiftAsyncErrorAttr::NonZeroArgument:
15271527
case clang::SwiftAsyncErrorAttr::ZeroArgument:
@@ -1856,7 +1856,7 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D,
18561856
case clang::OverloadedOperatorKind::OO_GreaterEqual:
18571857
case clang::OverloadedOperatorKind::OO_AmpAmp:
18581858
case clang::OverloadedOperatorKind::OO_PipePipe:
1859-
baseName = StringRef{"__operator" + std::string{getOperatorName(op)}};
1859+
baseName = isa<clang::CXXMethodDecl>(functionDecl) ? StringRef{"__operator" + std::string{getOperatorName(op)}} : clang::getOperatorSpelling(op);
18601860
isFunction = true;
18611861
addEmptyArgNamesForClangFunction(functionDecl, argumentNames);
18621862
break;

test/Interop/Cxx/implementation-only-imports/Inputs/module.modulemap

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,5 @@ module DeclB {
2727
export *
2828
requires cplusplus
2929
}
30+
31+

test/Interop/Cxx/operators/Inputs/class-members.h

Lines changed: 0 additions & 29 deletions
This file was deleted.

test/Interop/Cxx/operators/Inputs/module.modulemap

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,3 @@
1-
module ClassMembers {
2-
header "class-members.h"
3-
requires cplusplus
4-
}
5-
6-
71
module MemberInline {
82
header "member-inline.h"
93
requires cplusplus

test/Interop/Cxx/operators/member-inline-irgen.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ import MemberInline
77

88
public func sub(_ lhs: inout LoadableIntWrapper, _ rhs: LoadableIntWrapper) -> LoadableIntWrapper { lhs - rhs }
99

10-
// CHECK: call [[RES:i32|i64]] [[NAME:@(_ZN18LoadableIntWrappermiES_|"\?\?GLoadableIntWrapper@@QEAA\?AU0@U0@@Z")]](%struct.LoadableIntWrapper* {{%[0-9]+}}, {{i32|\[1 x i32\]|i64|%struct.LoadableIntWrapper\* byval\(.*\) align 4}} {{%[0-9]+}})
11-
// CHECK: define linkonce_odr [[RES]] [[NAME]](%struct.LoadableIntWrapper* nonnull align 4 dereferenceable(4) {{.*}}, {{i32 %.*.coerce|\[1 x i32\] %.*.coerce|i64 %.*.coerce|%struct.LoadableIntWrapper\* byval\(%struct.LoadableIntWrapper\) align 4 %.*}})
10+
// CHECK: call [[RESA:i32|i64]] [[NAMEA:@(_ZN18LoadableIntWrappermiES_|"\?\?GLoadableIntWrapper@@QEAA\?AU0@U0@@Z")]](%struct.LoadableIntWrapper* {{%[0-9]+}}, {{i32|\[1 x i32\]|i64|%struct.LoadableIntWrapper\* byval\(.*\) align 4}} {{%[0-9]+}})
1211

1312
public func call(_ wrapper: inout LoadableIntWrapper, _ arg: Int32) -> Int32 { wrapper(arg) }
1413

@@ -41,9 +40,12 @@ public func index(_ arr: inout ReadWriteIntArray, _ arg: Int32, _ val: Int32) {
4140
public func index(_ arr: inout NonTrivialIntArrayByVal, _ arg: Int32) -> Int32 { arr[arg] }
4241

4342
// CHECK: call [[RES:i32|i64]] [[NAME:@(_ZNK23NonTrivialIntArrayByValixEi|"\?\?ANonTrivialIntArrayByVal@@QEBAAEBHH@Z")]](%struct.NonTrivialIntArrayByVal* {{%[0-9]+}}, {{i32|i64}} {{%[0-9]+}})
43+
4444
// CHECK: define linkonce_odr [[RES]] [[NAME]](%struct.NonTrivialIntArrayByVal* nonnull align 4 dereferenceable(20) {{.*}}, {{i32 %.*|\[1 x i32\] %.*|i64 %.*|%struct.NonTrivialIntArrayByVal\* byval\(%struct.NonTrivialIntArrayByVal\) align 2 %.*}})
4545
// CHECK: [[THIS:%.*]] = load %struct.NonTrivialIntArrayByVal*, %struct.NonTrivialIntArrayByVal**
4646
// CHECK: [[VALUES:%.*]] = getelementptr inbounds %struct.NonTrivialIntArrayByVal, %struct.NonTrivialIntArrayByVal* [[THIS]]
4747
// CHECK: [[VALUE:%.*]] = getelementptr inbounds [5 x {{i32|i64}}], [5 x {{i32|i64}}]* [[VALUES]]
4848
// CHECK: [[VALUE2:%.*]] = load {{i32|i64}}, {{i32|i64}}* [[VALUE]]
4949
// CHECK: ret {{i32|i64}} [[VALUE2]]
50+
51+
// CHECK: define linkonce_odr [[RESA]] [[NAMEA]](%struct.LoadableIntWrapper* nonnull align 4 dereferenceable(4) {{.*}}, {{i32 %.*.coerce|\[1 x i32\] %.*.coerce|i64 %.*.coerce|%struct.LoadableIntWrapper\* byval\(%struct.LoadableIntWrapper\) align 4 %.*}})

test/Interop/Cxx/operators/member-inline-silgen.swift

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,21 @@ import MemberInline
66
public func sub(_ lhs: inout LoadableIntWrapper, _ rhs: LoadableIntWrapper) -> LoadableIntWrapper { lhs - rhs }
77

88
// CHECK: bb0([[SELF:%.*]] : $*LoadableIntWrapper, [[RHS:%.*]] : $LoadableIntWrapper):
9-
9+
// CHECK: [[METATYPE:%.*]] = metatype $@thin LoadableIntWrapper.Type
1010
// CHECK: [[SELFACCESS:%.*]] = begin_access [modify] [static] [[SELF]] : $*LoadableIntWrapper
11-
// CHECK: [[OP:%.*]] = function_ref [[NAME:@(_ZN18LoadableIntWrappermiES_|\?\?GLoadableIntWrapper@@QEAA\?AU0@U0@@Z)]] : $@convention(c) (@inout LoadableIntWrapper, LoadableIntWrapper) -> LoadableIntWrapper
12-
// CHECK: apply [[OP]]([[SELFACCESS]], [[RHS]]) : $@convention(c) (@inout LoadableIntWrapper, LoadableIntWrapper) -> LoadableIntWrapper
11+
// CHECK: [[OP:%.*]] = function_ref @$sSo18LoadableIntWrapperV1soiyA2Bz_ABtFZ : $@convention(method) (@inout LoadableIntWrapper, LoadableIntWrapper, @thin LoadableIntWrapper.Type) -> LoadableIntWrapper
12+
// CHECK: apply [[OP]]([[SELFACCESS]], [[RHS]], [[METATYPE]]) : $@convention(method) (@inout LoadableIntWrapper, LoadableIntWrapper, @thin LoadableIntWrapper.Type) -> LoadableIntWrapper
1313
// CHECK: end_access [[SELFACCESS]] : $*LoadableIntWrapper
1414

15-
// CHECK: sil [clang LoadableIntWrapper."-"] [[NAME]] : $@convention(c) (@inout LoadableIntWrapper, LoadableIntWrapper) -> LoadableIntWrapper
16-
1715
public func exclaim(_ wrapper: inout LoadableBoolWrapper) -> LoadableBoolWrapper { !wrapper }
1816

1917
// CHECK: bb0([[SELF:%.*]] : $*LoadableBoolWrapper):
18+
// CHECK: [[METATYPE:%.*]] = metatype $@thin LoadableBoolWrapper.Type
2019
// CHECK: [[SELFACCESS:%.*]] = begin_access [modify] [static] [[SELF]] : $*LoadableBoolWrapper
21-
// CHECK: [[OP:%.*]] = function_ref [[NAME:@(_ZN19LoadableBoolWrapperntEv|\?\?7LoadableBoolWrapper@@QEAA\?AU0@XZ)]] : $@convention(c) (@inout LoadableBoolWrapper) -> LoadableBoolWrapper
22-
// CHECK: apply [[OP]]([[SELFACCESS]]) : $@convention(c) (@inout LoadableBoolWrapper) -> LoadableBoolWrapper
20+
// CHECK: [[OP:%.*]] = function_ref @$sSo19LoadableBoolWrapperV1noiyA2BzFZ : $@convention(method) (@inout LoadableBoolWrapper, @thin LoadableBoolWrapper.Type) -> LoadableBoolWrapper
21+
// CHECK: apply [[OP]]([[SELFACCESS]], [[METATYPE]]) : $@convention(method) (@inout LoadableBoolWrapper, @thin LoadableBoolWrapper.Type) -> LoadableBoolWrapper
2322
// CHECK: end_access [[SELFACCESS]]
2423

25-
// CHECK: sil [clang LoadableBoolWrapper."!"] [[NAME]] : $@convention(c) (@inout LoadableBoolWrapper) -> LoadableBoolWrapper
26-
2724
public func call(_ wrapper: inout LoadableIntWrapper, _ arg: Int32) -> Int32 { wrapper(arg) }
2825

2926
// CHECK: bb0([[SELF:%.*]] : $*LoadableIntWrapper, [[RHS:%.*]] : $Int32):

test/Interop/Cxx/operators/member-out-of-line-silgen.swift

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@ import MemberOutOfLine
77
public func add(_ lhs: LoadableIntWrapper, _ rhs: LoadableIntWrapper) -> LoadableIntWrapper { lhs + rhs }
88

99
// CHECK-SYSV: bb0([[LHS:%.*]] : $LoadableIntWrapper, [[RHS:%.*]] : $LoadableIntWrapper):
10-
// CHECK-SYSV: [[FUNC:%.*]] = function_ref [[NAME:@_ZNK18LoadableIntWrapperplES_]] : $@convention(c) (@in LoadableIntWrapper, LoadableIntWrapper) -> LoadableIntWrapper
11-
// CHECK-SYSV: apply [[FUNC]]([[ACCESS:%.*]], [[RHS]]) : $@convention(c) (@in LoadableIntWrapper, LoadableIntWrapper) -> LoadableIntWrapper
10+
// CHECK-SYSV: store [[LHS]] to [[STORE_LOC:%.*]] : $*LoadableIntWrapper
11+
// CHECK-SYSV: [[FUNC:%.*]] = function_ref [[NAME:@_ZNK18LoadableIntWrapperplES_]] : $@convention(cxx_method) (LoadableIntWrapper, @in_guaranteed LoadableIntWrapper) -> LoadableIntWrapper
12+
// CHECK-SYSV: apply [[FUNC]]([[ACCESS:%.*]], [[STORE_LOC]]) : $@convention(cxx_method) (LoadableIntWrapper, @in_guaranteed LoadableIntWrapper) -> LoadableIntWrapper
1213

13-
// CHECK-SYSV: sil [clang LoadableIntWrapper."+"] [[NAME]] : $@convention(c) (@in LoadableIntWrapper, LoadableIntWrapper) -> LoadableIntWrapper
14+
// CHECK-SYSV: sil [clang LoadableIntWrapper.__operatorPlus] [[NAME]] : $@convention(cxx_method) (LoadableIntWrapper, @in_guaranteed LoadableIntWrapper) -> LoadableIntWrapper
1415

1516
// CHECK-WIN: bb0([[LHS:%.*]] : $LoadableIntWrapper, [[RHS:%.*]] : $LoadableIntWrapper):
16-
// CHECK-WIN: [[FUNC:%.*]] = function_ref [[NAME:@\?\?HLoadableIntWrapper@@QEBA\?AU0@U0@@Z]] : $@convention(c) (@in LoadableIntWrapper, LoadableIntWrapper) -> LoadableIntWrapper
17-
// CHECK-WIN: apply [[FUNC]]([[ACCESS:%.*]], [[RHS]]) : $@convention(c) (@in LoadableIntWrapper, LoadableIntWrapper) -> LoadableIntWrapper
17+
// CHECK-WIN: store [[LHS]] to [[STORE_LOC:%.*]] : $*LoadableIntWrapper
18+
// CHECK-WIN: [[FUNC:%.*]] = function_ref [[NAME:@\?\?HLoadableIntWrapper@@QEBA\?AU0@U0@@Z]] : $@convention(cxx_method) (LoadableIntWrapper, @in_guaranteed LoadableIntWrapper) -> LoadableIntWrapper
19+
// CHECK-WIN: apply [[FUNC]]([[ACCESS:%.*]], [[STORE_LOC]]) : $@convention(cxx_method) (LoadableIntWrapper, @in_guaranteed LoadableIntWrapper) -> LoadableIntWrapper
1820

19-
// CHECK-WIN: sil [clang LoadableIntWrapper."+"] [[NAME]] : $@convention(c) (@in LoadableIntWrapper, LoadableIntWrapper) -> LoadableIntWrapper
21+
// CHECK-WIN: sil [clang LoadableIntWrapper.__operatorPlus] [[NAME]] : $@convention(cxx_method) (LoadableIntWrapper, @in_guaranteed LoadableIntWrapper) -> LoadableIntWrapper

0 commit comments

Comments
 (0)