11
11
// ===----------------------------------------------------------------------===//
12
12
13
13
#include " ClangDerivedConformances.h"
14
- #include " swift/AST/NameLookup.h"
15
14
#include " swift/AST/ParameterList.h"
16
15
#include " swift/AST/PrettyStackTrace.h"
16
+ #include " swift/AST/ProtocolConformance.h"
17
+ #include " swift/ClangImporter/ClangImporterRequests.h"
17
18
18
19
using namespace swift ;
19
20
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
+
20
44
static clang::TypeDecl *
21
45
getIteratorCategoryDecl (const clang::CXXRecordDecl *clangDecl) {
22
46
clang::IdentifierInfo *iteratorCategoryDeclName =
@@ -55,7 +79,7 @@ static ValueDecl *getEqualEqualOperator(NominalTypeDecl *decl) {
55
79
};
56
80
57
81
// First look for `func ==` declared as a member.
58
- auto memberResults = decl-> lookupDirect ( id);
82
+ auto memberResults = lookupDirectWithoutExtensions (decl, id);
59
83
for (const auto &member : memberResults) {
60
84
if (isValid (member))
61
85
return member;
@@ -131,7 +155,7 @@ void swift::conformToCxxIteratorIfNeeded(
131
155
132
156
// Check if present: `var pointee: Pointee { get }`
133
157
auto pointeeId = ctx.getIdentifier (" pointee" );
134
- auto pointees = decl-> lookupDirect ( pointeeId);
158
+ auto pointees = lookupDirectWithoutExtensions (decl, pointeeId);
135
159
if (pointees.size () != 1 )
136
160
return ;
137
161
auto pointee = dyn_cast<VarDecl>(pointees.front ());
@@ -140,7 +164,7 @@ void swift::conformToCxxIteratorIfNeeded(
140
164
141
165
// Check if present: `func successor() -> Self`
142
166
auto successorId = ctx.getIdentifier (" successor" );
143
- auto successors = decl-> lookupDirect ( successorId);
167
+ auto successors = lookupDirectWithoutExtensions (decl, successorId);
144
168
if (successors.size () != 1 )
145
169
return ;
146
170
auto successor = dyn_cast<FuncDecl>(successors.front ());
0 commit comments