@@ -1024,15 +1024,6 @@ class swift::MemberLookupTable {
1024
1024
return Lookup.find (name);
1025
1025
}
1026
1026
1027
- // / \brief Add an empty entry to the lookup map for a given name if it does
1028
- // / not yet have one.
1029
- void addEmptyEntry (DeclName name) {
1030
- (void )Lookup[name];
1031
- if (!name.isSimpleName ()) {
1032
- (void )Lookup[name.getBaseName ()];
1033
- }
1034
- }
1035
-
1036
1027
// \brief Mark all Decls in this table as not-resident in a table, drop
1037
1028
// references to them. Should only be called when this was not fully-populated
1038
1029
// from an IterableDeclContext.
@@ -1247,55 +1238,19 @@ void ExtensionDecl::addedMember(Decl *member) {
1247
1238
// In all lookup routines, the 'ignoreNewExtensions' flag means that
1248
1239
// lookup should only use the set of extensions already observed.
1249
1240
1250
- void NominalTypeDecl::prepareLookupTable (bool ignoreNewExtensions) {
1251
- // If we haven't allocated the lookup table yet, do so now.
1252
- if (!LookupTable.getPointer ()) {
1253
- auto &ctx = getASTContext ();
1254
- LookupTable.setPointer (new (ctx) MemberLookupTable (ctx));
1255
- }
1256
-
1257
- // If we're an IDC that has not yet loaded its full member set, we're doing
1258
- // NamedLazyMemberLoading, and we should not force getMembers().
1259
- if (hasLazyMembers ())
1260
- return ;
1261
-
1262
- // If we haven't walked the member list yet to update the lookup
1263
- // table, do so now.
1264
- if (!LookupTable.getInt ()) {
1265
- // Note that we'll have walked the members now.
1266
- LookupTable.setInt (true );
1267
-
1268
- // Add the members of the nominal declaration to the table.
1269
- LookupTable.getPointer ()->addMembers (getMembers ());
1270
- }
1271
-
1272
- if (!ignoreNewExtensions) {
1273
- // Update the lookup table to introduce members from extensions.
1274
- LookupTable.getPointer ()->updateLookupTable (this );
1275
- }
1276
- }
1277
-
1278
- void NominalTypeDecl::makeMemberVisible (ValueDecl *member) {
1279
- if (!LookupTable.getPointer ()) {
1280
- auto &ctx = getASTContext ();
1281
- LookupTable.setPointer (new (ctx) MemberLookupTable (ctx));
1282
- }
1283
-
1284
- LookupTable.getPointer ()->addMember (member);
1285
- }
1286
-
1287
1241
static bool
1288
1242
populateLookupTableEntryFromLazyIDCLoader (ASTContext &ctx,
1289
1243
MemberLookupTable &LookupTable,
1290
1244
DeclName name,
1291
1245
IterableDeclContext *IDC) {
1246
+ if (IDC->isLoadingLazyMembers ()) {
1247
+ return false ;
1248
+ }
1249
+ IDC->setLoadingLazyMembers (true );
1292
1250
auto ci = ctx.getOrCreateLazyIterableContextData (IDC,
1293
1251
/* lazyLoader=*/ nullptr );
1294
- // Populate LookupTable with an empty vector before we call into our loader,
1295
- // so that any reentry of this routine will find the set-so-far, and not
1296
- // fall into infinite recursion.
1297
- LookupTable.addEmptyEntry (name);
1298
1252
if (auto res = ci->loader ->loadNamedMembers (IDC, name, ci->memberData )) {
1253
+ IDC->setLoadingLazyMembers (false );
1299
1254
if (auto s = ctx.Stats ) {
1300
1255
++s->getFrontendCounters ().NamedLazyMemberLoadSuccessCount ;
1301
1256
}
@@ -1304,19 +1259,18 @@ populateLookupTableEntryFromLazyIDCLoader(ASTContext &ctx,
1304
1259
}
1305
1260
return false ;
1306
1261
} else {
1262
+ IDC->setLoadingLazyMembers (false );
1307
1263
if (auto s = ctx.Stats ) {
1308
1264
++s->getFrontendCounters ().NamedLazyMemberLoadFailureCount ;
1309
1265
}
1310
1266
return true ;
1311
1267
}
1312
1268
}
1313
1269
1314
- static void
1315
- populateLookupTableEntryFromMembers (ASTContext &ctx,
1316
- MemberLookupTable &LookupTable,
1317
- DeclName name,
1318
- IterableDeclContext *IDC) {
1319
- for (auto m : IDC->getMembers ()) {
1270
+ static void populateLookupTableEntryFromCurrentMembersWithoutLoading (
1271
+ ASTContext &ctx, MemberLookupTable &LookupTable, DeclName name,
1272
+ IterableDeclContext *IDC) {
1273
+ for (auto m : IDC->getCurrentMembersWithoutLoading ()) {
1320
1274
if (auto v = dyn_cast<ValueDecl>(m)) {
1321
1275
if (v->getFullName ().matchesRef (name)) {
1322
1276
LookupTable.addMember (m);
@@ -1325,6 +1279,75 @@ populateLookupTableEntryFromMembers(ASTContext &ctx,
1325
1279
}
1326
1280
}
1327
1281
1282
+ static bool
1283
+ populateLookupTableEntryFromExtensions (ASTContext &ctx,
1284
+ MemberLookupTable &table,
1285
+ NominalTypeDecl *nominal,
1286
+ DeclName name,
1287
+ bool ignoreNewExtensions) {
1288
+ if (!ignoreNewExtensions) {
1289
+ for (auto e : nominal->getExtensions ()) {
1290
+ if (e->wasDeserialized () || e->hasClangNode ()) {
1291
+ if (populateLookupTableEntryFromLazyIDCLoader (ctx, table,
1292
+ name, e)) {
1293
+ return true ;
1294
+ }
1295
+ } else {
1296
+ populateLookupTableEntryFromCurrentMembersWithoutLoading (ctx, table,
1297
+ name, e);
1298
+ }
1299
+ }
1300
+ }
1301
+ return false ;
1302
+ }
1303
+
1304
+ void NominalTypeDecl::prepareLookupTable (bool ignoreNewExtensions) {
1305
+ // If we haven't allocated the lookup table yet, do so now.
1306
+ if (!LookupTable.getPointer ()) {
1307
+ auto &ctx = getASTContext ();
1308
+ LookupTable.setPointer (new (ctx) MemberLookupTable (ctx));
1309
+ }
1310
+
1311
+ if (hasLazyMembers ()) {
1312
+ // Lazy members: if the table needs population, populate the table _only
1313
+ // from those members already in the IDC member list_ such as implicits or
1314
+ // globals-as-members, then update table entries from the extensions that
1315
+ // have the same names as any such initial-population members.
1316
+ if (!LookupTable.getInt ()) {
1317
+ LookupTable.setInt (true );
1318
+ LookupTable.getPointer ()->addMembers (getCurrentMembersWithoutLoading ());
1319
+ for (auto *m : getCurrentMembersWithoutLoading ()) {
1320
+ if (auto v = dyn_cast<ValueDecl>(m)) {
1321
+ populateLookupTableEntryFromExtensions (getASTContext (),
1322
+ *LookupTable.getPointer (),
1323
+ this , v->getBaseName (),
1324
+ ignoreNewExtensions);
1325
+ }
1326
+ }
1327
+ }
1328
+
1329
+ } else {
1330
+ // No lazy members: if the table needs population, populate the table
1331
+ // en-masse; and in either case update the extensions.
1332
+ if (!LookupTable.getInt ()) {
1333
+ LookupTable.setInt (true );
1334
+ LookupTable.getPointer ()->addMembers (getMembers ());
1335
+ }
1336
+ if (!ignoreNewExtensions) {
1337
+ LookupTable.getPointer ()->updateLookupTable (this );
1338
+ }
1339
+ }
1340
+ }
1341
+
1342
+ void NominalTypeDecl::makeMemberVisible (ValueDecl *member) {
1343
+ if (!LookupTable.getPointer ()) {
1344
+ auto &ctx = getASTContext ();
1345
+ LookupTable.setPointer (new (ctx) MemberLookupTable (ctx));
1346
+ }
1347
+
1348
+ LookupTable.getPointer ()->addMember (member);
1349
+ }
1350
+
1328
1351
TinyPtrVector<ValueDecl *> NominalTypeDecl::lookupDirect (
1329
1352
DeclName name,
1330
1353
bool ignoreNewExtensions) {
@@ -1336,16 +1359,24 @@ TinyPtrVector<ValueDecl *> NominalTypeDecl::lookupDirect(
1336
1359
.NominalTypeDecl__lookupDirect .getGuard ();
1337
1360
}
1338
1361
1339
- DEBUG (llvm::dbgs () << getNameStr () << " .lookupDirect(" << name << " )"
1340
- << " , lookupTable.getInt()=" << LookupTable.getInt ()
1341
- << " , hasLazyMembers()=" << hasLazyMembers ()
1342
- << " \n " );
1343
-
1344
1362
// We only use NamedLazyMemberLoading when a user opts-in and we have
1345
1363
// not yet loaded all the members into the IDC list in the first place.
1346
1364
bool useNamedLazyMemberLoading = (ctx.LangOpts .NamedLazyMemberLoading &&
1347
1365
hasLazyMembers ());
1348
1366
1367
+ // FIXME: At present, lazy member loading conflicts with a bunch of other code
1368
+ // that appears to special-case initializers (clang-imported initializer
1369
+ // sorting, implicit initializer synthesis), so for the time being we have to
1370
+ // turn it off for them entirely.
1371
+ if (name.getBaseName () == ctx.Id_init )
1372
+ useNamedLazyMemberLoading = false ;
1373
+
1374
+ DEBUG (llvm::dbgs () << getNameStr () << " .lookupDirect(" << name << " )"
1375
+ << " , lookupTable.getInt()=" << LookupTable.getInt ()
1376
+ << " , hasLazyMembers()=" << hasLazyMembers ()
1377
+ << " , useNamedLazyMemberLoading=" << useNamedLazyMemberLoading
1378
+ << " \n " );
1379
+
1349
1380
// We check the LookupTable at most twice, possibly treating a miss in the
1350
1381
// first try as a cache-miss that we then do a cache-fill on, and retry.
1351
1382
for (int i = 0 ; i < 2 ; ++i) {
@@ -1354,12 +1385,22 @@ TinyPtrVector<ValueDecl *> NominalTypeDecl::lookupDirect(
1354
1385
// populated the IDC and brought it up to date with any extensions. This
1355
1386
// will flip the hasLazyMembers() flag to false as well.
1356
1387
if (!useNamedLazyMemberLoading) {
1357
- // If we're about to load members here, purge the MemberLookupTable;
1358
- // it will be rebuilt in prepareLookup, below.
1359
- if (hasLazyMembers () && LookupTable.getPointer ()) {
1360
- // We should not have scanned the IDC list yet. Double check.
1361
- assert (!LookupTable.getInt ());
1388
+ // It's possible that the lookup table exists but has information in it
1389
+ // that is either currently out of date or soon to be out of date.
1390
+ // This can happen two ways:
1391
+ //
1392
+ // - We've not yet indexed the members we have (LookupTable.getInt()
1393
+ // is zero).
1394
+ //
1395
+ // - We've still got more lazy members left to load; this can happen
1396
+ // even if we _did_ index some members.
1397
+ //
1398
+ // In either of these cases, we want to reset the table to empty and
1399
+ // mark it as needing reconstruction.
1400
+ if (LookupTable.getPointer () &&
1401
+ (hasLazyMembers () || !LookupTable.getInt ())) {
1362
1402
LookupTable.getPointer ()->clear ();
1403
+ LookupTable.setInt (false );
1363
1404
}
1364
1405
1365
1406
(void )getMembers ();
@@ -1373,8 +1414,7 @@ TinyPtrVector<ValueDecl *> NominalTypeDecl::lookupDirect(
1373
1414
}
1374
1415
1375
1416
// Next, in all cases, prepare the lookup table for use, possibly
1376
- // repopulating it from the IDC if just did our initial IDC population
1377
- // above.
1417
+ // repopulating it from the IDC if the IDC member list has just grown.
1378
1418
prepareLookupTable (ignoreNewExtensions);
1379
1419
1380
1420
// Look for a declaration with this name.
@@ -1395,23 +1435,10 @@ TinyPtrVector<ValueDecl *> NominalTypeDecl::lookupDirect(
1395
1435
// false, and we fall back to loading all members during the retry.
1396
1436
auto &Table = *LookupTable.getPointer ();
1397
1437
if (populateLookupTableEntryFromLazyIDCLoader (ctx, Table,
1398
- name, this )) {
1438
+ name, this ) ||
1439
+ populateLookupTableEntryFromExtensions (ctx, Table, this , name,
1440
+ ignoreNewExtensions)) {
1399
1441
useNamedLazyMemberLoading = false ;
1400
- } else {
1401
- if (!ignoreNewExtensions) {
1402
- for (auto E : getExtensions ()) {
1403
- if (E->wasDeserialized ()) {
1404
- if (populateLookupTableEntryFromLazyIDCLoader (ctx, Table,
1405
- name, E)) {
1406
- useNamedLazyMemberLoading = false ;
1407
- break ;
1408
- }
1409
- } else {
1410
- populateLookupTableEntryFromMembers (ctx, Table,
1411
- name, E);
1412
- }
1413
- }
1414
- }
1415
1442
}
1416
1443
}
1417
1444
0 commit comments