diff --git a/include/swift-c/DependencyScan/DependencyScan.h b/include/swift-c/DependencyScan/DependencyScan.h index 72a97da2ef3f8..4e2132cdbc021 100644 --- a/include/swift-c/DependencyScan/DependencyScan.h +++ b/include/swift-c/DependencyScan/DependencyScan.h @@ -217,6 +217,10 @@ SWIFTSCAN_PUBLIC swiftscan_string_ref_t swiftscan_swift_textual_detail_get_module_cache_key( swiftscan_module_details_t details); +SWIFTSCAN_PUBLIC swiftscan_string_ref_t +swiftscan_swift_textual_detail_get_user_module_version( + swiftscan_module_details_t details); + //=== Swift Binary Module Details query APIs ------------------------------===// SWIFTSCAN_PUBLIC swiftscan_string_ref_t diff --git a/include/swift/AST/ModuleDependencies.h b/include/swift/AST/ModuleDependencies.h index 992ee34b41ec7..7e9599ff664df 100644 --- a/include/swift/AST/ModuleDependencies.h +++ b/include/swift/AST/ModuleDependencies.h @@ -294,12 +294,16 @@ class SwiftInterfaceModuleDependenciesStorage /// Details common to Swift textual (interface or source) modules CommonSwiftTextualModuleDependencyDetails textualModuleDetails; + /// The user module version of this textual module interface. + const std::string userModuleVersion; + SwiftInterfaceModuleDependenciesStorage( StringRef moduleOutputPath, StringRef swiftInterfaceFile, ArrayRef compiledModuleCandidates, ArrayRef buildCommandLine, ArrayRef linkLibraries, ArrayRef extraPCMArgs, StringRef contextHash, bool isFramework, - bool isStatic, StringRef RootID, StringRef moduleCacheKey) + bool isStatic, StringRef RootID, StringRef moduleCacheKey, + StringRef userModuleVersion) : ModuleDependencyInfoStorageBase(ModuleDependencyKind::SwiftInterface, linkLibraries, moduleCacheKey), moduleOutputPath(moduleOutputPath), @@ -307,7 +311,8 @@ class SwiftInterfaceModuleDependenciesStorage compiledModuleCandidates(compiledModuleCandidates.begin(), compiledModuleCandidates.end()), contextHash(contextHash), isFramework(isFramework), isStatic(isStatic), - textualModuleDetails(extraPCMArgs, buildCommandLine, RootID) {} + textualModuleDetails(extraPCMArgs, buildCommandLine, RootID), + userModuleVersion(userModuleVersion) {} ModuleDependencyInfoStorageBase *clone() const override { return new SwiftInterfaceModuleDependenciesStorage(*this); @@ -592,12 +597,14 @@ class ModuleDependencyInfo { ArrayRef compiledCandidates, ArrayRef buildCommands, ArrayRef linkLibraries, ArrayRef extraPCMArgs, StringRef contextHash, bool isFramework, bool isStatic, - StringRef CASFileSystemRootID, StringRef moduleCacheKey) { + StringRef CASFileSystemRootID, StringRef moduleCacheKey, + StringRef userModuleVersion) { return ModuleDependencyInfo( std::make_unique( moduleOutputPath, swiftInterfaceFile, compiledCandidates, buildCommands, linkLibraries, extraPCMArgs, contextHash, - isFramework, isStatic, CASFileSystemRootID, moduleCacheKey)); + isFramework, isStatic, CASFileSystemRootID, moduleCacheKey, + userModuleVersion)); } /// Describe the module dependencies for a serialized or parsed Swift module. diff --git a/include/swift/AST/ModuleLoader.h b/include/swift/AST/ModuleLoader.h index f811454e70f69..10e12c812571b 100644 --- a/include/swift/AST/ModuleLoader.h +++ b/include/swift/AST/ModuleLoader.h @@ -214,7 +214,8 @@ struct InterfaceSubContextDelegate { SourceLoc diagLoc, llvm::function_ref, - ArrayRef, StringRef)> action) = 0; + ArrayRef, StringRef, + StringRef)> action) = 0; virtual std::error_code runInSubCompilerInstance(StringRef moduleName, StringRef interfacePath, StringRef sdkPath, diff --git a/include/swift/DependencyScan/DependencyScanImpl.h b/include/swift/DependencyScan/DependencyScanImpl.h index 69a5a817a8462..bea17618eed04 100644 --- a/include/swift/DependencyScan/DependencyScanImpl.h +++ b/include/swift/DependencyScan/DependencyScanImpl.h @@ -132,6 +132,9 @@ typedef struct { /// Macro dependecies. swiftscan_macro_dependency_set_t *macro_dependencies; + + /// User module version + swiftscan_string_ref_t user_module_version; } swiftscan_swift_textual_details_t; /// Swift modules with only a binary module file. diff --git a/include/swift/DependencyScan/SerializedModuleDependencyCacheFormat.h b/include/swift/DependencyScan/SerializedModuleDependencyCacheFormat.h index d8f7c0795088d..546d38bc3de1f 100644 --- a/include/swift/DependencyScan/SerializedModuleDependencyCacheFormat.h +++ b/include/swift/DependencyScan/SerializedModuleDependencyCacheFormat.h @@ -150,7 +150,8 @@ using SwiftInterfaceModuleDetailsLayout = DependencyIDArrayIDField, // swiftOverlayDependencies IdentifierIDField, // CASFileSystemRootID IdentifierIDField, // bridgingHeaderIncludeTree - IdentifierIDField // moduleCacheKey + IdentifierIDField, // moduleCacheKey + IdentifierIDField // UserModuleVersion >; using SwiftSourceModuleDetailsLayout = diff --git a/include/swift/Frontend/ModuleInterfaceLoader.h b/include/swift/Frontend/ModuleInterfaceLoader.h index 4f82b217ae3e6..cab9f91a63e1f 100644 --- a/include/swift/Frontend/ModuleInterfaceLoader.h +++ b/include/swift/Frontend/ModuleInterfaceLoader.h @@ -688,7 +688,7 @@ struct InterfaceSubContextDelegateImpl: InterfaceSubContextDelegate { SourceLoc diagLoc, llvm::function_ref, ArrayRef, - StringRef)> action) override; + StringRef, StringRef)> action) override; std::error_code runInSubCompilerInstance(StringRef moduleName, StringRef interfacePath, StringRef sdkPath, diff --git a/lib/DependencyScan/DependencyScanJSON.cpp b/lib/DependencyScan/DependencyScanJSON.cpp index 78384bb35dd57..7076b06d3c088 100644 --- a/lib/DependencyScan/DependencyScanJSON.cpp +++ b/lib/DependencyScan/DependencyScanJSON.cpp @@ -456,6 +456,9 @@ void writeJSON(llvm::raw_ostream &out, swiftTextualDeps->module_cache_key, 5, /*trailingComma=*/true); } + writeJSONSingleField(out, "userModuleVersion", + swiftTextualDeps->user_module_version, 5, + /*trailingComma=*/true); writeMacroDependencies(out, swiftTextualDeps->macro_dependencies, 5, /*trailingComma=*/true); writeJSONSingleField(out, "isFramework", swiftTextualDeps->is_framework, diff --git a/lib/DependencyScan/ModuleDependencyCacheSerialization.cpp b/lib/DependencyScan/ModuleDependencyCacheSerialization.cpp index 78f7d843d9e48..014be2f48a0b4 100644 --- a/lib/DependencyScan/ModuleDependencyCacheSerialization.cpp +++ b/lib/DependencyScan/ModuleDependencyCacheSerialization.cpp @@ -255,14 +255,15 @@ bool ModuleDependenciesCacheDeserializer::readGraph(SwiftDependencyScanningServi extraPCMArgsArrayID, contextHashID, isFramework, isStatic, bridgingHeaderFileID, sourceFilesArrayID, bridgingSourceFilesArrayID, bridgingModuleDependenciesArrayID, overlayDependencyIDArrayID, - CASFileSystemRootID, bridgingHeaderIncludeTreeID, moduleCacheKeyID; + CASFileSystemRootID, bridgingHeaderIncludeTreeID, moduleCacheKeyID, + userModuleVersionID; SwiftInterfaceModuleDetailsLayout::readRecord( Scratch, outputPathFileID, interfaceFileID, compiledModuleCandidatesArrayID, buildCommandLineArrayID, extraPCMArgsArrayID, contextHashID, isFramework, isStatic, bridgingHeaderFileID, sourceFilesArrayID, bridgingSourceFilesArrayID, bridgingModuleDependenciesArrayID, overlayDependencyIDArrayID, - CASFileSystemRootID, bridgingHeaderIncludeTreeID, moduleCacheKeyID); + CASFileSystemRootID, bridgingHeaderIncludeTreeID, moduleCacheKeyID, userModuleVersionID); auto outputModulePath = getIdentifier(outputPathFileID); if (!outputModulePath) @@ -304,13 +305,17 @@ bool ModuleDependenciesCacheDeserializer::readGraph(SwiftDependencyScanningServi auto moduleCacheKey = getIdentifier(moduleCacheKeyID); if (!moduleCacheKeyID) llvm::report_fatal_error("Bad moduleCacheKey"); + auto userModuleVersion = getIdentifier(userModuleVersionID); + if (!userModuleVersion) + llvm::report_fatal_error("Bad userModuleVersion"); // TODO: LinkLibraries, MacroDependencies // Form the dependencies storage object auto moduleDep = ModuleDependencyInfo::forSwiftInterfaceModule( outputModulePath.value(), optionalSwiftInterfaceFile.value(), compiledCandidatesRefs, buildCommandRefs, {}, extraPCMRefs, - *contextHash, isFramework, isStatic, *rootFileSystemID, *moduleCacheKey); + *contextHash, isFramework, isStatic, *rootFileSystemID, *moduleCacheKey, + *userModuleVersion); // Add imports of this module for (const auto &moduleName : currentModuleImports) @@ -1007,7 +1012,8 @@ void ModuleDependenciesCacheSerializer::writeModuleInfo( getIdentifier(swiftTextDeps->textualModuleDetails.CASFileSystemRootID), getIdentifier(swiftTextDeps->textualModuleDetails .CASBridgingHeaderIncludeTreeRootID), - getIdentifier(swiftTextDeps->moduleCacheKey)); + getIdentifier(swiftTextDeps->moduleCacheKey), + getIdentifier(swiftTextDeps->userModuleVersion)); break; } case swift::ModuleDependencyKind::SwiftSource: { diff --git a/lib/DependencyScan/ScanDependencies.cpp b/lib/DependencyScan/ScanDependencies.cpp index 9afe2b767b348..4f96100195b57 100644 --- a/lib/DependencyScan/ScanDependencies.cpp +++ b/lib/DependencyScan/ScanDependencies.cpp @@ -701,7 +701,8 @@ generateFullDependencyGraph(const CompilerInstance &instance, .CASBridgingHeaderIncludeTreeRootID.c_str()), create_clone(swiftTextualDeps->moduleCacheKey.c_str()), createMacroDependencySet( - swiftTextualDeps->textualModuleDetails.macroDependencies)}; + swiftTextualDeps->textualModuleDetails.macroDependencies), + create_clone(swiftTextualDeps->userModuleVersion.c_str())}; } else if (swiftSourceDeps) { swiftscan_string_ref_t moduleInterfacePath = create_null(); swiftscan_string_ref_t bridgingHeaderPath = diff --git a/lib/Frontend/ModuleInterfaceLoader.cpp b/lib/Frontend/ModuleInterfaceLoader.cpp index c15909bcf811e..6002546fd8a57 100644 --- a/lib/Frontend/ModuleInterfaceLoader.cpp +++ b/lib/Frontend/ModuleInterfaceLoader.cpp @@ -2135,15 +2135,18 @@ InterfaceSubContextDelegateImpl::runInSubContext(StringRef moduleName, StringRef outputPath, SourceLoc diagLoc, llvm::function_ref, - ArrayRef, StringRef)> action) { + ArrayRef, StringRef, StringRef)> action) { return runInSubCompilerInstance(moduleName, interfacePath, sdkPath, outputPath, diagLoc, /*silenceErrors=*/false, [&](SubCompilerInstanceInfo &info){ + std::string UserModuleVer = info.Instance->getInvocation().getFrontendOptions() + .UserModuleVersion.getAsString(); return action(info.Instance->getASTContext(), info.Instance->getMainModule(), info.BuildArguments, info.ExtraPCMArgs, - info.Hash); + info.Hash, + UserModuleVer); }); } diff --git a/lib/Serialization/ScanningLoaders.cpp b/lib/Serialization/ScanningLoaders.cpp index 40e3747842c6d..436fe9151e669 100644 --- a/lib/Serialization/ScanningLoaders.cpp +++ b/lib/Serialization/ScanningLoaders.cpp @@ -154,7 +154,7 @@ SwiftModuleScanner::scanInterfaceFile(Twine moduleInterfacePath, realModuleName.str(), moduleInterfacePath.str(), sdkPath, StringRef(), SourceLoc(), [&](ASTContext &Ctx, ModuleDecl *mainMod, ArrayRef BaseArgs, - ArrayRef PCMArgs, StringRef Hash) { + ArrayRef PCMArgs, StringRef Hash, StringRef UserModVer) { assert(mainMod); std::string InPath = moduleInterfacePath.str(); auto compiledCandidates = @@ -247,7 +247,7 @@ SwiftModuleScanner::scanInterfaceFile(Twine moduleInterfacePath, Result = ModuleDependencyInfo::forSwiftInterfaceModule( outputPathBase.str().str(), InPath, compiledCandidatesRefs, ArgsRefs, linkLibraries, PCMArgs, Hash, isFramework, isStatic, {}, - /*module-cache-key*/ ""); + /*module-cache-key*/ "", UserModVer); if (Ctx.CASOpts.EnableCaching) { std::vector clangDependencyFiles; diff --git a/test/ScanDependencies/scan_return_module_version_textual_interface.swift b/test/ScanDependencies/scan_return_module_version_textual_interface.swift index d37c886a68082..59fa35116912b 100644 --- a/test/ScanDependencies/scan_return_module_version_textual_interface.swift +++ b/test/ScanDependencies/scan_return_module_version_textual_interface.swift @@ -4,6 +4,8 @@ // RUN: %empty-directory(%t/DependencyModules) // Emit a textual module dependency +// RUN: %target-swift-frontend -emit-module -emit-module-interface-path %t/DependencyModules/TextualFoo.swiftinterface -module-cache-path %t/clang-module-cache -module-name TextualFoo %s -D TEXTUAL_FOO -user-module-version 12.3.4 + // RUN: %target-swift-frontend -emit-module -emit-module-path %t/DependencyModules/Foo.swiftmodule -module-cache-path %t/clang-module-cache -module-name Foo %s -D FOO -user-module-version 42.3.3 // RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %t/DependencyModules/ -module-name main @@ -15,9 +17,14 @@ public func foo() {} +#elseif TEXTUAL_FOO + + #else import Foo +import TextualFoo #endif +// CHECK: "userModuleVersion": "12.3.4" // CHECK: "userModuleVersion": "42.3.3.0" diff --git a/tools/libSwiftScan/libSwiftScan.cpp b/tools/libSwiftScan/libSwiftScan.cpp index 168781fd642a8..be881588b2c60 100644 --- a/tools/libSwiftScan/libSwiftScan.cpp +++ b/tools/libSwiftScan/libSwiftScan.cpp @@ -74,6 +74,8 @@ void swiftscan_dependency_info_details_dispose( details_impl->swift_textual_details.module_cache_key); swiftscan_macro_dependency_dispose( details_impl->swift_textual_details.macro_dependencies); + swiftscan_string_dispose( + details_impl->swift_textual_details.user_module_version); break; case SWIFTSCAN_DEPENDENCY_INFO_SWIFT_BINARY: swiftscan_string_dispose( @@ -393,6 +395,11 @@ swiftscan_string_ref_t swiftscan_swift_textual_detail_get_module_cache_key( return details->swift_textual_details.module_cache_key; } +swiftscan_string_ref_t swiftscan_swift_textual_detail_get_user_module_version( + swiftscan_module_details_t details) { + return details->swift_textual_details.user_module_version; +} + //=== Swift Binary Module Details query APIs ------------------------------===// swiftscan_string_ref_t swiftscan_swift_binary_detail_get_compiled_module_path( diff --git a/tools/libSwiftScan/libSwiftScan.exports b/tools/libSwiftScan/libSwiftScan.exports index 28dae3f014e29..fe59e642a75e1 100644 --- a/tools/libSwiftScan/libSwiftScan.exports +++ b/tools/libSwiftScan/libSwiftScan.exports @@ -24,6 +24,7 @@ swiftscan_swift_textual_detail_get_is_framework swiftscan_swift_textual_detail_get_swift_overlay_dependencies swiftscan_swift_textual_detail_get_cas_fs_root_id swiftscan_swift_textual_detail_get_module_cache_key +swiftscan_swift_textual_detail_get_user_module_version swiftscan_swift_binary_detail_get_compiled_module_path swiftscan_swift_binary_detail_get_module_doc_path swiftscan_swift_binary_detail_get_module_source_info_path