1111// ===----------------------------------------------------------------------===//
1212
1313#include " ClangDerivedConformances.h"
14- #include " swift/AST/NameLookup.h"
1514#include " swift/AST/ParameterList.h"
1615#include " swift/AST/PrettyStackTrace.h"
16+ #include " swift/AST/ProtocolConformance.h"
17+ #include " swift/ClangImporter/ClangImporterRequests.h"
1718
1819using namespace swift ;
1920
21+ // / Alternative to `NominalTypeDecl::lookupDirect`.
22+ // / This function does not attempt to load extensions of the nominal decl.
23+ static TinyPtrVector<ValueDecl *>
24+ lookupDirectWithoutExtensions (NominalTypeDecl *decl, Identifier id) {
25+ // First see if there is a Clang decl with the given name.
26+ TinyPtrVector<ValueDecl *> result = evaluateOrDefault (
27+ decl->getASTContext ().evaluator , ClangRecordMemberLookup ({decl, id}), {});
28+
29+ // Check if there are any synthesized Swift members that match the name.
30+ for (auto member : decl->getMembers ()) {
31+ if (auto namedMember = dyn_cast<ValueDecl>(member)) {
32+ if (namedMember->hasName () && !namedMember->getName ().isSpecial () &&
33+ namedMember->getName ().getBaseIdentifier ().is (id.str ()) &&
34+ // Make sure we don't add duplicate entries, as that would wrongly
35+ // imply that lookup is ambiguous.
36+ !llvm::is_contained (result, namedMember)) {
37+ result.push_back (namedMember);
38+ }
39+ }
40+ }
41+ return result;
42+ }
43+
2044static clang::TypeDecl *
2145getIteratorCategoryDecl (const clang::CXXRecordDecl *clangDecl) {
2246 clang::IdentifierInfo *iteratorCategoryDeclName =
@@ -55,7 +79,7 @@ static ValueDecl *getEqualEqualOperator(NominalTypeDecl *decl) {
5579 };
5680
5781 // First look for `func ==` declared as a member.
58- auto memberResults = decl-> lookupDirect ( id);
82+ auto memberResults = lookupDirectWithoutExtensions (decl, id);
5983 for (const auto &member : memberResults) {
6084 if (isValid (member))
6185 return member;
@@ -131,7 +155,7 @@ void swift::conformToCxxIteratorIfNeeded(
131155
132156 // Check if present: `var pointee: Pointee { get }`
133157 auto pointeeId = ctx.getIdentifier (" pointee" );
134- auto pointees = decl-> lookupDirect ( pointeeId);
158+ auto pointees = lookupDirectWithoutExtensions (decl, pointeeId);
135159 if (pointees.size () != 1 )
136160 return ;
137161 auto pointee = dyn_cast<VarDecl>(pointees.front ());
@@ -140,7 +164,7 @@ void swift::conformToCxxIteratorIfNeeded(
140164
141165 // Check if present: `func successor() -> Self`
142166 auto successorId = ctx.getIdentifier (" successor" );
143- auto successors = decl-> lookupDirect ( successorId);
167+ auto successors = lookupDirectWithoutExtensions (decl, successorId);
144168 if (successors.size () != 1 )
145169 return ;
146170 auto successor = dyn_cast<FuncDecl>(successors.front ());
0 commit comments