@@ -280,14 +280,17 @@ mergeBatchInputs(ArrayRef<const Job *> jobs,
280280 return false ;
281281}
282282
283- // / Debugging only: return whether the set of \p jobs is an ordered subsequence
284- // / of the sequence of top-level input files in the \c Compilation \p C.
285- static bool
286- jobsAreSubsequenceOfCompilationInputs (ArrayRef<const Job *> jobs,
287- Compilation &C) {
288- llvm::SmallVector<const Job *, 16 > sortedJobs;
283+ // / Unfortunately the success or failure of a Swift compilation is currently
284+ // / sensitive to the order in which files are processed, at least in terms of
285+ // / the order of processing extensions (and likely other ways we haven't
286+ // / discovered yet). So long as this is true, we need to make sure any batch job
287+ // / we build names its inputs in an order that's a subsequence of the sequence
288+ // / of inputs the driver was initially invoked with.
289+ static void sortJobsToMatchCompilationInputs (ArrayRef<const Job *> unsortedJobs,
290+ SmallVectorImpl<const Job *> &sortedJobs,
291+ Compilation &C) {
289292 llvm::StringMap<const Job *> jobsByInput;
290- for (const Job *J : jobs ) {
293+ for (const Job *J : unsortedJobs ) {
291294 const CompileJobAction *CJA = cast<CompileJobAction>(&J->getSource ());
292295 const InputAction* IA = findSingleSwiftInput (CJA);
293296 auto R = jobsByInput.insert (std::make_pair (IA->getInputArg ().getValue (),
@@ -300,40 +303,34 @@ jobsAreSubsequenceOfCompilationInputs(ArrayRef<const Job *> jobs,
300303 sortedJobs.push_back (I->second );
301304 }
302305 }
303- if (sortedJobs.size () != jobs.size ())
304- return false ;
305- for (size_t i = 0 ; i < sortedJobs.size (); ++i) {
306- if (sortedJobs[i] != jobs[i])
307- return false ;
308- }
309- return true ;
310306}
311307
312308// / Construct a \c BatchJob by merging the constituent \p jobs' CommandOutput,
313309// / input \c Job and \c Action members. Call through to \c constructInvocation
314310// / on \p BatchJob, to build the \c InvocationInfo.
315311std::unique_ptr<Job>
316- ToolChain::constructBatchJob (ArrayRef<const Job *> jobs ,
312+ ToolChain::constructBatchJob (ArrayRef<const Job *> unsortedJobs ,
317313 Compilation &C) const
318314{
319- if (jobs .empty ())
315+ if (unsortedJobs .empty ())
320316 return nullptr ;
321317
322- assert (jobsAreSubsequenceOfCompilationInputs (jobs, C));
318+ llvm::SmallVector<const Job *, 16 > sortedJobs;
319+ sortJobsToMatchCompilationInputs (unsortedJobs, sortedJobs, C);
323320
324321 // Synthetic OutputInfo is a slightly-modified version of the initial
325322 // compilation's OI.
326323 auto OI = C.getOutputInfo ();
327324 OI.CompilerMode = OutputInfo::Mode::BatchModeCompile;
328325
329- auto const *executablePath = jobs [0 ]->getExecutable ();
330- auto outputType = jobs [0 ]->getOutput ().getPrimaryOutputType ();
331- auto output = makeBatchCommandOutput (jobs , C, outputType);
326+ auto const *executablePath = sortedJobs [0 ]->getExecutable ();
327+ auto outputType = sortedJobs [0 ]->getOutput ().getPrimaryOutputType ();
328+ auto output = makeBatchCommandOutput (sortedJobs , C, outputType);
332329
333330 llvm::SmallSetVector<const Job *, 16 > inputJobs;
334331 llvm::SmallSetVector<const Action *, 16 > inputActions;
335332 auto *batchCJA = C.createAction <CompileJobAction>(outputType);
336- if (mergeBatchInputs (jobs , inputJobs, inputActions, batchCJA))
333+ if (mergeBatchInputs (sortedJobs , inputJobs, inputActions, batchCJA))
337334 return nullptr ;
338335
339336 JobContext context{C, inputJobs.getArrayRef (), inputActions.getArrayRef (),
@@ -346,7 +343,7 @@ ToolChain::constructBatchJob(ArrayRef<const Job *> jobs,
346343 std::move (invocationInfo.Arguments ),
347344 std::move (invocationInfo.ExtraEnvironment ),
348345 std::move (invocationInfo.FilelistInfos ),
349- jobs );
346+ sortedJobs );
350347}
351348
352349bool
0 commit comments