mutating func compileJob()

in Sources/SwiftDriver/Jobs/CompileJob.swift [221:387]


  mutating func compileJob(primaryInputs: [TypedVirtualPath],
                           outputType: FileType?,
                           addJobOutputs: ([TypedVirtualPath]) -> Void,
                           emitModuleTrace: Bool)
  throws -> Job {
    var commandLine: [Job.ArgTemplate] = swiftCompilerPrefixArgs.map { Job.ArgTemplate.flag($0) }
    var inputs: [TypedVirtualPath] = []
    var outputs: [TypedVirtualPath] = []
    // Used to map primaryInputs to primaryOutputs
    var inputOutputMap = [TypedVirtualPath: [TypedVirtualPath]]()

    commandLine.appendFlag("-frontend")
    addCompileModeOption(outputType: outputType, commandLine: &commandLine)

    let indexFilePath: TypedVirtualPath?
    if let indexFileArg = parsedOptions.getLastArgument(.indexFilePath)?.asSingle {
      let path = try VirtualPath(path: indexFileArg)
      indexFilePath = inputFiles.first { $0.file == path }
    } else {
      indexFilePath = nil
    }

    let (primaryOutputs, primaryIndexUnitOutputs) =
      addCompileInputs(primaryInputs: primaryInputs,
                       indexFilePath: indexFilePath,
                       inputs: &inputs,
                       inputOutputMap: &inputOutputMap,
                       outputType: outputType,
                       commandLine: &commandLine)
    outputs += primaryOutputs

    // FIXME: optimization record arguments are added before supplementary outputs
    // for compatibility with the integrated driver's test suite. We should adjust the tests
    // so we can organize this better.
    // -save-optimization-record and -save-optimization-record= have different meanings.
    // In this case, we specifically want to pass the EQ variant to the frontend
    // to control the output type of optimization remarks (YAML or bitstream).
    try commandLine.appendLast(.saveOptimizationRecordEQ, from: &parsedOptions)
    try commandLine.appendLast(.saveOptimizationRecordPasses, from: &parsedOptions)

    let inputsGeneratingCodeCount = primaryInputs.isEmpty
      ? inputs.count
      : primaryInputs.count

    outputs += try addFrontendSupplementaryOutputArguments(
      commandLine: &commandLine,
      primaryInputs: primaryInputs,
      inputsGeneratingCodeCount: inputsGeneratingCodeCount,
      inputOutputMap: &inputOutputMap,
      includeModuleTracePath: emitModuleTrace,
      indexFilePath: indexFilePath)

    // Forward migrator flags.
    try commandLine.appendLast(.apiDiffDataFile, from: &parsedOptions)
    try commandLine.appendLast(.apiDiffDataDir, from: &parsedOptions)
    try commandLine.appendLast(.dumpUsr, from: &parsedOptions)

    if parsedOptions.hasArgument(.parseStdlib) {
      commandLine.appendFlag(.disableObjcAttrRequiresFoundationModule)
    }

    try addCommonFrontendOptions(commandLine: &commandLine, inputs: &inputs)
    // FIXME: MSVC runtime flags

    if parsedOptions.hasArgument(.parseAsLibrary, .emitLibrary) {
      commandLine.appendFlag(.parseAsLibrary)
    }

    try commandLine.appendLast(.parseSil, from: &parsedOptions)

    try commandLine.appendLast(.migrateKeepObjcVisibility, from: &parsedOptions)

    if numThreads > 0 {
      commandLine.appendFlags("-num-threads", numThreads.description)
    }

    // Add primary outputs.
    if primaryOutputs.count > fileListThreshold {
      commandLine.appendFlag(.outputFilelist)
      let fileList = VirtualPath.createUniqueFilelist(RelativePath("outputs"),
                                                      .list(primaryOutputs.map { $0.file }))
      commandLine.appendPath(fileList)
    } else {
      for primaryOutput in primaryOutputs {
        commandLine.appendFlag(.o)
        commandLine.appendPath(primaryOutput.file)
      }
    }

    // Add index unit output paths if needed.
    if !primaryIndexUnitOutputs.isEmpty {
      if primaryIndexUnitOutputs.count > fileListThreshold {
        commandLine.appendFlag(.indexUnitOutputPathFilelist)
        let fileList = VirtualPath.createUniqueFilelist(RelativePath("index-unit-outputs"),
                                                        .list(primaryIndexUnitOutputs.map { $0.file }))
        commandLine.appendPath(fileList)
      } else {
        for primaryIndexUnitOutput in primaryIndexUnitOutputs {
          commandLine.appendFlag(.indexUnitOutputPath)
          commandLine.appendPath(primaryIndexUnitOutput.file)
        }
      }
    }

    try commandLine.appendLast(.embedBitcodeMarker, from: &parsedOptions)

    // For `-index-file` mode add `-disable-typo-correction`, since the errors
    // will be ignored and it can be expensive to do typo-correction.
    if compilerOutputType == FileType.indexData {
      commandLine.appendFlag(.disableTypoCorrection)
    }

    if parsedOptions.contains(.indexStorePath) {
      try commandLine.appendLast(.indexStorePath, from: &parsedOptions)
      if !parsedOptions.contains(.indexIgnoreSystemModules) {
        commandLine.appendFlag(.indexSystemModules)
      }
    }

    if parsedOptions.contains(.debugInfoStoreInvocation) ||
       toolchain.shouldStoreInvocationInDebugInfo {
      commandLine.appendFlag(.debugInfoStoreInvocation)
    }

    try commandLine.appendLast(.trackSystemDependencies, from: &parsedOptions)
    try commandLine.appendLast(.CrossModuleOptimization, from: &parsedOptions)
    try commandLine.appendLast(.disableAutolinkingRuntimeCompatibility, from: &parsedOptions)
    try commandLine.appendLast(.runtimeCompatibilityVersion, from: &parsedOptions)
    try commandLine.appendLast(.disableAutolinkingRuntimeCompatibilityDynamicReplacements, from: &parsedOptions)
    try commandLine.appendLast(.disableAutolinkingRuntimeCompatibilityConcurrency, from: &parsedOptions)
    try commandLine.appendLast(.checkApiAvailabilityOnly, from: &parsedOptions)

    if compilerMode.isSingleCompilation {
      try commandLine.appendLast(.emitSymbolGraph, from: &parsedOptions)
      try commandLine.appendLast(.emitSymbolGraphDir, from: &parsedOptions)
    }
    try commandLine.appendLast(.includeSpiSymbols, from: &parsedOptions)
    try commandLine.appendLast(.symbolGraphMinimumAccessLevel, from: &parsedOptions)

    addJobOutputs(outputs)

    // Bridging header is needed for compiling these .swift sources.
    if let pchPath = bridgingPrecompiledHeader {
      let pchInput = TypedVirtualPath(file: pchPath, type: .pch)
      inputs.append(pchInput)
    }

    let displayInputs : [TypedVirtualPath]
    if case .singleCompile = compilerMode {
      displayInputs = inputs
    } else {
      displayInputs = primaryInputs
    }

    return Job(
      moduleName: moduleOutputInfo.name,
      kind: .compile,
      tool: .absolute(try toolchain.getToolPath(.swiftCompiler)),
      commandLine: commandLine,
      displayInputs: displayInputs,
      inputs: inputs,
      primaryInputs: primaryInputs,
      outputs: outputs,
      inputOutputMap: inputOutputMap,
      supportsResponseFiles: true
    )
  }