Compilation.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. //===--- Compilation.cpp - Compilation Task Implementation ----------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "clang/Driver/Compilation.h"
  10. #include "clang/Driver/Action.h"
  11. #include "clang/Driver/Driver.h"
  12. #include "clang/Driver/DriverDiagnostic.h"
  13. #include "clang/Driver/Options.h"
  14. #include "clang/Driver/ToolChain.h"
  15. #include "llvm/ADT/STLExtras.h"
  16. #include "llvm/Option/ArgList.h"
  17. #include "llvm/Support/FileSystem.h"
  18. #include "llvm/Support/raw_ostream.h"
  19. using namespace clang::driver;
  20. using namespace clang;
  21. using namespace llvm::opt;
  22. Compilation::Compilation(const Driver &D, const ToolChain &_DefaultToolChain,
  23. InputArgList *_Args, DerivedArgList *_TranslatedArgs,
  24. bool ContainsError)
  25. : TheDriver(D), DefaultToolChain(_DefaultToolChain), ActiveOffloadMask(0u),
  26. Args(_Args), TranslatedArgs(_TranslatedArgs), Redirects(nullptr),
  27. ForDiagnostics(false), ContainsError(ContainsError) {
  28. // The offloading host toolchain is the default tool chain.
  29. OrderedOffloadingToolchains.insert(
  30. std::make_pair(Action::OFK_Host, &DefaultToolChain));
  31. }
  32. Compilation::~Compilation() {
  33. delete TranslatedArgs;
  34. delete Args;
  35. // Free any derived arg lists.
  36. for (auto Arg : TCArgs)
  37. if (Arg.second != TranslatedArgs)
  38. delete Arg.second;
  39. // Free redirections of stdout/stderr.
  40. if (Redirects) {
  41. delete Redirects[0];
  42. delete Redirects[1];
  43. delete Redirects[2];
  44. delete [] Redirects;
  45. }
  46. }
  47. const DerivedArgList &
  48. Compilation::getArgsForToolChain(const ToolChain *TC, StringRef BoundArch,
  49. Action::OffloadKind DeviceOffloadKind) {
  50. if (!TC)
  51. TC = &DefaultToolChain;
  52. DerivedArgList *&Entry = TCArgs[{TC, BoundArch, DeviceOffloadKind}];
  53. if (!Entry) {
  54. Entry = TC->TranslateArgs(*TranslatedArgs, BoundArch, DeviceOffloadKind);
  55. if (!Entry)
  56. Entry = TranslatedArgs;
  57. }
  58. return *Entry;
  59. }
  60. bool Compilation::CleanupFile(const char *File, bool IssueErrors) const {
  61. // FIXME: Why are we trying to remove files that we have not created? For
  62. // example we should only try to remove a temporary assembly file if
  63. // "clang -cc1" succeed in writing it. Was this a workaround for when
  64. // clang was writing directly to a .s file and sometimes leaving it behind
  65. // during a failure?
  66. // FIXME: If this is necessary, we can still try to split
  67. // llvm::sys::fs::remove into a removeFile and a removeDir and avoid the
  68. // duplicated stat from is_regular_file.
  69. // Don't try to remove files which we don't have write access to (but may be
  70. // able to remove), or non-regular files. Underlying tools may have
  71. // intentionally not overwritten them.
  72. if (!llvm::sys::fs::can_write(File) || !llvm::sys::fs::is_regular_file(File))
  73. return true;
  74. if (std::error_code EC = llvm::sys::fs::remove(File)) {
  75. // Failure is only failure if the file exists and is "regular". We checked
  76. // for it being regular before, and llvm::sys::fs::remove ignores ENOENT,
  77. // so we don't need to check again.
  78. if (IssueErrors)
  79. getDriver().Diag(clang::diag::err_drv_unable_to_remove_file)
  80. << EC.message();
  81. return false;
  82. }
  83. return true;
  84. }
  85. bool Compilation::CleanupFileList(const ArgStringList &Files,
  86. bool IssueErrors) const {
  87. bool Success = true;
  88. for (ArgStringList::const_iterator
  89. it = Files.begin(), ie = Files.end(); it != ie; ++it)
  90. Success &= CleanupFile(*it, IssueErrors);
  91. return Success;
  92. }
  93. bool Compilation::CleanupFileMap(const ArgStringMap &Files,
  94. const JobAction *JA,
  95. bool IssueErrors) const {
  96. bool Success = true;
  97. for (ArgStringMap::const_iterator
  98. it = Files.begin(), ie = Files.end(); it != ie; ++it) {
  99. // If specified, only delete the files associated with the JobAction.
  100. // Otherwise, delete all files in the map.
  101. if (JA && it->first != JA)
  102. continue;
  103. Success &= CleanupFile(it->second, IssueErrors);
  104. }
  105. return Success;
  106. }
  107. int Compilation::ExecuteCommand(const Command &C,
  108. const Command *&FailingCommand) const {
  109. if ((getDriver().CCPrintOptions ||
  110. getArgs().hasArg(options::OPT_v)) && !getDriver().CCGenDiagnostics) {
  111. raw_ostream *OS = &llvm::errs();
  112. // Follow gcc implementation of CC_PRINT_OPTIONS; we could also cache the
  113. // output stream.
  114. if (getDriver().CCPrintOptions && getDriver().CCPrintOptionsFilename) {
  115. std::error_code EC;
  116. OS = new llvm::raw_fd_ostream(getDriver().CCPrintOptionsFilename, EC,
  117. llvm::sys::fs::F_Append |
  118. llvm::sys::fs::F_Text);
  119. if (EC) {
  120. getDriver().Diag(clang::diag::err_drv_cc_print_options_failure)
  121. << EC.message();
  122. FailingCommand = &C;
  123. delete OS;
  124. return 1;
  125. }
  126. }
  127. if (getDriver().CCPrintOptions)
  128. *OS << "[Logging clang options]";
  129. C.Print(*OS, "\n", /*Quote=*/getDriver().CCPrintOptions);
  130. if (OS != &llvm::errs())
  131. delete OS;
  132. }
  133. std::string Error;
  134. bool ExecutionFailed;
  135. int Res = C.Execute(Redirects, &Error, &ExecutionFailed);
  136. if (!Error.empty()) {
  137. assert(Res && "Error string set with 0 result code!");
  138. getDriver().Diag(clang::diag::err_drv_command_failure) << Error;
  139. }
  140. if (Res)
  141. FailingCommand = &C;
  142. return ExecutionFailed ? 1 : Res;
  143. }
  144. void Compilation::ExecuteJobs(
  145. const JobList &Jobs,
  146. SmallVectorImpl<std::pair<int, const Command *>> &FailingCommands) const {
  147. for (const auto &Job : Jobs) {
  148. const Command *FailingCommand = nullptr;
  149. if (int Res = ExecuteCommand(Job, FailingCommand)) {
  150. FailingCommands.push_back(std::make_pair(Res, FailingCommand));
  151. // Bail as soon as one command fails, so we don't output duplicate error
  152. // messages if we die on e.g. the same file.
  153. return;
  154. }
  155. }
  156. }
  157. void Compilation::initCompilationForDiagnostics() {
  158. ForDiagnostics = true;
  159. // Free actions and jobs.
  160. Actions.clear();
  161. AllActions.clear();
  162. Jobs.clear();
  163. // Clear temporary/results file lists.
  164. TempFiles.clear();
  165. ResultFiles.clear();
  166. FailureResultFiles.clear();
  167. // Remove any user specified output. Claim any unclaimed arguments, so as
  168. // to avoid emitting warnings about unused args.
  169. OptSpecifier OutputOpts[] = { options::OPT_o, options::OPT_MD,
  170. options::OPT_MMD };
  171. for (unsigned i = 0, e = llvm::array_lengthof(OutputOpts); i != e; ++i) {
  172. if (TranslatedArgs->hasArg(OutputOpts[i]))
  173. TranslatedArgs->eraseArg(OutputOpts[i]);
  174. }
  175. TranslatedArgs->ClaimAllArgs();
  176. // Redirect stdout/stderr to /dev/null.
  177. Redirects = new const StringRef*[3]();
  178. Redirects[0] = nullptr;
  179. Redirects[1] = new StringRef();
  180. Redirects[2] = new StringRef();
  181. }
  182. StringRef Compilation::getSysRoot() const {
  183. return getDriver().SysRoot;
  184. }
  185. void Compilation::Redirect(const StringRef** Redirects) {
  186. this->Redirects = Redirects;
  187. }