diff options
author | Hans Wennborg <hans@hanshq.net> | 2013-09-19 20:32:16 +0000 |
---|---|---|
committer | Hans Wennborg <hans@hanshq.net> | 2013-09-19 20:32:16 +0000 |
commit | 87cfa71071d73c702a833f19c9fe035f31c1275d (patch) | |
tree | 7fabf6b99d4f70c5a4a31185757e950e69546ff8 /clang/lib/Driver/Job.cpp | |
parent | 70fefd515a14393d99aa2dcbcb9c45c8e121bbdd (diff) | |
download | bcm5719-llvm-87cfa71071d73c702a833f19c9fe035f31c1275d.tar.gz bcm5719-llvm-87cfa71071d73c702a833f19c9fe035f31c1275d.zip |
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
Diffstat (limited to 'clang/lib/Driver/Job.cpp')
-rw-r--r-- | clang/lib/Driver/Job.cpp | 37 |
1 files changed, 37 insertions, 0 deletions
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() { |