@@ -2450,19 +2450,116 @@ namespace {
24502450 auto importedName = importFullName (decl, correctSwiftName);
24512451 if (!importedName) return nullptr ;
24522452
2453- auto dc =
2453+ auto extensionDC =
24542454 Impl.importDeclContextOf (decl, importedName.getEffectiveContext ());
2455- if (!dc )
2455+ if (!extensionDC )
24562456 return nullptr ;
24572457
24582458 SourceLoc loc = Impl.importSourceLoc (decl->getBeginLoc ());
2459-
2460- // FIXME: If Swift gets namespaces, import as a namespace.
2461- auto enumDecl = Impl.createDeclWithClangNode <EnumDecl>(
2459+ DeclContext *dc = nullptr ;
2460+ // If this is a top-level namespace, don't put it in the module we're
2461+ // importing, put it in the "__ObjC" module that is implicitly imported.
2462+ // This way, if we have multiple modules that all open the same namespace,
2463+ // we won't import multiple enums with the same name in swift.
2464+ if (extensionDC->getContextKind () == DeclContextKind::FileUnit)
2465+ dc = Impl.ImportedHeaderUnit ;
2466+ else {
2467+ // This is a nested namespace, we need to find its extension decl
2468+ // context and then use that to find the parent enum. It's important
2469+ // that we add this to the parent enum (in the "__ObjC" module) and not
2470+ // to the extension.
2471+ auto parentNS = cast<clang::NamespaceDecl>(decl->getParent ());
2472+ auto parent = Impl.importDecl (parentNS, getVersion ());
2473+ // Sometimes when the parent namespace is imported, this namespace
2474+ // also gets imported. If that's the case, then the parent namespace
2475+ // will be an enum (because it was able to be fully imported) in which
2476+ // case we need to bail here.
2477+ auto cachedResult =
2478+ Impl.ImportedDecls .find ({decl->getCanonicalDecl (), getVersion ()});
2479+ if (cachedResult != Impl.ImportedDecls .end ())
2480+ return cachedResult->second ;
2481+ dc = cast<ExtensionDecl>(parent)
2482+ ->getExtendedType ()
2483+ ->getEnumOrBoundGenericEnum ();
2484+ }
2485+ auto *enumDecl = Impl.createDeclWithClangNode <EnumDecl>(
24622486 decl, AccessLevel::Public, loc,
24632487 importedName.getDeclName ().getBaseIdentifier (),
24642488 Impl.importSourceLoc (decl->getLocation ()), None, nullptr , dc);
2465- enumDecl->setMemberLoader (&Impl, 0 );
2489+ if (isa<clang::NamespaceDecl>(decl->getParent ()))
2490+ cast<EnumDecl>(dc)->addMember (enumDecl);
2491+
2492+ // We are creating an extension, so put it at the top level. This is done
2493+ // after creating the enum, though, because we may need the correctly
2494+ // nested decl context above when creating the enum.
2495+ while (extensionDC->getParent () &&
2496+ extensionDC->getContextKind () != DeclContextKind::FileUnit)
2497+ extensionDC = extensionDC->getParent ();
2498+
2499+ auto *extension = ExtensionDecl::create (Impl.SwiftContext , loc, nullptr ,
2500+ {}, extensionDC, nullptr , decl);
2501+ Impl.SwiftContext .evaluator .cacheOutput (ExtendedTypeRequest{extension},
2502+ enumDecl->getDeclaredType ());
2503+ Impl.SwiftContext .evaluator .cacheOutput (ExtendedNominalRequest{extension},
2504+ std::move (enumDecl));
2505+ // Keep track of what members we've already added so we don't add the same
2506+ // member twice. Note: we can't use "ImportedDecls" for this because we
2507+ // might import a decl that we don't add (for example, if it was a
2508+ // parameter to another decl).
2509+ SmallPtrSet<Decl *, 16 > addedMembers;
2510+ for (auto redecl : decl->redecls ()) {
2511+ // This will be reset as the EnumDecl after we return from
2512+ // VisitNamespaceDecl.
2513+ Impl.ImportedDecls [{redecl->getCanonicalDecl (), getVersion ()}] =
2514+ extension;
2515+
2516+ // Insert these backwards into "namespaceDecls" so we can pop them off
2517+ // the end without loosing order.
2518+ SmallVector<clang::Decl *, 16 > namespaceDecls;
2519+ auto addDeclsReversed = [&](auto decls) {
2520+ auto begin = decls.begin ();
2521+ auto end = decls.end ();
2522+ int currentSize = namespaceDecls.size ();
2523+ int declCount = currentSize + std::distance (begin, end);
2524+ namespaceDecls.resize (declCount);
2525+ for (int index = declCount - 1 ; index >= currentSize; --index)
2526+ namespaceDecls[index] = *(begin++);
2527+ };
2528+ addDeclsReversed (redecl->decls ());
2529+ while (!namespaceDecls.empty ()) {
2530+ auto nd = dyn_cast<clang::NamedDecl>(namespaceDecls.pop_back_val ());
2531+ // Make sure we only import the defenition of a record.
2532+ if (auto tagDecl = dyn_cast_or_null<clang::TagDecl>(nd))
2533+ // Some decls, for example ClassTemplateSpecializationDecls, won't
2534+ // have a definition here. That's OK.
2535+ nd = tagDecl->getDefinition () ? tagDecl->getDefinition () : tagDecl;
2536+ if (!nd)
2537+ continue ;
2538+
2539+ // Special case class templates: import all their specilizations here.
2540+ if (auto classTemplate = dyn_cast<clang::ClassTemplateDecl>(nd)) {
2541+ addDeclsReversed (classTemplate->specializations ());
2542+ continue ;
2543+ }
2544+
2545+ auto member = Impl.importDecl (nd, getVersion ());
2546+ if (!member || addedMembers.count (member) ||
2547+ isa<clang::NamespaceDecl>(nd))
2548+ continue ;
2549+ // This happens (for example) when a struct is declared inside another
2550+ // struct inside a namespace but defined out of line.
2551+ assert (member->getDeclContext ()->getAsDecl ());
2552+ if (dyn_cast<ExtensionDecl>(member->getDeclContext ()->getAsDecl ()) !=
2553+ extension)
2554+ continue ;
2555+ extension->addMember (member);
2556+ addedMembers.insert (member);
2557+ }
2558+ }
2559+
2560+ if (!extension->getMembers ().empty ())
2561+ enumDecl->addExtension (extension);
2562+
24662563 return enumDecl;
24672564 }
24682565
@@ -8543,6 +8640,7 @@ DeclContext *ClangImporter::Implementation::importDeclContextImpl(
85438640 auto decl = dyn_cast<clang::NamedDecl>(dc);
85448641 if (!decl)
85458642 return nullptr ;
8643+
85468644 // Category decls with same name can be merged and using canonical decl always
85478645 // leads to the first category of the given name. We'd like to keep these
85488646 // categories separated.
0 commit comments