Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Sources/SWBCore/Settings/BuiltinMacros.swift
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,7 @@ public final class BuiltinMacros {
public static let CLANG_EXPLICIT_MODULES_IGNORE_LIBCLANG_VERSION_MISMATCH = BuiltinMacros.declareBooleanMacro("CLANG_EXPLICIT_MODULES_IGNORE_LIBCLANG_VERSION_MISMATCH")
public static let CLANG_EXPLICIT_MODULES_OUTPUT_PATH = BuiltinMacros.declarePathMacro("CLANG_EXPLICIT_MODULES_OUTPUT_PATH")
public static let SWIFT_EXPLICIT_MODULES_OUTPUT_PATH = BuiltinMacros.declarePathMacro("SWIFT_EXPLICIT_MODULES_OUTPUT_PATH")
public static let CLANG_EXPLICIT_MODULES_ENABLE_REPRODUCER_FOR_ERRORS = BuiltinMacros.declareBooleanMacro("_EXPERIMENTAL_CLANG_EXPLICIT_MODULES_ENABLE_REPRODUCER_FOR_ERRORS")
public static let CLANG_ENABLE_COMPILE_CACHE = BuiltinMacros.declareBooleanMacro("CLANG_ENABLE_COMPILE_CACHE")
public static let CLANG_CACHE_FINE_GRAINED_OUTPUTS = BuiltinMacros.declareEnumMacro("CLANG_CACHE_FINE_GRAINED_OUTPUTS") as EnumMacroDeclaration<FineGrainedCachingSetting>
public static let CLANG_CACHE_FINE_GRAINED_OUTPUTS_VERIFICATION = BuiltinMacros.declareEnumMacro("CLANG_CACHE_FINE_GRAINED_OUTPUTS_VERIFICATION") as EnumMacroDeclaration<FineGrainedCachingVerificationSetting>
Expand Down Expand Up @@ -1510,6 +1511,7 @@ public final class BuiltinMacros {
CLANG_EXPLICIT_MODULES_IGNORE_LIBCLANG_VERSION_MISMATCH,
CLANG_EXPLICIT_MODULES_OUTPUT_PATH,
SWIFT_EXPLICIT_MODULES_OUTPUT_PATH,
CLANG_EXPLICIT_MODULES_ENABLE_REPRODUCER_FOR_ERRORS,
CLANG_EXTRACT_API_EXEC,
CLANG_GENERATE_OPTIMIZATION_REMARKS,
CLANG_GENERATE_OPTIMIZATION_REMARKS_FILTER,
Expand Down
13 changes: 9 additions & 4 deletions Sources/SWBCore/SpecImplementations/Tools/CCompiler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -361,8 +361,9 @@ public struct ClangExplicitModulesPayload: Serializable, Encodable, Sendable {
public let dependencyFilteringRootPath: Path?
public let reportRequiredTargetDependencies: BooleanWarningLevel
public let verifyingModule: String?
public let shouldGenerateReproducerForErrors: Bool

fileprivate init(uniqueID: String, sourcePath: Path, libclangPath: Path, usesCompilerLauncher: Bool, outputPath: Path, scanningOutputPath: Path, casOptions: CASOptions?, cacheFallbackIfNotAvailable: Bool, dependencyFilteringRootPath: Path?, reportRequiredTargetDependencies: BooleanWarningLevel, verifyingModule: String?) {
fileprivate init(uniqueID: String, sourcePath: Path, libclangPath: Path, usesCompilerLauncher: Bool, outputPath: Path, scanningOutputPath: Path, casOptions: CASOptions?, cacheFallbackIfNotAvailable: Bool, dependencyFilteringRootPath: Path?, reportRequiredTargetDependencies: BooleanWarningLevel, verifyingModule: String?, shouldGenerateReproducerForErrors: Bool) {
self.uniqueID = uniqueID
self.sourcePath = sourcePath
self.libclangPath = libclangPath
Expand All @@ -374,10 +375,11 @@ public struct ClangExplicitModulesPayload: Serializable, Encodable, Sendable {
self.dependencyFilteringRootPath = dependencyFilteringRootPath
self.reportRequiredTargetDependencies = reportRequiredTargetDependencies
self.verifyingModule = verifyingModule
self.shouldGenerateReproducerForErrors = shouldGenerateReproducerForErrors
}

public func serialize<T: Serializer>(to serializer: T) {
serializer.serializeAggregate(11) {
serializer.serializeAggregate(12) {
serializer.serialize(uniqueID)
serializer.serialize(sourcePath)
serializer.serialize(libclangPath)
Expand All @@ -389,11 +391,12 @@ public struct ClangExplicitModulesPayload: Serializable, Encodable, Sendable {
serializer.serialize(dependencyFilteringRootPath)
serializer.serialize(reportRequiredTargetDependencies)
serializer.serialize(verifyingModule)
serializer.serialize(shouldGenerateReproducerForErrors)
}
}

public init(from deserializer: any Deserializer) throws {
try deserializer.beginAggregate(11)
try deserializer.beginAggregate(12)
self.uniqueID = try deserializer.deserialize()
self.sourcePath = try deserializer.deserialize()
self.libclangPath = try deserializer.deserialize()
Expand All @@ -405,6 +408,7 @@ public struct ClangExplicitModulesPayload: Serializable, Encodable, Sendable {
self.dependencyFilteringRootPath = try deserializer.deserialize()
self.reportRequiredTargetDependencies = try deserializer.deserialize()
self.verifyingModule = try deserializer.deserialize()
self.shouldGenerateReproducerForErrors = try deserializer.deserialize()
}

}
Expand Down Expand Up @@ -997,7 +1001,8 @@ public class ClangCompilerSpec : CompilerSpec, SpecIdentifierType, GCCCompatible
// To match the behavior of -MMD, our scan task should filter out headers in the SDK when discovering dependencies. In the long run, libclang should do this for us.
dependencyFilteringRootPath: isForPCHTask ? nil : cbc.producer.sdk?.path,
reportRequiredTargetDependencies: cbc.scope.evaluate(BuiltinMacros.DIAGNOSE_MISSING_TARGET_DEPENDENCIES),
verifyingModule: verifyingModule(cbc)
verifyingModule: verifyingModule(cbc),
shouldGenerateReproducerForErrors: cbc.scope.evaluate(BuiltinMacros.CLANG_EXPLICIT_MODULES_ENABLE_REPRODUCER_FOR_ERRORS)
)
let explicitModulesSignatureData = cachedBuild ? "cached" : nil

Expand Down
7 changes: 7 additions & 0 deletions Sources/SWBCore/TaskResult.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ public enum TaskResult: Hashable, Sendable {
}
}

public var isCrashed: Bool {
if !self.isCancelled, case .exit(exitStatus: .uncaughtSignal, metrics: _) = self {
return true
}
return false
}

public var metrics: CommandMetrics? {
guard case let .exit(_, metrics) = self else {
return nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,10 @@ public final class ClangCompileTaskAction: TaskAction, BuildValueValidatingTaskA
outputDelegate.emitOutput(ByteString(encodingAsUTF8: commandString) + "\n")
}

if case .some(.failed) = lastResult, case .some(.exit(.uncaughtSignal, _)) = outputDelegate.result {
let shouldGenerateReproducer = (lastResult == .failed) &&
(explicitModulesPayload.shouldGenerateReproducerForErrors ||
(outputDelegate.result?.isCrashed ?? false))
Comment on lines +322 to +324
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've spent some time trying to improve this code, so let me share a few options I've discarded. If you prefer one of the mentioned options, let me know

let shouldGenerateReproducer: Bool
if lastResult == .failed {
    if explicitModulesPayload.shouldGenerateReproducerForErrors {
        shouldGenerateReproducer = true
    } else if case .exit(exitStatus: .uncaughtSignal, metrics: _) = outputDelegate.result {
        // In case of crash.
        shouldGenerateReproducer = true
    } else {
        shouldGenerateReproducer = false
    }
} else {
    shouldGenerateReproducer = false
}

Slight variation with if-expression

let shouldGenerateReproducer = if lastResult == .failed {
    if explicitModulesPayload.shouldGenerateReproducerForErrors {
        true
    } else if case .exit(exitStatus: .uncaughtSignal, metrics: _) = outputDelegate.result {
        // In case of crash.
        true
    } else {
        false
    }
} else {
    false
}

Try to add case

let shouldGenerateReproducer = if lastResult == .failed {
    switch (explicitModulesPayload.shouldGenerateReproducerForErrors, outputDelegate.result) {
    case (true, _): true
    case (_, .some(.exit(exitStatus: .uncaughtSignal, metrics: _))): true
    default: false
    }
} else {
    false
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No strong opinion from me, seems fine as it is.

if shouldGenerateReproducer {
do {
if let reproducerMessage = try clangModuleDependencyGraph.generateReproducer(
forFailedDependency: dependencyInfo,
Expand Down
Loading