diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp index 0bbcc47820825..8ee5a421681b2 100644 --- a/lib/ClangImporter/ImportDecl.cpp +++ b/lib/ClangImporter/ImportDecl.cpp @@ -3727,6 +3727,11 @@ namespace { clang::OverloadedOperatorKind cxxOperatorKind) { if (cxxOperatorKind == clang::OverloadedOperatorKind::OO_None) return true; + // If this operator was renamed via swift_name attribute, the imported + // Swift function already has the specified name. Do not apply any special + // handling to it. + if (importedName.hasCustomName()) + return true; auto dc = func->getDeclContext(); auto typeDecl = dc->getSelfNominalTypeDecl(); diff --git a/test/Interop/Cxx/operators/Inputs/module.modulemap b/test/Interop/Cxx/operators/Inputs/module.modulemap index 5863fbb4abba2..36515f4023af6 100644 --- a/test/Interop/Cxx/operators/Inputs/module.modulemap +++ b/test/Interop/Cxx/operators/Inputs/module.modulemap @@ -17,3 +17,8 @@ module NonMemberOutOfLine { header "non-member-out-of-line.h" requires cplusplus } + +module RenamedOperators { + header "renamed-operators.h" + requires cplusplus +} diff --git a/test/Interop/Cxx/operators/Inputs/renamed-operators.h b/test/Interop/Cxx/operators/Inputs/renamed-operators.h new file mode 100644 index 0000000000000..9a2dc77a37707 --- /dev/null +++ b/test/Interop/Cxx/operators/Inputs/renamed-operators.h @@ -0,0 +1,16 @@ +struct HasRenamedOperatorStar { + int value; + + const int &operator*() const __attribute__((swift_name("dereference()"))) { + return value; + } +}; + +struct HasRenamedOperatorPlusPlus { + int value; + + HasRenamedOperatorPlusPlus &operator++() __attribute__((swift_name("plusPlus()"))) { + value++; + return *this; + } +}; diff --git a/test/Interop/Cxx/operators/renamed-operators-module-interface.swift b/test/Interop/Cxx/operators/renamed-operators-module-interface.swift new file mode 100644 index 0000000000000..3c3dfb44b29eb --- /dev/null +++ b/test/Interop/Cxx/operators/renamed-operators-module-interface.swift @@ -0,0 +1,11 @@ +// RUN: %target-swift-ide-test -print-module -module-to-print=RenamedOperators -I %S/Inputs -source-filename=x -cxx-interoperability-mode=upcoming-swift | %FileCheck %s + +// CHECK: struct HasRenamedOperatorStar { +// CHECK-NOT: prefix static func * (lhs: HasRenamedOperatorStar) +// CHECK: func dereference() -> UnsafePointer +// CHECK: } + +// CHECK: struct HasRenamedOperatorPlusPlus { +// CHECK-NOT: prefix static func ++ (lhs: HasRenamedOperatorPlusPlus) +// CHECK: mutating func plusPlus() -> UnsafeMutablePointer +// CHECK: } diff --git a/test/Interop/Cxx/operators/renamed-operators-typechecker.swift b/test/Interop/Cxx/operators/renamed-operators-typechecker.swift new file mode 100644 index 0000000000000..0b92576e1a2f1 --- /dev/null +++ b/test/Interop/Cxx/operators/renamed-operators-typechecker.swift @@ -0,0 +1,9 @@ +// RUN: %target-typecheck-verify-swift -I %S/Inputs -cxx-interoperability-mode=default + +import RenamedOperators + +let star = HasRenamedOperatorStar(value: 123) +_ = *star // expected-error {{'*' is not a prefix unary operator}} + +let plusPlus = HasRenamedOperatorStar(value: 123) +plusPlus++ // expected-error {{cannot find operator '++' in scope; did you mean '+= 1'?}}