///
/// \param FailingCommands - For non-zero results, this will be a vector of
/// failing commands and their associated result code.
- void ExecuteJob(const Job &J,
- SmallVectorImpl< std::pair<int, const Command *> > &FailingCommands) const;
+ void ExecuteJobs(
+ const JobList &Jobs,
+ SmallVectorImpl<std::pair<int, const Command *>> &FailingCommands) const;
/// initCompilationForDiagnostics - Remove stale state and suppress output
/// so compilation can be reexecuted to generate additional diagnostic
class Command;
class Compilation;
class InputInfo;
- class Job;
+ class JobList;
class JobAction;
class SanitizerArgs;
class ToolChain;
llvm::opt::Arg **FinalPhaseArg = nullptr) const;
// Before executing jobs, sets up response files for commands that need them.
- void setUpResponseFiles(Compilation &C, Job &J);
+ void setUpResponseFiles(Compilation &C, Command &Cmd);
void generatePrefixedToolNames(const char *Tool, const ToolChain &TC,
SmallVectorImpl<std::string> &Names) const;
: Filename(Filename), VFSPath(VFSPath) {}
};
-class Job {
-public:
- enum JobClass {
- CommandClass,
- FallbackCommandClass,
- JobListClass
- };
-
-private:
- JobClass Kind;
-
-protected:
- Job(JobClass Kind) : Kind(Kind) {}
-public:
- virtual ~Job();
-
- JobClass getKind() const { return Kind; }
-
- /// Print - Print this Job in -### format.
- ///
- /// \param OS - The stream to print on.
- /// \param Terminator - A string to print at the end of the line.
- /// \param Quote - Should separate arguments be quoted.
- /// \param CrashInfo - Details for inclusion in a crash report.
- virtual void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
- CrashReportInfo *CrashInfo = nullptr) const = 0;
-};
-
/// Command - An executable path/name and argument vector to
/// execute.
-class Command : public Job {
+class Command {
/// Source - The action which caused the creation of this job.
const Action &Source;
public:
Command(const Action &Source, const Tool &Creator, const char *Executable,
const llvm::opt::ArgStringList &Arguments);
+ virtual ~Command() {}
- void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
- CrashReportInfo *CrashInfo = nullptr) const override;
+ virtual void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
+ CrashReportInfo *CrashInfo = nullptr) const;
virtual int Execute(const StringRef **Redirects, std::string *ErrMsg,
bool *ExecutionFailed) const;
const char *getExecutable() const { return Executable; }
const llvm::opt::ArgStringList &getArguments() const { return Arguments; }
-
- static bool classof(const Job *J) {
- return J->getKind() == CommandClass ||
- J->getKind() == FallbackCommandClass;
- }
};
/// Like Command, but with a fallback which is executed in case
int Execute(const StringRef **Redirects, std::string *ErrMsg,
bool *ExecutionFailed) const override;
- static bool classof(const Job *J) {
- return J->getKind() == FallbackCommandClass;
- }
-
private:
std::unique_ptr<Command> Fallback;
};
/// JobList - A sequence of jobs to perform.
-class JobList : public Job {
+class JobList {
public:
- typedef SmallVector<std::unique_ptr<Job>, 4> list_type;
+ typedef SmallVector<std::unique_ptr<Command>, 4> list_type;
typedef list_type::size_type size_type;
typedef llvm::pointee_iterator<list_type::iterator> iterator;
typedef llvm::pointee_iterator<list_type::const_iterator> const_iterator;
list_type Jobs;
public:
- JobList();
- ~JobList() override {}
-
void Print(llvm::raw_ostream &OS, const char *Terminator,
- bool Quote, CrashReportInfo *CrashInfo = nullptr) const override;
+ bool Quote, CrashReportInfo *CrashInfo = nullptr) const;
/// Add a job to the list (taking ownership).
- void addJob(std::unique_ptr<Job> J) { Jobs.push_back(std::move(J)); }
+ void addJob(std::unique_ptr<Command> J) { Jobs.push_back(std::move(J)); }
/// Clear the job list.
void clear();
const_iterator begin() const { return Jobs.begin(); }
iterator end() { return Jobs.end(); }
const_iterator end() const { return Jobs.end(); }
-
- static bool classof(const Job *J) {
- return J->getKind() == JobListClass;
- }
};
} // end namespace driver
return !ActionFailed(&C.getSource(), FailingCommands);
}
-void Compilation::ExecuteJob(const Job &J,
- FailingCommandList &FailingCommands) const {
- if (const Command *C = dyn_cast<Command>(&J)) {
- if (!InputsOk(*C, FailingCommands))
- return;
+void Compilation::ExecuteJobs(const JobList &Jobs,
+ FailingCommandList &FailingCommands) const {
+ for (const auto &Job : Jobs) {
+ if (!InputsOk(Job, FailingCommands))
+ continue;
const Command *FailingCommand = nullptr;
- if (int Res = ExecuteCommand(*C, FailingCommand))
+ if (int Res = ExecuteCommand(Job, FailingCommand))
FailingCommands.push_back(std::make_pair(Res, FailingCommand));
- } else {
- const JobList *Jobs = cast<JobList>(&J);
- for (const auto &Job : *Jobs)
- ExecuteJob(Job, FailingCommands);
}
}
// Generate preprocessed output.
SmallVector<std::pair<int, const Command *>, 4> FailingCommands;
- C.ExecuteJob(C.getJobs(), FailingCommands);
+ C.ExecuteJobs(C.getJobs(), FailingCommands);
// If any of the preprocessing commands failed, clean up and exit.
if (!FailingCommands.empty()) {
<< "\n\n********************";
}
-void Driver::setUpResponseFiles(Compilation &C, Job &J) {
- if (JobList *Jobs = dyn_cast<JobList>(&J)) {
- for (auto &Job : *Jobs)
- setUpResponseFiles(C, Job);
- return;
- }
-
- Command *CurCommand = dyn_cast<Command>(&J);
- if (!CurCommand)
- return;
-
+void Driver::setUpResponseFiles(Compilation &C, Command &Cmd) {
// Since argumentsFitWithinSystemLimits() may underestimate system's capacity
// if the tool does not support response files, there is a chance/ that things
// will just work without a response file, so we silently just skip it.
- if (CurCommand->getCreator().getResponseFilesSupport() == Tool::RF_None ||
- llvm::sys::argumentsFitWithinSystemLimits(CurCommand->getArguments()))
+ if (Cmd.getCreator().getResponseFilesSupport() == Tool::RF_None ||
+ llvm::sys::argumentsFitWithinSystemLimits(Cmd.getArguments()))
return;
std::string TmpName = GetTemporaryPath("response", "txt");
- CurCommand->setResponseFile(
+ Cmd.setResponseFile(
C.addTempFile(C.getArgs().MakeArgString(TmpName.c_str())));
}
return 1;
// Set up response file names for each command, if necessary
- setUpResponseFiles(C, C.getJobs());
+ for (auto &Job : C.getJobs())
+ setUpResponseFiles(C, Job);
- C.ExecuteJob(C.getJobs(), FailingCommands);
+ C.ExecuteJobs(C.getJobs(), FailingCommands);
// Remove temp files.
C.CleanupFileList(C.getTempFiles());
using llvm::StringRef;
using llvm::ArrayRef;
-Job::~Job() {}
-
Command::Command(const Action &Source, const Tool &Creator,
const char *Executable, const ArgStringList &Arguments)
- : Job(CommandClass), Source(Source), Creator(Creator),
- Executable(Executable), Arguments(Arguments), ResponseFile(nullptr) {}
+ : Source(Source), Creator(Creator), Executable(Executable),
+ Arguments(Arguments), ResponseFile(nullptr) {}
static int skipArgs(const char *Flag, bool HaveCrashVFS) {
// These flags are all of the form -Flag <Arg> and are treated as two
return SecondaryStatus;
}
-JobList::JobList() : Job(JobListClass) {}
-
void JobList::Print(raw_ostream &OS, const char *Terminator, bool Quote,
CrashReportInfo *CrashInfo) const {
for (const auto &Job : *this)
CompileJobAnalyzer CompileAnalyzer;
- for (const auto &Job : Jobs) {
- if (Job.getKind() == driver::Job::CommandClass) {
- const driver::Command &Cmd = cast<driver::Command>(Job);
- // Collect only for Assemble jobs. If we do all jobs we get duplicates
- // since Link jobs point to Assemble jobs as inputs.
- if (Cmd.getSource().getKind() == driver::Action::AssembleJobClass)
- CompileAnalyzer.run(&Cmd.getSource());
- }
+ for (const auto &Cmd : Jobs) {
+ // Collect only for Assemble jobs. If we do all jobs we get duplicates
+ // since Link jobs point to Assemble jobs as inputs.
+ if (Cmd.getSource().getKind() == driver::Action::AssembleJobClass)
+ CompileAnalyzer.run(&Cmd.getSource());
}
if (CompileAnalyzer.Inputs.empty()) {