Skip to content

Commit 4a3bb30

Browse files
committed
Force the entire inheritance hierarchy to load class members
An unfortunate pessimization that is needed in order to properly build the member table to run override checking. Considering this was happening anyways thanks to re-entrant lookups, there shouldn't actually be a perf hit here.
1 parent af6e9b9 commit 4a3bb30

File tree

2 files changed

+38
-6
lines changed

2 files changed

+38
-6
lines changed

lib/ClangImporter/ClangImporter.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2969,7 +2969,7 @@ void ClangImporter::loadExtensions(NominalTypeDecl *nominal,
29692969
E = objcClass->visible_categories_end();
29702970
I != E; ++I) {
29712971
// Delay installing categories that don't have an owning module.
2972-
if (!I->getOwningModule()) {
2972+
if (!I->hasOwningModule()) {
29732973
DelayedCategories.push_back(*I);
29742974
continue;
29752975
}
@@ -3714,6 +3714,24 @@ void ClangImporter::Implementation::lookupAllObjCMembers(
37143714
}
37153715
}
37163716

3717+
// Force the named member of the entire inheritance hierarchy to be loaded and
3718+
// deserialized before loading the named member of this class. This allows the
3719+
// decl members table to be warmed up and enables the correct identification of
3720+
// overrides.
3721+
static void loadNamedMemberOfSuperclassesIfNeeded(const ClassDecl *CD,
3722+
DeclBaseName name) {
3723+
if (!CD)
3724+
return;
3725+
3726+
while ((CD = CD->getSuperclassDecl())) {
3727+
if (CD->hasClangNode()) {
3728+
auto ci = CD->getASTContext().getOrCreateLazyIterableContextData(
3729+
CD, /*lazyLoader=*/nullptr);
3730+
ci->loader->loadNamedMembers(CD, name, ci->memberData);
3731+
}
3732+
}
3733+
}
3734+
37173735
Optional<TinyPtrVector<ValueDecl *>>
37183736
ClangImporter::Implementation::loadNamedMembers(
37193737
const IterableDeclContext *IDC, DeclBaseName N, uint64_t contextData) {
@@ -3775,6 +3793,8 @@ ClangImporter::Implementation::loadNamedMembers(
37753793

37763794
assert(isa<clang::ObjCContainerDecl>(CD) || isa<clang::NamespaceDecl>(CD));
37773795

3796+
loadNamedMemberOfSuperclassesIfNeeded(dyn_cast<ClassDecl>(D), N);
3797+
37783798
TinyPtrVector<ValueDecl *> Members;
37793799
for (auto entry : table->lookup(SerializedSwiftName(N),
37803800
effectiveClangContext)) {

lib/ClangImporter/ImportDecl.cpp

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5016,12 +5016,10 @@ namespace {
50165016
bool foundMethod = false;
50175017

50185018
if (auto *classDecl = dyn_cast<ClassDecl>(dc)) {
5019-
// If we're importing into the primary @interface for something, as
5020-
// opposed to an extension, make sure we don't try to load any
5021-
// categories...by just looking into the super type.
5019+
// Start looking into the superclass.
50225020
subject = classDecl->getSuperclassDecl();
50235021
}
5024-
5022+
50255023
for (; subject; (subject = subject->getSuperclassDecl())) {
50265024
llvm::SmallVector<ValueDecl *, 8> lookup;
50275025
auto found = Impl.MembersForNominal.find(subject);
@@ -5030,7 +5028,7 @@ namespace {
50305028
namelookup::pruneLookupResultSet(dc, NL_QualifiedDefault, lookup);
50315029
}
50325030

5033-
for (auto &result : lookup) {
5031+
for (auto *&result : lookup) {
50345032
// Skip declarations that don't match the name we're looking for.
50355033
if (result->getBaseName() != name)
50365034
continue;
@@ -8425,6 +8423,19 @@ createUnavailableDecl(Identifier name, DeclContext *dc, Type type,
84258423
return var;
84268424
}
84278425

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+
}
84288439

84298440
void
84308441
ClangImporter::Implementation::loadAllMembers(Decl *D, uint64_t extra) {
@@ -8438,6 +8449,7 @@ ClangImporter::Implementation::loadAllMembers(Decl *D, uint64_t extra) {
84388449

84398450
// If not, we're importing globals-as-members into an extension.
84408451
if (objcContainer) {
8452+
loadAllMembersOfSuperclassesIfNeeded(dyn_cast<ClassDecl>(D));
84418453
loadAllMembersOfObjcContainer(D, objcContainer);
84428454
return;
84438455
}

0 commit comments

Comments
 (0)