@@ -6222,13 +6222,11 @@ swift::extractNearestSourceLoc(const ClangCategoryLookupDescriptor &desc) {
6222
6222
6223
6223
TinyPtrVector<ValueDecl *>
6224
6224
ClangImporter::Implementation::loadNamedMembers (
6225
- const IterableDeclContext *IDC, DeclBaseName N, uint64_t contextData) {
6226
-
6225
+ const IterableDeclContext *IDC, DeclBaseName N, uint64_t extra) {
6227
6226
auto *D = IDC->getDecl ();
6228
6227
auto *DC = D->getInnermostDeclContext ();
6229
6228
auto *CD = D->getClangDecl ();
6230
- auto *CDC = cast<clang::DeclContext>(CD);
6231
- assert (CD && " loadNamedMembers on a Decl without a clangDecl" );
6229
+ auto *CDC = cast_or_null<clang::DeclContext>(CD);
6232
6230
6233
6231
auto *nominal = DC->getSelfNominalTypeDecl ();
6234
6232
auto effectiveClangContext = getEffectiveClangContext (nominal);
@@ -6248,15 +6246,22 @@ ClangImporter::Implementation::loadNamedMembers(
6248
6246
// findLookupTable, below, handles the first two cases; we assert on the
6249
6247
// third.
6250
6248
6251
- auto CMO = getClangSubmoduleForDecl (CD);
6249
+ llvm::Optional<clang::Module *> CMO;
6250
+ if (CD)
6251
+ CMO = getClangSubmoduleForDecl (CD);
6252
+ else {
6253
+ // IDC is an extension containing globals imported as members, so it doesn't
6254
+ // have a clang node but the submodule pointer has been stashed in `extra`.
6255
+ CMO = reinterpret_cast <clang::Module *>(static_cast <uintptr_t >(extra));
6256
+ }
6252
6257
assert (CMO && " loadNamedMembers on a forward-declared Decl" );
6253
6258
6254
6259
auto table = findLookupTable (*CMO);
6255
6260
assert (table && " clang module without lookup table" );
6256
6261
6257
- assert (!isa <clang::NamespaceDecl>(CD) && " Namespace members should be loaded "
6258
- " via a request." );
6259
- assert (isa<clang::ObjCContainerDecl>(CD));
6262
+ assert (!isa_and_nonnull <clang::NamespaceDecl>(CD)
6263
+ && " Namespace members should be loaded via a request." );
6264
+ assert (!CD || isa<clang::ObjCContainerDecl>(CD));
6260
6265
6261
6266
// Force the members of the entire inheritance hierarchy to be loaded and
6262
6267
// deserialized before loading the named member of a class. This warms up
@@ -6271,32 +6276,37 @@ ClangImporter::Implementation::loadNamedMembers(
6271
6276
6272
6277
// TODO: update this to use the requestified lookup.
6273
6278
TinyPtrVector<ValueDecl *> Members;
6274
- for (auto entry : table->lookup (SerializedSwiftName (N),
6275
- effectiveClangContext)) {
6276
- if (!entry.is <clang::NamedDecl *>()) continue ;
6277
- auto member = entry.get <clang::NamedDecl *>();
6278
- if (!isVisibleClangEntry (member)) continue ;
6279
-
6280
- // Skip Decls from different clang::DeclContexts
6281
- if (member->getDeclContext () != CDC) continue ;
6282
6279
6283
- SmallVector<Decl*, 4 > tmp;
6284
- insertMembersAndAlternates (member, tmp, DC);
6285
- for (auto *TD : tmp) {
6286
- if (auto *V = dyn_cast<ValueDecl>(TD)) {
6287
- // Skip ValueDecls if they import under different names.
6288
- if (V->getBaseName () == N) {
6289
- Members.push_back (V);
6280
+ // Lookup actual, factual clang-side members of the context. No need to do
6281
+ // this if we're handling an import-as-member extension.
6282
+ if (CD) {
6283
+ for (auto entry : table->lookup (SerializedSwiftName (N),
6284
+ effectiveClangContext)) {
6285
+ if (!entry.is <clang::NamedDecl *>()) continue ;
6286
+ auto member = entry.get <clang::NamedDecl *>();
6287
+ if (!isVisibleClangEntry (member)) continue ;
6288
+
6289
+ // Skip Decls from different clang::DeclContexts
6290
+ if (member->getDeclContext () != CDC) continue ;
6291
+
6292
+ SmallVector<Decl*, 4 > tmp;
6293
+ insertMembersAndAlternates (member, tmp, DC);
6294
+ for (auto *TD : tmp) {
6295
+ if (auto *V = dyn_cast<ValueDecl>(TD)) {
6296
+ // Skip ValueDecls if they import under different names.
6297
+ if (V->getBaseName () == N) {
6298
+ Members.push_back (V);
6299
+ }
6290
6300
}
6291
- }
6292
6301
6293
- // If the property's accessors have alternate decls, we might have
6294
- // to import those too.
6295
- if (auto *ASD = dyn_cast<AbstractStorageDecl>(TD)) {
6296
- for (auto *AD : ASD->getAllAccessors ()) {
6297
- for (auto *D : getAlternateDecls (AD)) {
6298
- if (D->getBaseName () == N)
6299
- Members.push_back (D);
6302
+ // If the property's accessors have alternate decls, we might have
6303
+ // to import those too.
6304
+ if (auto *ASD = dyn_cast<AbstractStorageDecl>(TD)) {
6305
+ for (auto *AD : ASD->getAllAccessors ()) {
6306
+ for (auto *D : getAlternateDecls (AD)) {
6307
+ if (D->getBaseName () == N)
6308
+ Members.push_back (D);
6309
+ }
6300
6310
}
6301
6311
}
6302
6312
}
@@ -6309,8 +6319,11 @@ ClangImporter::Implementation::loadNamedMembers(
6309
6319
auto member = entry.get <clang::NamedDecl *>();
6310
6320
if (!isVisibleClangEntry (member)) continue ;
6311
6321
6312
- // Skip Decls from different clang::DeclContexts
6313
- if (member->getDeclContext () != CDC) continue ;
6322
+ // Skip Decls from different clang::DeclContexts. We don't do this for
6323
+ // import-as-member extensions because we don't know what decl context to
6324
+ // expect; for instance, an enum constant is inside the enum decl, not in
6325
+ // the translation unit.
6326
+ if (CDC && member->getDeclContext () != CDC) continue ;
6314
6327
6315
6328
SmallVector<Decl*, 4 > tmp;
6316
6329
insertMembersAndAlternates (member, tmp, DC);
@@ -6324,7 +6337,7 @@ ClangImporter::Implementation::loadNamedMembers(
6324
6337
}
6325
6338
}
6326
6339
6327
- if (N.isConstructor ()) {
6340
+ if (CD && N.isConstructor ()) {
6328
6341
if (auto *classDecl = dyn_cast<ClassDecl>(D)) {
6329
6342
SmallVector<Decl *, 4 > ctors;
6330
6343
importInheritedConstructors (cast<clang::ObjCInterfaceDecl>(CD),
@@ -6334,7 +6347,7 @@ ClangImporter::Implementation::loadNamedMembers(
6334
6347
}
6335
6348
}
6336
6349
6337
- if (!isa<ProtocolDecl>(D)) {
6350
+ if (CD && !isa<ProtocolDecl>(D)) {
6338
6351
if (auto *OCD = dyn_cast<clang::ObjCContainerDecl>(CD)) {
6339
6352
SmallVector<Decl *, 1 > newMembers;
6340
6353
importMirroredProtocolMembers (OCD, DC, N, newMembers);
0 commit comments