Skip to content

Commit 14c53d3

Browse files
committed
Add interface verification with -verify-emitted-module-interface
1 parent 536cf8a commit 14c53d3

File tree

8 files changed

+142
-19
lines changed

8 files changed

+142
-19
lines changed

Sources/SwiftDriver/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ add_library(SwiftDriver
5757
Jobs/Toolchain+InterpreterSupport.swift
5858
Jobs/Toolchain+LinkerSupport.swift
5959
Jobs/VerifyDebugInfoJob.swift
60+
Jobs/VerifyModuleInterfaceJob.swift
6061

6162
Toolchains/DarwinToolchain.swift
6263
Toolchains/GenericUnixToolchain.swift

Sources/SwiftDriver/Jobs/CompileJob.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,18 +59,18 @@ extension Driver {
5959
/// Is this compile job top-level
6060
func isTopLevelOutput(type: FileType?) -> Bool {
6161
switch type {
62-
case .assembly, .sil, .raw_sil, .llvmIR, .ast, .jsonDependencies, .sib, .raw_sib, .importedModules, .indexData:
62+
case .assembly, .sil, .raw_sil, .llvmIR, .ast, .jsonDependencies, .sib, .raw_sib,
63+
.importedModules, .indexData:
6364
return true
6465
case .object:
6566
return (linkerOutputType == nil)
6667
case .swiftModule:
6768
return compilerMode.isSingleCompilation && moduleOutputInfo.output?.isTopLevel ?? false
6869
case .llvmBitcode:
6970
return compilerOutputType == type
70-
case .swift, .image, .dSYM, .dependencies, .autolink,
71-
.swiftDocumentation, .swiftInterface, .swiftSourceInfoFile, .diagnostics,
72-
.objcHeader, .swiftDeps, .remap, .importedModules, .tbd, .moduleTrace,
73-
.indexData, .yamlOptimizationRecord, .bitstreamOptimizationRecord, .pcm,
71+
case .swift, .image, .dSYM, .dependencies, .autolink, .swiftDocumentation, .swiftInterface,
72+
.privateSwiftInterface, .swiftSourceInfoFile, .diagnostics, .objcHeader, .swiftDeps,
73+
.remap, .tbd, .moduleTrace, .yamlOptimizationRecord, .bitstreamOptimizationRecord, .pcm,
7474
.pch, .clangModuleMap, .jsonTargetInfo, .jsonSwiftArtifacts, .jsonClangDependencies, nil:
7575
return false
7676
}
@@ -311,7 +311,7 @@ extension FileType {
311311
case .swift, .dSYM, .autolink, .dependencies, .swiftDocumentation, .pcm,
312312
.diagnostics, .objcHeader, .image, .swiftDeps, .moduleTrace, .tbd,
313313
.yamlOptimizationRecord, .bitstreamOptimizationRecord, .swiftInterface,
314-
.swiftSourceInfoFile, .clangModuleMap, .jsonSwiftArtifacts:
314+
.privateSwiftInterface, .swiftSourceInfoFile, .clangModuleMap, .jsonSwiftArtifacts:
315315
fatalError("Output type can never be a primary output")
316316
}
317317
}

Sources/SwiftDriver/Jobs/Job.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public struct Job: Codable, Equatable, Hashable {
3434
case versionRequest = "version-request"
3535
case scanDependencies = "scan-dependencies"
3636
case scanClangDependencies = "scan-clang-dependencies"
37+
case verifyModuleInterface = "verify-emitted-module-interface"
3738
case help
3839
}
3940

@@ -185,6 +186,9 @@ extension Job : CustomStringConvertible {
185186

186187
case .scanClangDependencies:
187188
return "Scanning dependencies for Clang module \(moduleName)"
189+
190+
case .verifyModuleInterface:
191+
return "Verifying emitted module interface for module \(moduleName)"
188192
}
189193
}
190194
}
@@ -195,7 +199,7 @@ extension Job.Kind {
195199
switch self {
196200
case .backend, .compile, .mergeModule, .emitModule, .generatePCH,
197201
.generatePCM, .interpret, .repl, .printTargetInfo,
198-
.versionRequest, .scanDependencies, .scanClangDependencies:
202+
.versionRequest, .scanDependencies, .scanClangDependencies, .verifyModuleInterface:
199203
return true
200204

201205
case .autolinkExtract, .generateDSYM, .help, .link, .verifyDebugInfo, .moduleWrap:
@@ -212,7 +216,7 @@ extension Job.Kind {
212216
.generatePCM, .interpret, .repl, .printTargetInfo,
213217
.versionRequest, .autolinkExtract, .generateDSYM,
214218
.help, .link, .verifyDebugInfo, .scanDependencies,
215-
.moduleWrap, .scanClangDependencies:
219+
.moduleWrap, .scanClangDependencies, .verifyModuleInterface:
216220
return false
217221
}
218222
}

Sources/SwiftDriver/Jobs/Planning.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,28 @@ extension Driver {
196196
mergeJob = mergeModule
197197
}
198198

199+
if let mergeJob = mergeJob,
200+
parsedOptions.hasArgument(.enableLibraryEvolution),
201+
parsedOptions.hasFlag(positive: .verifyEmittedModuleInterface,
202+
negative: .noVerifyEmittedModuleInterface,
203+
default: false) {
204+
if parsedOptions.hasArgument(.emitModuleInterface) ||
205+
parsedOptions.hasArgument(.emitModuleInterfacePath) {
206+
let mergeInterfaceOutputs = mergeJob.outputs.filter { $0.type == .swiftInterface }
207+
assert(mergeInterfaceOutputs.count == 1,
208+
"Merge module job should only have one swiftinterface output")
209+
let verifyJob = try verifyModuleInterfaceJob(interfaceInput: mergeInterfaceOutputs[0])
210+
jobs.append(verifyJob)
211+
}
212+
if parsedOptions.hasArgument(.emitPrivateModuleInterfacePath) {
213+
let mergeInterfaceOutputs = mergeJob.outputs.filter { $0.type == .privateSwiftInterface }
214+
assert(mergeInterfaceOutputs.count == 1,
215+
"Merge module job should only have one private swiftinterface output")
216+
let verifyJob = try verifyModuleInterfaceJob(interfaceInput: mergeInterfaceOutputs[0])
217+
jobs.append(verifyJob)
218+
}
219+
}
220+
199221
// If we need to autolink-extract, do so.
200222
let autolinkInputs = linkerInputs.filter { $0.type == .object }
201223
if let autolinkExtractJob = try autolinkExtractJob(inputs: autolinkInputs) {
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//===- VerifyModuleInterface.swift - Swift Module Interface Verification --===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2020 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
extension Driver {
14+
mutating func verifyModuleInterfaceJob(interfaceInput: TypedVirtualPath) throws -> Job {
15+
var commandLine: [Job.ArgTemplate] = swiftCompilerPrefixArgs.map { Job.ArgTemplate.flag($0) }
16+
var inputs: [TypedVirtualPath] = []
17+
commandLine.appendFlags("-frontend", "-typecheck-module-from-interface")
18+
try addCommonFrontendOptions(commandLine: &commandLine, inputs: &inputs)
19+
// FIXME: MSVC runtime flags
20+
21+
// Compute the serialized diagnostics output file
22+
let outputFile: TypedVirtualPath
23+
if let output = serializedDiagnosticsFilePath {
24+
outputFile = TypedVirtualPath(file: output, type: .diagnostics)
25+
} else {
26+
outputFile = TypedVirtualPath(file: interfaceInput.file.replacingExtension(with: .diagnostics),
27+
type: .diagnostics)
28+
}
29+
30+
return Job(
31+
moduleName: moduleOutputInfo.name,
32+
kind: .verifyModuleInterface,
33+
tool: .absolute(try toolchain.getToolPath(.swiftCompiler)),
34+
commandLine: commandLine,
35+
displayInputs: [],
36+
inputs: [interfaceInput],
37+
outputs: [outputFile]
38+
)
39+
}
40+
}

Sources/SwiftDriver/Utilities/FileType.swift

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ public enum FileType: String, Hashable, CaseIterable, Codable {
5151
/// A textual Swift interface file.
5252
case swiftInterface = "swiftinterface"
5353

54+
/// An SPI Swift Interface file.
55+
case privateSwiftInterface = "private.swiftinterface"
56+
5457
/// Serialized source information.
5558
case swiftSourceInfoFile = "swiftsourceinfo"
5659

@@ -154,6 +157,9 @@ extension FileType: CustomStringConvertible {
154157
case .llvmBitcode:
155158
return "llvm-bc"
156159

160+
case .privateSwiftInterface:
161+
return "private-swiftinterface"
162+
157163
case .objcHeader:
158164
return "objc-header"
159165

@@ -203,9 +209,9 @@ extension FileType {
203209
case .object, .pch, .ast, .llvmIR, .llvmBitcode, .assembly, .swiftModule,
204210
.importedModules, .indexData, .remap, .dSYM, .autolink, .dependencies,
205211
.swiftDocumentation, .pcm, .diagnostics, .objcHeader, .image,
206-
.swiftDeps, .moduleTrace, .tbd, .yamlOptimizationRecord, .bitstreamOptimizationRecord, .swiftInterface,
207-
.swiftSourceInfoFile, .jsonDependencies, .clangModuleMap, .jsonTargetInfo,
208-
.jsonSwiftArtifacts, .jsonClangDependencies:
212+
.swiftDeps, .moduleTrace, .tbd, .yamlOptimizationRecord, .bitstreamOptimizationRecord,
213+
.swiftInterface, .privateSwiftInterface, .swiftSourceInfoFile, .jsonDependencies,
214+
.clangModuleMap, .jsonTargetInfo, .jsonSwiftArtifacts, .jsonClangDependencies:
209215
return false
210216
}
211217
}
@@ -246,6 +252,8 @@ extension FileType {
246252
return "swiftdoc"
247253
case .swiftInterface:
248254
return "swiftinterface"
255+
case .privateSwiftInterface:
256+
return "private-swiftinterface"
249257
case .swiftSourceInfoFile:
250258
return "swiftsourceinfo"
251259
case .clangModuleMap:
@@ -303,8 +311,9 @@ extension FileType {
303311
switch self {
304312
case .swift, .sil, .dependencies, .assembly, .ast, .raw_sil, .llvmIR,
305313
.objcHeader, .autolink, .importedModules, .tbd, .moduleTrace,
306-
.yamlOptimizationRecord, .swiftInterface, .jsonDependencies, .clangModuleMap,
307-
.jsonTargetInfo, .jsonSwiftArtifacts, .jsonClangDependencies:
314+
.yamlOptimizationRecord, .swiftInterface, .privateSwiftInterface,
315+
.jsonDependencies, .clangModuleMap, .jsonTargetInfo, .jsonSwiftArtifacts,
316+
.jsonClangDependencies:
308317
return true
309318
case .image, .object, .dSYM, .pch, .sib, .raw_sib, .swiftModule,
310319
.swiftDocumentation, .swiftSourceInfoFile, .llvmBitcode, .diagnostics,
@@ -320,11 +329,11 @@ extension FileType {
320329
case .assembly, .llvmIR, .llvmBitcode, .object:
321330
return true
322331
case .swift, .sil, .sib, .ast, .image, .dSYM, .dependencies, .autolink,
323-
.swiftModule, .swiftDocumentation, .swiftInterface, .swiftSourceInfoFile,
324-
.raw_sil, .raw_sib, .diagnostics, .objcHeader, .swiftDeps, .remap, .importedModules,
325-
.tbd, .moduleTrace, .indexData, .yamlOptimizationRecord, .bitstreamOptimizationRecord,
326-
.pcm, .pch, .jsonDependencies, .clangModuleMap, .jsonTargetInfo, .jsonSwiftArtifacts,
327-
.jsonClangDependencies:
332+
.swiftModule, .swiftDocumentation, .swiftInterface, .privateSwiftInterface,
333+
.swiftSourceInfoFile, .raw_sil, .raw_sib, .diagnostics, .objcHeader, .swiftDeps, .remap,
334+
.importedModules, .tbd, .moduleTrace, .indexData, .yamlOptimizationRecord,
335+
.bitstreamOptimizationRecord, .pcm, .pch, .jsonDependencies, .clangModuleMap,
336+
.jsonTargetInfo, .jsonSwiftArtifacts, .jsonClangDependencies:
328337
return false
329338
}
330339
}

0 commit comments

Comments
 (0)