Skip to content

Commit 7a9bc26

Browse files
committed
[NamedLazyMemberLoading] Handle nominals with mix of added/lazy members.
1 parent c700e2e commit 7a9bc26

File tree

3 files changed

+40
-16
lines changed

3 files changed

+40
-16
lines changed

include/swift/AST/DeclContext.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,12 @@ class IterableDeclContext {
627627
/// Retrieve the \c ASTContext in which this iterable context occurs.
628628
ASTContext &getASTContext() const;
629629

630+
protected:
631+
/// Retrieve the set of members in this context without loading any from the
632+
/// associated lazy loader; this should only be used as part of implementing
633+
/// abstractions on top of member loading, such as a name lookup table.
634+
DeclRange getCurrentMembersWithoutLoading() const;
635+
630636
public:
631637
IterableDeclContext(IterableDeclContextKind kind)
632638
: LastDeclAndKind(nullptr, kind) { }

lib/AST/DeclContext.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -897,10 +897,14 @@ ASTContext &IterableDeclContext::getASTContext() const {
897897
return getDecl()->getASTContext();
898898
}
899899

900+
DeclRange IterableDeclContext::getCurrentMembersWithoutLoading() const {
901+
return DeclRange(FirstDeclAndLazyMembers.getPointer(), nullptr);
902+
}
903+
900904
DeclRange IterableDeclContext::getMembers() const {
901905
loadAllMembers();
902906

903-
return DeclRange(FirstDeclAndLazyMembers.getPointer(), nullptr);
907+
return getCurrentMembersWithoutLoading();
904908
}
905909

906910
/// Add a member to this context.

lib/AST/NameLookup.cpp

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1245,19 +1245,25 @@ void NominalTypeDecl::prepareLookupTable(bool ignoreNewExtensions) {
12451245
LookupTable.setPointer(new (ctx) MemberLookupTable(ctx));
12461246
}
12471247

1248-
// If we're an IDC that has not yet loaded its full member set, we're doing
1249-
// NamedLazyMemberLoading, and we should not force getMembers().
1250-
if (hasLazyMembers())
1251-
return;
1252-
12531248
// If we haven't walked the member list yet to update the lookup
12541249
// table, do so now.
12551250
if (!LookupTable.getInt()) {
12561251
// Note that we'll have walked the members now.
12571252
LookupTable.setInt(true);
12581253

1259-
// Add the members of the nominal declaration to the table.
1260-
LookupTable.getPointer()->addMembers(getMembers());
1254+
// We want to index the part of the member list in memory, but not force
1255+
// loading lazy members if we have them.
1256+
auto members = (hasLazyMembers()
1257+
? getCurrentMembersWithoutLoading()
1258+
: getMembers());
1259+
LookupTable.getPointer()->addMembers(members);
1260+
}
1261+
1262+
// Avoid indexing extensions until we're at the point of loading _all_
1263+
// members; if callers are doing named lazy lookup they will search the
1264+
// extension list explicitly.
1265+
if (hasLazyMembers()) {
1266+
return;
12611267
}
12621268

12631269
if (!ignoreNewExtensions) {
@@ -1354,13 +1360,22 @@ TinyPtrVector<ValueDecl *> NominalTypeDecl::lookupDirect(
13541360
// populated the IDC and brought it up to date with any extensions. This
13551361
// will flip the hasLazyMembers() flag to false as well.
13561362
if (!useNamedLazyMemberLoading) {
1357-
// If we're about to load members here, purge the MemberLookupTable;
1358-
// it will be rebuilt in prepareLookup, below. Base this decision on
1359-
// the LookupTable's int value, not hasLazyMembers(), since the latter
1360-
// can sometimes change underfoot if some other party calls getMembers
1361-
// outside of lookup (eg. typo correction).
1362-
if (LookupTable.getPointer() && !LookupTable.getInt()) {
1363+
// It's possible that the lookup table exists but has information in it
1364+
// that is either currently out of date or soon to be out of date.
1365+
// This can happen two ways:
1366+
//
1367+
// - We've not yet indexed the members we have (LookupTable.getInt()
1368+
// is zero).
1369+
//
1370+
// - We've still got more lazy members left to load; this can happen
1371+
// even if we _did_ index some members.
1372+
//
1373+
// In either of these cases, we want to reset the table to empty and
1374+
// mark it as needing reconstruction.
1375+
if (LookupTable.getPointer() &&
1376+
(hasLazyMembers() || !LookupTable.getInt())) {
13631377
LookupTable.getPointer()->clear();
1378+
LookupTable.setInt(false);
13641379
}
13651380

13661381
(void)getMembers();
@@ -1374,8 +1389,7 @@ TinyPtrVector<ValueDecl *> NominalTypeDecl::lookupDirect(
13741389
}
13751390

13761391
// Next, in all cases, prepare the lookup table for use, possibly
1377-
// repopulating it from the IDC if just did our initial IDC population
1378-
// above.
1392+
// repopulating it from the IDC if the IDC member list has just grown.
13791393
prepareLookupTable(ignoreNewExtensions);
13801394

13811395
// Look for a declaration with this name.

0 commit comments

Comments
 (0)