@@ -1041,9 +1041,9 @@ void NominalTypeDecl::addedMember(Decl *member) {
1041
1041
if (!vd)
1042
1042
return ;
1043
1043
1044
- // If we have a lookup table, add the new member to it.
1045
- auto *lookup = LookupTable. getPointer ();
1046
- if (lookup && isLookupTablePopulated () ) {
1044
+ // If we have a lookup table, add the new member to it. If not, we'll pick up
1045
+ // this member when we first create the table.
1046
+ if (auto * lookup = LookupTable ) {
1047
1047
if (hasLazyMembers ()) {
1048
1048
// If we have lazy members, only add the new member to the lookup
1049
1049
// table if we already have another member with the same name.
@@ -1057,11 +1057,6 @@ void NominalTypeDecl::addedMember(Decl *member) {
1057
1057
}
1058
1058
}
1059
1059
1060
- void NominalTypeDecl::addedExtension (ExtensionDecl *ext) {
1061
- if (hasLazyMembers ())
1062
- setLookupTablePopulated (false );
1063
- }
1064
-
1065
1060
void ExtensionDecl::addedMember (Decl *member) {
1066
1061
// If this extension has already been bound to a nominal, add the new member
1067
1062
// to the nominal's lookup table.
@@ -1126,16 +1121,15 @@ void ExtensionDecl::addedMember(Decl *member) {
1126
1121
//
1127
1122
// If the IDC list is later populated and/or an extension is added _after_
1128
1123
// MemberLookupTable is constructed (and possibly has entries in it),
1129
- // MemberLookupTable is purged and reconstructed from IDC's list .
1124
+ // MemberLookupTable is incrementally reconstituted with new members .
1130
1125
1131
1126
static bool
1132
1127
populateLookupTableEntryFromLazyIDCLoader (ASTContext &ctx,
1133
1128
MemberLookupTable &LookupTable,
1134
1129
DeclBaseName name,
1135
1130
IterableDeclContext *IDC) {
1136
- if (IDC->isLoadingLazyMembers ()) {
1137
- return false ;
1138
- }
1131
+ assert (!IDC->isLoadingLazyMembers () &&
1132
+ " Re-entrant member loading is not supported!" );
1139
1133
IDC->setLoadingLazyMembers (true );
1140
1134
auto ci = ctx.getOrCreateLazyIterableContextData (IDC,
1141
1135
/* lazyLoader=*/ nullptr );
@@ -1175,64 +1169,53 @@ populateLookupTableEntryFromExtensions(ASTContext &ctx,
1175
1169
NominalTypeDecl *nominal,
1176
1170
DeclBaseName name) {
1177
1171
for (auto e : nominal->getExtensions ()) {
1178
- if (e->wasDeserialized () || e->hasClangNode ()) {
1179
- assert (!e->hasUnparsedMembers ());
1180
- if (populateLookupTableEntryFromLazyIDCLoader (ctx, table,
1181
- name, e)) {
1182
- populateLookupTableEntryFromCurrentMembers (ctx, table, name, e);
1183
- }
1184
- } else {
1172
+ // If we can retrieve the members of this extension without deserializing
1173
+ // anything, do so now.
1174
+ if (!e->wasDeserialized () && !e->hasClangNode ()) {
1185
1175
populateLookupTableEntryFromCurrentMembers (ctx, table, name, e);
1176
+ continue ;
1186
1177
}
1187
- }
1188
- }
1189
-
1190
- bool NominalTypeDecl::isLookupTablePopulated () const {
1191
- return LookupTable.getInt ();
1192
- }
1193
1178
1194
- void NominalTypeDecl::setLookupTablePopulated (bool value) {
1195
- LookupTable.setInt (value);
1179
+ assert (!e->hasUnparsedMembers ());
1180
+ if (populateLookupTableEntryFromLazyIDCLoader (ctx, table, name, e)) {
1181
+ populateLookupTableEntryFromCurrentMembers (ctx, table, name, e);
1182
+ }
1183
+ }
1196
1184
}
1197
1185
1198
1186
void NominalTypeDecl::prepareLookupTable () {
1199
- // If we haven't allocated the lookup table yet, do so now.
1200
- if (!LookupTable. getPointer ()) {
1201
- auto &ctx = getASTContext ();
1202
- LookupTable. setPointer ( new (ctx) MemberLookupTable (ctx)) ;
1187
+ // If we have already allocated the lookup table, then there's nothing further
1188
+ // to do.
1189
+ if (LookupTable) {
1190
+ return ;
1203
1191
}
1204
1192
1193
+ // Otherwise start the first fill.
1194
+ auto &ctx = getASTContext ();
1195
+ LookupTable = new (ctx) MemberLookupTable (ctx);
1196
+
1205
1197
if (hasLazyMembers ()) {
1206
1198
assert (!hasUnparsedMembers ());
1207
1199
1208
1200
// Lazy members: if the table needs population, populate the table _only
1209
1201
// from those members already in the IDC member list_ such as implicits or
1210
1202
// globals-as-members, then update table entries from the extensions that
1211
1203
// have the same names as any such initial-population members.
1212
- if (!isLookupTablePopulated ()) {
1213
- setLookupTablePopulated (true );
1214
- LookupTable.getPointer ()->addMembers (getCurrentMembersWithoutLoading ());
1204
+ LookupTable->addMembers (getCurrentMembersWithoutLoading ());
1215
1205
1216
- llvm::SetVector<DeclBaseName> baseNamesPresent;
1217
- for (auto entry : *LookupTable.getPointer ()) {
1218
- baseNamesPresent.insert (entry.getFirst ().getBaseName ());
1219
- }
1206
+ llvm::SmallSet<DeclBaseName, 4 > baseNamesPresent;
1207
+ for (auto entry : *LookupTable) {
1208
+ auto baseName = entry.getFirst ().getBaseName ();
1209
+ if (!baseNamesPresent.insert (baseName).second )
1210
+ continue ;
1220
1211
1221
- for (auto baseName : baseNamesPresent) {
1222
- populateLookupTableEntryFromExtensions (getASTContext (),
1223
- *LookupTable.getPointer (),
1224
- this , baseName);
1225
- }
1212
+ populateLookupTableEntryFromExtensions (getASTContext (),
1213
+ *LookupTable,
1214
+ this , baseName);
1226
1215
}
1227
-
1228
1216
} else {
1229
- // No lazy members: if the table needs population, populate the table
1230
- // en-masse; and in either case update the extensions.
1231
- if (!isLookupTablePopulated ()) {
1232
- setLookupTablePopulated (true );
1233
- LookupTable.getPointer ()->addMembers (getMembers ());
1234
- }
1235
- LookupTable.getPointer ()->updateLookupTable (this );
1217
+ LookupTable->addMembers (getMembers ());
1218
+ LookupTable->updateLookupTable (this );
1236
1219
}
1237
1220
}
1238
1221
@@ -1258,96 +1241,82 @@ maybeFilterOutAttrImplements(TinyPtrVector<ValueDecl *> decls,
1258
1241
return result;
1259
1242
}
1260
1243
1261
- TinyPtrVector<ValueDecl *> NominalTypeDecl::lookupDirect (
1262
- DeclName name,
1263
- OptionSet<LookupDirectFlags> flags) {
1244
+ TinyPtrVector<ValueDecl *>
1245
+ NominalTypeDecl::lookupDirect ( DeclName name,
1246
+ OptionSet<LookupDirectFlags> flags) {
1264
1247
ASTContext &ctx = getASTContext ();
1265
1248
if (auto s = ctx.Stats ) {
1266
1249
++s->getFrontendCounters ().NominalTypeLookupDirectCount ;
1267
1250
}
1268
1251
1269
1252
// We only use NamedLazyMemberLoading when a user opts-in and we have
1270
1253
// not yet loaded all the members into the IDC list in the first place.
1271
- bool useNamedLazyMemberLoading = (ctx.LangOpts .NamedLazyMemberLoading &&
1272
- hasLazyMembers ());
1254
+ const bool useNamedLazyMemberLoading = (ctx.LangOpts .NamedLazyMemberLoading &&
1255
+ hasLazyMembers ());
1273
1256
1274
- bool includeAttrImplements =
1257
+ const bool includeAttrImplements =
1275
1258
flags.contains (LookupDirectFlags::IncludeAttrImplements);
1276
1259
1277
1260
LLVM_DEBUG (llvm::dbgs () << getNameStr () << " .lookupDirect("
1278
- << name << " )"
1279
- << " , isLookupTablePopulated()=" << isLookupTablePopulated ()
1280
- << " , hasLazyMembers()=" << hasLazyMembers ()
1281
- << " , useNamedLazyMemberLoading=" << useNamedLazyMemberLoading
1282
- << " \n " );
1283
-
1284
- // We check the LookupTable at most twice, possibly treating a miss in the
1285
- // first try as a cache-miss that we then do a cache-fill on, and retry.
1286
- for (int i = 0 ; i < 2 ; ++i) {
1287
-
1288
- // First, if we're _not_ doing NamedLazyMemberLoading, we make sure we've
1289
- // populated the IDC and brought it up to date with any extensions. This
1290
- // will flip the hasLazyMembers() flag to false as well.
1291
- if (!useNamedLazyMemberLoading) {
1292
- // It's possible that the lookup table exists but has information in it
1293
- // that is either currently out of date or soon to be out of date.
1294
- // This can happen two ways:
1295
- //
1296
- // - We've not yet indexed the members we have (isLookupTablePopulated()
1297
- // is zero).
1298
- //
1299
- // - We've still got more lazy members left to load; this can happen
1300
- // even if we _did_ index some members.
1301
- //
1302
- // In either of these cases, we want to reset the table to empty and
1303
- // mark it as needing reconstruction.
1304
- if (LookupTable.getPointer () &&
1305
- (hasLazyMembers () || !isLookupTablePopulated ())) {
1306
- LookupTable.getPointer ()->clear ();
1307
- setLookupTablePopulated (false );
1308
- }
1309
-
1310
- (void )getMembers ();
1261
+ << name << " )"
1262
+ << " , hasLazyMembers()=" << hasLazyMembers ()
1263
+ << " , useNamedLazyMemberLoading=" << useNamedLazyMemberLoading
1264
+ << " \n " );
1311
1265
1312
- // Make sure we have the complete list of members (in this nominal and in
1313
- // all extensions).
1314
- for (auto E : getExtensions ())
1315
- (void )E->getMembers ();
1316
- }
1317
1266
1318
- // Next, in all cases, prepare the lookup table for use, possibly
1319
- // repopulating it from the IDC if the IDC member list has just grown.
1320
- prepareLookupTable ();
1267
+ prepareLookupTable ();
1321
1268
1269
+ auto tryCacheLookup =
1270
+ [=](MemberLookupTable *table,
1271
+ DeclName name) -> Optional<TinyPtrVector<ValueDecl *>> {
1322
1272
// Look for a declaration with this name.
1323
- auto known = LookupTable.getPointer ()->find (name);
1273
+ auto known = table->find (name);
1274
+ if (known == table->end ())
1275
+ return None;
1324
1276
1325
1277
// We found something; return it.
1326
- if (known != LookupTable. getPointer ()-> end ())
1327
- return maybeFilterOutAttrImplements (known-> second , name,
1328
- includeAttrImplements) ;
1278
+ return maybeFilterOutAttrImplements (known-> second , name,
1279
+ includeAttrImplements);
1280
+ } ;
1329
1281
1330
- // If we have no more second chances, stop now.
1331
- if (!useNamedLazyMemberLoading || i > 0 )
1332
- break ;
1282
+ auto updateLookupTable = [this ](MemberLookupTable *table) {
1283
+ // Make sure we have the complete list of members (in this nominal and in
1284
+ // all extensions).
1285
+ (void )getMembers ();
1333
1286
1334
- // If we get here, we had a cache-miss and _are_ using
1335
- // NamedLazyMemberLoading. Try to populate a _single_ entry in the
1336
- // MemberLookupTable from both this nominal and all of its extensions, and
1337
- // retry. Any failure to load here flips the useNamedLazyMemberLoading to
1338
- // false, and we fall back to loading all members during the retry.
1339
- auto &Table = *LookupTable.getPointer ();
1340
- if (populateLookupTableEntryFromLazyIDCLoader (ctx, Table,
1341
- name.getBaseName (), this )) {
1342
- useNamedLazyMemberLoading = false ;
1343
- } else {
1344
- populateLookupTableEntryFromExtensions (ctx, Table, this ,
1345
- name.getBaseName ());
1346
- }
1287
+ for (auto E : getExtensions ())
1288
+ (void )E->getMembers ();
1289
+
1290
+ LookupTable->updateLookupTable (this );
1291
+ };
1292
+
1293
+ if (!useNamedLazyMemberLoading) {
1294
+ updateLookupTable (LookupTable);
1347
1295
}
1348
1296
1349
- // None of our attempts found anything.
1350
- return { };
1297
+ // Look for a declaration with this name.
1298
+ if (auto lookup = tryCacheLookup (LookupTable, name))
1299
+ return lookup.getValue ();
1300
+
1301
+ if (!useNamedLazyMemberLoading) {
1302
+ return { };
1303
+ }
1304
+
1305
+ // If we get here, we had a cache-miss and _are_ using
1306
+ // NamedLazyMemberLoading. Try to populate a _single_ entry in the
1307
+ // MemberLookupTable from both this nominal and all of its extensions, and
1308
+ // retry.
1309
+ auto &Table = *LookupTable;
1310
+ if (populateLookupTableEntryFromLazyIDCLoader (ctx, Table,
1311
+ name.getBaseName (), this )) {
1312
+ updateLookupTable (LookupTable);
1313
+ } else {
1314
+ populateLookupTableEntryFromExtensions (ctx, Table, this ,
1315
+ name.getBaseName ());
1316
+ }
1317
+
1318
+ return tryCacheLookup (LookupTable, name)
1319
+ .getValueOr (TinyPtrVector<ValueDecl *>());
1351
1320
}
1352
1321
1353
1322
void ClassDecl::createObjCMethodLookup () {
0 commit comments