Clang Project

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