@@ -2469,73 +2469,98 @@ namespace {
2469
2469
}
2470
2470
2471
2471
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 ());
2483
2472
DeclContext *dc = nullptr ;
2484
2473
// If this is a top-level namespace, don't put it in the module we're
2485
2474
// importing, put it in the "__ObjC" module that is implicitly imported.
2486
2475
// This way, if we have multiple modules that all open the same namespace,
2487
2476
// we won't import multiple enums with the same name in swift.
2488
- if (extensionDC-> getContextKind () == DeclContextKind::FileUnit )
2477
+ if (!decl-> getParent ()-> isNamespace () )
2489
2478
dc = Impl.ImportedHeaderUnit ;
2490
2479
else {
2491
2480
// This is a nested namespace, we need to find its extension decl
2492
2481
// context and then use that to find the parent enum. It's important
2493
2482
// that we add this to the parent enum (in the "__ObjC" module) and not
2494
2483
// to the extension.
2495
2484
auto parentNS = cast<clang::NamespaceDecl>(decl->getParent ());
2496
- auto parent = Impl.importDecl (parentNS, getVersion ());
2485
+ auto parent =
2486
+ Impl.importDecl (parentNS, getVersion (), /* UseCanonicalDecl*/ false );
2497
2487
// Sometimes when the parent namespace is imported, this namespace
2498
2488
// also gets imported. If that's the case, then the parent namespace
2499
2489
// will be an enum (because it was able to be fully imported) in which
2500
2490
// case we need to bail here.
2501
- auto cachedResult =
2502
- Impl.ImportedDecls .find ({decl->getCanonicalDecl (), getVersion ()});
2491
+ auto cachedResult = Impl.ImportedDecls .find ({decl, getVersion ()});
2503
2492
if (cachedResult != Impl.ImportedDecls .end ())
2504
2493
return cachedResult->second ;
2505
2494
dc = cast<ExtensionDecl>(parent)
2506
2495
->getExtendedType ()
2507
2496
->getEnumOrBoundGenericEnum ();
2508
2497
}
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.
2534
2501
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;
2539
2564
2540
2565
// Insert these backwards into "namespaceDecls" so we can pop them off
2541
2566
// the end without loosing order.
@@ -2566,7 +2591,8 @@ namespace {
2566
2591
continue ;
2567
2592
}
2568
2593
2569
- auto member = Impl.importDecl (nd, getVersion ());
2594
+ bool useCanonicalDecl = !isa<clang::NamespaceDecl>(nd);
2595
+ auto member = Impl.importDecl (nd, getVersion (), useCanonicalDecl);
2570
2596
if (!member || addedMembers.count (member) ||
2571
2597
isa<clang::NamespaceDecl>(nd))
2572
2598
continue ;
@@ -2581,10 +2607,7 @@ namespace {
2581
2607
}
2582
2608
}
2583
2609
2584
- if (!extension->getMembers ().empty ())
2585
- enumDecl->addExtension (extension);
2586
-
2587
- return enumDecl;
2610
+ return Impl.ImportedDecls [{decl, getVersion ()}];
2588
2611
}
2589
2612
2590
2613
Decl *VisitUsingDirectiveDecl (const clang::UsingDirectiveDecl *decl) {
@@ -9235,7 +9258,8 @@ DeclContext *ClangImporter::Implementation::importDeclContextImpl(
9235
9258
// Category decls with same name can be merged and using canonical decl always
9236
9259
// leads to the first category of the given name. We'd like to keep these
9237
9260
// categories separated.
9238
- auto useCanonical = !isa<clang::ObjCCategoryDecl>(decl);
9261
+ auto useCanonical =
9262
+ !isa<clang::ObjCCategoryDecl>(decl) && !isa<clang::NamespaceDecl>(decl);
9239
9263
auto swiftDecl = importDeclForDeclContext (ImportingDecl, decl->getName (),
9240
9264
decl, CurrentVersion, useCanonical);
9241
9265
if (!swiftDecl)
0 commit comments