@@ -2835,42 +2835,67 @@ ClangModuleUnit *ClangImporter::Implementation::getWrapperForModule(
2835
2835
implicitImportInfo = mainModule->getImplicitImportInfo ();
2836
2836
}
2837
2837
2838
- // Make sure that synthesized Swift code in the clang module wrapper
2839
- // (e.g. _SwiftifyImport macro expansions) can access the same symbols
2840
- // as if it were actually in the clang module, by copying the imports.
2841
- // Because this top-level module wrapper contains all the imported decls
2842
- // of the clang submodules, we need to add the imports of all the
2843
- // transitive submodules, since we don't know at this point of the
2844
- // compilation which submodules will contain relevant macros.
2845
2838
if (!underlying->isSubModule ()) {
2839
+ // Make sure that synthesized Swift code in the clang module wrapper
2840
+ // (e.g. _SwiftifyImport macro expansions) can access the same symbols
2841
+ // as if it were actually in the clang module, by copying the imports.
2842
+ // Because this top-level module wrapper contains all the imported decls
2843
+ // of the clang submodules, we need to add the imports of all the
2844
+ // transitive submodules, since we don't know at this point of the
2845
+ // compilation which submodules will contain relevant macros.
2846
+ // We also need to add (transitive) explicit submodules as imports,
2847
+ // to make sure that they are marked as imported *somewhere* (clang modules
2848
+ // including them don't count) - otherwise their decls won't be found after
2849
+ // non-visible clang decls are filtered out.
2846
2850
llvm::SmallVector<const clang::Module *, 32 > SubmoduleWorklist;
2847
2851
llvm::DenseSet<ImportPath> Imported;
2848
2852
SubmoduleWorklist.push_back (underlying);
2849
- std::string underlyingSwiftModuleName =
2850
- isCxxStdModule (underlying)
2851
- ? static_cast <std::string>(SwiftContext.Id_CxxStdlib )
2852
- : underlying->getFullModuleName ();
2853
- ImportPath::Builder underlyingImportPath (SwiftContext,
2854
- underlyingSwiftModuleName, ' .' );
2855
- Imported.insert (underlyingImportPath.get ());
2853
+ ImportPath::Builder underlyingSwiftModulePath =
2854
+ getSwiftModulePath (underlying);
2855
+ Imported.insert (underlyingSwiftModulePath.get ());
2856
2856
for (auto UI : implicitImportInfo.AdditionalUnloadedImports )
2857
2857
Imported.insert (UI.module .getImportPath ());
2858
2858
assert (implicitImportInfo.AdditionalImports .empty ());
2859
2859
2860
+ auto addImplicitImport = [&implicitImportInfo, &Imported,
2861
+ this ](const clang::Module *M,
2862
+ bool guaranteedUnique) {
2863
+ ImportPath::Builder builder = getSwiftModulePath (M);
2864
+ if (!guaranteedUnique && Imported.count (builder.get ()))
2865
+ return ;
2866
+
2867
+ // Don't perform this clone for modules already added to the list
2868
+ ImportPath importedModulePath = builder.copyTo (SwiftContext);
2869
+
2870
+ #ifndef NDEBUG
2871
+ const bool performSanityCheck = true ;
2872
+ #else
2873
+ const bool performSanityCheck = false ;
2874
+ #endif
2875
+ if (!guaranteedUnique || performSanityCheck) {
2876
+ bool WasInserted = Imported.insert (importedModulePath).second ;
2877
+ assert (WasInserted);
2878
+ }
2879
+
2880
+ UnloadedImportedModule importedModule (importedModulePath,
2881
+ ImportKind::Module);
2882
+ implicitImportInfo.AdditionalUnloadedImports .push_back (
2883
+ std::move (importedModule));
2884
+ };
2885
+
2860
2886
while (!SubmoduleWorklist.empty ()) {
2861
2887
const clang::Module *CurrModule = SubmoduleWorklist.pop_back_val ();
2888
+ if (CurrModule->IsExplicit ) {
2889
+ // We don't add imports under the same TLM, and submodules form
2890
+ // a tree, so these don't require deduplication.
2891
+ addImplicitImport (CurrModule, /* guaranteedUnique=*/ true );
2892
+ }
2862
2893
for (auto *I : CurrModule->Imports ) {
2863
- std::string swiftModuleName =
2864
- isCxxStdModule (I)
2865
- ? static_cast <std::string>(SwiftContext.Id_CxxStdlib )
2866
- : I->getFullModuleName ();
2867
- ImportPath::Builder importPath (SwiftContext, swiftModuleName, ' .' );
2868
- if (Imported.count (importPath.get ()))
2894
+ // `underlying` is the current TLM. Only explicit submodules need to
2895
+ // be imported under the same TLM, which is handled above.
2896
+ if (I->getTopLevelModule () == underlying)
2869
2897
continue ;
2870
- UnloadedImportedModule importedModule (importPath.copyTo (SwiftContext),
2871
- ImportKind::Module);
2872
- Imported.insert (importedModule.getImportPath ());
2873
- implicitImportInfo.AdditionalUnloadedImports .push_back (importedModule);
2898
+ addImplicitImport (I, /* guaranteedUnique=*/ false );
2874
2899
}
2875
2900
for (auto *Submodule : CurrModule->submodules ())
2876
2901
SubmoduleWorklist.push_back (Submodule);
@@ -3780,19 +3805,7 @@ ImportDecl *swift::createImportDecl(ASTContext &Ctx,
3780
3805
auto *ImportedMod = ClangN.getClangModule ();
3781
3806
assert (ImportedMod);
3782
3807
3783
- ImportPath::Builder importPath;
3784
- auto *TmpMod = ImportedMod;
3785
- while (TmpMod) {
3786
- // If this is a C++ stdlib module, print its name as `CxxStdlib` instead of
3787
- // `std`. `CxxStdlib` is the only accepted spelling of the C++ stdlib module
3788
- // name in Swift.
3789
- Identifier moduleName = !TmpMod->isSubModule () && TmpMod->Name == " std"
3790
- ? Ctx.Id_CxxStdlib
3791
- : Ctx.getIdentifier (TmpMod->Name );
3792
- importPath.push_back (moduleName);
3793
- TmpMod = TmpMod->Parent ;
3794
- }
3795
- std::reverse (importPath.begin (), importPath.end ());
3808
+ ImportPath::Builder importPath = getSwiftModulePath (Ctx, ImportedMod);
3796
3809
3797
3810
bool IsExported = false ;
3798
3811
for (auto *ExportedMod : Exported) {
@@ -8756,6 +8769,22 @@ bool importer::isCxxStdModule(StringRef moduleName, bool IsSystem) {
8756
8769
return false ;
8757
8770
}
8758
8771
8772
+ ImportPath::Builder importer::getSwiftModulePath (ASTContext &SwiftContext, const clang::Module *M) {
8773
+ if (isCxxStdModule (M))
8774
+ return ImportPath::Builder (SwiftContext.Id_CxxStdlib );
8775
+ ImportPath::Builder builder;
8776
+ while (M) {
8777
+ builder.push_back (SwiftContext.getIdentifier (M->Name ));
8778
+ M = M->Parent ;
8779
+ }
8780
+ std::reverse (builder.begin (), builder.end ());
8781
+ return builder;
8782
+ }
8783
+
8784
+ ImportPath::Builder ClangImporter::Implementation::getSwiftModulePath (const clang::Module *M) {
8785
+ return ::getSwiftModulePath (SwiftContext, M);
8786
+ }
8787
+
8759
8788
std::optional<clang::QualType>
8760
8789
importer::getCxxReferencePointeeTypeOrNone (const clang::Type *type) {
8761
8790
if (type->isReferenceType ())
0 commit comments