Skip to content

Commit 0a1bc7e

Browse files
authored
Merge pull request #1302 from artemcm/ClangModuleValidatePerSeshhhh
Add Swift compilation flags to enable Clang's validate-per-build-session module behavior
2 parents 6a83fd4 + b440954 commit 0a1bc7e

File tree

4 files changed

+61
-0
lines changed

4 files changed

+61
-0
lines changed

Sources/SwiftDriver/Driver/Driver.swift

+12
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,7 @@ public struct Driver {
626626
workingDirectory: workingDirectory,
627627
diagnosticEngine: diagnosticEngine)
628628
Self.validateEmitDependencyGraphArgs(&parsedOptions, diagnosticEngine: diagnosticEngine)
629+
Self.validateValidateClangModulesOnceOptions(&parsedOptions, diagnosticEngine: diagnosticEngine)
629630
Self.validateParseableOutputArgs(&parsedOptions, diagnosticEngine: diagnosticEngine)
630631
Self.validateCompilationConditionArgs(&parsedOptions, diagnosticEngine: diagnosticEngine)
631632
Self.validateFrameworkSearchPathArgs(&parsedOptions, diagnosticEngine: diagnosticEngine)
@@ -2701,6 +2702,17 @@ extension Driver {
27012702
}
27022703
}
27032704

