@@ -1028,25 +1028,25 @@ void MemberLookupTable::updateLookupTable(NominalTypeDecl *nominal) {
1028
1028
}
1029
1029
}
1030
1030
1031
- void NominalTypeDecl::addedMember (Decl *member) {
1032
- auto *vd = dyn_cast<ValueDecl>(member);
1033
- if (!vd)
1034
- return ;
1031
+ void NominalTypeDecl::addedExtension (ExtensionDecl *ext) {
1032
+ if (!LookupTable) return ;
1035
1033
1034
+ if (ext->hasLazyMembers ()) {
1035
+ LookupTable->addMembers (ext->getCurrentMembersWithoutLoading ());
1036
+ } else {
1037
+ LookupTable->addMembers (ext->getMembers ());
1038
+ }
1039
+ }
1040
+
1041
+ void NominalTypeDecl::addedMember (Decl *member) {
1036
1042
// If we have a lookup table, add the new member to it. If not, we'll pick up
1037
1043
// this member when we first create the table.
1038
- if (auto *lookup = LookupTable) {
1039
- if (hasLazyMembers ()) {
1040
- // If we have lazy members, only add the new member to the lookup
1041
- // table if we already have another member with the same name.
1042
- // The presence of a lookup table entry indicates that the
1043
- // nominal as well as all extensions have already been searched.
1044
- if (lookup->find (vd->getBaseName ()) == lookup->end ())
1045
- return ;
1046
- }
1044
+ auto *vd = dyn_cast<ValueDecl>(member);
1045
+ auto *lookup = LookupTable;
1046
+ if (!vd || !lookup)
1047
+ return ;
1047
1048
1048
- lookup->addMember (vd);
1049
- }
1049
+ lookup->addMember (vd);
1050
1050
}
1051
1051
1052
1052
void ExtensionDecl::addedMember (Decl *member) {
@@ -1079,8 +1079,8 @@ void ExtensionDecl::addedMember(Decl *member) {
1079
1079
// │ExtensionDecl *LastExtension ─┼───────┐│ │ └───┐
1080
1080
// │ │ ││ └──────────────────────┐│
1081
1081
// │MemberLookupTable *LookupTable├─┐ ││ ││
1082
- // │bool LookupTableComplete │ │ ││ ┌─────────────────┐ ││
1083
- // └──────────────────────────────┘ │ ││ │ExtensionDecl │ ││
1082
+ // └──────────────────────────────┘ │ ││ ┌─────────────────┐ ││
1083
+ // │ ││ │ExtensionDecl │ ││
1084
1084
// │ ││ │------------- │ ││
1085
1085
// ┌─────────────┘ │└────▶│ExtensionDecl │ ││
1086
1086
// │ │ │ *NextExtension ├──┐ ││
@@ -1141,34 +1141,27 @@ populateLookupTableEntryFromLazyIDCLoader(ASTContext &ctx,
1141
1141
}
1142
1142
}
1143
1143
1144
- static void populateLookupTableEntryFromCurrentMembers (
1145
- ASTContext &ctx, MemberLookupTable &LookupTable, DeclBaseName name,
1146
- IterableDeclContext *IDC) {
1147
- for (auto m : IDC->getMembers ()) {
1148
- if (auto v = dyn_cast<ValueDecl>(m)) {
1149
- if (v->getBaseName () == name) {
1150
- LookupTable.addMember (m);
1151
- }
1152
- }
1153
- }
1154
- }
1155
-
1156
1144
static void
1157
1145
populateLookupTableEntryFromExtensions (ASTContext &ctx,
1158
1146
MemberLookupTable &table,
1159
1147
NominalTypeDecl *nominal,
1160
1148
DeclBaseName name) {
1161
1149
for (auto e : nominal->getExtensions ()) {
1162
- // If we can retrieve the members of this extension without deserializing
1163
- // anything, do so now.
1164
- if (!e->wasDeserialized () && !e->hasClangNode ()) {
1165
- populateLookupTableEntryFromCurrentMembers (ctx, table, name, e);
1150
+ // If there's no lazy members to look at, all the members of this extension
1151
+ // are present in the lookup table.
1152
+ if (!e->hasLazyMembers ()) {
1166
1153
continue ;
1167
1154
}
1168
1155
1156
+ assert (e->wasDeserialized () || e->hasClangNode () &&
1157
+ " Extension without deserializable content has lazy members!" );
1169
1158
assert (!e->hasUnparsedMembers ());
1159
+
1160
+ // Try lazy loading. If that fails, then we fall back by loading the
1161
+ // entire extension. FIXME: It's rather unfortunate that we fall off the
1162
+ // happy path because the Clang Importer can't handle lazy import-as-member.
1170
1163
if (populateLookupTableEntryFromLazyIDCLoader (ctx, table, name, e)) {
1171
- populateLookupTableEntryFromCurrentMembers (ctx, table, name, e );
1164
+ e-> loadAllMembers ( );
1172
1165
}
1173
1166
}
1174
1167
}
@@ -1189,19 +1182,18 @@ void NominalTypeDecl::prepareLookupTable() {
1189
1182
1190
1183
// Lazy members: if the table needs population, populate the table _only
1191
1184
// from those members already in the IDC member list_ such as implicits or
1192
- // globals-as-members, then update table entries from the extensions that
1193
- // have the same names as any such initial-population members.
1185
+ // globals-as-members.
1194
1186
LookupTable->addMembers (getCurrentMembersWithoutLoading ());
1195
-
1196
- llvm::SmallSet<DeclBaseName, 4 > baseNamesPresent;
1197
- for ( auto entry : *LookupTable) {
1198
- auto baseName = entry. getFirst (). getBaseName ();
1199
- if (!baseNamesPresent. insert (baseName). second )
1187
+ for ( auto e : getExtensions ()) {
1188
+ // If we can lazy-load this extension, only take the members we've loaded
1189
+ // so far.
1190
+ if (e-> wasDeserialized () || e-> hasClangNode ()) {
1191
+ LookupTable-> addMembers (e-> getCurrentMembersWithoutLoading ());
1200
1192
continue ;
1193
+ }
1201
1194
1202
- populateLookupTableEntryFromExtensions (getASTContext (),
1203
- *LookupTable,
1204
- this , baseName);
1195
+ // Else, load all the members into the table.
1196
+ LookupTable->addMembers (e->getMembers ());
1205
1197
}
1206
1198
} else {
1207
1199
LookupTable->addMembers (getMembers ());
@@ -1261,8 +1253,9 @@ NominalTypeDecl::lookupDirect(DeclName name,
1261
1253
DeclName name) -> Optional<TinyPtrVector<ValueDecl *>> {
1262
1254
// Look for a declaration with this name.
1263
1255
auto known = table->find (name);
1264
- if (known == table->end ())
1256
+ if (known == table->end ()) {
1265
1257
return None;
1258
+ }
1266
1259
1267
1260
// We found something; return it.
1268
1261
return maybeFilterOutAttrImplements (known->second , name,
@@ -1282,29 +1275,17 @@ NominalTypeDecl::lookupDirect(DeclName name,
1282
1275
1283
1276
if (!useNamedLazyMemberLoading) {
1284
1277
updateLookupTable (LookupTable);
1285
- }
1286
-
1287
- // Look for a declaration with this name.
1288
- if (auto lookup = tryCacheLookup (LookupTable, name))
1289
- return lookup.getValue ();
1290
-
1291
- if (!useNamedLazyMemberLoading) {
1292
- return { };
1293
- }
1294
-
1295
- // If we get here, we had a cache-miss and _are_ using
1296
- // NamedLazyMemberLoading. Try to populate a _single_ entry in the
1297
- // MemberLookupTable from both this nominal and all of its extensions, and
1298
- // retry.
1299
- auto &Table = *LookupTable;
1300
- if (populateLookupTableEntryFromLazyIDCLoader (ctx, Table,
1301
- name.getBaseName (), this )) {
1302
- updateLookupTable (LookupTable);
1303
1278
} else {
1304
- populateLookupTableEntryFromExtensions (ctx, Table, this ,
1305
- name.getBaseName ());
1279
+ if (populateLookupTableEntryFromLazyIDCLoader (ctx, *LookupTable,
1280
+ name.getBaseName (), this )) {
1281
+ updateLookupTable (LookupTable);
1282
+ } else {
1283
+ populateLookupTableEntryFromExtensions (ctx, *LookupTable, this ,
1284
+ name.getBaseName ());
1285
+ }
1306
1286
}
1307
1287
1288
+ // Look for a declaration with this name.
1308
1289
return tryCacheLookup (LookupTable, name)
1309
1290
.getValueOr (TinyPtrVector<ValueDecl *>());
1310
1291
}
0 commit comments