Skip to content

Commit 31d2556

Browse files
authored
Merge branch 'master' into windows-toolchain
2 parents 4b69ec6 + 0b620cf commit 31d2556

15 files changed

+290
-65
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
Jobs/WindowsToolchain+LinkerSupport.swift
6162

6263
Toolchains/DarwinToolchain.swift

Sources/SwiftDriver/Driver/Driver.swift

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -258,8 +258,10 @@ public struct Driver {
258258
/// at the beginning.
259259
/// - Parameter env: The environment variables to use. This is a hook for testing;
260260
/// in production, you should use the default argument, which copies the current environment.
261-
/// - Parameter diagnosticsHandler: A callback executed when a diagnostic is
262-
/// emitted. The default argument prints diagnostics to stderr.
261+
/// - Parameter diagnosticsEngine: The diagnotic engine used by the driver to emit errors
262+
/// and warnings.
263+
/// - Parameter fileSystem: The filesystem used by the driver to find resources/SDKs,
264+
/// expand response files, etc. By default this is the local filesystem.
263265
/// - Parameter executor: Used by the driver to execute jobs. The default argument
264266
/// is present to streamline testing, it shouldn't be used in production.
265267
/// - Parameter externalModuleDependencies: A collection of external modules that the main module
@@ -340,6 +342,16 @@ public struct Driver {
340342
self.outputFileMap = outputFileMap
341343
}
342344

345+
// If requested, print the output file map
346+
if parsedOptions.contains(.driverPrintOutputFileMap) {
347+
if let outputFileMap = self.outputFileMap {
348+
stderrStream <<< outputFileMap.description
349+
stderrStream.flush()
350+
} else {
351+
diagnosticsEngine.emit(.error_no_output_file_map_specified)
352+
}
353+
}
354+
343355
self.fileListThreshold = try Self.computeFileListThreshold(&self.parsedOptions, diagnosticsEngine: diagnosticsEngine)
344356
self.shouldUseInputFileList = inputFiles.count > fileListThreshold
345357
if shouldUseInputFileList {
@@ -510,7 +522,7 @@ extension Driver {
510522
/// Determines whether the given arguments constitute a normal invocation,
511523
/// or whether they invoke a subcommand.
512524
///
513-
/// Returns the invocation mode along with the arguments modified for that mode.
525+
/// - Returns: the invocation mode along with the arguments modified for that mode.
514526
public static func invocationRunMode(
515527
forArgs args: [String]
516528
) throws -> (mode: InvocationRunMode, args: [String]) {
@@ -665,7 +677,7 @@ extension Driver {
665677
}
666678

667679
/// Expand response files in the input arguments and return a new argument list.
668-
public static func expandResponseFiles(
680+
@_spi(Testing) public static func expandResponseFiles(
669681
_ args: [String],
670682
fileSystem: FileSystem,
671683
diagnosticsEngine: DiagnosticsEngine
@@ -684,7 +696,7 @@ extension Diagnostic.Message {
684696
extension Driver {
685697
/// Determine the driver kind based on the command-line arguments, consuming the arguments
686698
/// conveying this information.
687-
public static func determineDriverKind(
699+
@_spi(Testing) public static func determineDriverKind(
688700
args: inout [String]
689701
) throws -> DriverKind {
690702
// Get the basename of the driver executable.
@@ -771,7 +783,7 @@ extension Driver {
771783
}
772784
}
773785

774-
public mutating func createToolExecutionDelegate() -> ToolExecutionDelegate {
786+
mutating func createToolExecutionDelegate() -> ToolExecutionDelegate {
775787
var mode: ToolExecutionDelegate.Mode = .regular
776788

777789
// FIXME: Old driver does _something_ if both are passed. Not sure if we want to support that.
@@ -817,6 +829,10 @@ extension Diagnostic.Message {
817829
static var warning_cannot_multithread_batch_mode: Diagnostic.Message {
818830
.warning("ignoring -num-threads argument; cannot multithread batch mode")
819831
}
832+
833+
static var error_no_output_file_map_specified: Diagnostic.Message {
834+
.error("no output file map specified")
835+
}
820836
}
821837

822838
extension Driver {

Sources/SwiftDriver/Driver/OutputFileMap.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,23 @@ public struct OutputFileMap: Hashable, Codable {
106106
let contents = try encoder.encode(OutputFileMapJSON.fromVirtualOutputFileMap(entries).entries)
107107
try fileSystem.writeFileContents(file, bytes: ByteString(contents))
108108
}
109+
110+
/// Human-readable texual representation
111+
var description: String {
112+
var result = ""
113+
func outputPairDescription(inputPath: VirtualPath, outputPair: (FileType, VirtualPath))
114+
-> String {
115+
"\(inputPath.description) -> \(outputPair.0.description): \"\(outputPair.1.description)\"\n"
116+
}
117+
let maps = entries.map { ($0, $1) }.sorted { $0.0.description < $1.0.description }
118+
for (input, map) in maps {
119+
let pairs = map.map { ($0, $1) }.sorted { $0.0.description < $1.0.description }
120+
for (outputType, outputPath) in pairs {
121+
result += outputPairDescription(inputPath: input, outputPair: (outputType, outputPath))
122+
}
123+
}
124+
return result
125+
}
109126
}
110127

111128
/// Struct for loading the JSON file from disk.

Sources/SwiftDriver/Jobs/CompileJob.swift

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,17 +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:
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
68-
case .swift, .sib, .image, .dSYM, .dependencies, .autolink,
69-
.swiftDocumentation, .swiftInterface,
70-
.swiftSourceInfoFile, .raw_sib, .llvmBitcode, .diagnostics,
71-
.objcHeader, .swiftDeps, .remap, .importedModules, .tbd, .moduleTrace,
72-
.indexData, .yamlOptimizationRecord, .bitstreamOptimizationRecord, .pcm,
69+
case .llvmBitcode:
70+
return compilerOutputType == type
71+
case .swift, .image, .dSYM, .dependencies, .autolink, .swiftDocumentation, .swiftInterface,
72+
.privateSwiftInterface, .swiftSourceInfoFile, .diagnostics, .objcHeader, .swiftDeps,
73+
.remap, .tbd, .moduleTrace, .yamlOptimizationRecord, .bitstreamOptimizationRecord, .pcm,
7374
.pch, .clangModuleMap, .jsonTargetInfo, .jsonSwiftArtifacts, .jsonClangDependencies, nil:
7475
return false
7576
}
@@ -310,7 +311,7 @@ extension FileType {
310311
case .swift, .dSYM, .autolink, .dependencies, .swiftDocumentation, .pcm,
311312
.diagnostics, .objcHeader, .image, .swiftDeps, .moduleTrace, .tbd,
312313
.yamlOptimizationRecord, .bitstreamOptimizationRecord, .swiftInterface,
313-
.swiftSourceInfoFile, .clangModuleMap, .jsonSwiftArtifacts:
314+
.privateSwiftInterface, .swiftSourceInfoFile, .clangModuleMap, .jsonSwiftArtifacts:
314315
fatalError("Output type can never be a primary output")
315316
}
316317
}

Sources/SwiftDriver/Jobs/DarwinToolchain+LinkerSupport.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,11 @@ extension DarwinToolchain {
303303
commandLine.appendFlag("-application_extension")
304304
}
305305

306+
// On Darwin, we only support libc++.
307+
if parsedOptions.contains(.enableExperimentalCxxInterop) {
308+
commandLine.appendFlag("-lc++")
309+
}
310+
306311
// inputs LinkFileList
307312
if shouldUseInputFileList {
308313
commandLine.appendFlag(.filelist)

Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,15 @@ extension Driver {
9191
commandLine.appendFlag(.disableObjcInterop)
9292
}
9393

94+
// Add flags for C++ interop
95+
if parsedOptions.hasArgument(.enableExperimentalCxxInterop) {
96+
commandLine.appendFlag(.enableCxxInterop)
97+
}
98+
if let stdlibVariant = parsedOptions.getLastArgument(.experimentalCxxStdlib)?.asSingle {
99+
commandLine.appendFlag("-Xcc")
100+
commandLine.appendFlag("-stdlib=\(stdlibVariant)")
101+
}
102+
94103
// Handle the CPU and its preferences.
95104
try commandLine.appendLast(.targetCpu, from: &parsedOptions)
96105

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: 22 additions & 11 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

@@ -132,10 +135,12 @@ public enum FileType: String, Hashable, CaseIterable, Codable {
132135
extension FileType: CustomStringConvertible {
133136
public var description: String {
134137
switch self {
135-
case .swift, .sil, .sib, .image, .object, .dSYM, .dependencies, .autolink,
138+
case .swift, .sil, .sib, .image, .dSYM, .dependencies, .autolink,
136139
.swiftModule, .swiftDocumentation, .swiftInterface, .swiftSourceInfoFile, .assembly,
137140
.remap, .tbd, .pcm, .pch, .clangModuleMap:
138141
return rawValue
142+
case .object:
143+
return "object"
139144

140145
case .ast:
141146
return "ast-dump"
@@ -152,6 +157,9 @@ extension FileType: CustomStringConvertible {
152157
case .llvmBitcode:
153158
return "llvm-bc"
154159

160+
case .privateSwiftInterface:
161+
return "private-swiftinterface"
162+
155163
case .objcHeader:
156164
return "objc-header"
157165

@@ -201,9 +209,9 @@ extension FileType {
201209
case .object, .pch, .ast, .llvmIR, .llvmBitcode, .assembly, .swiftModule,
202210
.importedModules, .indexData, .remap, .dSYM, .autolink, .dependencies,
203211
.swiftDocumentation, .pcm, .diagnostics, .objcHeader, .image,
204-
.swiftDeps, .moduleTrace, .tbd, .yamlOptimizationRecord, .bitstreamOptimizationRecord, .swiftInterface,
205-
.swiftSourceInfoFile, .jsonDependencies, .clangModuleMap, .jsonTargetInfo,
206-
.jsonSwiftArtifacts, .jsonClangDependencies:
212+
.swiftDeps, .moduleTrace, .tbd, .yamlOptimizationRecord, .bitstreamOptimizationRecord,
213+
.swiftInterface, .privateSwiftInterface, .swiftSourceInfoFile, .jsonDependencies,
214+
.clangModuleMap, .jsonTargetInfo, .jsonSwiftArtifacts, .jsonClangDependencies:
207215
return false
208216
}
209217
}
@@ -244,6 +252,8 @@ extension FileType {
244252
return "swiftdoc"
245253
case .swiftInterface:
246254
return "swiftinterface"
255+
case .privateSwiftInterface:
256+
return "private-swiftinterface"
247257
case .swiftSourceInfoFile:
248258
return "swiftsourceinfo"
249259
case .clangModuleMap:
@@ -301,8 +311,9 @@ extension FileType {
301311
switch self {
302312
case .swift, .sil, .dependencies, .assembly, .ast, .raw_sil, .llvmIR,
303313
.objcHeader, .autolink, .importedModules, .tbd, .moduleTrace,
304-
.yamlOptimizationRecord, .swiftInterface, .jsonDependencies, .clangModuleMap,
305-
.jsonTargetInfo, .jsonSwiftArtifacts, .jsonClangDependencies:
314+
.yamlOptimizationRecord, .swiftInterface, .privateSwiftInterface,
315+
.jsonDependencies, .clangModuleMap, .jsonTargetInfo, .jsonSwiftArtifacts,
316+
.jsonClangDependencies:
306317
return true
307318
case .image, .object, .dSYM, .pch, .sib, .raw_sib, .swiftModule,
308319
.swiftDocumentation, .swiftSourceInfoFile, .llvmBitcode, .diagnostics,
@@ -318,11 +329,11 @@ extension FileType {
318329
case .assembly, .llvmIR, .llvmBitcode, .object:
319330
return true
320331
case .swift, .sil, .sib, .ast, .image, .dSYM, .dependencies, .autolink,
321-
.swiftModule, .swiftDocumentation, .swiftInterface, .swiftSourceInfoFile,
322-
.raw_sil, .raw_sib, .diagnostics, .objcHeader, .swiftDeps, .remap, .importedModules,
323-
.tbd, .moduleTrace, .indexData, .yamlOptimizationRecord, .bitstreamOptimizationRecord,
324-
.pcm, .pch, .jsonDependencies, .clangModuleMap, .jsonTargetInfo, .jsonSwiftArtifacts,
325-
.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:
326337
return false
327338
}
328339
}

0 commit comments

Comments
 (0)