Skip to content

Commit e7dfa93

Browse files
committed
[cxx-interop] Import iterator dereference operators
1 parent a00c0b4 commit e7dfa93

File tree

6 files changed

+56
-3
lines changed

6 files changed

+56
-3
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3596,8 +3596,10 @@ namespace {
35963596
auto cxxOperatorKind = cxxMethod->getOverloadedOperator();
35973597

35983598
// 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 &&
3599+
// call / subscript / dereference. Those 3 operators do not need
3600+
// static versions.
3601+
if (!isCXXDereferenceOperator(cxxMethod) &&
3602+
cxxOperatorKind != clang::OverloadedOperatorKind::OO_None &&
36013603
cxxOperatorKind != clang::OverloadedOperatorKind::OO_Call &&
36023604
cxxOperatorKind !=
36033605
clang::OverloadedOperatorKind::OO_Subscript) {
@@ -8872,6 +8874,11 @@ bool importer::isSpecialUIKitStructZeroProperty(const clang::NamedDecl *decl) {
88728874
return ident->isStr("UIEdgeInsetsZero") || ident->isStr("UIOffsetZero");
88738875
}
88748876

8877+
bool importer::isCXXDereferenceOperator(const clang::FunctionDecl *decl) {
8878+
return decl->getOverloadedOperator() == clang::OO_Star &&
8879+
isa<clang::CXXMethodDecl>(decl) && decl->param_empty();
8880+
}
8881+
88758882
bool importer::hasSameUnderlyingType(const clang::Type *a,
88768883
const clang::TemplateTypeParmDecl *b) {
88778884
while (a->isPointerType() || a->isReferenceType())

lib/ClangImporter/ImportName.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1838,9 +1838,18 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D,
18381838
return ImportedName();
18391839

18401840
switch (op) {
1841+
case clang::OverloadedOperatorKind::OO_Star: {
1842+
if (isCXXDereferenceOperator(functionDecl)) {
1843+
// This is not an arithmetic operator, and it is handled differently.
1844+
baseName = "dereference";
1845+
isFunction = true;
1846+
break;
1847+
}
1848+
// This is a multiplication operator.
1849+
LLVM_FALLTHROUGH;
1850+
}
18411851
case clang::OverloadedOperatorKind::OO_Plus:
18421852
case clang::OverloadedOperatorKind::OO_Minus:
1843-
case clang::OverloadedOperatorKind::OO_Star:
18441853
case clang::OverloadedOperatorKind::OO_Slash:
18451854
case clang::OverloadedOperatorKind::OO_Percent:
18461855
case clang::OverloadedOperatorKind::OO_Caret:

lib/ClangImporter/ImporterImpl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1771,6 +1771,9 @@ bool shouldSuppressDeclImport(const clang::Decl *decl);
17711771
/// but are now renamed using the swift_name attribute.
17721772
bool isSpecialUIKitStructZeroProperty(const clang::NamedDecl *decl);
17731773

1774+
/// Whether this is a C++ `operator*()`.
1775+
bool isCXXDereferenceOperator(const clang::FunctionDecl *decl);
1776+
17741777
/// \returns true if \p a has the same underlying type as \p b after removing
17751778
/// any pointer/reference specifiers. Note that this does not currently look through
17761779
/// nested types other than pointers or references.

test/Interop/Cxx/operators/Inputs/member-inline.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,4 +274,18 @@ struct DerivedFromReadWriteIntArray : ReadWriteIntArray {};
274274

275275
struct DerivedFromNonTrivialArrayByVal : NonTrivialArrayByVal {};
276276

277+
struct Iterator {
278+
private:
279+
int value = 123;
280+
public:
281+
int &operator*() { return value; }
282+
};
283+
284+
struct ConstIterator {
285+
private:
286+
int value = 234;
287+
public:
288+
const int &operator*() const { return value; }
289+
};
290+
277291
#endif

test/Interop/Cxx/operators/member-inline-module-interface.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,3 +190,11 @@
190190
// CHECK: subscript(x: Int32) -> NonTrivial { get }
191191
// CHECK: mutating func __operatorSubscriptConst(_ x: Int32) -> NonTrivial
192192
// CHECK: }
193+
194+
// CHECK: struct Iterator {
195+
// CHECK: mutating func dereference() -> UnsafeMutablePointer<Int32>
196+
// CHECK: }
197+
198+
// CHECK: struct ConstIterator {
199+
// CHECK: func dereference() -> UnsafePointer<Int32>
200+
// CHECK: }

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,4 +240,16 @@ OperatorsTestSuite.test("PtrToPtr.subscript (inline)") {
240240
// expectEqual(23, arr[0])
241241
//}
242242

243+
OperatorsTestSuite.test("Iterator.dereference") {
244+
var iter = Iterator()
245+
let res = iter.dereference()
246+
expectEqual(123, res.pointee)
247+
}
248+
249+
OperatorsTestSuite.test("ConstIterator.dereference") {
250+
let iter = ConstIterator()
251+
let res = iter.dereference()
252+
expectEqual(234, res.pointee)
253+
}
254+
243255
runAllTests()

0 commit comments

Comments
 (0)