@@ -2174,6 +2174,13 @@ namespace {
2174
2174
return getVersion () == getActiveSwiftVersion ();
2175
2175
}
2176
2176
2177
+ template <typename T>
2178
+ T *recordMemberInContext (DeclContext *dc, T *member) {
2179
+ assert (member && " Attempted to record null member!" );
2180
+ Impl.MembersForNominal [dc->getSelfNominalTypeDecl ()].push_back (member);
2181
+ return member;
2182
+ }
2183
+
2177
2184
// / Import the name of the given entity.
2178
2185
// /
2179
2186
// / This version of importFullName introduces any context-specific
@@ -3734,7 +3741,7 @@ namespace {
3734
3741
if (correctSwiftName)
3735
3742
markAsVariant (result, *correctSwiftName);
3736
3743
3737
- return result;
3744
+ return recordMemberInContext (dc, result) ;
3738
3745
}
3739
3746
3740
3747
void finishFuncDecl (const clang::FunctionDecl *decl,
@@ -4344,7 +4351,7 @@ namespace {
4344
4351
}
4345
4352
}
4346
4353
4347
- return result;
4354
+ return recordMemberInContext (dc, result) ;
4348
4355
}
4349
4356
4350
4357
public:
@@ -5002,44 +5009,55 @@ namespace {
5002
5009
return nullptr ;
5003
5010
5004
5011
VarDecl *overridden = nullptr ;
5005
- if (dc-> getSelfClassDecl ()) {
5006
- // Check whether there is a function with the same name as this
5007
- // property. If so, suppress the property; the user will have to use
5008
- // the methods directly, to avoid ambiguities.
5009
- NominalTypeDecl *lookupContext = dc-> getSelfNominalTypeDecl () ;
5012
+ // Check whether there is a function with the same name as this
5013
+ // property. If so, suppress the property; the user will have to use
5014
+ // the methods directly, to avoid ambiguities.
5015
+ if ( auto *subject = dc-> getSelfClassDecl ()) {
5016
+ bool foundMethod = false ;
5010
5017
5011
5018
if (auto *classDecl = dyn_cast<ClassDecl>(dc)) {
5012
- // If we're importing into the primary @interface for something, as
5013
- // opposed to an extension, make sure we don't try to load any
5014
- // categories...by just looking into the super type.
5015
- lookupContext = classDecl->getSuperclassDecl ();
5019
+ // Start looking into the superclass.
5020
+ subject = classDecl->getSuperclassDecl ();
5016
5021
}
5017
5022
5018
- if (lookupContext) {
5019
- SmallVector<ValueDecl *, 2 > lookup;
5020
- dc->lookupQualified (lookupContext, DeclNameRef (name),
5021
- NL_QualifiedDefault | NL_KnownNoDependency,
5022
- lookup);
5023
- bool foundMethod = false ;
5024
- for (auto result : lookup) {
5025
- if (isa<FuncDecl>(result) &&
5026
- result->isInstanceMember () == decl->isInstanceProperty () &&
5027
- result->getFullName ().getArgumentNames ().empty ())
5028
- foundMethod = true ;
5029
-
5030
- if (auto var = dyn_cast<VarDecl>(result)) {
5023
+ for (; subject; (subject = subject->getSuperclassDecl ())) {
5024
+ llvm::SmallVector<ValueDecl *, 8 > lookup;
5025
+ auto found = Impl.MembersForNominal .find (subject);
5026
+ if (found != Impl.MembersForNominal .end ()) {
5027
+ lookup.append (found->second .begin (), found->second .end ());
5028
+ namelookup::pruneLookupResultSet (dc, NL_QualifiedDefault, lookup);
5029
+ }
5030
+
5031
+ for (auto *&result : lookup) {
5032
+ // Skip declarations that don't match the name we're looking for.
5033
+ if (result->getBaseName () != name)
5034
+ continue ;
5035
+
5036
+ if (auto *fd = dyn_cast<FuncDecl>(result)) {
5037
+ if (fd->isInstanceMember () != decl->isInstanceProperty ())
5038
+ continue ;
5039
+
5040
+ if (fd->getFullName ().getArgumentNames ().empty ()) {
5041
+ foundMethod = true ;
5042
+ }
5043
+ } else {
5044
+ auto *var = cast<VarDecl>(result);
5045
+ if (var->isInstanceMember () != decl->isInstanceProperty ())
5046
+ continue ;
5047
+
5031
5048
// If the selectors of the getter match in Objective-C, we have an
5032
5049
// override.
5033
- if (var->isInstanceMember () == decl->isInstanceProperty () &&
5034
- var->getObjCGetterSelector () ==
5035
- Impl.importSelector (decl->getGetterName ()))
5050
+ if (var->getObjCGetterSelector () ==
5051
+ Impl.importSelector (decl->getGetterName ())) {
5036
5052
overridden = var;
5053
+ }
5037
5054
}
5038
5055
}
5039
- if (foundMethod && !overridden)
5040
- return nullptr ;
5041
5056
}
5042
5057
5058
+ if (foundMethod && !overridden)
5059
+ return nullptr ;
5060
+
5043
5061
if (overridden) {
5044
5062
const DeclContext *overrideContext = overridden->getDeclContext ();
5045
5063
// It's okay to compare interface types directly because Objective-C
@@ -5130,7 +5148,7 @@ namespace {
5130
5148
if (correctSwiftName)
5131
5149
markAsVariant (result, *correctSwiftName);
5132
5150
5133
- return result;
5151
+ return recordMemberInContext (dc, result) ;
5134
5152
}
5135
5153
5136
5154
Decl *
@@ -8405,6 +8423,19 @@ createUnavailableDecl(Identifier name, DeclContext *dc, Type type,
8405
8423
return var;
8406
8424
}
8407
8425
8426
+ // Force the members of the entire inheritance hierarchy to be loaded and
8427
+ // deserialized before loading the members of this class. This allows the
8428
+ // decl members table to be warmed up and enables the correct identification of
8429
+ // overrides.
8430
+ static void loadAllMembersOfSuperclassesIfNeeded (const ClassDecl *CD) {
8431
+ if (!CD)
8432
+ return ;
8433
+
8434
+ while ((CD = CD->getSuperclassDecl ())) {
8435
+ if (CD->hasClangNode ())
8436
+ CD->loadAllMembers ();
8437
+ }
8438
+ }
8408
8439
8409
8440
void
8410
8441
ClangImporter::Implementation::loadAllMembers (Decl *D, uint64_t extra) {
@@ -8418,6 +8449,7 @@ ClangImporter::Implementation::loadAllMembers(Decl *D, uint64_t extra) {
8418
8449
8419
8450
// If not, we're importing globals-as-members into an extension.
8420
8451
if (objcContainer) {
8452
+ loadAllMembersOfSuperclassesIfNeeded (dyn_cast<ClassDecl>(D));
8421
8453
loadAllMembersOfObjcContainer (D, objcContainer);
8422
8454
return ;
8423
8455
}
0 commit comments