@@ -2469,73 +2469,98 @@ namespace {
24692469 }
24702470
24712471 Decl *VisitNamespaceDecl (const clang::NamespaceDecl *decl) {
2472- // If we have a name for this declaration, use it.
2473- Optional<ImportedName> correctSwiftName;
2474- auto importedName = importFullName (decl, correctSwiftName);
2475- if (!importedName) return nullptr ;
2476-
2477- auto extensionDC =
2478- Impl.importDeclContextOf (decl, importedName.getEffectiveContext ());
2479- if (!extensionDC)
2480- return nullptr ;
2481-
2482- SourceLoc loc = Impl.importSourceLoc (decl->getBeginLoc ());
24832472 DeclContext *dc = nullptr ;
24842473 // If this is a top-level namespace, don't put it in the module we're
24852474 // importing, put it in the "__ObjC" module that is implicitly imported.
24862475 // This way, if we have multiple modules that all open the same namespace,
24872476 // we won't import multiple enums with the same name in swift.
2488- if (extensionDC-> getContextKind () == DeclContextKind::FileUnit )
2477+ if (!decl-> getParent ()-> isNamespace () )
24892478 dc = Impl.ImportedHeaderUnit ;
24902479 else {
24912480 // This is a nested namespace, we need to find its extension decl
24922481 // context and then use that to find the parent enum. It's important
24932482 // that we add this to the parent enum (in the "__ObjC" module) and not
24942483 // to the extension.
24952484 auto parentNS = cast<clang::NamespaceDecl>(decl->getParent ());
2496- auto parent = Impl.importDecl (parentNS, getVersion ());
2485+ auto parent =
2486+ Impl.importDecl (parentNS, getVersion (), /* UseCanonicalDecl*/ false );
24972487 // Sometimes when the parent namespace is imported, this namespace
24982488 // also gets imported. If that's the case, then the parent namespace
24992489 // will be an enum (because it was able to be fully imported) in which
25002490 // case we need to bail here.
2501- auto cachedResult =
2502- Impl.ImportedDecls .find ({decl->getCanonicalDecl (), getVersion ()});
2491+ auto cachedResult = Impl.ImportedDecls .find ({decl, getVersion ()});
25032492 if (cachedResult != Impl.ImportedDecls .end ())
25042493 return cachedResult->second ;
25052494 dc = cast<ExtensionDecl>(parent)
25062495 ->getExtendedType ()
25072496 ->getEnumOrBoundGenericEnum ();
25082497 }
2509- auto *enumDecl = Impl.createDeclWithClangNode <EnumDecl>(
2510- decl, AccessLevel::Public, loc,
2511- importedName.getDeclName ().getBaseIdentifier (),
2512- Impl.importSourceLoc (decl->getLocation ()), None, nullptr , dc);
2513- if (isa<clang::NamespaceDecl>(decl->getParent ()))
2514- cast<EnumDecl>(dc)->addMember (enumDecl);
2515-
2516- // We are creating an extension, so put it at the top level. This is done
2517- // after creating the enum, though, because we may need the correctly
2518- // nested decl context above when creating the enum.
2519- while (extensionDC->getParent () &&
2520- extensionDC->getContextKind () != DeclContextKind::FileUnit)
2521- extensionDC = extensionDC->getParent ();
2522-
2523- auto *extension = ExtensionDecl::create (Impl.SwiftContext , loc, nullptr ,
2524- {}, extensionDC, nullptr , decl);
2525- Impl.SwiftContext .evaluator .cacheOutput (ExtendedTypeRequest{extension},
2526- enumDecl->getDeclaredType ());
2527- Impl.SwiftContext .evaluator .cacheOutput (ExtendedNominalRequest{extension},
2528- std::move (enumDecl));
2529- // Keep track of what members we've already added so we don't add the same
2530- // member twice. Note: we can't use "ImportedDecls" for this because we
2531- // might import a decl that we don't add (for example, if it was a
2532- // parameter to another decl).
2533- SmallPtrSet<Decl *, 16 > addedMembers;
2498+
2499+ EnumDecl *enumDecl = nullptr ;
2500+ // Try to find an already created enum for this namespace.
25342501 for (auto redecl : decl->redecls ()) {
2535- // This will be reset as the EnumDecl after we return from
2536- // VisitNamespaceDecl.
2537- Impl.ImportedDecls [{redecl->getCanonicalDecl (), getVersion ()}] =
2538- extension;
2502+ auto extension = Impl.ImportedDecls .find ({redecl, getVersion ()});
2503+ if (extension != Impl.ImportedDecls .end ()) {
2504+ enumDecl = cast<EnumDecl>(
2505+ cast<ExtensionDecl>(extension->second )->getExtendedNominal ());
2506+ break ;
2507+ }
2508+ }
2509+ // If we're seeing this namespace for the first time, we need to create a
2510+ // new enum in the "__ObjC" module.
2511+ if (!enumDecl) {
2512+ // If we don't have a name for this declaration, bail.
2513+ Optional<ImportedName> correctSwiftName;
2514+ auto importedName = importFullName (decl, correctSwiftName);
2515+ if (!importedName)
2516+ return nullptr ;
2517+
2518+ enumDecl = Impl.createDeclWithClangNode <EnumDecl>(
2519+ decl, AccessLevel::Public,
2520+ Impl.importSourceLoc (decl->getBeginLoc ()),
2521+ importedName.getDeclName ().getBaseIdentifier (),
2522+ Impl.importSourceLoc (decl->getLocation ()), None, nullptr , dc);
2523+ if (isa<clang::NamespaceDecl>(decl->getParent ()))
2524+ cast<EnumDecl>(dc)->addMember (enumDecl);
2525+ }
2526+
2527+ for (auto redecl : decl->redecls ()) {
2528+ if (Impl.ImportedDecls .find ({redecl, getVersion ()}) !=
2529+ Impl.ImportedDecls .end ())
2530+ continue ;
2531+
2532+ Optional<ImportedName> correctSwiftName;
2533+ auto importedName = importFullName (redecl, correctSwiftName);
2534+ if (!importedName)
2535+ continue ;
2536+
2537+ auto extensionDC = Impl.importDeclContextOf (
2538+ redecl, importedName.getEffectiveContext ());
2539+ if (!extensionDC)
2540+ continue ;
2541+
2542+ // We are creating an extension, so put it at the top level. This is
2543+ // done after creating the enum, though, because we may need the
2544+ // correctly nested decl context above when creating the enum.
2545+ while (extensionDC->getParent () &&
2546+ extensionDC->getContextKind () != DeclContextKind::FileUnit)
2547+ extensionDC = extensionDC->getParent ();
2548+
2549+ auto *extension = ExtensionDecl::create (
2550+ Impl.SwiftContext , Impl.importSourceLoc (decl->getBeginLoc ()),
2551+ nullptr , {}, extensionDC, nullptr , redecl);
2552+ enumDecl->addExtension (extension);
2553+ Impl.ImportedDecls [{redecl, getVersion ()}] = extension;
2554+
2555+ Impl.SwiftContext .evaluator .cacheOutput (ExtendedTypeRequest{extension},
2556+ enumDecl->getDeclaredType ());
2557+ Impl.SwiftContext .evaluator .cacheOutput (ExtendedNominalRequest{extension},
2558+ std::move (enumDecl));
2559+ // Keep track of what members we've already added so we don't add the
2560+ // same member twice. Note: we can't use "ImportedDecls" for this
2561+ // because we might import a decl that we don't add (for example, if it
2562+ // was a parameter to another decl).
2563+ SmallPtrSet<Decl *, 16 > addedMembers;
25392564
25402565 // Insert these backwards into "namespaceDecls" so we can pop them off
25412566 // the end without loosing order.
@@ -2566,7 +2591,8 @@ namespace {
25662591 continue ;
25672592 }
25682593
2569- auto member = Impl.importDecl (nd, getVersion ());
2594+ bool useCanonicalDecl = !isa<clang::NamespaceDecl>(nd);
2595+ auto member = Impl.importDecl (nd, getVersion (), useCanonicalDecl);
25702596 if (!member || addedMembers.count (member) ||
25712597 isa<clang::NamespaceDecl>(nd))
25722598 continue ;
@@ -2581,10 +2607,7 @@ namespace {
25812607 }
25822608 }
25832609
2584- if (!extension->getMembers ().empty ())
2585- enumDecl->addExtension (extension);
2586-
2587- return enumDecl;
2610+ return Impl.ImportedDecls [{decl, getVersion ()}];
25882611 }
25892612
25902613 Decl *VisitUsingDirectiveDecl (const clang::UsingDirectiveDecl *decl) {
@@ -9235,7 +9258,8 @@ DeclContext *ClangImporter::Implementation::importDeclContextImpl(
92359258 // Category decls with same name can be merged and using canonical decl always
92369259 // leads to the first category of the given name. We'd like to keep these
92379260 // categories separated.
9238- auto useCanonical = !isa<clang::ObjCCategoryDecl>(decl);
9261+ auto useCanonical =
9262+ !isa<clang::ObjCCategoryDecl>(decl) && !isa<clang::NamespaceDecl>(decl);
92399263 auto swiftDecl = importDeclForDeclContext (ImportingDecl, decl->getName (),
92409264 decl, CurrentVersion, useCanonical);
92419265 if (!swiftDecl)
0 commit comments