1193326Sed//===-- driver.cpp - Clang GCC-Compatible Driver --------------------------===//
2193326Sed//
3193326Sed//                     The LLVM Compiler Infrastructure
4193326Sed//
5193326Sed// This file is distributed under the University of Illinois Open Source
6193326Sed// License. See LICENSE.TXT for details.
7193326Sed//
8193326Sed//===----------------------------------------------------------------------===//
9193326Sed//
10193326Sed// This is the entry point to the clang driver; it is a thin wrapper
11193326Sed// for functionality in the Driver clang library.
12193326Sed//
13193326Sed//===----------------------------------------------------------------------===//
14193326Sed
15249423Sdim#include "clang/Basic/CharInfo.h"
16243830Sdim#include "clang/Basic/DiagnosticOptions.h"
17193326Sed#include "clang/Driver/Compilation.h"
18193326Sed#include "clang/Driver/Driver.h"
19249423Sdim#include "clang/Driver/DriverDiagnostic.h"
20249423Sdim#include "clang/Driver/Options.h"
21234353Sdim#include "clang/Frontend/CompilerInvocation.h"
22204643Srdivacky#include "clang/Frontend/TextDiagnosticPrinter.h"
23234353Sdim#include "clang/Frontend/Utils.h"
24221345Sdim#include "llvm/ADT/ArrayRef.h"
25249423Sdim#include "llvm/ADT/OwningPtr.h"
26193326Sed#include "llvm/ADT/SmallString.h"
27212904Sdim#include "llvm/ADT/SmallVector.h"
28263508Sdim#include "llvm/ADT/STLExtras.h"
29263508Sdim#include "llvm/Option/ArgList.h"
30263508Sdim#include "llvm/Option/OptTable.h"
31263508Sdim#include "llvm/Option/Option.h"
32263508Sdim#include "llvm/Support/CommandLine.h"
33212904Sdim#include "llvm/Support/ErrorHandling.h"
34218893Sdim#include "llvm/Support/FileSystem.h"
35249423Sdim#include "llvm/Support/Host.h"
36193326Sed#include "llvm/Support/ManagedStatic.h"
37212904Sdim#include "llvm/Support/MemoryBuffer.h"
38249423Sdim#include "llvm/Support/Path.h"
39193326Sed#include "llvm/Support/PrettyStackTrace.h"
40263508Sdim#include "llvm/Support/Process.h"
41249423Sdim#include "llvm/Support/Program.h"
42204643Srdivacky#include "llvm/Support/Regex.h"
43218893Sdim#include "llvm/Support/Signals.h"
44226633Sdim#include "llvm/Support/TargetRegistry.h"
45226633Sdim#include "llvm/Support/TargetSelect.h"
46249423Sdim#include "llvm/Support/Timer.h"
47249423Sdim#include "llvm/Support/raw_ostream.h"
48218893Sdim#include "llvm/Support/system_error.h"
49193326Sedusing namespace clang;
50193326Sedusing namespace clang::driver;
51263508Sdimusing namespace llvm::opt;
52193326Sed
53263508Sdimstd::string GetExecutablePath(const char *Argv0, bool CanonicalPrefixes) {
54200583Srdivacky  if (!CanonicalPrefixes)
55263508Sdim    return Argv0;
56200583Srdivacky
57193326Sed  // This just needs to be some symbol in the binary; C++ doesn't
58193326Sed  // allow taking the address of ::main however.
59193326Sed  void *P = (void*) (intptr_t) GetExecutablePath;
60263508Sdim  return llvm::sys::fs::getMainExecutable(Argv0, P);
61193326Sed}
62193326Sed
63198092Srdivackystatic const char *SaveStringInSet(std::set<std::string> &SavedStrings,
64226633Sdim                                   StringRef S) {
65193326Sed  return SavedStrings.insert(S).first->c_str();
66193326Sed}
67193326Sed
68193326Sed/// ApplyQAOverride - Apply a list of edits to the input argument lists.
69193326Sed///
70193326Sed/// The input string is a space separate list of edits to perform,
71193326Sed/// they are applied in order to the input argument lists. Edits
72193326Sed/// should be one of the following forms:
73193326Sed///
74198092Srdivacky///  '#': Silence information about the changes to the command line arguments.
75198092Srdivacky///
76193326Sed///  '^': Add FOO as a new argument at the beginning of the command line.
77193326Sed///
78193326Sed///  '+': Add FOO as a new argument at the end of the command line.
79193326Sed///
80204643Srdivacky///  's/XXX/YYY/': Substitute the regular expression XXX with YYY in the command
81204643Srdivacky///  line.
82193326Sed///
83193326Sed///  'xOPTION': Removes all instances of the literal argument OPTION.
84193326Sed///
85193326Sed///  'XOPTION': Removes all instances of the literal argument OPTION,
86193326Sed///  and the following argument.
87193326Sed///
88193326Sed///  'Ox': Removes all flags matching 'O' or 'O[sz0-9]' and adds 'Ox'
89193326Sed///  at the end of the command line.
90198092Srdivacky///
91198092Srdivacky/// \param OS - The stream to write edit information to.
92198092Srdivacky/// \param Args - The vector of command line arguments.
93198092Srdivacky/// \param Edit - The override command to perform.
94198092Srdivacky/// \param SavedStrings - Set to use for storing string representations.
95226633Sdimstatic void ApplyOneQAOverride(raw_ostream &OS,
96226633Sdim                               SmallVectorImpl<const char*> &Args,
97226633Sdim                               StringRef Edit,
98206084Srdivacky                               std::set<std::string> &SavedStrings) {
99193326Sed  // This does not need to be efficient.
100193326Sed
101198092Srdivacky  if (Edit[0] == '^') {
102198092Srdivacky    const char *Str =
103204643Srdivacky      SaveStringInSet(SavedStrings, Edit.substr(1));
104198092Srdivacky    OS << "### Adding argument " << Str << " at beginning\n";
105198092Srdivacky    Args.insert(Args.begin() + 1, Str);
106198092Srdivacky  } else if (Edit[0] == '+') {
107198092Srdivacky    const char *Str =
108204643Srdivacky      SaveStringInSet(SavedStrings, Edit.substr(1));
109198092Srdivacky    OS << "### Adding argument " << Str << " at end\n";
110198092Srdivacky    Args.push_back(Str);
111204643Srdivacky  } else if (Edit[0] == 's' && Edit[1] == '/' && Edit.endswith("/") &&
112226633Sdim             Edit.slice(2, Edit.size()-1).find('/') != StringRef::npos) {
113226633Sdim    StringRef MatchPattern = Edit.substr(2).split('/').first;
114226633Sdim    StringRef ReplPattern = Edit.substr(2).split('/').second;
115204643Srdivacky    ReplPattern = ReplPattern.slice(0, ReplPattern.size()-1);
116204643Srdivacky
117204643Srdivacky    for (unsigned i = 1, e = Args.size(); i != e; ++i) {
118204643Srdivacky      std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
119204643Srdivacky
120204643Srdivacky      if (Repl != Args[i]) {
121204643Srdivacky        OS << "### Replacing '" << Args[i] << "' with '" << Repl << "'\n";
122204643Srdivacky        Args[i] = SaveStringInSet(SavedStrings, Repl);
123204643Srdivacky      }
124204643Srdivacky    }
125198092Srdivacky  } else if (Edit[0] == 'x' || Edit[0] == 'X') {
126198092Srdivacky    std::string Option = Edit.substr(1, std::string::npos);
127198092Srdivacky    for (unsigned i = 1; i < Args.size();) {
128198092Srdivacky      if (Option == Args[i]) {
129198092Srdivacky        OS << "### Deleting argument " << Args[i] << '\n';
130198092Srdivacky        Args.erase(Args.begin() + i);
131198092Srdivacky        if (Edit[0] == 'X') {
132198092Srdivacky          if (i < Args.size()) {
133198092Srdivacky            OS << "### Deleting argument " << Args[i] << '\n';
134198092Srdivacky            Args.erase(Args.begin() + i);
135198092Srdivacky          } else
136198092Srdivacky            OS << "### Invalid X edit, end of command line!\n";
137198092Srdivacky        }
138198092Srdivacky      } else
139198092Srdivacky        ++i;
140198092Srdivacky    }
141198092Srdivacky  } else if (Edit[0] == 'O') {
142198092Srdivacky    for (unsigned i = 1; i < Args.size();) {
143198092Srdivacky      const char *A = Args[i];
144198092Srdivacky      if (A[0] == '-' && A[1] == 'O' &&
145198092Srdivacky          (A[2] == '\0' ||
146198092Srdivacky           (A[3] == '\0' && (A[2] == 's' || A[2] == 'z' ||
147198092Srdivacky                             ('0' <= A[2] && A[2] <= '9'))))) {
148198092Srdivacky        OS << "### Deleting argument " << Args[i] << '\n';
149198092Srdivacky        Args.erase(Args.begin() + i);
150198092Srdivacky      } else
151198092Srdivacky        ++i;
152198092Srdivacky    }
153198092Srdivacky    OS << "### Adding argument " << Edit << " at end\n";
154204643Srdivacky    Args.push_back(SaveStringInSet(SavedStrings, '-' + Edit.str()));
155198092Srdivacky  } else {
156198092Srdivacky    OS << "### Unrecognized edit: " << Edit << "\n";
157198092Srdivacky  }
158193326Sed}
159193326Sed
160193326Sed/// ApplyQAOverride - Apply a comma separate list of edits to the
161193326Sed/// input argument lists. See ApplyOneQAOverride.
162226633Sdimstatic void ApplyQAOverride(SmallVectorImpl<const char*> &Args,
163206084Srdivacky                            const char *OverrideStr,
164206084Srdivacky                            std::set<std::string> &SavedStrings) {
165226633Sdim  raw_ostream *OS = &llvm::errs();
166193326Sed
167198092Srdivacky  if (OverrideStr[0] == '#') {
168198092Srdivacky    ++OverrideStr;
169198092Srdivacky    OS = &llvm::nulls();
170198092Srdivacky  }
171198092Srdivacky
172198092Srdivacky  *OS << "### QA_OVERRIDE_GCC3_OPTIONS: " << OverrideStr << "\n";
173198092Srdivacky
174193326Sed  // This does not need to be efficient.
175193326Sed
176193326Sed  const char *S = OverrideStr;
177193326Sed  while (*S) {
178193326Sed    const char *End = ::strchr(S, ' ');
179193326Sed    if (!End)
180193326Sed      End = S + strlen(S);
181193326Sed    if (End != S)
182198092Srdivacky      ApplyOneQAOverride(*OS, Args, std::string(S, End), SavedStrings);
183193326Sed    S = End;
184193326Sed    if (*S != '\0')
185193326Sed      ++S;
186193326Sed  }
187193326Sed}
188193326Sed
189199990Srdivackyextern int cc1_main(const char **ArgBegin, const char **ArgEnd,
190199990Srdivacky                    const char *Argv0, void *MainAddr);
191208600Srdivackyextern int cc1as_main(const char **ArgBegin, const char **ArgEnd,
192208600Srdivacky                      const char *Argv0, void *MainAddr);
193199512Srdivacky
194226633Sdimstatic void ParseProgName(SmallVectorImpl<const char *> &ArgVector,
195221345Sdim                          std::set<std::string> &SavedStrings,
196221345Sdim                          Driver &TheDriver)
197221345Sdim{
198221345Sdim  // Try to infer frontend type and default target from the program name.
199221345Sdim
200221345Sdim  // suffixes[] contains the list of known driver suffixes.
201221345Sdim  // Suffixes are compared against the program name in order.
202221345Sdim  // If there is a match, the frontend type is updated as necessary (CPP/C++).
203221345Sdim  // If there is no match, a second round is done after stripping the last
204221345Sdim  // hyphen and everything following it. This allows using something like
205221345Sdim  // "clang++-2.9".
206221345Sdim
207221345Sdim  // If there is a match in either the first or second round,
208221345Sdim  // the function tries to identify a target as prefix. E.g.
209221345Sdim  // "x86_64-linux-clang" as interpreted as suffix "clang" with
210221345Sdim  // target prefix "x86_64-linux". If such a target prefix is found,
211234353Sdim  // is gets added via -target as implicit first argument.
212221345Sdim  static const struct {
213221345Sdim    const char *Suffix;
214263508Sdim    const char *ModeFlag;
215221345Sdim  } suffixes [] = {
216263508Sdim    { "clang",     0 },
217263508Sdim    { "clang++",   "--driver-mode=g++" },
218263508Sdim    { "clang-c++", "--driver-mode=g++" },
219263508Sdim    { "clang-cc",  0 },
220263508Sdim    { "clang-cpp", "--driver-mode=cpp" },
221263508Sdim    { "clang-g++", "--driver-mode=g++" },
222263508Sdim    { "clang-gcc", 0 },
223263508Sdim    { "clang-cl",  "--driver-mode=cl"  },
224263508Sdim    { "cc",        0 },
225263508Sdim    { "cpp",       "--driver-mode=cpp" },
226263508Sdim    { "cl" ,       "--driver-mode=cl"  },
227263508Sdim    { "++",        "--driver-mode=g++" },
228221345Sdim  };
229221345Sdim  std::string ProgName(llvm::sys::path::stem(ArgVector[0]));
230263508Sdim#ifdef _WIN32
231263508Sdim  std::transform(ProgName.begin(), ProgName.end(), ProgName.begin(),
232263508Sdim                 toLowercase);
233263508Sdim#endif
234226633Sdim  StringRef ProgNameRef(ProgName);
235226633Sdim  StringRef Prefix;
236221345Sdim
237221345Sdim  for (int Components = 2; Components; --Components) {
238221345Sdim    bool FoundMatch = false;
239221345Sdim    size_t i;
240221345Sdim
241221345Sdim    for (i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); ++i) {
242221345Sdim      if (ProgNameRef.endswith(suffixes[i].Suffix)) {
243221345Sdim        FoundMatch = true;
244263508Sdim        SmallVectorImpl<const char *>::iterator it = ArgVector.begin();
245263508Sdim        if (it != ArgVector.end())
246263508Sdim          ++it;
247263508Sdim        if (suffixes[i].ModeFlag)
248263508Sdim          ArgVector.insert(it, suffixes[i].ModeFlag);
249221345Sdim        break;
250221345Sdim      }
251221345Sdim    }
252221345Sdim
253221345Sdim    if (FoundMatch) {
254226633Sdim      StringRef::size_type LastComponent = ProgNameRef.rfind('-',
255221345Sdim        ProgNameRef.size() - strlen(suffixes[i].Suffix));
256226633Sdim      if (LastComponent != StringRef::npos)
257221345Sdim        Prefix = ProgNameRef.slice(0, LastComponent);
258221345Sdim      break;
259221345Sdim    }
260221345Sdim
261226633Sdim    StringRef::size_type LastComponent = ProgNameRef.rfind('-');
262226633Sdim    if (LastComponent == StringRef::npos)
263221345Sdim      break;
264221345Sdim    ProgNameRef = ProgNameRef.slice(0, LastComponent);
265221345Sdim  }
266221345Sdim
267221345Sdim  if (Prefix.empty())
268221345Sdim    return;
269221345Sdim
270221345Sdim  std::string IgnoredError;
271221345Sdim  if (llvm::TargetRegistry::lookupTarget(Prefix, IgnoredError)) {
272226633Sdim    SmallVectorImpl<const char *>::iterator it = ArgVector.begin();
273224145Sdim    if (it != ArgVector.end())
274224145Sdim      ++it;
275263508Sdim    const char* Strings[] =
276263508Sdim      { SaveStringInSet(SavedStrings, std::string("-target")),
277263508Sdim        SaveStringInSet(SavedStrings, Prefix) };
278263508Sdim    ArgVector.insert(it, Strings, Strings + llvm::array_lengthof(Strings));
279221345Sdim  }
280221345Sdim}
281221345Sdim
282263508Sdimnamespace {
283263508Sdim  class StringSetSaver : public llvm::cl::StringSaver {
284263508Sdim  public:
285263508Sdim    StringSetSaver(std::set<std::string> &Storage) : Storage(Storage) {}
286263508Sdim    const char *SaveString(const char *Str) LLVM_OVERRIDE {
287263508Sdim      return SaveStringInSet(Storage, Str);
288263508Sdim    }
289263508Sdim  private:
290263508Sdim    std::set<std::string> &Storage;
291263508Sdim  };
292263508Sdim}
293263508Sdim
294212904Sdimint main(int argc_, const char **argv_) {
295193326Sed  llvm::sys::PrintStackTraceOnErrorSignal();
296212904Sdim  llvm::PrettyStackTraceProgram X(argc_, argv_);
297193326Sed
298263508Sdim  SmallVector<const char *, 256> argv;
299263508Sdim  llvm::SpecificBumpPtrAllocator<char> ArgAllocator;
300263508Sdim  llvm::error_code EC = llvm::sys::Process::GetArgumentVector(
301263508Sdim      argv, llvm::ArrayRef<const char *>(argv_, argc_), ArgAllocator);
302263508Sdim  if (EC) {
303263508Sdim    llvm::errs() << "error: couldn't get arguments: " << EC.message() << '\n';
304263508Sdim    return 1;
305263508Sdim  }
306263508Sdim
307212904Sdim  std::set<std::string> SavedStrings;
308263508Sdim  StringSetSaver Saver(SavedStrings);
309263508Sdim  llvm::cl::ExpandResponseFiles(Saver, llvm::cl::TokenizeGNUCommandLine, argv);
310212904Sdim
311208600Srdivacky  // Handle -cc1 integrated tools.
312226633Sdim  if (argv.size() > 1 && StringRef(argv[1]).startswith("-cc1")) {
313226633Sdim    StringRef Tool = argv[1] + 4;
314199990Srdivacky
315208600Srdivacky    if (Tool == "")
316212904Sdim      return cc1_main(argv.data()+2, argv.data()+argv.size(), argv[0],
317208600Srdivacky                      (void*) (intptr_t) GetExecutablePath);
318208600Srdivacky    if (Tool == "as")
319212904Sdim      return cc1as_main(argv.data()+2, argv.data()+argv.size(), argv[0],
320208600Srdivacky                      (void*) (intptr_t) GetExecutablePath);
321208600Srdivacky
322208600Srdivacky    // Reject unknown tools.
323208600Srdivacky    llvm::errs() << "error: unknown integrated tool '" << Tool << "'\n";
324208600Srdivacky    return 1;
325208600Srdivacky  }
326208600Srdivacky
327200583Srdivacky  bool CanonicalPrefixes = true;
328212904Sdim  for (int i = 1, size = argv.size(); i < size; ++i) {
329226633Sdim    if (StringRef(argv[i]) == "-no-canonical-prefixes") {
330200583Srdivacky      CanonicalPrefixes = false;
331200583Srdivacky      break;
332200583Srdivacky    }
333200583Srdivacky  }
334200583Srdivacky
335249423Sdim  // Handle QA_OVERRIDE_GCC3_OPTIONS and CCC_ADD_ARGS, used for editing a
336249423Sdim  // command line behind the scenes.
337249423Sdim  if (const char *OverrideStr = ::getenv("QA_OVERRIDE_GCC3_OPTIONS")) {
338249423Sdim    // FIXME: Driver shouldn't take extra initial argument.
339249423Sdim    ApplyQAOverride(argv, OverrideStr, SavedStrings);
340249423Sdim  }
341249423Sdim
342263508Sdim  std::string Path = GetExecutablePath(argv[0], CanonicalPrefixes);
343200583Srdivacky
344243830Sdim  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions;
345234353Sdim  {
346263508Sdim    OwningPtr<OptTable> Opts(createDriverOptTable());
347234353Sdim    unsigned MissingArgIndex, MissingArgCount;
348263508Sdim    OwningPtr<InputArgList> Args(Opts->ParseArgs(argv.begin()+1, argv.end(),
349263508Sdim                                                 MissingArgIndex,
350263508Sdim                                                 MissingArgCount));
351234353Sdim    // We ignore MissingArgCount and the return value of ParseDiagnosticArgs.
352234353Sdim    // Any errors that would be diagnosed here will also be diagnosed later,
353234353Sdim    // when the DiagnosticsEngine actually exists.
354243830Sdim    (void) ParseDiagnosticArgs(*DiagOpts, *Args);
355234353Sdim  }
356234353Sdim  // Now we can create the DiagnosticsEngine with a properly-filled-out
357234353Sdim  // DiagnosticOptions instance.
358212904Sdim  TextDiagnosticPrinter *DiagClient
359243830Sdim    = new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts);
360263508Sdim
361263508Sdim  // If the clang binary happens to be named cl.exe for compatibility reasons,
362263508Sdim  // use clang-cl.exe as the prefix to avoid confusion between clang and MSVC.
363263508Sdim  StringRef ExeBasename(llvm::sys::path::filename(Path));
364263508Sdim  if (ExeBasename.equals_lower("cl.exe"))
365263508Sdim    ExeBasename = "clang-cl.exe";
366263508Sdim  DiagClient->setPrefix(ExeBasename);
367263508Sdim
368234353Sdim  IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
369234353Sdim
370243830Sdim  DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient);
371249423Sdim  ProcessWarningOptions(Diags, *DiagOpts, /*ReportDiags=*/false);
372193326Sed
373263508Sdim  Driver TheDriver(Path, llvm::sys::getDefaultTargetTriple(), "a.out", Diags);
374193326Sed
375212904Sdim  // Attempt to find the original path used to invoke the driver, to determine
376212904Sdim  // the installed path. We do this manually, because we want to support that
377212904Sdim  // path being a symlink.
378218893Sdim  {
379234353Sdim    SmallString<128> InstalledPath(argv[0]);
380212904Sdim
381218893Sdim    // Do a PATH lookup, if there are no directory components.
382218893Sdim    if (llvm::sys::path::filename(InstalledPath) == InstalledPath) {
383263508Sdim      std::string Tmp = llvm::sys::FindProgramByName(
384218893Sdim        llvm::sys::path::filename(InstalledPath.str()));
385218893Sdim      if (!Tmp.empty())
386263508Sdim        InstalledPath = Tmp;
387218893Sdim    }
388218893Sdim    llvm::sys::fs::make_absolute(InstalledPath);
389218893Sdim    InstalledPath = llvm::sys::path::parent_path(InstalledPath);
390218893Sdim    bool exists;
391218893Sdim    if (!llvm::sys::fs::exists(InstalledPath.str(), exists) && exists)
392218893Sdim      TheDriver.setInstalledDir(InstalledPath);
393212904Sdim  }
394212904Sdim
395221345Sdim  llvm::InitializeAllTargets();
396221345Sdim  ParseProgName(argv, SavedStrings, TheDriver);
397199482Srdivacky
398205408Srdivacky  // Handle CC_PRINT_OPTIONS and CC_PRINT_OPTIONS_FILE.
399205408Srdivacky  TheDriver.CCPrintOptions = !!::getenv("CC_PRINT_OPTIONS");
400205408Srdivacky  if (TheDriver.CCPrintOptions)
401205408Srdivacky    TheDriver.CCPrintOptionsFilename = ::getenv("CC_PRINT_OPTIONS_FILE");
402205408Srdivacky
403218893Sdim  // Handle CC_PRINT_HEADERS and CC_PRINT_HEADERS_FILE.
404218893Sdim  TheDriver.CCPrintHeaders = !!::getenv("CC_PRINT_HEADERS");
405218893Sdim  if (TheDriver.CCPrintHeaders)
406218893Sdim    TheDriver.CCPrintHeadersFilename = ::getenv("CC_PRINT_HEADERS_FILE");
407218893Sdim
408221345Sdim  // Handle CC_LOG_DIAGNOSTICS and CC_LOG_DIAGNOSTICS_FILE.
409221345Sdim  TheDriver.CCLogDiagnostics = !!::getenv("CC_LOG_DIAGNOSTICS");
410221345Sdim  if (TheDriver.CCLogDiagnostics)
411221345Sdim    TheDriver.CCLogDiagnosticsFilename = ::getenv("CC_LOG_DIAGNOSTICS_FILE");
412221345Sdim
413234353Sdim  OwningPtr<Compilation> C(TheDriver.BuildCompilation(argv));
414193326Sed  int Res = 0;
415249423Sdim  SmallVector<std::pair<int, const Command *>, 4> FailingCommands;
416193326Sed  if (C.get())
417249423Sdim    Res = TheDriver.ExecuteCompilation(*C, FailingCommands);
418226633Sdim
419239462Sdim  // Force a crash to test the diagnostics.
420249423Sdim  if (::getenv("FORCE_CLANG_DIAGNOSTICS_CRASH")) {
421249423Sdim    Diags.Report(diag::err_drv_force_crash) << "FORCE_CLANG_DIAGNOSTICS_CRASH";
422249423Sdim    const Command *FailingCommand = 0;
423249423Sdim    FailingCommands.push_back(std::make_pair(-1, FailingCommand));
424249423Sdim  }
425239462Sdim
426249423Sdim  for (SmallVectorImpl< std::pair<int, const Command *> >::iterator it =
427249423Sdim         FailingCommands.begin(), ie = FailingCommands.end(); it != ie; ++it) {
428249423Sdim    int CommandRes = it->first;
429249423Sdim    const Command *FailingCommand = it->second;
430249423Sdim    if (!Res)
431249423Sdim      Res = CommandRes;
432226633Sdim
433249423Sdim    // If result status is < 0, then the driver command signalled an error.
434249423Sdim    // If result status is 70, then the driver command reported a fatal error.
435249423Sdim    // In these cases, generate additional diagnostic information if possible.
436249423Sdim    if (CommandRes < 0 || CommandRes == 70) {
437249423Sdim      TheDriver.generateCompilationDiagnostics(*C, FailingCommand);
438249423Sdim      break;
439249423Sdim    }
440249423Sdim  }
441249423Sdim
442206084Srdivacky  // If any timers were active but haven't been destroyed yet, print their
443206084Srdivacky  // results now.  This happens in -disable-free mode.
444206084Srdivacky  llvm::TimerGroup::printAll(llvm::errs());
445206084Srdivacky
446193326Sed  llvm::llvm_shutdown();
447193326Sed
448239462Sdim#ifdef _WIN32
449239462Sdim  // Exit status should not be negative on Win32, unless abnormal termination.
450239462Sdim  // Once abnormal termiation was caught, negative status should not be
451239462Sdim  // propagated.
452239462Sdim  if (Res < 0)
453239462Sdim    Res = 1;
454239462Sdim#endif
455239462Sdim
456249423Sdim  // If we have multiple failing commands, we return the result of the first
457249423Sdim  // failing command.
458193326Sed  return Res;
459193326Sed}
460