@@ -2149,45 +2149,46 @@ namespace {
21492149 }
21502150 };
21512151
2152- // / Search the member tables for this class and its superclasses and try to identify the nearest VarDecl
2153- // / that serves as a base for an override. We have to do this ourselves because Objective-C has no
2154- // / semantic notion of overrides, and freely allows users to refine the type of any member property in a
2155- // / derived class.
2152+ // / Search the member tables for this class and its superclasses and try to
2153+ // / identify the nearest VarDecl that serves as a base for an override. We
2154+ // / have to do this ourselves because Objective-C has no semantic notion of
2155+ // / overrides, and freely allows users to refine the type of any member
2156+ // / property in a derived class.
21562157 // /
2157- // / The override must be the nearest possible one so there are not breaks in the override chain. That is,
2158- // / suppose C refines B refines A and each successively redeclares a member with a different type. It
2159- // / should be the case that the nearest override from C is B and from B is A. If the override point from
2160- // / C were A, then B would record an override on A as well and we would introduce a semantic ambiguity.
2158+ // / The override must be the nearest possible one so there are not breaks
2159+ // / in the override chain. That is, suppose C refines B refines A and each
2160+ // / successively redeclares a member with a different type. It should be
2161+ // / the case that the nearest override from C is B and from B is A. If the
2162+ // / override point from C were A, then B would record an override on A as
2163+ // / well and we would introduce a semantic ambiguity.
21612164 // /
2162- // / There is also a special case for finding a method that stomps over a getter. If this is the case and no
2163- // / override point is identified, we will not import the property to force users to explicitly call the method.
2165+ // / There is also a special case for finding a method that stomps over a
2166+ // / getter. If this is the case and no override point is identified, we will
2167+ // / not import the property to force users to explicitly call the method.
21642168 static std::pair<VarDecl *, bool >
2165- identifyNearestOverridenDecl (ClangImporter::Implementation &Impl,
2166- DeclContext *dc,
2167- const clang::ObjCPropertyDecl *decl,
2168- Identifier name,
2169- ClassDecl *subject) {
2169+ identifyNearestOverriddenDecl (ClangImporter::Implementation &Impl,
2170+ DeclContext *dc,
2171+ const clang::ObjCPropertyDecl *decl,
2172+ Identifier name,
2173+ ClassDecl *subject) {
21702174 bool foundMethod = false ;
21712175 for (; subject; (subject = subject->getSuperclassDecl ())) {
21722176 llvm::SmallVector<ValueDecl *, 8 > lookup;
2173- auto found = Impl.MembersForNominal .find (subject);
2174- if (found != Impl.MembersForNominal .end ()) {
2175- lookup.append (found->second .begin (), found->second .end ());
2176- namelookup::pruneLookupResultSet (dc, NL_QualifiedDefault, lookup);
2177+ auto foundNames = Impl.MembersForNominal .find (subject);
2178+ if (foundNames != Impl.MembersForNominal .end ()) {
2179+ auto foundDecls = foundNames->second .find (name);
2180+ if (foundDecls != foundNames->second .end ()) {
2181+ lookup.append (foundDecls->second .begin (), foundDecls->second .end ());
2182+ }
21772183 }
21782184
21792185 for (auto *&result : lookup) {
2180- // Skip declarations that don't match the name we're looking for.
2181- if (result->getBaseName () != name)
2182- continue ;
2183-
21842186 if (auto *fd = dyn_cast<FuncDecl>(result)) {
21852187 if (fd->isInstanceMember () != decl->isInstanceProperty ())
21862188 continue ;
21872189
2188- if (fd->getFullName ().getArgumentNames ().empty ()) {
2189- foundMethod = true ;
2190- }
2190+ assert (fd->getFullName ().getArgumentNames ().empty ());
2191+ foundMethod = true ;
21912192 } else {
21922193 auto *var = cast<VarDecl>(result);
21932194 if (var->isInstanceMember () != decl->isInstanceProperty ())
@@ -2231,11 +2232,11 @@ namespace {
22312232 return getVersion () == getActiveSwiftVersion ();
22322233 }
22332234
2234- template <typename T>
2235- T *recordMemberInContext (DeclContext *dc, T *member) {
2235+ void recordMemberInContext (DeclContext *dc, ValueDecl *member) {
22362236 assert (member && " Attempted to record null member!" );
2237- Impl.MembersForNominal [dc->getSelfNominalTypeDecl ()].push_back (member);
2238- return member;
2237+ auto *nominal = dc->getSelfNominalTypeDecl ();
2238+ auto name = member->getBaseName ();
2239+ Impl.MembersForNominal [nominal][name].push_back (member);
22392240 }
22402241
22412242 // / Import the name of the given entity.
@@ -3798,7 +3799,7 @@ namespace {
37983799 if (correctSwiftName)
37993800 markAsVariant (result, *correctSwiftName);
38003801
3801- return recordMemberInContext (dc, result) ;
3802+ return result;
38023803 }
38033804
38043805 void finishFuncDecl (const clang::FunctionDecl *decl,
@@ -4408,7 +4409,14 @@ namespace {
44084409 }
44094410 }
44104411
4411- return recordMemberInContext (dc, result);
4412+ // We only care about recording methods with no arguments here, because
4413+ // they can shadow imported properties.
4414+ if (!isa<AccessorDecl>(result) &&
4415+ result->getFullName ().getArgumentNames ().empty ()) {
4416+ recordMemberInContext (dc, result);
4417+ }
4418+
4419+ return result;
44124420 }
44134421
44144422 public:
@@ -5070,7 +5078,7 @@ namespace {
50705078
50715079 bool foundMethod = false ;
50725080 std::tie (overridden, foundMethod)
5073- = identifyNearestOverridenDecl (Impl, dc, decl, name, subject);
5081+ = identifyNearestOverriddenDecl (Impl, dc, decl, name, subject);
50745082
50755083 if (foundMethod && !overridden)
50765084 return nullptr ;
@@ -5165,7 +5173,8 @@ namespace {
51655173 if (correctSwiftName)
51665174 markAsVariant (result, *correctSwiftName);
51675175
5168- return recordMemberInContext (dc, result);
5176+ recordMemberInContext (dc, result);
5177+ return result;
51695178 }
51705179
51715180 Decl *
0 commit comments