@@ -1245,19 +1245,25 @@ void NominalTypeDecl::prepareLookupTable(bool ignoreNewExtensions) {
1245
1245
LookupTable.setPointer (new (ctx) MemberLookupTable (ctx));
1246
1246
}
1247
1247
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
-
1253
1248
// If we haven't walked the member list yet to update the lookup
1254
1249
// table, do so now.
1255
1250
if (!LookupTable.getInt ()) {
1256
1251
// Note that we'll have walked the members now.
1257
1252
LookupTable.setInt (true );
1258
1253
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 ;
1261
1267
}
1262
1268
1263
1269
if (!ignoreNewExtensions) {
@@ -1354,13 +1360,22 @@ TinyPtrVector<ValueDecl *> NominalTypeDecl::lookupDirect(
1354
1360
// populated the IDC and brought it up to date with any extensions. This
1355
1361
// will flip the hasLazyMembers() flag to false as well.
1356
1362
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 ())) {
1363
1377
LookupTable.getPointer ()->clear ();
1378
+ LookupTable.setInt (false );
1364
1379
}
1365
1380
1366
1381
(void )getMembers ();
@@ -1374,8 +1389,7 @@ TinyPtrVector<ValueDecl *> NominalTypeDecl::lookupDirect(
1374
1389
}
1375
1390
1376
1391
// 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.
1379
1393
prepareLookupTable (ignoreNewExtensions);
1380
1394
1381
1395
// Look for a declaration with this name.
0 commit comments