1111// ===----------------------------------------------------------------------===//
1212
1313#include " swift/Basic/ParseableOutput.h"
14-
1514#include " swift/Basic/FileTypes.h"
1615#include " swift/Basic/JSONSerialization.h"
1716#include " swift/Basic/TaskQueue.h"
2120#include " llvm/Support/Path.h"
2221#include " llvm/Support/raw_ostream.h"
2322
23+ #include < sstream>
24+
2425using namespace swift ::parseable_output;
2526using namespace swift ::driver;
2627using namespace swift ::sys;
@@ -221,17 +222,9 @@ class DetailedInvocationBasedMessage : public InvocationBasedMessage {
221222public:
222223 DetailedInvocationBasedMessage (StringRef Kind,
223224 const CompilerInvocation &Invocation,
225+ const InputFile &PrimaryInput,
224226 ArrayRef<const char *> Args)
225227 : InvocationBasedMessage(Kind, Invocation), Args(Args) {
226- const auto &IO = Invocation.getFrontendOptions ().InputsAndOutputs ;
227- // This frontend invocation correpsonds to a BatchJob:
228- // A container of multiple StandardCompile Jobs.
229- if (IO.hasMultiplePrimaryInputs ()) {
230- llvm::dbgs () << " Batch JOB.\n " ;
231- } else {
232- llvm::dbgs () << " Single JOB.\n " ;
233- }
234-
235228 // Command line and arguments
236229 Executable = Invocation.getFrontendOptions ().MainExecutablePath ;
237230 CommandLine += Executable;
@@ -240,30 +233,23 @@ class DetailedInvocationBasedMessage : public InvocationBasedMessage {
240233 CommandLine += std::string (" " ) + A;
241234 }
242235
243- // Primary Inputs
244- IO.forEachPrimaryInput ([&](const InputFile &input) -> bool {
245- Inputs.push_back (CommandInput (input.getFileName ()));
246- return false ;
247- });
236+ // Primary Input only
237+ Inputs.push_back (CommandInput (PrimaryInput.getFileName ()));
248238
249- // Outputs
250- IO.forEachOutputFilename ([&](const StringRef &output) {
251- Outputs.push_back (OutputPair (file_types::lookupTypeForExtension (
252- llvm::sys::path::extension (output)),
253- output.str ()));
254- });
239+ // Output for this Primary
240+ auto OutputFile = PrimaryInput.outputFilename ();
241+ Outputs.push_back (OutputPair (file_types::lookupTypeForExtension (
242+ llvm::sys::path::extension (OutputFile)),
243+ OutputFile));
255244
256245 // Supplementary outputs
257- IO.forEachPrimaryInput ([&](const InputFile &input) -> bool {
258- const auto &primarySpecificFiles = input.getPrimarySpecificPaths ();
259- const auto &supplementaryOutputPaths =
260- primarySpecificFiles.SupplementaryOutputs ;
261- supplementaryOutputPaths.forEachSetOutput ([&](const std::string &output) {
262- Outputs.push_back (OutputPair (file_types::lookupTypeForExtension (
263- llvm::sys::path::extension (output)),
264- output));
265- });
266- return false ;
246+ const auto &primarySpecificFiles = PrimaryInput.getPrimarySpecificPaths ();
247+ const auto &supplementaryOutputPaths =
248+ primarySpecificFiles.SupplementaryOutputs ;
249+ supplementaryOutputPaths.forEachSetOutput ([&](const std::string &output) {
250+ Outputs.push_back (OutputPair (file_types::lookupTypeForExtension (
251+ llvm::sys::path::extension (output)),
252+ output));
267253 });
268254 }
269255
@@ -290,22 +276,6 @@ class TaskBasedMessage : public CommandBasedMessage {
290276 }
291277};
292278
293- class FinishedInvocationBasedMessage : public InvocationBasedMessage {
294- int64_t Pid;
295-
296- public:
297- FinishedInvocationBasedMessage (StringRef Kind,
298- const CompilerInvocation &Invocation,
299- int64_t Pid,
300- StringRef Output,
301- int ExitStatus)
302- : InvocationBasedMessage(Kind, Invocation), Pid(Pid) {}
303- void provideMapping (swift::json::Output &out) override {
304- InvocationBasedMessage::provideMapping (out);
305- out.mapRequired (" pid" , Pid);
306- }
307- };
308-
309279class BeganCommandMessage : public DetailedCommandBasedMessage {
310280 int64_t Pid;
311281 TaskProcessInformation ProcInfo;
@@ -329,10 +299,11 @@ class BeganInvocationMessage : public DetailedInvocationBasedMessage {
329299
330300public:
331301 BeganInvocationMessage (const CompilerInvocation &Invocation,
302+ const InputFile &PrimaryInput,
332303 ArrayRef<const char *> Args, int64_t Pid,
333304 TaskProcessInformation ProcInfo)
334- : DetailedInvocationBasedMessage(" began" , Invocation, Args), Pid(Pid ),
335- ProcInfo (ProcInfo) {}
305+ : DetailedInvocationBasedMessage(" began" , Invocation, PrimaryInput, Args ),
306+ Pid (Pid), ProcInfo(ProcInfo) {}
336307
337308 void provideMapping (swift::json::Output &out) override {
338309 DetailedInvocationBasedMessage::provideMapping (out);
@@ -341,6 +312,27 @@ class BeganInvocationMessage : public DetailedInvocationBasedMessage {
341312 }
342313};
343314
315+ class FinishedInvocationMessage : public InvocationBasedMessage {
316+ int64_t Pid;
317+ int ExitStatus;
318+ std::string Output;
319+ TaskProcessInformation ProcInfo;
320+
321+ public:
322+ FinishedInvocationMessage (const CompilerInvocation &Invocation, int64_t Pid,
323+ StringRef Output, int ExitStatus,
324+ TaskProcessInformation ProcInfo)
325+ : InvocationBasedMessage(" finished" , Invocation), Pid(Pid),
326+ ExitStatus (ExitStatus), Output(Output), ProcInfo(ProcInfo) {}
327+ void provideMapping (swift::json::Output &out) override {
328+ InvocationBasedMessage::provideMapping (out);
329+ out.mapOptional (" output" , Output, std::string ());
330+ out.mapRequired (" process" , ProcInfo);
331+ out.mapRequired (" pid" , Pid);
332+ out.mapRequired (" exit-status" , ExitStatus);
333+ }
334+ };
335+
344336class TaskOutputMessage : public TaskBasedMessage {
345337 std::string Output;
346338 TaskProcessInformation ProcInfo;
@@ -362,7 +354,7 @@ class FinishedCommandMessage : public TaskOutputMessage {
362354
363355public:
364356 FinishedCommandMessage (const driver::Job &Cmd, int64_t Pid, StringRef Output,
365- TaskProcessInformation ProcInfo, int ExitStatus)
357+ TaskProcessInformation ProcInfo, int ExitStatus)
366358 : TaskOutputMessage(" finished" , Cmd, Pid, Output, ProcInfo),
367359 ExitStatus (ExitStatus) {}
368360
@@ -418,27 +410,58 @@ static void emitMessage(raw_ostream &os, Message &msg) {
418410 os << JSONString << ' \n ' ;
419411}
420412
421- void parseable_output::emitBeganMessage (
422- raw_ostream &os, const driver::Job &Cmd, int64_t Pid,
423- TaskProcessInformation ProcInfo) {
413+ void parseable_output::emitBeganMessage (raw_ostream &os, const driver::Job &Cmd,
414+ int64_t Pid,
415+ TaskProcessInformation ProcInfo) {
424416 BeganCommandMessage msg (Cmd, Pid, ProcInfo);
425417 emitMessage (os, msg);
426418}
427419
428- void parseable_output::emitBeganMessage (
429- raw_ostream &os, const CompilerInvocation &Invocation,
430- ArrayRef<const char *> Args, int64_t Pid, TaskProcessInformation ProcInfo) {
431- BeganInvocationMessage msg (Invocation, Args, Pid, ProcInfo);
432- emitMessage (os, msg);
420+ void parseable_output::emitBeganMessage (raw_ostream &os,
421+ const CompilerInvocation &Invocation,
422+ ArrayRef<const char *> Args,
423+ int64_t Pid,
424+ TaskProcessInformation ProcInfo) {
425+ const auto &IO = Invocation.getFrontendOptions ().InputsAndOutputs ;
426+ IO.forEachPrimaryInput ([&](const InputFile &Input) -> bool {
427+ BeganInvocationMessage msg (Invocation, Input, Args, Pid, ProcInfo);
428+ emitMessage (os, msg);
429+ return false ;
430+ });
433431}
434432
435- void parseable_output::emitFinishedMessage (
436- raw_ostream &os, const driver::Job &Cmd, int64_t Pid, int ExitStatus,
437- StringRef Output, TaskProcessInformation ProcInfo) {
433+ void parseable_output::emitFinishedMessage (raw_ostream &os,
434+ const driver::Job &Cmd, int64_t Pid,
435+ int ExitStatus, StringRef Output,
436+ TaskProcessInformation ProcInfo) {
438437 FinishedCommandMessage msg (Cmd, Pid, Output, ProcInfo, ExitStatus);
439438 emitMessage (os, msg);
440439}
441440
441+ void parseable_output::emitFinishedMessage (
442+ raw_ostream &os, const CompilerInvocation &Invocation, int64_t Pid,
443+ int ExitStatus,
444+ const llvm::StringMap<std::vector<std::string>> &FileSpecificDiagnostics,
445+ TaskProcessInformation ProcInfo) {
446+ const auto &IO = Invocation.getFrontendOptions ().InputsAndOutputs ;
447+ IO.forEachPrimaryInput ([&](const InputFile &Input) -> bool {
448+ assert (FileSpecificDiagnostics.count (Input.getFileName ()) != 0 &&
449+ " Expected diagnostic collection for input." );
450+
451+ // Join all diagnostics produced for this file into a single output.
452+ auto PrimaryDiags = FileSpecificDiagnostics.lookup (Input.getFileName ());
453+ const char * const Delim = " \n " ;
454+ std::ostringstream JoinedDiags;
455+ std::copy (PrimaryDiags.begin (), PrimaryDiags.end (),
456+ std::ostream_iterator<std::string>(JoinedDiags, Delim));
457+ FinishedInvocationMessage msg (Invocation, Pid,
458+ JoinedDiags.str (),
459+ ExitStatus, ProcInfo);
460+ emitMessage (os, msg);
461+ return false ;
462+ });
463+ }
464+
442465void parseable_output::emitSignalledMessage (
443466 raw_ostream &os, const driver::Job &Cmd, int64_t Pid, StringRef ErrorMsg,
444467 StringRef Output, Optional<int > Signal, TaskProcessInformation ProcInfo) {
@@ -447,7 +470,7 @@ void parseable_output::emitSignalledMessage(
447470}
448471
449472void parseable_output::emitSkippedMessage (raw_ostream &os,
450- const driver::Job &Cmd) {
473+ const driver::Job &Cmd) {
451474 SkippedMessage msg (Cmd);
452475 emitMessage (os, msg);
453476}
0 commit comments