mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[ModuleInterface] Version string (semi)finalization, format version checking.
This commit is contained in:
@@ -265,6 +265,9 @@ WARNING(parseable_interface_scoped_import_unsupported,none,
|
|||||||
())
|
())
|
||||||
ERROR(error_extracting_version_from_parseable_interface,none,
|
ERROR(error_extracting_version_from_parseable_interface,none,
|
||||||
"error extracting version from parseable module interface", ())
|
"error extracting version from parseable module interface", ())
|
||||||
|
ERROR(unsupported_version_of_parseable_interface,none,
|
||||||
|
"unsupported version of parseable module interface '%0': '%1'",
|
||||||
|
(StringRef, llvm::VersionTuple))
|
||||||
ERROR(error_extracting_flags_from_parseable_interface,none,
|
ERROR(error_extracting_flags_from_parseable_interface,none,
|
||||||
"error extracting flags from parseable module interface", ())
|
"error extracting flags from parseable module interface", ())
|
||||||
ERROR(missing_dependency_of_parseable_module_interface,none,
|
ERROR(missing_dependency_of_parseable_module_interface,none,
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ struct ParseableInterfaceOptions {
|
|||||||
std::string ParseableInterfaceFlags;
|
std::string ParseableInterfaceFlags;
|
||||||
};
|
};
|
||||||
|
|
||||||
llvm::Regex getSwiftInterfaceToolsVersionRegex();
|
llvm::Regex getSwiftInterfaceFormatVersionRegex();
|
||||||
llvm::Regex getSwiftInterfaceModuleFlagsRegex();
|
llvm::Regex getSwiftInterfaceModuleFlagsRegex();
|
||||||
|
|
||||||
/// Emit a stable, parseable interface for \p M, which can be used by a client
|
/// Emit a stable, parseable interface for \p M, which can be used by a client
|
||||||
|
|||||||
@@ -39,9 +39,12 @@
|
|||||||
using namespace swift;
|
using namespace swift;
|
||||||
using FileDependency = SerializationOptions::FileDependency;
|
using FileDependency = SerializationOptions::FileDependency;
|
||||||
|
|
||||||
|
#define SWIFT_INTERFACE_FORMAT_VERSION_KEY "swift-interface-format-version"
|
||||||
#define SWIFT_TOOLS_VERSION_KEY "swift-tools-version"
|
#define SWIFT_TOOLS_VERSION_KEY "swift-tools-version"
|
||||||
#define SWIFT_MODULE_FLAGS_KEY "swift-module-flags"
|
#define SWIFT_MODULE_FLAGS_KEY "swift-module-flags"
|
||||||
|
|
||||||
|
static swift::version::Version InterfaceFormatVersion({1, 0});
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
extractSwiftInterfaceVersionAndArgs(DiagnosticEngine &Diags,
|
extractSwiftInterfaceVersionAndArgs(DiagnosticEngine &Diags,
|
||||||
clang::vfs::FileSystem &FS,
|
clang::vfs::FileSystem &FS,
|
||||||
@@ -56,7 +59,7 @@ extractSwiftInterfaceVersionAndArgs(DiagnosticEngine &Diags,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
auto SB = FileOrError.get()->getBuffer();
|
auto SB = FileOrError.get()->getBuffer();
|
||||||
auto VersRe = getSwiftInterfaceToolsVersionRegex();
|
auto VersRe = getSwiftInterfaceFormatVersionRegex();
|
||||||
auto FlagRe = getSwiftInterfaceModuleFlagsRegex();
|
auto FlagRe = getSwiftInterfaceModuleFlagsRegex();
|
||||||
SmallVector<StringRef, 1> VersMatches, FlagMatches;
|
SmallVector<StringRef, 1> VersMatches, FlagMatches;
|
||||||
if (!VersRe.match(SB, &VersMatches)) {
|
if (!VersRe.match(SB, &VersMatches)) {
|
||||||
@@ -286,6 +289,17 @@ static bool buildSwiftModuleFromSwiftInterface(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For now: we support anything with the same "major version" and assume
|
||||||
|
// minor versions might be interesting for debugging, or special-casing a
|
||||||
|
// compatible field variant.
|
||||||
|
if (Vers.asMajorVersion() != InterfaceFormatVersion.asMajorVersion()) {
|
||||||
|
Diags.diagnose(SourceLoc(),
|
||||||
|
diag::unsupported_version_of_parseable_interface,
|
||||||
|
InPath, Vers);
|
||||||
|
SubError = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (SubInvocation.parseArgs(SubArgs, Diags)) {
|
if (SubInvocation.parseArgs(SubArgs, Diags)) {
|
||||||
SubError = true;
|
SubError = true;
|
||||||
return;
|
return;
|
||||||
@@ -415,21 +429,26 @@ static void diagnoseScopedImports(DiagnosticEngine &diags,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prints to \p out a comment containing a tool-versions identifier as well
|
/// Prints to \p out a comment containing a format version number, tool version
|
||||||
/// as any relevant command-line flags in \p Opts used to construct \p M.
|
/// string as well as any relevant command-line flags in \p Opts used to
|
||||||
|
/// construct \p M.
|
||||||
static void printToolVersionAndFlagsComment(raw_ostream &out,
|
static void printToolVersionAndFlagsComment(raw_ostream &out,
|
||||||
ParseableInterfaceOptions const &Opts,
|
ParseableInterfaceOptions const &Opts,
|
||||||
ModuleDecl *M) {
|
ModuleDecl *M) {
|
||||||
auto &Ctx = M->getASTContext();
|
auto &Ctx = M->getASTContext();
|
||||||
|
auto ToolsVersion = swift::version::getSwiftFullVersion(
|
||||||
|
Ctx.LangOpts.EffectiveLanguageVersion);
|
||||||
|
out << "// " SWIFT_INTERFACE_FORMAT_VERSION_KEY ": "
|
||||||
|
<< InterfaceFormatVersion << "\n";
|
||||||
out << "// " SWIFT_TOOLS_VERSION_KEY ": "
|
out << "// " SWIFT_TOOLS_VERSION_KEY ": "
|
||||||
<< Ctx.LangOpts.EffectiveLanguageVersion << "\n";
|
<< ToolsVersion << "\n";
|
||||||
out << "// " SWIFT_MODULE_FLAGS_KEY ": "
|
out << "// " SWIFT_MODULE_FLAGS_KEY ": "
|
||||||
<< Opts.ParseableInterfaceFlags << "\n";
|
<< Opts.ParseableInterfaceFlags << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Regex swift::getSwiftInterfaceToolsVersionRegex() {
|
llvm::Regex swift::getSwiftInterfaceFormatVersionRegex() {
|
||||||
return llvm::Regex("^// " SWIFT_TOOLS_VERSION_KEY ": ([0-9\\.]+)$",
|
return llvm::Regex("^// " SWIFT_INTERFACE_FORMAT_VERSION_KEY
|
||||||
llvm::Regex::Newline);
|
": ([0-9\\.]+)$", llvm::Regex::Newline);
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Regex swift::getSwiftInterfaceModuleFlagsRegex() {
|
llvm::Regex swift::getSwiftInterfaceModuleFlagsRegex() {
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
// RUN: %empty-directory(%t)
|
||||||
|
// RUN: %empty-directory(%t/modulecache)
|
||||||
|
//
|
||||||
|
// Test will build a module TestModule that depends LeafModule (built from leaf.swift).
|
||||||
|
//
|
||||||
|
// RUN: echo 'public func LeafFunc() -> Int { return 10; }' >%t/leaf.swift
|
||||||
|
//
|
||||||
|
// RUN: %target-swift-frontend -I %t -emit-parseable-module-interface-path %t/LeafModule.swiftinterface -module-name LeafModule %t/leaf.swift -emit-module -o /dev/null
|
||||||
|
// RUN: test -f %t/LeafModule.swiftinterface
|
||||||
|
// RUN: %FileCheck %s -check-prefix=CHECK-LEAFINTERFACE <%t/LeafModule.swiftinterface
|
||||||
|
// CHECK-LEAFINTERFACE: {{swift-interface-format-version: [0-9\\.]+}}
|
||||||
|
// CHECK-LEAFINTERFACE: LeafFunc
|
||||||
|
//
|
||||||
|
// Break LeafModule's version number
|
||||||
|
// RUN: sed -i.prev -e 's/swift-interface-format-version:.*/swift-interface-format-version: 9999.999/' %t/LeafModule.swiftinterface
|
||||||
|
//
|
||||||
|
// Try to build TestModule into a .swiftmodule explicitly using LeafModule via LeafModule.swiftinterface, but fail because version mismatch in LeafModule.swiftinterface.
|
||||||
|
//
|
||||||
|
// RUN: not %target-swift-frontend -I %t -module-cache-path %t/modulecache -enable-parseable-module-interface -emit-module -o %t/TestModule.swiftmodule -module-name TestModule %s >%t/err.txt 2>&1
|
||||||
|
// RUN: test ! -f %t/TestModule.swiftmodule
|
||||||
|
// RUN: test ! -f %t/modulecache/LeafModule-*.swiftmodule
|
||||||
|
// RUN: %FileCheck %s -check-prefix=CHECK-ERR <%t/err.txt
|
||||||
|
// CHECK-ERR: {{error: unsupported version of parseable module interface '.*/LeafModule.swiftinterface': '9999.999'}}
|
||||||
|
// CHECK-ERR: error: no such module 'LeafModule
|
||||||
|
|
||||||
|
import LeafModule
|
||||||
|
|
||||||
|
public func TestFunc() {
|
||||||
|
print(LeafFunc())
|
||||||
|
}
|
||||||
@@ -54,8 +54,8 @@
|
|||||||
// RUN: not %target-swift-frontend -I %t -module-cache-path %t/modulecache -enable-parseable-module-interface -emit-module -o %t/TestModule.swiftmodule -module-name TestModule %s >%t/err.txt 2>&1
|
// RUN: not %target-swift-frontend -I %t -module-cache-path %t/modulecache -enable-parseable-module-interface -emit-module -o %t/TestModule.swiftmodule -module-name TestModule %s >%t/err.txt 2>&1
|
||||||
// RUN: %S/Inputs/check-is-old.py %t/modulecache/OtherModule-*.swiftmodule %t/modulecache/LeafModule-*.swiftmodule
|
// RUN: %S/Inputs/check-is-old.py %t/modulecache/OtherModule-*.swiftmodule %t/modulecache/LeafModule-*.swiftmodule
|
||||||
// RUN: %FileCheck %s -check-prefix=CHECK-ERROR <%t/err.txt
|
// RUN: %FileCheck %s -check-prefix=CHECK-ERROR <%t/err.txt
|
||||||
// CHECK-ERROR: LeafModule.swiftinterface:5:8: error: no such module 'NotAModule'
|
// CHECK-ERROR: LeafModule.swiftinterface:6:8: error: no such module 'NotAModule'
|
||||||
// CHECK-ERROR: OtherModule.swiftinterface:3:8: error: no such module 'LeafModule'
|
// CHECK-ERROR: OtherModule.swiftinterface:4:8: error: no such module 'LeafModule'
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Next test: same as above, but with a .dia file
|
// Next test: same as above, but with a .dia file
|
||||||
|
|||||||
Reference in New Issue
Block a user