Optionally separate Tasks` stderr from stdout.

Fixes a serious problem where spurious output from xcrun breaks
swift's discovery of libarclite.

<rdar://problem/28573949>
This commit is contained in:
Sean Callanan
2017-01-11 11:11:23 -08:00
parent 240ab32961
commit 399709ccb8
7 changed files with 122 additions and 42 deletions

View File

@@ -72,12 +72,15 @@ public:
/// \param ReturnCode the return code of the task which finished execution.
/// \param Output the output from the task which finished execution,
/// if available. (This may not be available on all platforms.)
/// \param Errors the errors from the task which finished execution, if
/// available and SeparateErrors was true. (This may not be available on all
/// platforms.)
/// \param Context the context which was passed when the task was added
///
/// \returns true if further execution of tasks should stop,
/// false if execution should continue
typedef std::function<TaskFinishedResponse(ProcessId Pid, int ReturnCode,
StringRef Output, void *Context)>
StringRef Output, StringRef Errors, void *Context)>
TaskFinishedCallback;
/// \brief A callback which will be executed if a task exited abnormally due
@@ -88,12 +91,15 @@ public:
/// no reason could be deduced, this may be empty.
/// \param Output the output from the task which exited abnormally, if
/// available. (This may not be available on all platforms.)
/// \param Errors the errors from the task which exited abnormally, if
/// available and SeparateErrors was true. (This may not be available on all
/// platforms.)
/// \param Context the context which was passed when the task was added
///
/// \returns a TaskFinishedResponse indicating whether or not execution
/// should proceed
typedef std::function<TaskFinishedResponse(ProcessId Pid, StringRef ErrorMsg,
StringRef Output, void *Context)>
StringRef Output, StringRef Errors, void *Context)>
TaskSignalledCallback;
#pragma clang diagnostic pop
@@ -120,9 +126,10 @@ public:
/// \param Env the environment which should be used for the task;
/// must be null-terminated. If empty, inherits the parent's environment.
/// \param Context an optional context which will be associated with the task
/// \param SeparateErrors Controls whether error output is reported separately
virtual void addTask(const char *ExecPath, ArrayRef<const char *> Args,
ArrayRef<const char *> Env = llvm::None,
void *Context = nullptr);
void *Context = nullptr, bool SeparateErrors = false);
/// \brief Synchronously executes the tasks in the TaskQueue.
///
@@ -153,10 +160,13 @@ class DummyTaskQueue : public TaskQueue {
ArrayRef<const char *> Args;
ArrayRef<const char *> Env;
void *Context;
bool SeparateErrors;
DummyTask(const char *ExecPath, ArrayRef<const char *> Args,
ArrayRef<const char *> Env = llvm::None, void *Context = nullptr)
: ExecPath(ExecPath), Args(Args), Env(Env), Context(Context) {}
ArrayRef<const char *> Env = llvm::None, void *Context = nullptr,
bool SeparateErrors = false)
: ExecPath(ExecPath), Args(Args), Env(Env), Context(Context),
SeparateErrors(SeparateErrors) {}
};
std::queue<std::unique_ptr<DummyTask>> QueuedTasks;
@@ -168,7 +178,7 @@ public:
virtual void addTask(const char *ExecPath, ArrayRef<const char *> Args,
ArrayRef<const char *> Env = llvm::None,
void *Context = nullptr);
void *Context = nullptr, bool SeparateErrors = false);
virtual bool
execute(TaskBeganCallback Began = TaskBeganCallback(),