Skip to content

Commit 6cb4b59

Browse files
authored
Merge pull request #77216 from xedin/add-swift-compiler-version
[Frontend/AST] Add `-interface-compiler-version` option to frontend/modules
2 parents 1499229 + 84a62fc commit 6cb4b59

20 files changed

+151
-8
lines changed

include/swift/AST/FileUnit.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,12 @@ class FileUnit : public DeclContext, public ASTAllocated<FileUnit> {
345345
return {};
346346
}
347347

348+
/// Returns the version of the Swift compiler used to create generate
349+
/// .swiftinterface file if this file is produced from one.
350+
virtual llvm::VersionTuple getSwiftInterfaceCompilerVersion() const {
351+
return {};
352+
}
353+
348354
SWIFT_DEBUG_DUMPER(dumpDisplayDecls());
349355
SWIFT_DEBUG_DUMPER(dumpTopLevelDecls());
350356

include/swift/AST/Module.h

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,10 @@ class ModuleDecl
254254

255255
mutable Identifier PublicModuleName;
256256

257+
/// Indicates a version of the Swift compiler used to generate
258+
/// .swiftinterface file that this module was produced from (if any).
259+
mutable llvm::VersionTuple InterfaceCompilerVersion;
260+
257261
public:
258262
/// Produces the components of a given module's full name in reverse order.
259263
///
@@ -518,11 +522,20 @@ class ModuleDecl
518522
PublicModuleName = name;
519523
}
520524

525+
/// See \c InterfaceCompilerVersion
526+
llvm::VersionTuple getSwiftInterfaceCompilerVersion() const {
527+
return InterfaceCompilerVersion;
528+
}
529+
530+
void setSwiftInterfaceCompilerVersion(llvm::VersionTuple version) {
531+
InterfaceCompilerVersion = version;
532+
}
533+
521534
/// Retrieve the actual module name of an alias used for this module (if any).
522535
///
523-
/// For example, if '-module-alias Foo=Bar' is passed in when building the main module,
524-
/// and this module is (a) not the main module and (b) is named Foo, then it returns
525-
/// the real (physically on-disk) module name Bar.
536+
/// For example, if '-module-alias Foo=Bar' is passed in when building the
537+
/// main module, and this module is (a) not the main module and (b) is named
538+
/// Foo, then it returns the real (physically on-disk) module name Bar.
526539
///
527540
/// If no module aliasing is set, it will return getName(), i.e. Foo.
528541
Identifier getRealName() const;

include/swift/Basic/Version.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,10 @@ StringRef getCurrentCompilerChannel();
187187
/// users.
188188
unsigned getUpcomingCxxInteropCompatVersion();
189189

190+
/// Retrieves the version of the running compiler. It could be a tag or
191+
/// a "development" version that only has major/minor.
192+
std::string getCompilerVersion();
193+
190194
} // end namespace version
191195
} // end namespace swift
192196

