Skip to content

Commit 3b745ee

Browse files
artemcmArtem Chikin
authored andcommitted
Add supplementary output path handling for extracted compile-time-known values
1 parent 10cbd8e commit 3b745ee

File tree

4 files changed

+158
-1
lines changed

4 files changed

+158
-1
lines changed

Sources/SwiftDriver/Driver/Driver.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,9 @@ public struct Driver {
287287
/// Path to the discovered dependencies file of the emit-module task.
288288
let emitModuleDependenciesFilePath: VirtualPath.Handle?
289289

290+
/// Path to emitted compile-time-known values.
291+
let constValuesFilePath: VirtualPath.Handle?
292+
290293
/// Path to the Objective-C generated header.
291294
let objcGeneratedHeaderPath: VirtualPath.Handle?
292295

@@ -733,6 +736,14 @@ public struct Driver {
733736
emitModuleSeparately: emitModuleSeparately,
734737
outputFileMap: self.outputFileMap,
735738
moduleName: moduleOutputInfo.name)
739+
self.constValuesFilePath = try Self.computeSupplementaryOutputPath(
740+
&parsedOptions, type: .swiftConstValues, isOutputOptions: [.emitConstValues],
741+
outputPath: .emitConstValuesPath,
742+
compilerOutputType: compilerOutputType,
743+
compilerMode: compilerMode,
744+
emitModuleSeparately: emitModuleSeparately,
745+
outputFileMap: self.outputFileMap,
746+
moduleName: moduleOutputInfo.name)
736747
// FIXME: -fixits-output-path
737748
self.objcGeneratedHeaderPath = try Self.computeSupplementaryOutputPath(
738749
&parsedOptions, type: .objcHeader, isOutputOptions: [.emitObjcHeader],

Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,12 @@ extension Driver {
394394
input: input,
395395
flag: "-emit-dependencies-path")
396396

397+
addOutputOfType(
398+
outputType: .swiftConstValues,
399+
finalOutputPath: constValuesFilePath,
400+
input: input,
401+
flag: "-emit-const-values-path")
402+
397403
addOutputOfType(
398404
outputType: .swiftDeps,
399405
finalOutputPath: referenceDependenciesPath,

Sources/SwiftOptions/Options.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,8 @@ extension Option {
223223
public static let emitAssembly: Option = Option("-emit-assembly", .flag, attributes: [.frontend, .noInteractive, .doesNotAffectIncrementalBuild], helpText: "Emit assembly file(s) (-S)", group: .modes)
224224
public static let emitBc: Option = Option("-emit-bc", .flag, attributes: [.frontend, .noInteractive, .doesNotAffectIncrementalBuild], helpText: "Emit LLVM BC file(s)", group: .modes)
225225
public static let emitClangHeaderPath: Option = Option("-emit-clang-header-path", .separate, alias: Option.emitObjcHeaderPath, attributes: [.frontend, .noDriver, .noInteractive, .argumentIsPath, .supplementaryOutput], helpText: "Emit an Objective-C and C++ header file to <path>")
226-
public static let emitConstValuesPath: Option = Option("-emit-const-values-path", .separate, attributes: [.frontend, .noDriver], metaVar: "<path>", helpText: "Output the extracted compile-time known values")
226+
public static let emitConstValuesPath: Option = Option("-emit-const-values-path", .separate, attributes: [.frontend, .noInteractive, .argumentIsPath, .supplementaryOutput], metaVar: "<path>", helpText: "Emit the extracted compile-time known values to <path>")
227+
public static let emitConstValues: Option = Option("-emit-const-values", .flag, attributes: [.noInteractive, .supplementaryOutput])
227228
public static let emitDependenciesPath: Option = Option("-emit-dependencies-path", .separate, attributes: [.frontend, .noDriver], metaVar: "<path>", helpText: "Output basic Make-compatible dependencies file to <path>")
228229
public static let emitDependencies: Option = Option("-emit-dependencies", .flag, attributes: [.frontend, .noInteractive, .supplementaryOutput], helpText: "Emit basic Make-compatible dependencies files")
229230
public static let emitExecutable: Option = Option("-emit-executable", .flag, attributes: [.noInteractive, .doesNotAffectIncrementalBuild], helpText: "Emit a linked executable", group: .modes)
@@ -900,6 +901,7 @@ extension Option {
900901
Option.emitBc,
901902
Option.emitClangHeaderPath,
902903
Option.emitConstValuesPath,
904+
Option.emitConstValues,
903905
Option.emitDependenciesPath,
904906
Option.emitDependencies,
905907
Option.emitExecutable,

Tests/SwiftDriverTests/SwiftDriverTests.swift

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,6 +1047,144 @@ final class SwiftDriverTests: XCTestCase {
10471047
XCTAssertTrue(plannedJobs[0].commandLine.contains(.flag("-serialize-diagnostics-path")))
10481048
}
10491049

1050+
func testEmitConstValues() throws {
1051+
do { // Just single files
1052+
var driver = try Driver(args: ["swiftc", "foo.swift", "bar.swift", "baz.swift",
1053+
"-module-name", "Foo", "-emit-const-values"])
1054+
let plannedJobs = try driver.planBuild().removingAutolinkExtractJobs()
1055+
XCTAssertEqual(plannedJobs.count, 4)
1056+
XCTAssertEqual(plannedJobs[0].kind, .compile)
1057+
XCTAssertTrue(plannedJobs[0].commandLine.contains("-emit-const-values-path"))
1058+
XCTAssertTrue(plannedJobs[0].outputs.contains(where: { $0.type == .swiftConstValues }))
1059+
XCTAssertEqual(plannedJobs[1].kind, .compile)
1060+
XCTAssertTrue(plannedJobs[1].commandLine.contains("-emit-const-values-path"))
1061+
XCTAssertTrue(plannedJobs[1].outputs.contains(where: { $0.type == .swiftConstValues }))
1062+
XCTAssertEqual(plannedJobs[2].kind, .compile)
1063+
XCTAssertTrue(plannedJobs[2].commandLine.contains("-emit-const-values-path"))
1064+
XCTAssertTrue(plannedJobs[2].outputs.contains(where: { $0.type == .swiftConstValues }))
1065+
XCTAssertEqual(plannedJobs[3].kind, .link)
1066+
}
1067+
1068+
do { // Just single files with emit-module
1069+
var driver = try Driver(args: ["swiftc", "foo.swift", "bar.swift", "baz.swift", "-emit-module",
1070+
"-module-name", "Foo", "-emit-const-values"])
1071+
let plannedJobs = try driver.planBuild().removingAutolinkExtractJobs()
1072+
XCTAssertEqual(plannedJobs.count, 4)
1073+
XCTAssertEqual(plannedJobs[0].kind, .emitModule)
1074+
// Ensure the emit-module job does *not* contain this flag
1075+
XCTAssertFalse(plannedJobs[0].commandLine.contains("-emit-const-values-path"))
1076+
XCTAssertEqual(plannedJobs[1].kind, .compile)
1077+
XCTAssertTrue(plannedJobs[1].commandLine.contains("-emit-const-values-path"))
1078+
XCTAssertTrue(plannedJobs[1].outputs.contains(where: { $0.type == .swiftConstValues }))
1079+
XCTAssertEqual(plannedJobs[2].kind, .compile)
1080+
XCTAssertTrue(plannedJobs[2].commandLine.contains("-emit-const-values-path"))
1081+
XCTAssertTrue(plannedJobs[2].outputs.contains(where: { $0.type == .swiftConstValues }))
1082+
XCTAssertEqual(plannedJobs[3].kind, .compile)
1083+
XCTAssertTrue(plannedJobs[3].commandLine.contains("-emit-const-values-path"))
1084+
XCTAssertTrue(plannedJobs[3].outputs.contains(where: { $0.type == .swiftConstValues }))
1085+
}
1086+
1087+
do { // Batch
1088+
var driver = try Driver(args: ["swiftc", "foo.swift", "bar.swift", "baz.swift",
1089+
"-enable-batch-mode","-driver-batch-size-limit", "2",
1090+
"-module-name", "Foo", "-emit-const-values"])
1091+
let plannedJobs = try driver.planBuild().removingAutolinkExtractJobs()
1092+
XCTAssertEqual(plannedJobs.count, 3)
1093+
XCTAssertEqual(plannedJobs[0].kind, .compile)
1094+
XCTAssertTrue(plannedJobs[0].primaryInputs.map{ $0.file.description }.elementsEqual(["foo.swift",
1095+
"bar.swift"]))
1096+
XCTAssertTrue(plannedJobs[0].commandLine.contains("-emit-const-values-path"))
1097+
XCTAssertEqual(plannedJobs[0].outputs.filter({ $0.type == .swiftConstValues }).count, 2)
1098+
XCTAssertEqual(plannedJobs[1].kind, .compile)
1099+
XCTAssertTrue(plannedJobs[1].primaryInputs.map{ $0.file.description }.elementsEqual(["baz.swift"]))
1100+
XCTAssertTrue(plannedJobs[1].commandLine.contains("-emit-const-values-path"))
1101+
XCTAssertEqual(plannedJobs[1].outputs.filter({ $0.type == .swiftConstValues }).count, 1)
1102+
XCTAssertEqual(plannedJobs[2].kind, .link)
1103+
}
1104+
1105+
try withTemporaryFile { fileMapFile in // Batch with output-file-map
1106+
let outputMapContents = """
1107+
{
1108+
"foo.swift": {
1109+
"object": "/tmp/foo.build/foo.swift.o",
1110+
"const-values": "/tmp/foo.build/foo.swiftconstvalues"
1111+
},
1112+
"bar.swift": {
1113+
"object": "/tmp/foo.build/bar.swift.o",
1114+
"const-values": "/tmp/foo.build/bar.swiftconstvalues"
1115+
},
1116+
"baz.swift": {
1117+
"object": "/tmp/foo.build/baz.swift.o",
1118+
"const-values": "/tmp/foo.build/baz.swiftconstvalues"
1119+
}
1120+
}
1121+
"""
1122+
try localFileSystem.writeFileContents(fileMapFile.path) { $0 <<< outputMapContents }
1123+
var driver = try Driver(args: ["swiftc", "foo.swift", "bar.swift", "baz.swift",
1124+
"-enable-batch-mode","-driver-batch-size-limit", "2",
1125+
"-module-name", "Foo", "-emit-const-values",
1126+
"-output-file-map", fileMapFile.path.description])
1127+
let plannedJobs = try driver.planBuild().removingAutolinkExtractJobs()
1128+
XCTAssertEqual(plannedJobs.count, 3)
1129+
XCTAssertEqual(plannedJobs[0].kind, .compile)
1130+
XCTAssertTrue(plannedJobs[0].primaryInputs.map{ $0.file.description }.elementsEqual(["foo.swift",
1131+
"bar.swift"]))
1132+
XCTAssertTrue(plannedJobs[0].commandLine.contains(subsequence: [.flag("-emit-const-values-path"), .path(.absolute(.init("/tmp/foo.build/foo.swiftconstvalues")))]))
1133+
XCTAssertTrue(plannedJobs[0].commandLine.contains(subsequence: [.flag("-emit-const-values-path"), .path(.absolute(.init("/tmp/foo.build/bar.swiftconstvalues")))]))
1134+
XCTAssertEqual(plannedJobs[0].outputs.filter({ $0.type == .swiftConstValues }).count, 2)
1135+
XCTAssertEqual(plannedJobs[1].kind, .compile)
1136+
XCTAssertTrue(plannedJobs[1].primaryInputs.map{ $0.file.description }.elementsEqual(["baz.swift"]))
1137+
XCTAssertTrue(plannedJobs[1].commandLine.contains("-emit-const-values-path"))
1138+
XCTAssertEqual(plannedJobs[1].outputs.filter({ $0.type == .swiftConstValues }).count, 1)
1139+
XCTAssertTrue(plannedJobs[1].commandLine.contains(subsequence: [.flag("-emit-const-values-path"), .path(.absolute(.init("/tmp/foo.build/baz.swiftconstvalues")))]))
1140+
XCTAssertEqual(plannedJobs[2].kind, .link)
1141+
}
1142+
1143+
do { // WMO
1144+
var driver = try Driver(args: ["swiftc", "foo.swift", "bar.swift", "baz.swift",
1145+
"-whole-module-optimization",
1146+
"-module-name", "Foo", "-emit-const-values"])
1147+
let plannedJobs = try driver.planBuild().removingAutolinkExtractJobs()
1148+
XCTAssertEqual(plannedJobs.count, 2)
1149+
XCTAssertEqual(plannedJobs[0].kind, .compile)
1150+
XCTAssertEqual(plannedJobs[0].outputs.filter({ $0.type == .swiftConstValues }).count, 1)
1151+
XCTAssertEqual(plannedJobs[1].kind, .link)
1152+
}
1153+
1154+
try withTemporaryFile { fileMapFile in // WMO with output-file-map
1155+
let outputMapContents = """
1156+
{
1157+
"": {
1158+
"const-values": "/tmp/foo.build/foo.master.swiftconstvalues"
1159+
},
1160+
"foo.swift": {
1161+
"object": "/tmp/foo.build/foo.swift.o",
1162+
"const-values": "/tmp/foo.build/foo.swiftconstvalues"
1163+
},
1164+
"bar.swift": {
1165+
"object": "/tmp/foo.build/bar.swift.o",
1166+
"const-values": "/tmp/foo.build/bar.swiftconstvalues"
1167+
},
1168+
"baz.swift": {
1169+
"object": "/tmp/foo.build/baz.swift.o",
1170+
"const-values": "/tmp/foo.build/baz.swiftconstvalues"
1171+
}
1172+
}
1173+
"""
1174+
try localFileSystem.writeFileContents(fileMapFile.path) { $0 <<< outputMapContents }
1175+
var driver = try Driver(args: ["swiftc", "foo.swift", "bar.swift", "baz.swift",
1176+
"-whole-module-optimization",
1177+
"-module-name", "Foo", "-emit-const-values",
1178+
"-output-file-map", fileMapFile.path.description])
1179+
let plannedJobs = try driver.planBuild().removingAutolinkExtractJobs()
1180+
XCTAssertEqual(plannedJobs.count, 2)
1181+
XCTAssertEqual(plannedJobs[0].kind, .compile)
1182+
XCTAssertEqual(plannedJobs[0].outputs.first(where: { $0.type == .swiftConstValues })?.file,
1183+
.absolute(.init("/tmp/foo.build/foo.master.swiftconstvalues")))
1184+
XCTAssertEqual(plannedJobs[1].kind, .link)
1185+
}
1186+
}
1187+
10501188
func testEmitModuleSepratelyEmittingDiagnosticsWithOutputFileMap() throws {
10511189
try withTemporaryDirectory { path in
10521190
let outputFileMap = path.appending(component: "outputFileMap.json")

0 commit comments

Comments
 (0)