From 87cfa71071d73c702a833f19c9fe035f31c1275d Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 19 Sep 2013 20:32:16 +0000 Subject: clang-cl: implement /fallback mode When this flag is enabled, clang-cl falls back to cl.exe if it cannot compile the code itself for some reason. The idea is to use this to help build projects that almost compile with clang-cl, except for some files that can then be built with the fallback mechanism. Differential Revision: http://llvm-reviews.chandlerc.com/D1711 llvm-svn: 191034 --- clang/lib/Driver/Job.cpp | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'clang/lib/Driver/Job.cpp') diff --git a/clang/lib/Driver/Job.cpp b/clang/lib/Driver/Job.cpp index 7df46d348c1..ee68e6f14d5 100644 --- a/clang/lib/Driver/Job.cpp +++ b/clang/lib/Driver/Job.cpp @@ -126,6 +126,43 @@ int Command::Execute(const StringRef **Redirects, std::string *ErrMsg, /*memoryLimit*/ 0, ErrMsg, ExecutionFailed); } +FallbackCommand::FallbackCommand(const Action &Source_, const Tool &Creator_, + const char *Executable_, + const ArgStringList &Arguments_, + Command *Fallback_) + : Command(Source_, Creator_, Executable_, Arguments_), Fallback(Fallback_) { +} + +void FallbackCommand::Print(raw_ostream &OS, const char *Terminator, + bool Quote, bool CrashReport) const { + Command::Print(OS, "", Quote, CrashReport); + OS << " ||"; + Fallback->Print(OS, Terminator, Quote, CrashReport); +} + +static bool ShouldFallback(int ExitCode) { + // FIXME: We really just want to fall back for internal errors, such + // as when some symbol cannot be mangled, when we should be able to + // parse something but can't, etc. + return ExitCode != 0; +} + +int FallbackCommand::Execute(const StringRef **Redirects, std::string *ErrMsg, + bool *ExecutionFailed) const { + int PrimaryStatus = Command::Execute(Redirects, ErrMsg, ExecutionFailed); + if (!ShouldFallback(PrimaryStatus)) + return PrimaryStatus; + + // Clear ExecutionFailed and ErrMsg before falling back. + if (ErrMsg) + ErrMsg->clear(); + if (ExecutionFailed) + *ExecutionFailed = false; + + int SecondaryStatus = Fallback->Execute(Redirects, ErrMsg, ExecutionFailed); + return SecondaryStatus; +} + JobList::JobList() : Job(JobListClass) {} JobList::~JobList() { -- cgit v1.2.3