include/swift/Frontend/FrontendOptions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,10 @@ class FrontendOptions {
110110
/// User-defined module version number.
111111
llvm::VersionTuple UserModuleVersion;
112112

113+
/// The Swift compiler version number that would be used to synthesize
114+
/// swiftinterface files and subsequently their swiftmodules.
115+
llvm::VersionTuple SwiftInterfaceCompilerVersion;
116+
113117
/// A set of modules allowed to import this module.
114118
std::set<std::string> AllowableClients;
115119

include/swift/Option/Options.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,11 @@ def package_description_version: Separate<["-"], "package-description-version">,
303303
HelpText<"The version number to be applied on the input for the PackageDescription availability kind">,
304304
MetaVarName<"<vers>">;
305305

306+
def swiftinterface_compiler_version : Separate<["-"], "interface-compiler-version">,
307+
Flags<[FrontendOption, HelpHidden]>,
308+
HelpText<"The version of the Swift compiler used to generate a .swiftinterface file">,
309+
MetaVarName<"<intcvers>">;
310+
306311
def tools_directory : Separate<["-"], "tools-directory">,
307312
Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild,
308313
ArgumentIsPath]>,

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,8 @@ class SerializedASTFile final : public LoadedFile {
539539

540540
virtual StringRef getPublicModuleName() const override;
541541

542+
virtual llvm::VersionTuple getSwiftInterfaceCompilerVersion() const override;
543+
542544
ValueDecl *getMainDecl() const override;
543545

544546
bool hasEntryPoint() const override;

include/swift/Serialization/Validation.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ class ExtendedValidationInfo {
131131
StringRef ExportAsName;
132132
StringRef PublicModuleName;
133133
CXXStdlibKind CXXStdlib;
134+
llvm::VersionTuple SwiftInterfaceCompilerVersion;
134135
struct {
135136
unsigned ArePrivateImportsEnabled : 1;
136137
unsigned IsSIB : 1;
@@ -250,6 +251,16 @@ class ExtendedValidationInfo {
250251

251252
CXXStdlibKind getCXXStdlibKind() const { return CXXStdlib; }
252253
void setCXXStdlibKind(CXXStdlibKind kind) { CXXStdlib = kind; }
254+
255+
llvm::VersionTuple getSwiftInterfaceCompilerVersion() const {
256+
return SwiftInterfaceCompilerVersion;
257+
}
258+
void setSwiftInterfaceCompilerVersion(StringRef version) {
259+
llvm::VersionTuple compilerVersion;
260+
if (compilerVersion.tryParse(version))
261+
return;
262+
SwiftInterfaceCompilerVersion = compilerVersion;
263+
}
253264
};
254265

255266
struct SearchPath {

lib/Basic/Version.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,5 +339,18 @@ unsigned getUpcomingCxxInteropCompatVersion() {
339339
return SWIFT_VERSION_MAJOR + 1;
340340
}
341341

342+
std::string getCompilerVersion() {
343+
std::string buf;
344+
llvm::raw_string_ostream OS(buf);
345+
346+
#if defined(SWIFT_COMPILER_VERSION)
347+
OS << SWIFT_COMPILER_VERSION;
348+
#else
349+
OS << SWIFT_VERSION_STRING;
350+
#endif
351+
352+
return OS.str();
353+
}
354+
342355
} // end namespace version
343356
} // end namespace swift

lib/Frontend/ArgsToFrontendOptionsConverter.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,13 @@ bool ArgsToFrontendOptionsConverter::convert(
299299
if (const Arg *A = Args.getLastArg(OPT_public_module_name))
300300
Opts.PublicModuleName = A->getValue();
301301

302+
if (auto A = Args.getLastArg(OPT_swiftinterface_compiler_version)) {
303+
if (Opts.SwiftInterfaceCompilerVersion.tryParse(A->getValue())) {
304+
Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
305+
A->getAsString(Args), A->getValue());
306+
}
307+
}
308+
302309
// This must be called after computing module name, module abi name,
303310
// and module link name. If computing module aliases is unsuccessful,
304311
// return early.

lib/Frontend/Frontend.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1491,6 +1491,11 @@ ModuleDecl *CompilerInstance::getMainModule() const {
14911491
if (Invocation.getSILOptions().EnableSerializePackage)
14921492
MainModule->setSerializePackageEnabled();
14931493

1494+
if (auto compilerVersion =
1495+
Invocation.getFrontendOptions().SwiftInterfaceCompilerVersion) {
1496+
MainModule->setSwiftInterfaceCompilerVersion(compilerVersion);
1497+
}
1498+
14941499
// Register the main module with the AST context.
14951500
Context->addLoadedModule(MainModule);
14961501
Context->MainModule = MainModule;

lib/Frontend/ModuleInterfaceSupport.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ static void printToolVersionAndFlagsComment(raw_ostream &out,
124124
!Opts.PackageFlags.IgnorableFlags.empty())
125125
ignorableFlags.push_back(Opts.PackageFlags.IgnorableFlags);
126126

127+
ignorableFlags.push_back("-interface-compiler-version");
128+
ignorableFlags.push_back(version::getCompilerVersion());
129+
127130
if (!ignorableFlags.empty()) {
128131
out << "// " SWIFT_MODULE_FLAGS_IGNORABLE_KEY ": ";
129132
llvm::interleave(

lib/Serialization/ModuleFile.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1408,3 +1408,7 @@ StringRef SerializedASTFile::getExportedModuleName() const {
14081408
StringRef SerializedASTFile::getPublicModuleName() const {
14091409
return File.getPublicModuleName();
14101410
}
1411+
1412+
llvm::VersionTuple SerializedASTFile::getSwiftInterfaceCompilerVersion() const {
1413+
return File.getSwiftInterfaceCompilerVersion();
1414+
}

lib/Serialization/ModuleFile.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,10 @@ class ModuleFile
603603
return Core->UserModuleVersion;
604604
}
605605

606+
llvm::VersionTuple getSwiftInterfaceCompilerVersion() const {
607+
return Core->SwiftInterfaceCompilerVersion;
608+
}
609+
606610
ArrayRef<StringRef> getAllowableClientNames() const {
607611
return Core->AllowableClientNames;
608612
}

lib/Serialization/ModuleFileSharedCore.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,9 @@ static bool readOptionsBlock(llvm::BitstreamCursor &cursor,
215215
case options_block::PUBLIC_MODULE_NAME:
216216
extendedInfo.setPublicModuleName(blobData);
217217
break;
218+
case options_block::SWIFT_INTERFACE_COMPILER_VERSION:
219+
extendedInfo.setSwiftInterfaceCompilerVersion(blobData);
220+
break;
218221
default:
219222
// Unknown options record, possibly for use by a future version of the
220223
// module format.
@@ -1497,6 +1500,8 @@ ModuleFileSharedCore::ModuleFileSharedCore(
14971500
ModulePackageName = extInfo.getModulePackageName();
14981501
ModuleExportAsName = extInfo.getExportAsName();
14991502
PublicModuleName = extInfo.getPublicModuleName();
1503+
SwiftInterfaceCompilerVersion =
1504+
extInfo.getSwiftInterfaceCompilerVersion();
15001505

15011506
hasValidControlBlock = true;
15021507
break;

lib/Serialization/ModuleFileSharedCore.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,11 @@ class ModuleFileSharedCore {
103103
/// Name to use in public facing diagnostics and documentation.
104104
StringRef PublicModuleName;
105105

106+
/// The version of the Swift compiler used to produce swiftinterface
107+
/// this module is based on. This is the most precise version possible
108+
/// - a compiler tag or version if this is a development compiler.
109+
llvm::VersionTuple SwiftInterfaceCompilerVersion;
110+
106111
/// \c true if this module has incremental dependency information.
107112
bool HasIncrementalInfo = false;
108113

lib/Serialization/ModuleFormat.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5858
/// describe what change you made. The content of this comment isn't important;
5959
/// it just ensures a conflict if two people change the module format.
6060
/// Don't worry about adhering to the 80-column limit for this line.
61-
const uint16_t SWIFTMODULE_VERSION_MINOR = 897; // Builtin.FixedArray
61+
const uint16_t SWIFTMODULE_VERSION_MINOR = 898; // interface-compiler-version
6262

6363
/// A standard hash seed used for all string hashes in a serialized module.
6464
///
@@ -966,6 +966,7 @@ namespace options_block {
966966
SERIALIZE_PACKAGE_ENABLED,
967967
CXX_STDLIB_KIND,
968968
PUBLIC_MODULE_NAME,
969+
SWIFT_INTERFACE_COMPILER_VERSION,
969970
};
970971

971972
using SDKPathLayout = BCRecordLayout<
@@ -1066,6 +1067,11 @@ namespace options_block {
10661067
PUBLIC_MODULE_NAME,
10671068
BCBlob
10681069
>;
1070+
1071+
using SwiftInterfaceCompilerVersionLayout = BCRecordLayout<
1072+
SWIFT_INTERFACE_COMPILER_VERSION,
1073+
BCBlob // version tuple
1074+
>;
10691075
}
10701076

10711077
/// The record types within the input block.

lib/Serialization/Serialization.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,7 @@ void Serializer::writeBlockInfoBlock() {
864864
BLOCK_RECORD(options_block, SERIALIZE_PACKAGE_ENABLED);
865865
BLOCK_RECORD(options_block, CXX_STDLIB_KIND);
866866
BLOCK_RECORD(options_block, PUBLIC_MODULE_NAME);
867+
BLOCK_RECORD(options_block, SWIFT_INTERFACE_COMPILER_VERSION);
867868

868869
BLOCK(INPUT_BLOCK);
869870
BLOCK_RECORD(input_block, IMPORTED_MODULE);
@@ -1139,6 +1140,13 @@ void Serializer::writeHeader() {
11391140
PublicModuleName.emit(ScratchRecord, publicModuleName.str());
11401141
}
11411142

1143+
llvm::VersionTuple compilerVersion =
1144+
M->getSwiftInterfaceCompilerVersion();
1145+
if (compilerVersion) {
1146+
options_block::SwiftInterfaceCompilerVersionLayout Version(Out);
1147+
Version.emit(ScratchRecord, compilerVersion.getAsString());
1148+
}
1149+
11421150
if (M->isConcurrencyChecked()) {
11431151
options_block::IsConcurrencyCheckedLayout IsConcurrencyChecked(Out);
11441152
IsConcurrencyChecked.emit(ScratchRecord);

lib/Serialization/SerializedModuleLoader.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,6 +1035,8 @@ LoadedFile *SerializedModuleLoaderBase::loadAST(
10351035
M.setPackageName(Ctx.getIdentifier(loadedModuleFile->getModulePackageName()));
10361036
}
10371037
M.setUserModuleVersion(loadedModuleFile->getUserModuleVersion());
1038+
M.setSwiftInterfaceCompilerVersion(
1039+
loadedModuleFile->getSwiftInterfaceCompilerVersion());
10381040
for (auto name: loadedModuleFile->getAllowableClientNames()) {
10391041
M.addAllowableClientName(Ctx.getIdentifier(name));
10401042
}

test/ModuleInterface/ModuleCache/module-cache-diagnostics.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@
6161
// RUN: not %target-swift-frontend -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import -I %t -module-cache-path %t/modulecache -emit-module -o %t/TestModule.swiftmodule -module-name TestModule %s >%t/err.txt 2>&1
6262
// RUN: %{python} %S/Inputs/check-is-old.py %t/modulecache/OtherModule-*.swiftmodule %t/modulecache/LeafModule-*.swiftmodule
6363
// RUN: %FileCheck %s -check-prefix=CHECK-ERROR <%t/err.txt
64-
// CHECK-ERROR: LeafModule.swiftinterface:7:8: error: no such module 'NotAModule'
65-
// CHECK-ERROR: OtherModule.swiftinterface:4:8: error: failed to build module 'LeafModule' for importation due to the errors above; the textual interface may be broken by project issues or a compiler bug
64+
// CHECK-ERROR: LeafModule.swiftinterface:8:8: error: no such module 'NotAModule'
65+
// CHECK-ERROR: OtherModule.swiftinterface:5:8: error: failed to build module 'LeafModule' for importation due to the errors above; the textual interface may be broken by project issues or a compiler bug
6666
// CHECK-ERROR: module-cache-diagnostics.swift:{{[0-9]+}}:8: error: failed to build module 'OtherModule' for importation due to the errors above; the textual interface may be broken by project issues or a compiler bug
6767
//
6868
//
@@ -85,8 +85,8 @@
8585
// RUN: not %target-swift-frontend -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import -I %t -module-cache-path %t/modulecache -emit-module -o %t/TestModule.swiftmodule -module-name TestModule %s >%t/err-inline.txt 2>&1
8686
// RUN: %{python} %S/Inputs/check-is-old.py %t/modulecache/OtherModule-*.swiftmodule %t/modulecache/LeafModule-*.swiftmodule
8787
// RUN: %FileCheck %s -check-prefix=CHECK-ERROR-INLINE <%t/err-inline.txt
88-
// CHECK-ERROR-INLINE: LeafModule.swiftinterface:6:33: error: cannot find 'unresolved' in scope
89-
// CHECK-ERROR-INLINE: OtherModule.swiftinterface:4:8: error: failed to build module 'LeafModule' for importation due to the errors above; the textual interface may be broken by project issues or a compiler bug
88+
// CHECK-ERROR-INLINE: LeafModule.swiftinterface:7:33: error: cannot find 'unresolved' in scope
89+
// CHECK-ERROR-INLINE: OtherModule.swiftinterface:5:8: error: failed to build module 'LeafModule' for importation due to the errors above; the textual interface may be broken by project issues or a compiler bug
9090
// CHECK-ERROR-INLINE: module-cache-diagnostics.swift:{{[0-9]+}}:8: error: failed to build module 'OtherModule' for importation due to the errors above; the textual interface may be broken by project issues or a compiler bug
9191
//
9292
//
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// RUN: %empty-directory(%t)
2+
3+
/// Build the libraries.
4+
// RUN: %target-swift-frontend %s \
5+
// RUN: -module-name Lib \
6+
// RUN: -emit-module-path %t/Lib.swiftmodule \
7+
// RUN: -emit-module-interface-path %t/Lib.swiftinterface \
8+
// RUN: -enable-library-evolution \
9+
// RUN: -swift-version 6
10+
11+
// RUN: %target-swift-typecheck-module-from-interface(%t/Lib.swiftinterface)
12+
13+
/// Check option in swiftinterface
14+
// RUN: cat %t/Lib.swiftinterface | %FileCheck --check-prefix=CHECK-OPTION %s
15+
// CHECK-OPTION: swift-module-flags-ignorable:
16+
// CHECK-SAME-OPTION: -swift-compiler-version {{.*}}
17+
18+
/// Check option in swiftmodule
19+
// RUN: llvm-bcanalyzer --dump %t/Lib.swiftmodule | %FileCheck --check-prefix=CHECK-MODULE-OPTION %s
20+
// CHECK-MODULE-OPTION: <OPTIONS_BLOCK
21+
// CHECK-NOT-MODULE-OPTION: <SWIFT_INTERFACE_COMPILER_VERSION abbrevid={{.*}}/> blob data = '{{.*}}'
22+
// CHECK-MODULE-OPTION: </OPTIONS_BLOCK>
23+
24+
// Drop and rebuilt swiftmodule to make sure that the version is inferred from the interface file.
25+
// RUN: rm %t/Lib.swiftmodule
26+
// RUN: %target-swift-frontend -compile-module-from-interface %t/Lib.swiftinterface -o %t/Lib.swiftmodule -module-name Lib
27+
28+
/// Check option in swiftmodule
29+
// RUN: llvm-bcanalyzer --dump %t/Lib.swiftmodule | %FileCheck --check-prefix=CHECK-REBUILT-MODULE-OPTION %s
30+
// CHECK-REBUILT-MODULE-OPTION: <OPTIONS_BLOCK
31+
// CHECK-REBUILT-MODULE-OPTION: <SWIFT_INTERFACE_COMPILER_VERSION abbrevid={{.*}}/> blob data = '{{.*}}'
32+
// CHECK-REBUILT-MODULE-OPTION: </OPTIONS_BLOCK>
33+
34+
public struct S {
35+
public var test: Int = 42
36+
}

0 commit comments

Comments
 (0)