@@ -6222,13 +6222,11 @@ swift::extractNearestSourceLoc(const ClangCategoryLookupDescriptor &desc) {
62226222
62236223TinyPtrVector<ValueDecl *>
62246224ClangImporter::Implementation::loadNamedMembers (
6225- const IterableDeclContext *IDC, DeclBaseName N, uint64_t contextData) {
6226-
6225+ const IterableDeclContext *IDC, DeclBaseName N, uint64_t extra) {
62276226 auto *D = IDC->getDecl ();
62286227 auto *DC = D->getInnermostDeclContext ();
62296228 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);
62326230
62336231 auto *nominal = DC->getSelfNominalTypeDecl ();
62346232 auto effectiveClangContext = getEffectiveClangContext (nominal);
@@ -6248,15 +6246,22 @@ ClangImporter::Implementation::loadNamedMembers(
62486246 // findLookupTable, below, handles the first two cases; we assert on the
62496247 // third.
62506248
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+ }
62526257 assert (CMO && " loadNamedMembers on a forward-declared Decl" );
62536258
62546259 auto table = findLookupTable (*CMO);
62556260 assert (table && " clang module without lookup table" );
62566261
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));
62606265
62616266 // Force the members of the entire inheritance hierarchy to be loaded and
62626267 // deserialized before loading the named member of a class. This warms up
@@ -6271,32 +6276,37 @@ ClangImporter::Implementation::loadNamedMembers(
62716276
62726277 // TODO: update this to use the requestified lookup.
62736278 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 ;
62826279
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+ }
62906300 }
6291- }
62926301
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+ }
63006310 }
63016311 }
63026312 }
@@ -6309,8 +6319,11 @@ ClangImporter::Implementation::loadNamedMembers(
63096319 auto member = entry.get <clang::NamedDecl *>();
63106320 if (!isVisibleClangEntry (member)) continue ;
63116321
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 ;
63146327
63156328 SmallVector<Decl*, 4 > tmp;
63166329 insertMembersAndAlternates (member, tmp, DC);
@@ -6324,7 +6337,7 @@ ClangImporter::Implementation::loadNamedMembers(
63246337 }
63256338 }
63266339
6327- if (N.isConstructor ()) {
6340+ if (CD && N.isConstructor ()) {
63286341 if (auto *classDecl = dyn_cast<ClassDecl>(D)) {
63296342 SmallVector<Decl *, 4 > ctors;
63306343 importInheritedConstructors (cast<clang::ObjCInterfaceDecl>(CD),
@@ -6334,7 +6347,7 @@ ClangImporter::Implementation::loadNamedMembers(
63346347 }
63356348 }
63366349
6337- if (!isa<ProtocolDecl>(D)) {
6350+ if (CD && !isa<ProtocolDecl>(D)) {
63386351 if (auto *OCD = dyn_cast<clang::ObjCContainerDecl>(CD)) {
63396352 SmallVector<Decl *, 1 > newMembers;
63406353 importMirroredProtocolMembers (OCD, DC, N, newMembers);
0 commit comments