Skip to content

Commit d38271c

Browse files
authored
Merge pull request #62764 from apple/egorzhdan/cxx-op-witness
[cxx-interop] Allow instantiated operator methods to serve as protocol conformance witnesses
2 parents cebc00e + 745d92d commit d38271c

File tree

5 files changed

+50
-9
lines changed

5 files changed

+50
-9
lines changed

lib/ClangImporter/ClangImporter.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4021,6 +4021,30 @@ SwiftLookupTable *ClangImporter::Implementation::findLookupTable(
40214021
return known->second.get();
40224022
}
40234023

4024+
SwiftLookupTable *
4025+
ClangImporter::Implementation::findLookupTable(const clang::Decl *decl) {
4026+
// Contents of a C++ namespace are added to the __ObjC module.
4027+
bool isWithinNamespace = false;
4028+
auto declContext = decl->getDeclContext();
4029+
while (!declContext->isTranslationUnit()) {
4030+
if (declContext->isNamespace()) {
4031+
isWithinNamespace = true;
4032+
break;
4033+
}
4034+
declContext = declContext->getParent();
4035+
}
4036+
4037+
clang::Module *owningModule = nullptr;
4038+
if (!isWithinNamespace) {
4039+
// Members of class template specializations don't have an owning module.
4040+
if (auto spec = dyn_cast<clang::ClassTemplateSpecializationDecl>(decl))
4041+
owningModule = spec->getSpecializedTemplate()->getOwningModule();
4042+
else
4043+
owningModule = decl->getOwningModule();
4044+
}
4045+
return findLookupTable(owningModule);
4046+
}
4047+
40244048
bool ClangImporter::Implementation::forEachLookupTable(
40254049
llvm::function_ref<bool(SwiftLookupTable &table)> fn) {
40264050
// Visit the bridging header's lookup table.

lib/ClangImporter/ImportDecl.cpp

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2118,15 +2118,7 @@ namespace {
21182118
if (friendDecl->getFriendDecl()) {
21192119
m = friendDecl->getFriendDecl();
21202120

2121-
// Find the owning module of the class template. Members of class
2122-
// template specializations don't have an owning module.
2123-
clang::Module *owningModule = nullptr;
2124-
if (auto spec = dyn_cast<clang::ClassTemplateSpecializationDecl>(decl))
2125-
owningModule = spec->getSpecializedTemplate()->getOwningModule();
2126-
else
2127-
owningModule = decl->getOwningModule();
2128-
2129-
auto lookupTable = Impl.findLookupTable(owningModule);
2121+
auto lookupTable = Impl.findLookupTable(decl);
21302122
addEntryToLookupTable(*lookupTable, friendDecl->getFriendDecl(),
21312123
Impl.getNameImporter());
21322124
}
@@ -2243,6 +2235,9 @@ namespace {
22432235

22442236
// Make sure the synthesized decl can be found by lookupDirect.
22452237
result->addMemberToLookupTable(opFuncDecl);
2238+
2239+
addEntryToLookupTable(*Impl.findLookupTable(decl), cxxMethod,
2240+
Impl.getNameImporter());
22462241
}
22472242
}
22482243
methods.push_back(MD);

lib/ClangImporter/ImporterImpl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1644,6 +1644,9 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
16441644
/// about the directly-parsed headers.
16451645
SwiftLookupTable *findLookupTable(const clang::Module *clangModule);
16461646

1647+
/// Find the lookup table that should contain the given Clang declaration.
1648+
SwiftLookupTable *findLookupTable(const clang::Decl *decl);
1649+
16471650
/// Visit each of the lookup tables in some deterministic order.
16481651
///
16491652
/// \param fn Invoke the given visitor for each table. If the

test/Interop/Cxx/class/Inputs/protocol-conformance.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,16 @@ struct HasOperatorEqualEqual {
5555
}
5656
};
5757

58+
template <typename T>
59+
struct HasOperatorPlusEqual {
60+
T value;
61+
62+
HasOperatorPlusEqual &operator+=(int x) {
63+
value += x;
64+
return *this;
65+
}
66+
};
67+
68+
using HasOperatorPlusEqualInt = HasOperatorPlusEqual<int>;
69+
5870
#endif // TEST_INTEROP_CXX_CLASS_INPUTS_PROTOCOL_CONFORMANCE_H

test/Interop/Cxx/class/protocol-conformance-typechecker.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,10 @@ protocol Invertable {
3535
extension HasOperatorExclaim: Invertable {}
3636

3737
extension HasOperatorEqualEqual: Equatable {}
38+
39+
40+
protocol HasOperatorPlusEqualProtocol {
41+
static func +=(lhs: inout Self, x: Int32)
42+
}
43+
44+
extension HasOperatorPlusEqualInt : HasOperatorPlusEqualProtocol {}

0 commit comments

Comments
 (0)