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