2705+
static func validateValidateClangModulesOnceOptions(_ parsedOptions: inout ParsedOptions,
2706+
diagnosticEngine: DiagnosticsEngine) {
2707+
// '-validate-clang-modules-once' requires '-clang-build-session-file'
2708+
if parsedOptions.hasArgument(.validateClangModulesOnce) &&
2709+
!parsedOptions.hasArgument(.clangBuildSessionFile) {
2710+
diagnosticEngine.emit(.error(Error.optionRequiresAnother(Option.validateClangModulesOnce.spelling,
2711+
Option.clangBuildSessionFile.spelling)),
2712+
location: nil)
2713+
}
2714+
}
2715+
27042716
static func validateEmitDependencyGraphArgs(_ parsedOptions: inout ParsedOptions,
27052717
diagnosticEngine: DiagnosticsEngine) {
27062718
// '-print-explicit-dependency-graph' requires '-explicit-module-build'

Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift

+8
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,14 @@ extension Driver {
263263
commandLine.appendFlag(ver)
264264
}
265265

266+
// Pass down -validate-clang-modules-once if we are working with a compiler that
267+
// supports it.
268+
if isFrontendArgSupported(.validateClangModulesOnce),
269+
isFrontendArgSupported(.clangBuildSessionFile) {
270+
try commandLine.appendLast(.validateClangModulesOnce, from: &parsedOptions)
271+
try commandLine.appendLast(.clangBuildSessionFile, from: &parsedOptions)
272+
}
273+
266274
if let workingDirectory = workingDirectory {
267275
// Add -Xcc -working-directory before any other -Xcc options to ensure it is
268276
// overridden by an explicit -Xcc -working-directory, although having a

Sources/SwiftOptions/Options.swift

+8
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ extension Option {
5252
public static let candidateModuleFile: Option = Option("-candidate-module-file", .separate, attributes: [.helpHidden, .frontend, .noDriver], metaVar: "<path>", helpText: "Specify Swift module may be ready to use for an interface")
5353
public static let checkApiAvailabilityOnly: Option = Option("-check-api-availability-only", .flag, attributes: [.helpHidden, .frontend, .noInteractive], helpText: "Only check the availability of the APIs, ignore function bodies")
5454
public static let checkOnoneCompleteness: Option = Option("-check-onone-completeness", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Print errors if the compile OnoneSupport module is missing symbols")
55+
public static let clangBuildSessionFile: Option = Option("-clang-build-session-file", .separate, attributes: [.frontend, .argumentIsPath], helpText: "Use the last modification time of <file> as the underlying Clang build session timestamp")
5556
public static let clangHeaderExposeDecls: Option = Option("-clang-header-expose-decls=", .joined, attributes: [.helpHidden, .frontend, .noDriver], metaVar: "all-public|has-expose-attr", helpText: "Which declarations should be exposed in the generated clang header.")
5657
public static let clangTarget: Option = Option("-clang-target", .separate, attributes: [.frontend], helpText: "Separately set the target we should use for internal Clang instance")
5758
public static let codeCompleteCallPatternHeuristics: Option = Option("-code-complete-call-pattern-heuristics", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Use heuristics to guess whether we want call pattern completions")
@@ -128,6 +129,7 @@ extension Option {
128129
public static let disableClangimporterSourceImport: Option = Option("-disable-clangimporter-source-import", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Disable ClangImporter and forward all requests straight the DWARF importer.")
129130
public static let disableCrossModuleOptimization: Option = Option("-disable-cmo", .flag, attributes: [.helpHidden, .frontend], helpText: "Disable cross-module optimization")
130131
public static let disableCollocateMetadataFunctions: Option = Option("-disable-collocate-metadata-functions", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Disable collocate metadata functions")
132+
public static let disableColocateTypeDescriptors: Option = Option("-disable-colocate-type-descriptors", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Disable colocate type descriptors")
131133
public static let disableConcreteTypeMetadataMangledNameAccessors: Option = Option("-disable-concrete-type-metadata-mangled-name-accessors", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Disable concrete type metadata access by mangled name")
132134
public static let disableConformanceAvailabilityErrors: Option = Option("-disable-conformance-availability-errors", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Diagnose conformance availability violations as warnings")
133135
public static let disableConstraintSolverPerformanceHacks: Option = Option("-disable-constraint-solver-performance-hacks", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Disable all the hacks in the constraint solver")
@@ -321,6 +323,7 @@ extension Option {
321323
public static let enableBridgingPch: Option = Option("-enable-bridging-pch", .flag, attributes: [.helpHidden], helpText: "Enable automatic generation of bridging PCH files")
322324
public static let enableBuiltinModule: Option = Option("-enable-builtin-module", .flag, attributes: [.frontend, .moduleInterface], helpText: "Enables the explicit import of the Builtin module")
323325
public static let enableCollocateMetadataFunctions: Option = Option("-enable-collocate-metadata-functions", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Enable collocate metadata functions")
326+
public static let enableColocateTypeDescriptors: Option = Option("-enable-colocate-type-descriptors", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Enable colocate type descriptors")
324327
public static let enableConformanceAvailabilityErrors: Option = Option("-enable-conformance-availability-errors", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Diagnose conformance availability violations as errors")
325328
public static let copyPropagationStateEQ: Option = Option("-enable-copy-propagation=", .joined, attributes: [.frontend, .noDriver], metaVar: "true|requested-passes-only|false", helpText: "Whether to enable copy propagation")
326329
public static let enableCopyPropagation: Option = Option("-enable-copy-propagation", .flag, attributes: [.frontend, .noDriver], helpText: "Run SIL copy propagation with lexical lifetimes to shorten object lifetimes while preserving variable lifetimes.")
@@ -714,6 +717,7 @@ extension Option {
714717
public static let useStaticResourceDir: Option = Option("-use-static-resource-dir", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Use resources in the static resource directory")
715718
public static let useTabs: Option = Option("-use-tabs", .flag, attributes: [.noInteractive, .noBatch, .indent], helpText: "Use tabs for indentation.", group: .codeFormatting)
716719
public static let userModuleVersion: Option = Option("-user-module-version", .separate, attributes: [.frontend], metaVar: "<vers>", helpText: "Module version specified from Swift module authors")
720+
public static let validateClangModulesOnce: Option = Option("-validate-clang-modules-once", .flag, attributes: [.frontend], helpText: "Don't verify input files for Clang modules if the module has been successfully validated or loaded during this build session")
717721
public static let validateTbdAgainstIrEQ: Option = Option("-validate-tbd-against-ir=", .joined, attributes: [.helpHidden, .frontend, .noDriver], metaVar: "<level>", helpText: "Compare the symbols in the IR against the TBD file that would be generated.")
718722
public static let valueRecursionThreshold: Option = Option("-value-recursion-threshold", .separate, attributes: [.helpHidden, .frontend, .doesNotAffectIncrementalBuild], helpText: "Set the maximum depth for direct recursion in value types")
719723
public static let verifyAdditionalFile: Option = Option("-verify-additional-file", .separate, attributes: [.frontend, .noDriver], helpText: "Verify diagnostics in this file in addition to source files")
@@ -801,6 +805,7 @@ extension Option {
801805
Option.candidateModuleFile,
802806
Option.checkApiAvailabilityOnly,
803807
Option.checkOnoneCompleteness,
808+
Option.clangBuildSessionFile,
804809
Option.clangHeaderExposeDecls,
805810
Option.clangTarget,
806811
Option.codeCompleteCallPatternHeuristics,
@@ -877,6 +882,7 @@ extension Option {
877882
Option.disableClangimporterSourceImport,
878883
Option.disableCrossModuleOptimization,
879884
Option.disableCollocateMetadataFunctions,
885+
Option.disableColocateTypeDescriptors,
880886
Option.disableConcreteTypeMetadataMangledNameAccessors,
881887
Option.disableConformanceAvailabilityErrors,
882888
Option.disableConstraintSolverPerformanceHacks,
@@ -1070,6 +1076,7 @@ extension Option {
10701076
Option.enableBridgingPch,
10711077
Option.enableBuiltinModule,
10721078
Option.enableCollocateMetadataFunctions,
1079+
Option.enableColocateTypeDescriptors,
10731080
Option.enableConformanceAvailabilityErrors,
10741081
Option.copyPropagationStateEQ,
10751082
Option.enableCopyPropagation,
@@ -1463,6 +1470,7 @@ extension Option {
14631470
Option.useStaticResourceDir,
14641471
Option.useTabs,
14651472
Option.userModuleVersion,
1473+
Option.validateClangModulesOnce,
14661474
Option.validateTbdAgainstIrEQ,
14671475
Option.valueRecursionThreshold,
14681476
Option.verifyAdditionalFile,

Tests/SwiftDriverTests/SwiftDriverTests.swift

+33
Original file line numberDiff line numberDiff line change
@@ -6663,6 +6663,39 @@ final class SwiftDriverTests: XCTestCase {
66636663
XCTAssertTrue(job.commandLine.contains(.path(.absolute(try driver.toolchain.executableDir.parentDirectory.appending(components: "lib", "swift", "host", "plugins")))))
66646664
}
66656665

6666+
func testClangModuleValidateOnce() throws {
6667+
let flagTest = try Driver(args: ["swiftc", "-typecheck", "foo.swift"])
6668+
guard flagTest.isFrontendArgSupported(.clangBuildSessionFile),
6669+
flagTest.isFrontendArgSupported(.validateClangModulesOnce) else {
6670+
return
6671+
}
6672+
6673+
do {
6674+
var driver = try Driver(args: ["swiftc", "-typecheck", "foo.swift"])
6675+
let jobs = try driver.planBuild().removingAutolinkExtractJobs()
6676+
let job = jobs.first!
6677+
XCTAssertFalse(job.commandLine.contains(.flag("-validate-clang-modules-once")))
6678+
XCTAssertFalse(job.commandLine.contains(.flag("-clang-build-session-file")))
6679+
}
6680+
6681+
do {
6682+
try assertDriverDiagnostics(args: ["swiftc", "-validate-clang-modules-once",
6683+
"foo.swift"]) {
6684+
$1.expect(.error("'-validate-clang-modules-once' cannot be specified if '-clang-build-session-file' is not present"))
6685+
}
6686+
}
6687+
6688+
do {
6689+
var driver = try Driver(args: ["swiftc", "-validate-clang-modules-once",
6690+
"-clang-build-session-file", "testClangModuleValidateOnce.session",
6691+
"foo.swift"])
6692+
let jobs = try driver.planBuild().removingAutolinkExtractJobs()
6693+
let job = jobs.first!
6694+
XCTAssertTrue(job.commandLine.contains(.flag("-validate-clang-modules-once")))
6695+
XCTAssertTrue(job.commandLine.contains(.flag("-clang-build-session-file")))
6696+
}
6697+
}
6698+
66666699
func testRegistrarLookup() throws {
66676700
#if os(Windows)
66686701
let SDKROOT: AbsolutePath = localFileSystem.currentWorkingDirectory!.appending(components: "SDKROOT")

0 commit comments

Comments
 (0)