diff --git a/include/swift/AST/Module.h b/include/swift/AST/Module.h index e6b2077189478..4a78fd02e94e2 100644 --- a/include/swift/AST/Module.h +++ b/include/swift/AST/Module.h @@ -173,6 +173,8 @@ class ModuleDecl /// The ABI name of the module, if it differs from the module name. mutable Identifier ModuleABIName; + /// The name of the package this module belongs to + mutable Identifier PackageName; public: /// Produces the components of a given module's full name in reverse order. /// @@ -400,6 +402,14 @@ class ModuleDecl ModuleABIName = name; } + /// Get the package name of the module + Identifier getPackageName() const { return PackageName; } + + /// Set the name of the package this module belongs to + void setPackageName(Identifier name) { + PackageName = name; + } + /// Retrieve the actual module name of an alias used for this module (if any). /// /// For example, if '-module-alias Foo=Bar' is passed in when building the main module, diff --git a/include/swift/Frontend/FrontendOptions.h b/include/swift/Frontend/FrontendOptions.h index 01dc7f12f68e6..c47fdaae886e7 100644 --- a/include/swift/Frontend/FrontendOptions.h +++ b/include/swift/Frontend/FrontendOptions.h @@ -64,6 +64,9 @@ class FrontendOptions { /// The name of the library to link against when using this module. std::string ModuleLinkName; + /// The name of the package this module belongs to. + std::string PackageName; + /// Arguments which should be passed in immediate mode. std::vector ImmediateArgv; diff --git a/include/swift/Option/Options.td b/include/swift/Option/Options.td index f745c8634891a..02300bd795117 100644 --- a/include/swift/Option/Options.td +++ b/include/swift/Option/Options.td @@ -481,6 +481,9 @@ def autolink_force_load : Flag<["-"], "autolink-force-load">, def module_abi_name : Separate<["-"], "module-abi-name">, Flags<[FrontendOption, ModuleInterfaceOption]>, HelpText<"ABI name to use for the contents of this module">; +def package_name : Separate<["-"], "package-name">, + Flags<[FrontendOption, ModuleInterfaceOptionIgnorable]>, + HelpText<"Name of the package the module belongs to">; def emit_module : Flag<["-"], "emit-module">, Flags<[FrontendOption, NoInteractiveOption, SupplementaryOutput]>, diff --git a/include/swift/Serialization/Validation.h b/include/swift/Serialization/Validation.h index dd83ece9be8c9..99517345ecccf 100644 --- a/include/swift/Serialization/Validation.h +++ b/include/swift/Serialization/Validation.h @@ -107,6 +107,7 @@ class ExtendedValidationInfo { SmallVector ExtraClangImporterOpts; std::string SDKPath; StringRef ModuleABIName; + StringRef ModulePackageName; struct { unsigned ArePrivateImportsEnabled : 1; unsigned IsSIB : 1; @@ -179,6 +180,9 @@ class ExtendedValidationInfo { StringRef getModuleABIName() const { return ModuleABIName; } void setModuleABIName(StringRef name) { ModuleABIName = name; } + StringRef getModulePackageName() const { return ModulePackageName; } + void setModulePackageName(StringRef name) { ModulePackageName = name; } + bool isConcurrencyChecked() const { return Bits.IsConcurrencyChecked; } diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index 26d42bd2a8073..c0ee9217e86fa 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -252,6 +252,7 @@ void ToolChain::addCommonFrontendArgs(const OutputInfo &OI, inputArgs.AddLastArg(arguments, options::OPT_module_cache_path); inputArgs.AddLastArg(arguments, options::OPT_module_link_name); inputArgs.AddLastArg(arguments, options::OPT_module_abi_name); + inputArgs.AddLastArg(arguments, options::OPT_package_name); inputArgs.AddLastArg(arguments, options::OPT_nostdimport); inputArgs.AddLastArg(arguments, options::OPT_parse_stdlib); inputArgs.AddLastArg(arguments, options::OPT_resource_dir); diff --git a/lib/Frontend/ArgsToFrontendOptionsConverter.cpp b/lib/Frontend/ArgsToFrontendOptionsConverter.cpp index a9354dc84fedf..8b62929526033 100644 --- a/lib/Frontend/ArgsToFrontendOptionsConverter.cpp +++ b/lib/Frontend/ArgsToFrontendOptionsConverter.cpp @@ -269,6 +269,9 @@ bool ArgsToFrontendOptionsConverter::convert( if (const Arg *A = Args.getLastArg(OPT_module_link_name)) Opts.ModuleLinkName = A->getValue(); + if (const Arg *A = Args.getLastArg(OPT_package_name)) + Opts.PackageName = A->getValue(); + // This must be called after computing module name, module abi name, // and module link name. If computing module aliases is unsuccessful, // return early. diff --git a/lib/Frontend/Frontend.cpp b/lib/Frontend/Frontend.cpp index 6ee558dc03de1..17f75a72987fa 100644 --- a/lib/Frontend/Frontend.cpp +++ b/lib/Frontend/Frontend.cpp @@ -1059,6 +1059,10 @@ ModuleDecl *CompilerInstance::getMainModule() const { MainModule->setABIName(getASTContext().getIdentifier( Invocation.getFrontendOptions().ModuleABIName)); } + if (!Invocation.getFrontendOptions().PackageName.empty()) { + MainModule->setPackageName(getASTContext().getIdentifier( + Invocation.getFrontendOptions().PackageName)); + } if (Invocation.getFrontendOptions().EnableLibraryEvolution) MainModule->setResilienceStrategy(ResilienceStrategy::Resilient); if (Invocation.getLangOptions().isSwiftVersionAtLeast(6)) diff --git a/lib/Serialization/ModuleFile.h b/lib/Serialization/ModuleFile.h index 0eca215cf0c3b..186258478f4df 100644 --- a/lib/Serialization/ModuleFile.h +++ b/lib/Serialization/ModuleFile.h @@ -532,6 +532,9 @@ class ModuleFile return Core->Name; } + StringRef getModulePackageName() const { + return Core->ModulePackageName; + } /// The ABI name of the module. StringRef getModuleABIName() const { return Core->ModuleABIName; diff --git a/lib/Serialization/ModuleFileSharedCore.cpp b/lib/Serialization/ModuleFileSharedCore.cpp index dd8085c787877..95d080f3a591b 100644 --- a/lib/Serialization/ModuleFileSharedCore.cpp +++ b/lib/Serialization/ModuleFileSharedCore.cpp @@ -163,6 +163,9 @@ static bool readOptionsBlock(llvm::BitstreamCursor &cursor, case options_block::IS_CONCURRENCY_CHECKED: extendedInfo.setIsConcurrencyChecked(true); break; + case options_block::MODULE_PACKAGE_NAME: + extendedInfo.setModulePackageName(blobData); + break; default: // Unknown options record, possibly for use by a future version of the // module format. @@ -1346,6 +1349,7 @@ ModuleFileSharedCore::ModuleFileSharedCore( Bits.IsConcurrencyChecked = extInfo.isConcurrencyChecked(); MiscVersion = info.miscVersion; ModuleABIName = extInfo.getModuleABIName(); + ModulePackageName = extInfo.getModulePackageName(); hasValidControlBlock = true; break; diff --git a/lib/Serialization/ModuleFileSharedCore.h b/lib/Serialization/ModuleFileSharedCore.h index b4e4fa601d19f..b9b2b66b921cf 100644 --- a/lib/Serialization/ModuleFileSharedCore.h +++ b/lib/Serialization/ModuleFileSharedCore.h @@ -82,6 +82,9 @@ class ModuleFileSharedCore { /// The module ABI name. StringRef ModuleABIName; + /// The name of the package this module belongs to. + StringRef ModulePackageName; + /// \c true if this module has incremental dependency information. bool HasIncrementalInfo = false; diff --git a/lib/Serialization/ModuleFormat.h b/lib/Serialization/ModuleFormat.h index c3973648a4082..5565f5d4fbef9 100644 --- a/lib/Serialization/ModuleFormat.h +++ b/lib/Serialization/ModuleFormat.h @@ -58,7 +58,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0; /// describe what change you made. The content of this comment isn't important; /// it just ensures a conflict if two people change the module format. /// Don't worry about adhering to the 80-column limit for this line. -const uint16_t SWIFTMODULE_VERSION_MINOR = 727; // closure capture args +const uint16_t SWIFTMODULE_VERSION_MINOR = 728; // package name field /// A standard hash seed used for all string hashes in a serialized module. /// @@ -836,6 +836,7 @@ namespace options_block { IS_ALLOW_MODULE_WITH_COMPILER_ERRORS_ENABLED, MODULE_ABI_NAME, IS_CONCURRENCY_CHECKED, + MODULE_PACKAGE_NAME, }; using SDKPathLayout = BCRecordLayout< @@ -894,6 +895,11 @@ namespace options_block { using IsConcurrencyCheckedLayout = BCRecordLayout< IS_CONCURRENCY_CHECKED >; + + using ModulePackageNameLayout = BCRecordLayout< + MODULE_PACKAGE_NAME, + BCBlob + >; } /// The record types within the input block. diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp index cc8e5233ecf16..d1c4e39a2aa00 100644 --- a/lib/Serialization/Serialization.cpp +++ b/lib/Serialization/Serialization.cpp @@ -842,6 +842,7 @@ void Serializer::writeBlockInfoBlock() { BLOCK_RECORD(options_block, IS_ALLOW_MODULE_WITH_COMPILER_ERRORS_ENABLED); BLOCK_RECORD(options_block, MODULE_ABI_NAME); BLOCK_RECORD(options_block, IS_CONCURRENCY_CHECKED); + BLOCK_RECORD(options_block, MODULE_PACKAGE_NAME); BLOCK(INPUT_BLOCK); BLOCK_RECORD(input_block, IMPORTED_MODULE); @@ -1064,6 +1065,11 @@ void Serializer::writeHeader(const SerializationOptions &options) { ABIName.emit(ScratchRecord, M->getABIName().str()); } + if (!M->getPackageName().empty()) { + options_block::ModulePackageNameLayout PackageName(Out); + PackageName.emit(ScratchRecord, M->getPackageName().str()); + } + if (M->isConcurrencyChecked()) { options_block::IsConcurrencyCheckedLayout IsConcurrencyChecked(Out); IsConcurrencyChecked.emit(ScratchRecord); diff --git a/lib/Serialization/SerializedModuleLoader.cpp b/lib/Serialization/SerializedModuleLoader.cpp index e9080e3a25f29..360585f53d115 100644 --- a/lib/Serialization/SerializedModuleLoader.cpp +++ b/lib/Serialization/SerializedModuleLoader.cpp @@ -779,6 +779,8 @@ LoadedFile *SerializedModuleLoaderBase::loadAST( M.setABIName(Ctx.getIdentifier(loadedModuleFile->getModuleABIName())); if (loadedModuleFile->isConcurrencyChecked()) M.setIsConcurrencyChecked(); + if (!loadedModuleFile->getModulePackageName().empty()) + M.setPackageName(Ctx.getIdentifier(loadedModuleFile->getModulePackageName())); M.setUserModuleVersion(loadedModuleFile->getUserModuleVersion()); for (auto name: loadedModuleFile->getAllowableClientNames()) { M.addAllowableClientName(Ctx.getIdentifier(name)); diff --git a/test/Serialization/module_package_name.swift b/test/Serialization/module_package_name.swift new file mode 100644 index 0000000000000..5dc1512337af3 --- /dev/null +++ b/test/Serialization/module_package_name.swift @@ -0,0 +1,15 @@ +// RUN: %empty-directory(%t) +// RUN: %{python} %utils/split_file.py -o %t %s + +// RUN: %target-swift-frontend -module-name Logging -package-name MyLoggingPkg %t/File.swift -emit-module -emit-module-path %t/Logging.swiftmodule +// RUN: test -f %t/Logging.swiftmodule +// RUN: llvm-bcanalyzer -dump %t/Logging.swiftmodule | %FileCheck %s -check-prefix CHECK-BLOB +// CHECK-BLOB: blob data = 'MyLoggingPkg' + +// RUN: %target-swift-frontend -module-name Logging -package-name MyLoggingPkg %t/File.swift -emit-module -emit-module-interface-path %t/Logging.swiftinterface -swift-version 5 -enable-library-evolution -I %t +// RUN: test -f %t/Logging.swiftinterface +// RUN: %FileCheck %s -input-file %t/Logging.swiftinterface -check-prefix CHECK-FLAG +// CHECK-FLAG: -package-name MyLoggingPkg + +// BEGIN File.swift +public func log(level: Int) {}