Home | History | Annotate | Line # | Download | only in driver
driver.cpp revision 1.1
      1  1.1  joerg //===-- driver.cpp - Clang GCC-Compatible Driver --------------------------===//
      2  1.1  joerg //
      3  1.1  joerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4  1.1  joerg // See https://llvm.org/LICENSE.txt for license information.
      5  1.1  joerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6  1.1  joerg //
      7  1.1  joerg //===----------------------------------------------------------------------===//
      8  1.1  joerg //
      9  1.1  joerg // This is the entry point to the clang driver; it is a thin wrapper
     10  1.1  joerg // for functionality in the Driver clang library.
     11  1.1  joerg //
     12  1.1  joerg //===----------------------------------------------------------------------===//
     13  1.1  joerg 
     14  1.1  joerg #include "clang/Driver/Driver.h"
     15  1.1  joerg #include "clang/Basic/DiagnosticOptions.h"
     16  1.1  joerg #include "clang/Basic/Stack.h"
     17  1.1  joerg #include "clang/Driver/Compilation.h"
     18  1.1  joerg #include "clang/Driver/DriverDiagnostic.h"
     19  1.1  joerg #include "clang/Driver/Options.h"
     20  1.1  joerg #include "clang/Driver/ToolChain.h"
     21  1.1  joerg #include "clang/Frontend/ChainedDiagnosticConsumer.h"
     22  1.1  joerg #include "clang/Frontend/CompilerInvocation.h"
     23  1.1  joerg #include "clang/Frontend/SerializedDiagnosticPrinter.h"
     24  1.1  joerg #include "clang/Frontend/TextDiagnosticPrinter.h"
     25  1.1  joerg #include "clang/Frontend/Utils.h"
     26  1.1  joerg #include "llvm/ADT/ArrayRef.h"
     27  1.1  joerg #include "llvm/ADT/SmallString.h"
     28  1.1  joerg #include "llvm/ADT/SmallVector.h"
     29  1.1  joerg #include "llvm/Option/ArgList.h"
     30  1.1  joerg #include "llvm/Option/OptTable.h"
     31  1.1  joerg #include "llvm/Option/Option.h"
     32  1.1  joerg #include "llvm/Support/CommandLine.h"
     33  1.1  joerg #include "llvm/Support/ErrorHandling.h"
     34  1.1  joerg #include "llvm/Support/FileSystem.h"
     35  1.1  joerg #include "llvm/Support/Host.h"
     36  1.1  joerg #include "llvm/Support/InitLLVM.h"
     37  1.1  joerg #include "llvm/Support/Path.h"
     38  1.1  joerg #include "llvm/Support/Process.h"
     39  1.1  joerg #include "llvm/Support/Program.h"
     40  1.1  joerg #include "llvm/Support/Regex.h"
     41  1.1  joerg #include "llvm/Support/Signals.h"
     42  1.1  joerg #include "llvm/Support/StringSaver.h"
     43  1.1  joerg #include "llvm/Support/TargetSelect.h"
     44  1.1  joerg #include "llvm/Support/Timer.h"
     45  1.1  joerg #include "llvm/Support/raw_ostream.h"
     46  1.1  joerg #include <memory>
     47  1.1  joerg #include <set>
     48  1.1  joerg #include <system_error>
     49  1.1  joerg using namespace clang;
     50  1.1  joerg using namespace clang::driver;
     51  1.1  joerg using namespace llvm::opt;
     52  1.1  joerg 
     53  1.1  joerg std::string GetExecutablePath(const char *Argv0, bool CanonicalPrefixes) {
     54  1.1  joerg   if (!CanonicalPrefixes) {
     55  1.1  joerg     SmallString<128> ExecutablePath(Argv0);
     56  1.1  joerg     // Do a PATH lookup if Argv0 isn't a valid path.
     57  1.1  joerg     if (!llvm::sys::fs::exists(ExecutablePath))
     58  1.1  joerg       if (llvm::ErrorOr<std::string> P =
     59  1.1  joerg               llvm::sys::findProgramByName(ExecutablePath))
     60  1.1  joerg         ExecutablePath = *P;
     61  1.1  joerg     return ExecutablePath.str();
     62  1.1  joerg   }
     63  1.1  joerg 
     64  1.1  joerg   // This just needs to be some symbol in the binary; C++ doesn't
     65  1.1  joerg   // allow taking the address of ::main however.
     66  1.1  joerg   void *P = (void*) (intptr_t) GetExecutablePath;
     67  1.1  joerg   return llvm::sys::fs::getMainExecutable(Argv0, P);
     68  1.1  joerg }
     69  1.1  joerg 
     70  1.1  joerg static const char *GetStableCStr(std::set<std::string> &SavedStrings,
     71  1.1  joerg                                  StringRef S) {
     72  1.1  joerg   return SavedStrings.insert(S).first->c_str();
     73  1.1  joerg }
     74  1.1  joerg 
     75  1.1  joerg /// ApplyQAOverride - Apply a list of edits to the input argument lists.
     76  1.1  joerg ///
     77  1.1  joerg /// The input string is a space separate list of edits to perform,
     78  1.1  joerg /// they are applied in order to the input argument lists. Edits
     79  1.1  joerg /// should be one of the following forms:
     80  1.1  joerg ///
     81  1.1  joerg ///  '#': Silence information about the changes to the command line arguments.
     82  1.1  joerg ///
     83  1.1  joerg ///  '^': Add FOO as a new argument at the beginning of the command line.
     84  1.1  joerg ///
     85  1.1  joerg ///  '+': Add FOO as a new argument at the end of the command line.
     86  1.1  joerg ///
     87  1.1  joerg ///  's/XXX/YYY/': Substitute the regular expression XXX with YYY in the command
     88  1.1  joerg ///  line.
     89  1.1  joerg ///
     90  1.1  joerg ///  'xOPTION': Removes all instances of the literal argument OPTION.
     91  1.1  joerg ///
     92  1.1  joerg ///  'XOPTION': Removes all instances of the literal argument OPTION,
     93  1.1  joerg ///  and the following argument.
     94  1.1  joerg ///
     95  1.1  joerg ///  'Ox': Removes all flags matching 'O' or 'O[sz0-9]' and adds 'Ox'
     96  1.1  joerg ///  at the end of the command line.
     97  1.1  joerg ///
     98  1.1  joerg /// \param OS - The stream to write edit information to.
     99  1.1  joerg /// \param Args - The vector of command line arguments.
    100  1.1  joerg /// \param Edit - The override command to perform.
    101  1.1  joerg /// \param SavedStrings - Set to use for storing string representations.
    102  1.1  joerg static void ApplyOneQAOverride(raw_ostream &OS,
    103  1.1  joerg                                SmallVectorImpl<const char*> &Args,
    104  1.1  joerg                                StringRef Edit,
    105  1.1  joerg                                std::set<std::string> &SavedStrings) {
    106  1.1  joerg   // This does not need to be efficient.
    107  1.1  joerg 
    108  1.1  joerg   if (Edit[0] == '^') {
    109  1.1  joerg     const char *Str =
    110  1.1  joerg       GetStableCStr(SavedStrings, Edit.substr(1));
    111  1.1  joerg     OS << "### Adding argument " << Str << " at beginning\n";
    112  1.1  joerg     Args.insert(Args.begin() + 1, Str);
    113  1.1  joerg   } else if (Edit[0] == '+') {
    114  1.1  joerg     const char *Str =
    115  1.1  joerg       GetStableCStr(SavedStrings, Edit.substr(1));
    116  1.1  joerg     OS << "### Adding argument " << Str << " at end\n";
    117  1.1  joerg     Args.push_back(Str);
    118  1.1  joerg   } else if (Edit[0] == 's' && Edit[1] == '/' && Edit.endswith("/") &&
    119  1.1  joerg              Edit.slice(2, Edit.size()-1).find('/') != StringRef::npos) {
    120  1.1  joerg     StringRef MatchPattern = Edit.substr(2).split('/').first;
    121  1.1  joerg     StringRef ReplPattern = Edit.substr(2).split('/').second;
    122  1.1  joerg     ReplPattern = ReplPattern.slice(0, ReplPattern.size()-1);
    123  1.1  joerg 
    124  1.1  joerg     for (unsigned i = 1, e = Args.size(); i != e; ++i) {
    125  1.1  joerg       // Ignore end-of-line response file markers
    126  1.1  joerg       if (Args[i] == nullptr)
    127  1.1  joerg         continue;
    128  1.1  joerg       std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
    129  1.1  joerg 
    130  1.1  joerg       if (Repl != Args[i]) {
    131  1.1  joerg         OS << "### Replacing '" << Args[i] << "' with '" << Repl << "'\n";
    132  1.1  joerg         Args[i] = GetStableCStr(SavedStrings, Repl);
    133  1.1  joerg       }
    134  1.1  joerg     }
    135  1.1  joerg   } else if (Edit[0] == 'x' || Edit[0] == 'X') {
    136  1.1  joerg     auto Option = Edit.substr(1);
    137  1.1  joerg     for (unsigned i = 1; i < Args.size();) {
    138  1.1  joerg       if (Option == Args[i]) {
    139  1.1  joerg         OS << "### Deleting argument " << Args[i] << '\n';
    140  1.1  joerg         Args.erase(Args.begin() + i);
    141  1.1  joerg         if (Edit[0] == 'X') {
    142  1.1  joerg           if (i < Args.size()) {
    143  1.1  joerg             OS << "### Deleting argument " << Args[i] << '\n';
    144  1.1  joerg             Args.erase(Args.begin() + i);
    145  1.1  joerg           } else
    146  1.1  joerg             OS << "### Invalid X edit, end of command line!\n";
    147  1.1  joerg         }
    148  1.1  joerg       } else
    149  1.1  joerg         ++i;
    150  1.1  joerg     }
    151  1.1  joerg   } else if (Edit[0] == 'O') {
    152  1.1  joerg     for (unsigned i = 1; i < Args.size();) {
    153  1.1  joerg       const char *A = Args[i];
    154  1.1  joerg       // Ignore end-of-line response file markers
    155  1.1  joerg       if (A == nullptr)
    156  1.1  joerg         continue;
    157  1.1  joerg       if (A[0] == '-' && A[1] == 'O' &&
    158  1.1  joerg           (A[2] == '\0' ||
    159  1.1  joerg            (A[3] == '\0' && (A[2] == 's' || A[2] == 'z' ||
    160  1.1  joerg                              ('0' <= A[2] && A[2] <= '9'))))) {
    161  1.1  joerg         OS << "### Deleting argument " << Args[i] << '\n';
    162  1.1  joerg         Args.erase(Args.begin() + i);
    163  1.1  joerg       } else
    164  1.1  joerg         ++i;
    165  1.1  joerg     }
    166  1.1  joerg     OS << "### Adding argument " << Edit << " at end\n";
    167  1.1  joerg     Args.push_back(GetStableCStr(SavedStrings, '-' + Edit.str()));
    168  1.1  joerg   } else {
    169  1.1  joerg     OS << "### Unrecognized edit: " << Edit << "\n";
    170  1.1  joerg   }
    171  1.1  joerg }
    172  1.1  joerg 
    173  1.1  joerg /// ApplyQAOverride - Apply a comma separate list of edits to the
    174  1.1  joerg /// input argument lists. See ApplyOneQAOverride.
    175  1.1  joerg static void ApplyQAOverride(SmallVectorImpl<const char*> &Args,
    176  1.1  joerg                             const char *OverrideStr,
    177  1.1  joerg                             std::set<std::string> &SavedStrings) {
    178  1.1  joerg   raw_ostream *OS = &llvm::errs();
    179  1.1  joerg 
    180  1.1  joerg   if (OverrideStr[0] == '#') {
    181  1.1  joerg     ++OverrideStr;
    182  1.1  joerg     OS = &llvm::nulls();
    183  1.1  joerg   }
    184  1.1  joerg 
    185  1.1  joerg   *OS << "### CCC_OVERRIDE_OPTIONS: " << OverrideStr << "\n";
    186  1.1  joerg 
    187  1.1  joerg   // This does not need to be efficient.
    188  1.1  joerg 
    189  1.1  joerg   const char *S = OverrideStr;
    190  1.1  joerg   while (*S) {
    191  1.1  joerg     const char *End = ::strchr(S, ' ');
    192  1.1  joerg     if (!End)
    193  1.1  joerg       End = S + strlen(S);
    194  1.1  joerg     if (End != S)
    195  1.1  joerg       ApplyOneQAOverride(*OS, Args, std::string(S, End), SavedStrings);
    196  1.1  joerg     S = End;
    197  1.1  joerg     if (*S != '\0')
    198  1.1  joerg       ++S;
    199  1.1  joerg   }
    200  1.1  joerg }
    201  1.1  joerg 
    202  1.1  joerg extern int cc1_main(ArrayRef<const char *> Argv, const char *Argv0,
    203  1.1  joerg                     void *MainAddr);
    204  1.1  joerg extern int cc1as_main(ArrayRef<const char *> Argv, const char *Argv0,
    205  1.1  joerg                       void *MainAddr);
    206  1.1  joerg extern int cc1gen_reproducer_main(ArrayRef<const char *> Argv,
    207  1.1  joerg                                   const char *Argv0, void *MainAddr);
    208  1.1  joerg 
    209  1.1  joerg static void insertTargetAndModeArgs(const ParsedClangName &NameParts,
    210  1.1  joerg                                     SmallVectorImpl<const char *> &ArgVector,
    211  1.1  joerg                                     std::set<std::string> &SavedStrings) {
    212  1.1  joerg   // Put target and mode arguments at the start of argument list so that
    213  1.1  joerg   // arguments specified in command line could override them. Avoid putting
    214  1.1  joerg   // them at index 0, as an option like '-cc1' must remain the first.
    215  1.1  joerg   int InsertionPoint = 0;
    216  1.1  joerg   if (ArgVector.size() > 0)
    217  1.1  joerg     ++InsertionPoint;
    218  1.1  joerg 
    219  1.1  joerg   if (NameParts.DriverMode) {
    220  1.1  joerg     // Add the mode flag to the arguments.
    221  1.1  joerg     ArgVector.insert(ArgVector.begin() + InsertionPoint,
    222  1.1  joerg                      GetStableCStr(SavedStrings, NameParts.DriverMode));
    223  1.1  joerg   }
    224  1.1  joerg 
    225  1.1  joerg   if (NameParts.TargetIsValid) {
    226  1.1  joerg     const char *arr[] = {"-target", GetStableCStr(SavedStrings,
    227  1.1  joerg                                                   NameParts.TargetPrefix)};
    228  1.1  joerg     ArgVector.insert(ArgVector.begin() + InsertionPoint,
    229  1.1  joerg                      std::begin(arr), std::end(arr));
    230  1.1  joerg   }
    231  1.1  joerg }
    232  1.1  joerg 
    233  1.1  joerg static void getCLEnvVarOptions(std::string &EnvValue, llvm::StringSaver &Saver,
    234  1.1  joerg                                SmallVectorImpl<const char *> &Opts) {
    235  1.1  joerg   llvm::cl::TokenizeWindowsCommandLine(EnvValue, Saver, Opts);
    236  1.1  joerg   // The first instance of '#' should be replaced with '=' in each option.
    237  1.1  joerg   for (const char *Opt : Opts)
    238  1.1  joerg     if (char *NumberSignPtr = const_cast<char *>(::strchr(Opt, '#')))
    239  1.1  joerg       *NumberSignPtr = '=';
    240  1.1  joerg }
    241  1.1  joerg 
    242  1.1  joerg static void SetBackdoorDriverOutputsFromEnvVars(Driver &TheDriver) {
    243  1.1  joerg   // Handle CC_PRINT_OPTIONS and CC_PRINT_OPTIONS_FILE.
    244  1.1  joerg   TheDriver.CCPrintOptions = !!::getenv("CC_PRINT_OPTIONS");
    245  1.1  joerg   if (TheDriver.CCPrintOptions)
    246  1.1  joerg     TheDriver.CCPrintOptionsFilename = ::getenv("CC_PRINT_OPTIONS_FILE");
    247  1.1  joerg 
    248  1.1  joerg   // Handle CC_PRINT_HEADERS and CC_PRINT_HEADERS_FILE.
    249  1.1  joerg   TheDriver.CCPrintHeaders = !!::getenv("CC_PRINT_HEADERS");
    250  1.1  joerg   if (TheDriver.CCPrintHeaders)
    251  1.1  joerg     TheDriver.CCPrintHeadersFilename = ::getenv("CC_PRINT_HEADERS_FILE");
    252  1.1  joerg 
    253  1.1  joerg   // Handle CC_LOG_DIAGNOSTICS and CC_LOG_DIAGNOSTICS_FILE.
    254  1.1  joerg   TheDriver.CCLogDiagnostics = !!::getenv("CC_LOG_DIAGNOSTICS");
    255  1.1  joerg   if (TheDriver.CCLogDiagnostics)
    256  1.1  joerg     TheDriver.CCLogDiagnosticsFilename = ::getenv("CC_LOG_DIAGNOSTICS_FILE");
    257  1.1  joerg }
    258  1.1  joerg 
    259  1.1  joerg static void FixupDiagPrefixExeName(TextDiagnosticPrinter *DiagClient,
    260  1.1  joerg                                    const std::string &Path) {
    261  1.1  joerg   // If the clang binary happens to be named cl.exe for compatibility reasons,
    262  1.1  joerg   // use clang-cl.exe as the prefix to avoid confusion between clang and MSVC.
    263  1.1  joerg   StringRef ExeBasename(llvm::sys::path::stem(Path));
    264  1.1  joerg   if (ExeBasename.equals_lower("cl"))
    265  1.1  joerg     ExeBasename = "clang-cl";
    266  1.1  joerg   DiagClient->setPrefix(ExeBasename);
    267  1.1  joerg }
    268  1.1  joerg 
    269  1.1  joerg // This lets us create the DiagnosticsEngine with a properly-filled-out
    270  1.1  joerg // DiagnosticOptions instance.
    271  1.1  joerg static DiagnosticOptions *
    272  1.1  joerg CreateAndPopulateDiagOpts(ArrayRef<const char *> argv) {
    273  1.1  joerg   auto *DiagOpts = new DiagnosticOptions;
    274  1.1  joerg   unsigned MissingArgIndex, MissingArgCount;
    275  1.1  joerg   InputArgList Args = getDriverOptTable().ParseArgs(
    276  1.1  joerg       argv.slice(1), MissingArgIndex, MissingArgCount);
    277  1.1  joerg   // We ignore MissingArgCount and the return value of ParseDiagnosticArgs.
    278  1.1  joerg   // Any errors that would be diagnosed here will also be diagnosed later,
    279  1.1  joerg   // when the DiagnosticsEngine actually exists.
    280  1.1  joerg   (void)ParseDiagnosticArgs(*DiagOpts, Args);
    281  1.1  joerg   return DiagOpts;
    282  1.1  joerg }
    283  1.1  joerg 
    284  1.1  joerg static void SetInstallDir(SmallVectorImpl<const char *> &argv,
    285  1.1  joerg                           Driver &TheDriver, bool CanonicalPrefixes) {
    286  1.1  joerg   // Attempt to find the original path used to invoke the driver, to determine
    287  1.1  joerg   // the installed path. We do this manually, because we want to support that
    288  1.1  joerg   // path being a symlink.
    289  1.1  joerg   SmallString<128> InstalledPath(argv[0]);
    290  1.1  joerg 
    291  1.1  joerg   // Do a PATH lookup, if there are no directory components.
    292  1.1  joerg   if (llvm::sys::path::filename(InstalledPath) == InstalledPath)
    293  1.1  joerg     if (llvm::ErrorOr<std::string> Tmp = llvm::sys::findProgramByName(
    294  1.1  joerg             llvm::sys::path::filename(InstalledPath.str())))
    295  1.1  joerg       InstalledPath = *Tmp;
    296  1.1  joerg 
    297  1.1  joerg   // FIXME: We don't actually canonicalize this, we just make it absolute.
    298  1.1  joerg   if (CanonicalPrefixes)
    299  1.1  joerg     llvm::sys::fs::make_absolute(InstalledPath);
    300  1.1  joerg 
    301  1.1  joerg   StringRef InstalledPathParent(llvm::sys::path::parent_path(InstalledPath));
    302  1.1  joerg   if (llvm::sys::fs::exists(InstalledPathParent))
    303  1.1  joerg     TheDriver.setInstalledDir(InstalledPathParent);
    304  1.1  joerg }
    305  1.1  joerg 
    306  1.1  joerg static int ExecuteCC1Tool(ArrayRef<const char *> argv, StringRef Tool) {
    307  1.1  joerg   void *GetExecutablePathVP = (void *)(intptr_t) GetExecutablePath;
    308  1.1  joerg   if (Tool == "")
    309  1.1  joerg     return cc1_main(argv.slice(2), argv[0], GetExecutablePathVP);
    310  1.1  joerg   if (Tool == "as")
    311  1.1  joerg     return cc1as_main(argv.slice(2), argv[0], GetExecutablePathVP);
    312  1.1  joerg   if (Tool == "gen-reproducer")
    313  1.1  joerg     return cc1gen_reproducer_main(argv.slice(2), argv[0], GetExecutablePathVP);
    314  1.1  joerg 
    315  1.1  joerg   // Reject unknown tools.
    316  1.1  joerg   llvm::errs() << "error: unknown integrated tool '" << Tool << "'. "
    317  1.1  joerg                << "Valid tools include '-cc1' and '-cc1as'.\n";
    318  1.1  joerg   return 1;
    319  1.1  joerg }
    320  1.1  joerg 
    321  1.1  joerg int main(int argc_, const char **argv_) {
    322  1.1  joerg   noteBottomOfStack();
    323  1.1  joerg   llvm::InitLLVM X(argc_, argv_);
    324  1.1  joerg   SmallVector<const char *, 256> argv(argv_, argv_ + argc_);
    325  1.1  joerg 
    326  1.1  joerg   if (llvm::sys::Process::FixupStandardFileDescriptors())
    327  1.1  joerg     return 1;
    328  1.1  joerg 
    329  1.1  joerg   llvm::InitializeAllTargets();
    330  1.1  joerg   auto TargetAndMode = ToolChain::getTargetAndModeFromProgramName(argv[0]);
    331  1.1  joerg 
    332  1.1  joerg   llvm::BumpPtrAllocator A;
    333  1.1  joerg   llvm::StringSaver Saver(A);
    334  1.1  joerg 
    335  1.1  joerg   // Parse response files using the GNU syntax, unless we're in CL mode. There
    336  1.1  joerg   // are two ways to put clang in CL compatibility mode: argv[0] is either
    337  1.1  joerg   // clang-cl or cl, or --driver-mode=cl is on the command line. The normal
    338  1.1  joerg   // command line parsing can't happen until after response file parsing, so we
    339  1.1  joerg   // have to manually search for a --driver-mode=cl argument the hard way.
    340  1.1  joerg   // Finally, our -cc1 tools don't care which tokenization mode we use because
    341  1.1  joerg   // response files written by clang will tokenize the same way in either mode.
    342  1.1  joerg   bool ClangCLMode = false;
    343  1.1  joerg   if (StringRef(TargetAndMode.DriverMode).equals("--driver-mode=cl") ||
    344  1.1  joerg       llvm::find_if(argv, [](const char *F) {
    345  1.1  joerg         return F && strcmp(F, "--driver-mode=cl") == 0;
    346  1.1  joerg       }) != argv.end()) {
    347  1.1  joerg     ClangCLMode = true;
    348  1.1  joerg   }
    349  1.1  joerg   enum { Default, POSIX, Windows } RSPQuoting = Default;
    350  1.1  joerg   for (const char *F : argv) {
    351  1.1  joerg     if (strcmp(F, "--rsp-quoting=posix") == 0)
    352  1.1  joerg       RSPQuoting = POSIX;
    353  1.1  joerg     else if (strcmp(F, "--rsp-quoting=windows") == 0)
    354  1.1  joerg       RSPQuoting = Windows;
    355  1.1  joerg   }
    356  1.1  joerg 
    357  1.1  joerg   // Determines whether we want nullptr markers in argv to indicate response
    358  1.1  joerg   // files end-of-lines. We only use this for the /LINK driver argument with
    359  1.1  joerg   // clang-cl.exe on Windows.
    360  1.1  joerg   bool MarkEOLs = ClangCLMode;
    361  1.1  joerg 
    362  1.1  joerg   llvm::cl::TokenizerCallback Tokenizer;
    363  1.1  joerg   if (RSPQuoting == Windows || (RSPQuoting == Default && ClangCLMode))
    364  1.1  joerg     Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
    365  1.1  joerg   else
    366  1.1  joerg     Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
    367  1.1  joerg 
    368  1.1  joerg   if (MarkEOLs && argv.size() > 1 && StringRef(argv[1]).startswith("-cc1"))
    369  1.1  joerg     MarkEOLs = false;
    370  1.1  joerg   llvm::cl::ExpandResponseFiles(Saver, Tokenizer, argv, MarkEOLs);
    371  1.1  joerg 
    372  1.1  joerg   // Handle -cc1 integrated tools, even if -cc1 was expanded from a response
    373  1.1  joerg   // file.
    374  1.1  joerg   auto FirstArg = std::find_if(argv.begin() + 1, argv.end(),
    375  1.1  joerg                                [](const char *A) { return A != nullptr; });
    376  1.1  joerg   if (FirstArg != argv.end() && StringRef(*FirstArg).startswith("-cc1")) {
    377  1.1  joerg     // If -cc1 came from a response file, remove the EOL sentinels.
    378  1.1  joerg     if (MarkEOLs) {
    379  1.1  joerg       auto newEnd = std::remove(argv.begin(), argv.end(), nullptr);
    380  1.1  joerg       argv.resize(newEnd - argv.begin());
    381  1.1  joerg     }
    382  1.1  joerg     return ExecuteCC1Tool(argv, argv[1] + 4);
    383  1.1  joerg   }
    384  1.1  joerg 
    385  1.1  joerg   bool CanonicalPrefixes = true;
    386  1.1  joerg   for (int i = 1, size = argv.size(); i < size; ++i) {
    387  1.1  joerg     // Skip end-of-line response file markers
    388  1.1  joerg     if (argv[i] == nullptr)
    389  1.1  joerg       continue;
    390  1.1  joerg     if (StringRef(argv[i]) == "-no-canonical-prefixes") {
    391  1.1  joerg       CanonicalPrefixes = false;
    392  1.1  joerg       break;
    393  1.1  joerg     }
    394  1.1  joerg   }
    395  1.1  joerg 
    396  1.1  joerg   // Handle CL and _CL_ which permits additional command line options to be
    397  1.1  joerg   // prepended or appended.
    398  1.1  joerg   if (ClangCLMode) {
    399  1.1  joerg     // Arguments in "CL" are prepended.
    400  1.1  joerg     llvm::Optional<std::string> OptCL = llvm::sys::Process::GetEnv("CL");
    401  1.1  joerg     if (OptCL.hasValue()) {
    402  1.1  joerg       SmallVector<const char *, 8> PrependedOpts;
    403  1.1  joerg       getCLEnvVarOptions(OptCL.getValue(), Saver, PrependedOpts);
    404  1.1  joerg 
    405  1.1  joerg       // Insert right after the program name to prepend to the argument list.
    406  1.1  joerg       argv.insert(argv.begin() + 1, PrependedOpts.begin(), PrependedOpts.end());
    407  1.1  joerg     }
    408  1.1  joerg     // Arguments in "_CL_" are appended.
    409  1.1  joerg     llvm::Optional<std::string> Opt_CL_ = llvm::sys::Process::GetEnv("_CL_");
    410  1.1  joerg     if (Opt_CL_.hasValue()) {
    411  1.1  joerg       SmallVector<const char *, 8> AppendedOpts;
    412  1.1  joerg       getCLEnvVarOptions(Opt_CL_.getValue(), Saver, AppendedOpts);
    413  1.1  joerg 
    414  1.1  joerg       // Insert at the end of the argument list to append.
    415  1.1  joerg       argv.append(AppendedOpts.begin(), AppendedOpts.end());
    416  1.1  joerg     }
    417  1.1  joerg   }
    418  1.1  joerg 
    419  1.1  joerg   std::set<std::string> SavedStrings;
    420  1.1  joerg   // Handle CCC_OVERRIDE_OPTIONS, used for editing a command line behind the
    421  1.1  joerg   // scenes.
    422  1.1  joerg   if (const char *OverrideStr = ::getenv("CCC_OVERRIDE_OPTIONS")) {
    423  1.1  joerg     // FIXME: Driver shouldn't take extra initial argument.
    424  1.1  joerg     ApplyQAOverride(argv, OverrideStr, SavedStrings);
    425  1.1  joerg   }
    426  1.1  joerg 
    427  1.1  joerg   std::string Path = GetExecutablePath(argv[0], CanonicalPrefixes);
    428  1.1  joerg 
    429  1.1  joerg   IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts =
    430  1.1  joerg       CreateAndPopulateDiagOpts(argv);
    431  1.1  joerg 
    432  1.1  joerg   TextDiagnosticPrinter *DiagClient
    433  1.1  joerg     = new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts);
    434  1.1  joerg   FixupDiagPrefixExeName(DiagClient, Path);
    435  1.1  joerg 
    436  1.1  joerg   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
    437  1.1  joerg 
    438  1.1  joerg   DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient);
    439  1.1  joerg 
    440  1.1  joerg   if (!DiagOpts->DiagnosticSerializationFile.empty()) {
    441  1.1  joerg     auto SerializedConsumer =
    442  1.1  joerg         clang::serialized_diags::create(DiagOpts->DiagnosticSerializationFile,
    443  1.1  joerg                                         &*DiagOpts, /*MergeChildRecords=*/true);
    444  1.1  joerg     Diags.setClient(new ChainedDiagnosticConsumer(
    445  1.1  joerg         Diags.takeClient(), std::move(SerializedConsumer)));
    446  1.1  joerg   }
    447  1.1  joerg 
    448  1.1  joerg   ProcessWarningOptions(Diags, *DiagOpts, /*ReportDiags=*/false);
    449  1.1  joerg 
    450  1.1  joerg   Driver TheDriver(Path, llvm::sys::getDefaultTargetTriple(), Diags);
    451  1.1  joerg   SetInstallDir(argv, TheDriver, CanonicalPrefixes);
    452  1.1  joerg   TheDriver.setTargetAndMode(TargetAndMode);
    453  1.1  joerg 
    454  1.1  joerg   insertTargetAndModeArgs(TargetAndMode, argv, SavedStrings);
    455  1.1  joerg 
    456  1.1  joerg   SetBackdoorDriverOutputsFromEnvVars(TheDriver);
    457  1.1  joerg 
    458  1.1  joerg   std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(argv));
    459  1.1  joerg   int Res = 1;
    460  1.1  joerg   if (C && !C->containsError()) {
    461  1.1  joerg     SmallVector<std::pair<int, const Command *>, 4> FailingCommands;
    462  1.1  joerg     Res = TheDriver.ExecuteCompilation(*C, FailingCommands);
    463  1.1  joerg 
    464  1.1  joerg     // Force a crash to test the diagnostics.
    465  1.1  joerg     if (TheDriver.GenReproducer) {
    466  1.1  joerg       Diags.Report(diag::err_drv_force_crash)
    467  1.1  joerg         << !::getenv("FORCE_CLANG_DIAGNOSTICS_CRASH");
    468  1.1  joerg 
    469  1.1  joerg       // Pretend that every command failed.
    470  1.1  joerg       FailingCommands.clear();
    471  1.1  joerg       for (const auto &J : C->getJobs())
    472  1.1  joerg         if (const Command *C = dyn_cast<Command>(&J))
    473  1.1  joerg           FailingCommands.push_back(std::make_pair(-1, C));
    474  1.1  joerg     }
    475  1.1  joerg 
    476  1.1  joerg     for (const auto &P : FailingCommands) {
    477  1.1  joerg       int CommandRes = P.first;
    478  1.1  joerg       const Command *FailingCommand = P.second;
    479  1.1  joerg       if (!Res)
    480  1.1  joerg         Res = CommandRes;
    481  1.1  joerg 
    482  1.1  joerg       // If result status is < 0, then the driver command signalled an error.
    483  1.1  joerg       // If result status is 70, then the driver command reported a fatal error.
    484  1.1  joerg       // On Windows, abort will return an exit code of 3.  In these cases,
    485  1.1  joerg       // generate additional diagnostic information if possible.
    486  1.1  joerg       bool DiagnoseCrash = CommandRes < 0 || CommandRes == 70;
    487  1.1  joerg #ifdef _WIN32
    488  1.1  joerg       DiagnoseCrash |= CommandRes == 3;
    489  1.1  joerg #endif
    490  1.1  joerg       if (DiagnoseCrash) {
    491  1.1  joerg         TheDriver.generateCompilationDiagnostics(*C, *FailingCommand);
    492  1.1  joerg         break;
    493  1.1  joerg       }
    494  1.1  joerg     }
    495  1.1  joerg   }
    496  1.1  joerg 
    497  1.1  joerg   Diags.getClient()->finish();
    498  1.1  joerg 
    499  1.1  joerg   // If any timers were active but haven't been destroyed yet, print their
    500  1.1  joerg   // results now.  This happens in -disable-free mode.
    501  1.1  joerg   llvm::TimerGroup::printAll(llvm::errs());
    502  1.1  joerg   llvm::TimerGroup::clearAll();
    503  1.1  joerg 
    504  1.1  joerg #ifdef _WIN32
    505  1.1  joerg   // Exit status should not be negative on Win32, unless abnormal termination.
    506  1.1  joerg   // Once abnormal termiation was caught, negative status should not be
    507  1.1  joerg   // propagated.
    508  1.1  joerg   if (Res < 0)
    509  1.1  joerg     Res = 1;
    510  1.1  joerg #endif
    511  1.1  joerg 
    512  1.1  joerg   // If we have multiple failing commands, we return the result of the first
    513  1.1  joerg   // failing command.
    514  1.1  joerg   return Res;
    515  1.1  joerg }
    516