diff --git a/include/swift/AST/ASTContext.h b/include/swift/AST/ASTContext.h index 80156adc89c..c136634716a 100644 --- a/include/swift/AST/ASTContext.h +++ b/include/swift/AST/ASTContext.h @@ -1250,6 +1250,13 @@ public: /// in this context. void addLoadedModule(ModuleDecl *M); + /// Remove an externally-sourced module from the set of known loaded modules + /// in this context. Modules are added to the cache before being loaded to + /// avoid loading a module twice when there is a cyclic dependency between an + /// overlay and its Clang module. If a module import fails, the non-imported + /// module should be removed from the cache again. + void removeLoadedModule(Identifier RealName); + /// Change the behavior of all loaders to ignore swiftmodules next to /// swiftinterfaces. void setIgnoreAdjacentModules(bool value); diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 01110d8809c..add9e262454 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -2267,6 +2267,10 @@ void ASTContext::addLoadedModule(ModuleDecl *M) { getImpl().LoadedModules[M->getRealName()] = M; } +void ASTContext::removeLoadedModule(Identifier RealName) { + getImpl().LoadedModules.erase(RealName); +} + void ASTContext::setIgnoreAdjacentModules(bool value) { IgnoreAdjacentModules = value; } diff --git a/lib/Serialization/SerializedModuleLoader.cpp b/lib/Serialization/SerializedModuleLoader.cpp index f7089856023..3eb0cf981b6 100644 --- a/lib/Serialization/SerializedModuleLoader.cpp +++ b/lib/Serialization/SerializedModuleLoader.cpp @@ -1527,12 +1527,16 @@ MemoryBufferSerializedModuleLoader::loadModule(SourceLoc importLoc, auto *M = ModuleDecl::create(moduleID.Item, Ctx); SWIFT_DEFER { M->setHasResolvedImports(); }; + if (AllowMemoryCache) + Ctx.addLoadedModule(M); auto *file = loadAST(*M, moduleID.Loc, /*moduleInterfacePath=*/"", /*moduleInterfaceSourcePath=*/"", std::move(moduleInputBuffer), {}, {}, isFramework); - if (!file) + if (!file) { + Ctx.removeLoadedModule(moduleID.Item); return nullptr; + } // The MemoryBuffer loader is used by LLDB during debugging. Modules imported // from .swift_ast sections are never produced from textual interfaces. By @@ -1540,8 +1544,6 @@ MemoryBufferSerializedModuleLoader::loadModule(SourceLoc importLoc, if (BypassResilience) M->setBypassResilience(); M->addFile(*file); - if (AllowMemoryCache) - Ctx.addLoadedModule(M); return M; } diff --git a/test/DWARFImporter/basic.swift b/test/DWARFImporter/basic.swift index a5c30f96495..57490f61dd2 100644 --- a/test/DWARFImporter/basic.swift +++ b/test/DWARFImporter/basic.swift @@ -16,9 +16,13 @@ // RUN: %lldb-moduleimport-test -verbose -dump-module %t/a.out \ // RUN: -dummy-dwarfimporter | %FileCheck %s --check-prefix=SWIFTONLY -// CHECK: Importing basic... ok! -// FAIL: Importing basic... ok! -// SWIFTONLY: Importing basic... ok! +// CHECK: Importing basic... +// CHECK: Import successful! +// FAIL: Importing basic... +// FAIL: Import successful! +// SWIFTONLY: Importing basic... +// SWIFTONLY: Import successful! + import ObjCModule let pureSwift = Int32(42) diff --git a/test/DebugInfo/ASTSection-multi.swift b/test/DebugInfo/ASTSection-multi.swift index 3d719608841..1ef3c531de2 100644 --- a/test/DebugInfo/ASTSection-multi.swift +++ b/test/DebugInfo/ASTSection-multi.swift @@ -42,8 +42,11 @@ // RUN: %t/a3.o %t/a3-mod.o // RUN: %lldb-moduleimport-test -verbose %t/a.out | %FileCheck %s -// CHECK: Importing a0... ok! -// CHECK: Importing a1... ok! -// CHECK: Importing a2... ok! -// CHECK: Importing a3... ok! +// CHECK-DAG: Importing a0... +// CHECK-DAG: Import successful! +// CHECK-DAG: Importing a1... +// CHECK-DAG: Import successful! +// CHECK-DAG: Importing a2... +// CHECK-DAG: Import successful! +// CHECK-DAG: Importing a3... diff --git a/test/DebugInfo/ASTSection-single.swift b/test/DebugInfo/ASTSection-single.swift index 11b4fc260d5..ab434c725a8 100644 --- a/test/DebugInfo/ASTSection-single.swift +++ b/test/DebugInfo/ASTSection-single.swift @@ -11,4 +11,5 @@ // RUN: %lldb-moduleimport-test -verbose %t/a0-mod.o | %FileCheck %s // CHECK: Path: {{.*}}/Inputs, framework=false, system=false -// CHECK: Importing a0... ok! +// CHECK: Importing a0... +// CHECK: Import successful! diff --git a/test/DebugInfo/ASTSection.swift b/test/DebugInfo/ASTSection.swift index b55b5faedd3..33fcb54dd88 100644 --- a/test/DebugInfo/ASTSection.swift +++ b/test/DebugInfo/ASTSection.swift @@ -26,7 +26,8 @@ func objCUser(_ obj: ObjCClass) {} #endif // CHECK: - Target: {{.+}}-{{.+}}-{{.+}} -// CHECK: Importing ASTSection... ok! +// CHECK: Importing ASTSection... +// CHECK: Import successful! // LINETABLE-CHECK-NOT: ASTSection diff --git a/test/DebugInfo/ASTSectionOverlay.swift b/test/DebugInfo/ASTSectionOverlay.swift new file mode 100644 index 00000000000..7c561cc1bf1 --- /dev/null +++ b/test/DebugInfo/ASTSectionOverlay.swift @@ -0,0 +1,16 @@ +// REQUIRES: executable_test +// REQUIRES: objc_interop + +// RUN: %empty-directory(%t) +// RUN: %target-build-swift -emit-module %S/Inputs/overlay.swift -module-name ClangModuleWithOverlay -I %S/Inputs -emit-module-path %t/ClangModuleWithOverlay.swiftmodule +// RUN: %target-build-swift -c %S/Inputs/overlay.swift -module-name ClangModuleWithOverlay -I %S/Inputs -o %t/ClangModuleWithOverlay.o -parse-as-library +// RUN: %target-build-swift -emit-executable %s %t/ClangModuleWithOverlay.o -I %t -g -o %t/ASTSectionOverlay -module-name ASTSectionOverlay -emit-module -Xlinker -add_ast_path -Xlinker %t/ClangModuleWithOverlay.swiftmodule + +// RUN: %lldb-moduleimport-test -verbose %t/ASTSectionOverlay | %FileCheck %s +// CHECK: Loading ClangModuleWithOverlay +// CHECK-NOT: Loading (overlay) ClangModuleWithOverlay +// CHECK-NOT: Loading{{.*}}ClangModuleWithOverlay + +import ClangModuleWithOverlay +let c = ClangType(i: 0) +fromSwiftOverlay() diff --git a/test/DebugInfo/ASTSection_ObjC.swift b/test/DebugInfo/ASTSection_ObjC.swift index 35f8bf3a885..872c114f06a 100644 --- a/test/DebugInfo/ASTSection_ObjC.swift +++ b/test/DebugInfo/ASTSection_ObjC.swift @@ -14,6 +14,7 @@ // RUN: %lldb-moduleimport-test -verbose %t/ASTSection | %FileCheck %s --allow-empty --check-prefix=LINETABLE-CHECK // CHECK: - Target: {{.+}}-{{.+}}-{{.+}} -// CHECK: Importing ASTSection... ok! +// CHECK: Importing ASTSection... +// CHECK: Import successful! // LINETABLE-CHECK-NOT: ASTSection diff --git a/test/DebugInfo/ASTSection_linker.swift b/test/DebugInfo/ASTSection_linker.swift index dcf3b9f94ff..cda2450c836 100644 --- a/test/DebugInfo/ASTSection_linker.swift +++ b/test/DebugInfo/ASTSection_linker.swift @@ -21,4 +21,6 @@ // CHECK: - Target: {{.+}}-{{.+}}-{{.+}} // CHECK: - SDK path: {{.*}}MacOS{{.*}}.sdk // CHECK: - -Xcc options: -working-directory {{.+}} -DA -DB -// CHECK: Importing ASTSection... ok! +// CHECK: Importing ASTSection... +// CHECK: Import successful! + diff --git a/test/DebugInfo/Inputs/ClangModuleWithOverlay.h b/test/DebugInfo/Inputs/ClangModuleWithOverlay.h new file mode 100644 index 00000000000..0957ab6f8cf --- /dev/null +++ b/test/DebugInfo/Inputs/ClangModuleWithOverlay.h @@ -0,0 +1,3 @@ +struct ClangType { + int i; +}; diff --git a/test/DebugInfo/Inputs/module.modulemap b/test/DebugInfo/Inputs/module.modulemap index 8153b4ecf54..5dd48f36d74 100644 --- a/test/DebugInfo/Inputs/module.modulemap +++ b/test/DebugInfo/Inputs/module.modulemap @@ -20,3 +20,7 @@ module Macro { header "Macro.h" } +module ClangModuleWithOverlay { + header "ClangModuleWithOverlay.h" + export * +} diff --git a/test/DebugInfo/Inputs/overlay.swift b/test/DebugInfo/Inputs/overlay.swift new file mode 100644 index 00000000000..80ee1ebc66a --- /dev/null +++ b/test/DebugInfo/Inputs/overlay.swift @@ -0,0 +1,3 @@ +@_exported import ClangModuleWithOverlay + +public func fromSwiftOverlay() {} diff --git a/tools/lldb-moduleimport-test/lldb-moduleimport-test.cpp b/tools/lldb-moduleimport-test/lldb-moduleimport-test.cpp index 3ef93ca99d8..3664f45db48 100644 --- a/tools/lldb-moduleimport-test/lldb-moduleimport-test.cpp +++ b/tools/lldb-moduleimport-test/lldb-moduleimport-test.cpp @@ -381,7 +381,25 @@ int main(int argc, char **argv) { auto *ClangImporter = static_cast( CI.getASTContext().getClangModuleLoader()); ClangImporter->setDWARFImporterDelegate(dummyDWARFImporter); - } + } + + if (Verbose) + CI.getASTContext().SetPreModuleImportCallback( + [&](llvm::StringRef module_name, + swift::ASTContext::ModuleImportKind kind) { + switch (kind) { + case swift::ASTContext::Module: + llvm::outs() << "Loading " << module_name.str() << "\n"; + break; + case swift::ASTContext::Overlay: + llvm::outs() << "Loading (overlay) " << module_name.str() << "\n"; + break; + case swift::ASTContext::BridgingHeader: + llvm::outs() << "Compiling bridging header: " << module_name.str() + << "\n"; + break; + } + }); llvm::SmallString<0> error; llvm::raw_svector_ostream errs(error); @@ -401,7 +419,7 @@ int main(int argc, char **argv) { // Attempt to import all modules we found. for (auto path : modules) { if (Verbose) - llvm::outs() << "Importing " << path << "... "; + llvm::outs() << "Importing " << path << "...\n"; swift::ImportPath::Module::Builder modulePath; #ifdef SWIFT_SUPPORTS_SUBMODULES @@ -420,7 +438,7 @@ int main(int argc, char **argv) { return 1; } if (Verbose) - llvm::outs() << "ok!\n"; + llvm::outs() << "Import successful!\n"; if (DumpModule) { llvm::SmallVector Decls; Module->getTopLevelDecls(Decls);