Skip to content

Commit c7b383c

Browse files
authored
Merge pull request swiftlang#37177 from nkcsgexi/73992299-1
ModuleInterface/Serialization: allow library authors to define a custom module version number
2 parents 36f1c34 + 01800ff commit c7b383c

17 files changed

+79
-6
lines changed

include/swift/AST/Module.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,14 @@ class ModuleDecl : public DeclContext, public TypeDecl {
356356
ModuleABIName = name;
357357
}
358358

359+
/// User-defined module version number.
360+
llvm::VersionTuple UserModuleVersion;
361+
void setUserModuleVersion(llvm::VersionTuple UserVer) {
362+
UserModuleVersion = UserVer;
363+
}
364+
llvm::VersionTuple getUserModuleVersion() const {
365+
return UserModuleVersion;
366+
}
359367
private:
360368
/// A cache of this module's underlying module and required bystander if it's
361369
/// an underscored cross-import overlay.

include/swift/Frontend/FrontendOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ class FrontendOptions {
8484
/// For these modules, we should prefer using Swift interface when importing them.
8585
std::vector<std::string> PreferInterfaceForModules;
8686

87+
/// User-defined module version number.
88+
llvm::VersionTuple UserModuleVersion;
89+
8790
/// Emit index data for imported serialized swift system modules.
8891
bool IndexSystemModules = false;
8992

include/swift/Option/Options.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,6 +1172,11 @@ def working_directory : Separate<["-"], "working-directory">,
11721172
def working_directory_EQ : Joined<["-"], "working-directory=">,
11731173
Alias<working_directory>;
11741174

1175+
def user_module_version : Separate<["-"], "user-module-version">,
1176+
Flags<[FrontendOption, ModuleInterfaceOption]>,
1177+
HelpText<"Module version specified from Swift module authors">,
1178+
MetaVarName<"<vers>">;
1179+
11751180
// VFS
11761181

11771182
def vfsoverlay : JoinedOrSeparate<["-"], "vfsoverlay">,

include/swift/Serialization/SerializationOptions.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#define SWIFT_SERIALIZATION_SERIALIZATIONOPTIONS_H
1515

1616
#include "swift/Basic/LLVM.h"
17+
#include "llvm/Support/VersionTuple.h"
1718

1819
namespace swift {
1920

@@ -32,6 +33,7 @@ namespace swift {
3233
const char *SourceInfoOutputPath = nullptr;
3334
std::string SymbolGraphOutputDir;
3435
bool SkipSymbolGraphInheritedDocs = true;
36+
llvm::VersionTuple UserModuleVersion;
3537

3638
StringRef GroupInfoPath;
3739
StringRef ImportedHeader;

include/swift/Serialization/Validation.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ struct ValidationInfo {
7979
StringRef shortVersion = {};
8080
StringRef miscVersion = {};
8181
version::Version compatibilityVersion = {};
82+
llvm::VersionTuple userModuleVersion;
8283
size_t bytes = 0;
8384
Status status = Status::Malformed;
8485
};

lib/Frontend/ArgsToFrontendOptionsConverter.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,13 @@ bool ArgsToFrontendOptionsConverter::convert(
9999
Opts.BadFileDescriptorRetryCount = limit;
100100
}
101101

102+
if (auto A = Args.getLastArg(OPT_user_module_version)) {
103+
if (Opts.UserModuleVersion.tryParse(StringRef(A->getValue()))) {
104+
Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
105+
A->getAsString(Args), A->getValue());
106+
}
107+
}
108+
102109
Opts.DisableImplicitModules |= Args.hasArg(OPT_disable_implicit_swift_modules);
103110

104111
Opts.ImportPrescan |= Args.hasArg(OPT_import_prescan);

lib/Frontend/Frontend.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ SerializationOptions CompilerInvocation::computeSerializationOptions(
154154
if (opts.SerializeBridgingHeader && !outs.ModuleOutputPath.empty())
155155
serializationOpts.ImportedHeader = opts.ImplicitObjCHeaderPath;
156156
serializationOpts.ModuleLinkName = opts.ModuleLinkName;
157+
serializationOpts.UserModuleVersion = opts.UserModuleVersion;
157158
serializationOpts.ExtraClangOptions = getClangImporterOptions().ExtraArgs;
158159

159160
if (opts.EmitSymbolGraph) {

lib/Frontend/ModuleInterfaceBuilder.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ bool ModuleInterfaceBuilder::buildSwiftModuleInternal(
245245
SerializationOpts.ModuleLinkName = FEOpts.ModuleLinkName;
246246
SerializationOpts.AutolinkForceLoad =
247247
!subInvocation.getIRGenOptions().ForceLoadSymbolName.empty();
248+
SerializationOpts.UserModuleVersion = FEOpts.UserModuleVersion;
248249

249250
// Record any non-SDK module interface files for the debug info.
250251
StringRef SDKPath = SubInstance.getASTContext().SearchPathOpts.SDKPath;

lib/Serialization/ModuleFile.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,10 @@ class ModuleFile
435435
return Core->ModuleABIName;
436436
}
437437

438+
llvm::VersionTuple getUserModuleVersion() const {
439+
return Core->UserModuleVersion;
440+
}
441+
438442
/// The Swift compatibility version in use when this module was built.
439443
const version::Version &getCompatibilityVersion() const {
440444
return Core->CompatibilityVersion;

lib/Serialization/ModuleFileSharedCore.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,12 @@ validateControlBlock(llvm::BitstreamCursor &cursor,
251251
// These fields were added later; be resilient against their absence.
252252
switch (scratch.size()) {
253253
default:
254-
// Add new cases here, in descending order.
254+
// Add new cases here, in descending order.
255+
case 6:
256+
case 5: {
257+
result.userModuleVersion = llvm::VersionTuple(scratch[4], scratch[5]);
258+
LLVM_FALLTHROUGH;
259+
}
255260
case 4:
256261
if (scratch[3] != 0) {
257262
result.compatibilityVersion =
@@ -1172,6 +1177,7 @@ ModuleFileSharedCore::ModuleFileSharedCore(
11721177
Name = info.name;
11731178
TargetTriple = info.targetTriple;
11741179
CompatibilityVersion = info.compatibilityVersion;
1180+
UserModuleVersion = info.userModuleVersion;
11751181
Bits.ArePrivateImportsEnabled = extInfo.arePrivateImportsEnabled();
11761182
Bits.IsSIB = extInfo.isSIB();
11771183
Bits.IsTestable = extInfo.isTestable();

lib/Serialization/ModuleFileSharedCore.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ class ModuleFileSharedCore {
6666
/// The Swift compatibility version in use when this module was built.
6767
version::Version CompatibilityVersion;
6868

69+
/// User-defined module version number.
70+
llvm::VersionTuple UserModuleVersion;
71+
6972
/// The data blob containing all of the module's identifiers.
7073
StringRef IdentifierData;
7174

lib/Serialization/ModuleFormat.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5656
/// describe what change you made. The content of this comment isn't important;
5757
/// it just ensures a conflict if two people change the module format.
5858
/// Don't worry about adhering to the 80-column limit for this line.
59-
const uint16_t SWIFTMODULE_VERSION_MINOR = 611; // implicit bit for CompletionHandlerAsyncAttr
59+
const uint16_t SWIFTMODULE_VERSION_MINOR = 612; // add user-defined module version
6060

6161
/// A standard hash seed used for all string hashes in a serialized module.
6262
///
@@ -763,6 +763,8 @@ namespace control_block {
763763
BCFixed<16>, // Module format minor version
764764
BCVBR<8>, // length of "short version string" in the blob
765765
BCVBR<8>, // length of "short compatibility version string" in the blob
766+
BCVBR<17>, // User module format major version
767+
BCVBR<17>, // User module format minor version
766768
BCBlob // misc. version information
767769
>;
768770

lib/Serialization/Serialization.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -961,10 +961,16 @@ void Serializer::writeHeader(const SerializationOptions &options) {
961961
size_t compatibilityVersionStringLength =
962962
versionString.tell() - shortVersionStringLength - 1;
963963
versionString << ")/" << version::getSwiftFullVersion();
964+
auto userModuleMajor = options.UserModuleVersion.getMajor();
965+
auto userModuleMinor = 0;
966+
if (auto minor = options.UserModuleVersion.getMinor()) {
967+
userModuleMinor = *minor;
968+
}
964969
Metadata.emit(ScratchRecord,
965970
SWIFTMODULE_VERSION_MAJOR, SWIFTMODULE_VERSION_MINOR,
966971
shortVersionStringLength,
967972
compatibilityVersionStringLength,
973+
userModuleMajor, userModuleMinor,
968974
versionString.str());
969975

970976
Target.emit(ScratchRecord, M->getASTContext().LangOpts.Target.str());

lib/Serialization/SerializeDoc.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -489,10 +489,11 @@ void DocSerializer::writeDocHeader() {
489489
control_block::TargetLayout Target(Out);
490490

491491
auto& LangOpts = M->getASTContext().LangOpts;
492+
auto verText = version::getSwiftFullVersion(LangOpts.EffectiveLanguageVersion);
492493
Metadata.emit(ScratchRecord, SWIFTDOC_VERSION_MAJOR, SWIFTDOC_VERSION_MINOR,
493494
/*short version string length*/0, /*compatibility length*/0,
494-
version::getSwiftFullVersion(
495-
LangOpts.EffectiveLanguageVersion));
495+
/*user module version major*/0,
496+
/*user module version minor*/0, verText);
496497

497498
ModuleName.emit(ScratchRecord, M->getName().str());
498499
Target.emit(ScratchRecord, LangOpts.Target.str());
@@ -872,10 +873,12 @@ class SourceInfoSerializer : public SerializerBase {
872873
control_block::TargetLayout Target(Out);
873874

874875
auto& LangOpts = M->getASTContext().LangOpts;
876+
auto verText = version::getSwiftFullVersion(LangOpts.EffectiveLanguageVersion);
875877
Metadata.emit(ScratchRecord, SWIFTSOURCEINFO_VERSION_MAJOR,
876878
SWIFTSOURCEINFO_VERSION_MINOR,
877879
/*short version string length*/0, /*compatibility length*/0,
878-
version::getSwiftFullVersion(LangOpts.EffectiveLanguageVersion));
880+
/*user module version major*/0,
881+
/*user module version minor*/0, verText);
879882

880883
ModuleName.emit(ScratchRecord, M->getName().str());
881884
Target.emit(ScratchRecord, LangOpts.Target.str());

lib/Serialization/SerializedModuleLoader.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -725,7 +725,7 @@ LoadedFile *SerializedModuleLoaderBase::loadAST(
725725
M.setHasIncrementalInfo();
726726
if (!loadedModuleFile->getModuleABIName().empty())
727727
M.setABIName(Ctx.getIdentifier(loadedModuleFile->getModuleABIName()));
728-
728+
M.setUserModuleVersion(loadedModuleFile->getUserModuleVersion());
729729
auto diagLocOrInvalid = diagLoc.getValueOr(SourceLoc());
730730
loadInfo.status = loadedModuleFile->associateWithFileContext(
731731
fileUnit, diagLocOrInvalid, Ctx.LangOpts.AllowModuleWithCompilerErrors);
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %empty-directory(%t/textual)
3+
// RUN: %empty-directory(%t/binary)
4+
// RUN: %empty-directory(%t/module-cache)
5+
6+
// RUN: %target-swift-frontend -emit-module %s -module-name Foo -swift-version 5 -disable-implicit-concurrency-module-import -user-module-version 113.33 -emit-module-interface-path %t/textual/Foo.swiftinterface -enable-library-evolution -emit-module-path %t/binary/Foo.swiftmodule
7+
8+
// RUN: %FileCheck %s --check-prefix=INTERFACE-FLAG < %t/textual/Foo.swiftinterface
9+
10+
// RUN: %target-swift-ide-test -print-module-metadata -module-to-print Foo -I %t/textual -source-filename %s -module-cache-path %t/module-cache | %FileCheck %s --check-prefix=USER-MODULE-PRINT
11+
12+
// RUN: %target-swift-ide-test -print-module-metadata -module-to-print Foo -I %t/binary -source-filename %s | %FileCheck %s --check-prefix=USER-MODULE-PRINT
13+
14+
// RUN: rm %t/binary/Foo.swiftmodule
15+
// RUN: %target-swift-frontend -compile-module-from-interface %t/textual/Foo.swiftinterface -o %t/binary/Foo.swiftmodule
16+
// RUN: %target-swift-ide-test -print-module-metadata -module-to-print Foo -I %t/binary -source-filename %s | %FileCheck %s --check-prefix=USER-MODULE-PRINT
17+
18+
// INTERFACE-FLAG: -user-module-version 113.33
19+
20+
// USER-MODULE-PRINT: user module version: 113.33

tools/swift-ide-test/swift-ide-test.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2515,6 +2515,7 @@ static int doPrintModuleGroups(const CompilerInvocation &InitInvok,
25152515

25162516
static void printModuleMetadata(ModuleDecl *MD) {
25172517
auto &OS = llvm::outs();
2518+
OS << "user module version: " << MD->getUserModuleVersion().getAsString() << "\n";
25182519
OS << "fingerprint=" << MD->getFingerprint().getRawValue() << "\n";
25192520
MD->collectLinkLibraries([&](LinkLibrary lib) {
25202521
OS << "link library: " << lib.getName()

0 commit comments

Comments
 (0)