Skip to content

Commit db07ad4

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

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
@@ -860,6 +860,7 @@ void IterableDeclContext::addMember(Decl *member, Decl *hint, bool insertAtHead)
860860
}
861861
}
862862

863+
863864
void IterableDeclContext::addMemberSilently(Decl *member, Decl *hint,
864865
bool insertAtHead) const {
865866
assert(!isa<AccessorDecl>(member) && "Accessors should not be added here");
@@ -1375,4 +1376,4 @@ bool DeclContext::isAlwaysAvailableConformanceContext() const {
13751376
AvailabilityContext::forDeploymentTarget(ctx);
13761377

13771378
return deploymentTarget.isContainedIn(conformanceAvailability);
1378-
}
1379+
}

lib/ClangImporter/ClangImporter.cpp

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
#include "llvm/Support/YAMLParser.h"
7474
#include "llvm/Support/YAMLTraits.h"
7575
#include <algorithm>
76+
#include <string>
7677
#include <memory>
7778

7879
using namespace swift;
@@ -84,6 +85,17 @@ using clang::CompilerInvocation;
8485

8586
#pragma mark Internal data structures
8687

88+
namespace {
89+
static std::string getOperatorNameForToken(std::string OperatorToken) {
90+
#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
91+
if(OperatorToken == Spelling) { \
92+
return #Name; \
93+
};
94+
#include "clang/Basic/OperatorKinds.def"
95+
return "None";
96+
}
97+
}
98+
8799
namespace {
88100
class HeaderImportCallbacks : public clang::PPCallbacks {
89101
ClangImporter::Implementation &Impl;
@@ -3997,25 +4009,47 @@ bool ClangImporter::Implementation::forEachLookupTable(
39974009
bool ClangImporter::Implementation::lookupValue(SwiftLookupTable &table,
39984010
DeclName name,
39994011
VisibleDeclConsumer &consumer) {
4012+
40004013
auto &clangCtx = getClangASTContext();
40014014
auto clangTU = clangCtx.getTranslationUnitDecl();
40024015

40034016
bool declFound = false;
4004-
40054017
// For operators we have to look up static member functions in addition to the
40064018
// top-level function lookup below.
4019+
auto declBaseName = (SwiftContext.LangOpts.EnableCXXInterop && name.isOperator())
4020+
? DeclBaseName(SwiftContext.getIdentifier("__operator" + getOperatorNameForToken(std::string{name.getBaseName().getIdentifier()})))
4021+
: name.getBaseName();
4022+
40074023
if (name.isOperator()) {
4008-
auto declBaseName = SwiftContext.LangOpts.EnableCXXInterop
4009-
? name.getBaseName()
4010-
: DeclBaseName(SwiftContext.getIdentifier("__operatorMinus"));
4011-
for (auto entry : table.lookupMemberOperators( declBaseName)) {
4012-
if (isVisibleClangEntry(entry)) {
4013-
if (auto decl = dyn_cast_or_null<ValueDecl>(
4014-
importDeclReal(entry->getMostRecentDecl(), CurrentVersion))) {
4015-
consumer.foundDecl(decl, DeclVisibilityKind::VisibleAtTopLevel);
4016-
declFound = true;
4024+
for (auto entry : table.lookupMemberOperators(declBaseName)) {
4025+
if (isVisibleClangEntry(entry)) {
4026+
if (auto decl = dyn_cast_or_null<ValueDecl>(
4027+
importDeclReal(entry->getMostRecentDecl(), CurrentVersion))) {
4028+
consumer.foundDecl(decl, DeclVisibilityKind::VisibleAtTopLevel);
4029+
declFound = true;
4030+
for (auto alternate: getAlternateDecls(decl)) {
4031+
if (alternate->getName().matchesRef(name)) {
4032+
consumer.foundDecl(alternate, DeclVisibilityKind::DynamicLookup,
4033+
DynamicLookupInfo::AnyObject);
4034+
}
4035+
}
4036+
}
40174037
}
4018-
}
4038+
}
4039+
for (auto entry : table.lookupMemberOperators(name.getBaseName())) {
4040+
if (isVisibleClangEntry(entry)) {
4041+
if (auto decl = dyn_cast_or_null<ValueDecl>(
4042+
importDeclReal(entry->getMostRecentDecl(), CurrentVersion))) {
4043+
consumer.foundDecl(decl, DeclVisibilityKind::VisibleAtTopLevel);
4044+
declFound = true;
4045+
for (auto alternate : getAlternateDecls(decl)) {
4046+
if (alternate->getName().matchesRef(name)) {
4047+
consumer.foundDecl(alternate, DeclVisibilityKind::DynamicLookup,
4048+
DynamicLookupInfo::AnyObject);
4049+
}
4050+
}
4051+
}
4052+
}
40194053
}
40204054
}
40214055

lib/ClangImporter/ImportDecl.cpp

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

36083608
auto d = makeOperator(MD, cxxMethod);
3609-
result->addMember(d);
3610-
result->addMemberToLookupTable(d);
3611-
3612-
result->addMemberToLookupTable(member);
3613-
3614-
// Make a note that we've imported this method into this context.
3615-
recordMemberInContext(d, result);
3616-
36173609
Impl.addAlternateDecl(MD, d);
36183610

36193611
Impl.markUnavailable(MD, "use - operator");
@@ -8094,8 +8086,17 @@ synthesizeOperatorMethodBody(AbstractFunctionDecl *afd, void *context) {
80948086
// We start from +1 since the first param is our lhs. All other params are forwarded
80958087
for(auto itr = funcDecl->getParameters()->begin() + 1; itr != funcDecl->getParameters()->end(); itr++) {
80968088
auto param = *itr;
8097-
auto paramRefExpr = new (ctx) DeclRefExpr(param, DeclNameLoc(), /*Implicit=*/true);
8089+
Expr *paramRefExpr = new (ctx) DeclRefExpr(param, DeclNameLoc(), /*Implicit=*/true);
80988090
paramRefExpr->setType(param->getType());
8091+
8092+
if (param->isInOut()) {
8093+
paramRefExpr->setType(LValueType::get(param->getType()));
8094+
8095+
paramRefExpr = new (ctx) InOutExpr(
8096+
SourceLoc(), paramRefExpr, param->getType(), /*isImplicit*/ true);
8097+
paramRefExpr->setType(InOutType::get(param->getType()));
8098+
}
8099+
80998100
forwardingParams.push_back(paramRefExpr);
81008101
}
81018102

@@ -8104,8 +8105,15 @@ synthesizeOperatorMethodBody(AbstractFunctionDecl *afd, void *context) {
81048105

81058106
// Lhs parameter
81068107
auto baseParam = funcDecl->getParameters()->front();
8107-
auto baseExpr = new (ctx) DeclRefExpr(baseParam, DeclNameLoc(), /*implicit*/ true);
8108+
Expr *baseExpr = new (ctx) DeclRefExpr(baseParam, DeclNameLoc(), /*implicit*/ true);
81088109
baseExpr->setType(baseParam->getType());
8110+
if (baseParam->isInOut()) {
8111+
baseExpr->setType(LValueType::get(baseParam->getType()));
8112+
8113+
baseExpr = new (ctx) InOutExpr(SourceLoc(), baseExpr, baseParam->getType(), /*isImplicit*/ true);
8114+
baseExpr->setType(InOutType::get(baseParam->getType()));
8115+
}
8116+
81098117
auto dotCallExpr = DotSyntaxCallExpr::create(ctx, methodExpr, SourceLoc(), baseExpr);
81108118
dotCallExpr->setType(methodDecl->getMethodInterfaceType());
81118119
dotCallExpr->setThrows(false);

lib/ClangImporter/ImportName.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1494,14 +1494,14 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D,
14941494
completionHandlerParamIndex =
14951495
swiftAsyncAttr->getCompletionHandlerIndex().getASTIndex();
14961496
}
1497-
1497+
14981498
if (const auto *asyncErrorAttr = D->getAttr<clang::SwiftAsyncErrorAttr>()) {
14991499
switch (auto convention = asyncErrorAttr->getConvention()) {
15001500
// No flag parameter in these cases.
15011501
case clang::SwiftAsyncErrorAttr::NonNullError:
15021502
case clang::SwiftAsyncErrorAttr::None:
15031503
break;
1504-
1504+
15051505
// Get the flag argument index and polarity from the attribute.
15061506
case clang::SwiftAsyncErrorAttr::NonZeroArgument:
15071507
case clang::SwiftAsyncErrorAttr::ZeroArgument:
@@ -1821,7 +1821,7 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D,
18211821
case clang::OverloadedOperatorKind::OO_GreaterEqual:
18221822
case clang::OverloadedOperatorKind::OO_AmpAmp:
18231823
case clang::OverloadedOperatorKind::OO_PipePipe:
1824-
baseName = StringRef{"__operator" + std::string{getOperatorName(op)}};
1824+
baseName = isa<clang::CXXMethodDecl>(functionDecl) ? StringRef{"__operator" + std::string{getOperatorName(op)}} : clang::getOperatorSpelling(op);
18251825
isFunction = true;
18261826
addEmptyArgNamesForClangFunction(functionDecl, argumentNames);
18271827
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
@@ -5,24 +5,21 @@ import MemberInline
55
public func sub(_ lhs: inout LoadableIntWrapper, _ rhs: LoadableIntWrapper) -> LoadableIntWrapper { lhs - rhs }
66

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

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

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

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

2825
// 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
@@ -5,13 +5,15 @@ import MemberOutOfLine
55
public func add(_ lhs: LoadableIntWrapper, _ rhs: LoadableIntWrapper) -> LoadableIntWrapper { lhs + rhs }
66

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

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

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

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

0 commit comments

Comments
 (0)