Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- Compilation.h - Compilation Task Data Structure ----------*- C++ -*-===//
  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. #ifndef LLVM_CLANG_DRIVER_COMPILATION_H
  10. #define LLVM_CLANG_DRIVER_COMPILATION_H
  11.  
  12. #include "clang/Basic/LLVM.h"
  13. #include "clang/Driver/Action.h"
  14. #include "clang/Driver/Job.h"
  15. #include "clang/Driver/Util.h"
  16. #include "llvm/ADT/ArrayRef.h"
  17. #include "llvm/ADT/DenseMap.h"
  18. #include "llvm/ADT/StringRef.h"
  19. #include "llvm/Option/Option.h"
  20. #include <cassert>
  21. #include <iterator>
  22. #include <map>
  23. #include <memory>
  24. #include <optional>
  25. #include <utility>
  26. #include <vector>
  27.  
  28. namespace llvm {
  29. namespace opt {
  30.  
  31. class DerivedArgList;
  32. class InputArgList;
  33.  
  34. } // namespace opt
  35. } // namespace llvm
  36.  
  37. namespace clang {
  38. namespace driver {
  39.  
  40. class Driver;
  41. class ToolChain;
  42.  
  43. /// Compilation - A set of tasks to perform for a single driver
  44. /// invocation.
  45. class Compilation {
  46.   /// The driver we were created by.
  47.   const Driver &TheDriver;
  48.  
  49.   /// The default tool chain.
  50.   const ToolChain &DefaultToolChain;
  51.  
  52.   /// A mask of all the programming models the host has to support in the
  53.   /// current compilation.
  54.   unsigned ActiveOffloadMask = 0;
  55.  
  56.   /// Array with the toolchains of offloading host and devices in the order they
  57.   /// were requested by the user. We are preserving that order in case the code
  58.   /// generation needs to derive a programming-model-specific semantic out of
  59.   /// it.
  60.   std::multimap<Action::OffloadKind, const ToolChain *>
  61.       OrderedOffloadingToolchains;
  62.  
  63.   /// The original (untranslated) input argument list.
  64.   llvm::opt::InputArgList *Args;
  65.  
  66.   /// The driver translated arguments. Note that toolchains may perform their
  67.   /// own argument translation.
  68.   llvm::opt::DerivedArgList *TranslatedArgs;
  69.  
  70.   /// The list of actions we've created via MakeAction.  This is not accessible
  71.   /// to consumers; it's here just to manage ownership.
  72.   std::vector<std::unique_ptr<Action>> AllActions;
  73.  
  74.   /// The list of actions.  This is maintained and modified by consumers, via
  75.   /// getActions().
  76.   ActionList Actions;
  77.  
  78.   /// The root list of jobs.
  79.   JobList Jobs;
  80.  
  81.   /// Cache of translated arguments for a particular tool chain, bound
  82.   /// architecture, and device offload kind.
  83.   struct TCArgsKey final {
  84.     const ToolChain *TC = nullptr;
  85.     StringRef BoundArch;
  86.     Action::OffloadKind DeviceOffloadKind = Action::OFK_None;
  87.  
  88.     TCArgsKey(const ToolChain *TC, StringRef BoundArch,
  89.               Action::OffloadKind DeviceOffloadKind)
  90.         : TC(TC), BoundArch(BoundArch), DeviceOffloadKind(DeviceOffloadKind) {}
  91.  
  92.     bool operator<(const TCArgsKey &K) const {
  93.       if (TC < K.TC)
  94.         return true;
  95.       else if (TC == K.TC && BoundArch < K.BoundArch)
  96.         return true;
  97.       else if (TC == K.TC && BoundArch == K.BoundArch &&
  98.                DeviceOffloadKind < K.DeviceOffloadKind)
  99.         return true;
  100.       return false;
  101.     }
  102.   };
  103.   std::map<TCArgsKey, llvm::opt::DerivedArgList *> TCArgs;
  104.  
  105.   /// Temporary files which should be removed on exit.
  106.   llvm::opt::ArgStringList TempFiles;
  107.  
  108.   /// Result files which should be removed on failure.
  109.   ArgStringMap ResultFiles;
  110.  
  111.   /// Result files which are generated correctly on failure, and which should
  112.   /// only be removed if we crash.
  113.   ArgStringMap FailureResultFiles;
  114.  
  115.   /// Optional redirection for stdin, stdout, stderr.
  116.   std::vector<std::optional<StringRef>> Redirects;
  117.  
  118.   /// Callback called after compilation job has been finished.
  119.   /// Arguments of the callback are the compilation job as an instance of
  120.   /// class Command and the exit status of the corresponding child process.
  121.   std::function<void(const Command &, int)> PostCallback;
  122.  
  123.   /// Whether we're compiling for diagnostic purposes.
  124.   bool ForDiagnostics = false;
  125.  
  126.   /// Whether an error during the parsing of the input args.
  127.   bool ContainsError;
  128.  
  129.   /// Whether to keep temporary files regardless of -save-temps.
  130.   bool ForceKeepTempFiles = false;
  131.  
  132. public:
  133.   Compilation(const Driver &D, const ToolChain &DefaultToolChain,
  134.               llvm::opt::InputArgList *Args,
  135.               llvm::opt::DerivedArgList *TranslatedArgs, bool ContainsError);
  136.   ~Compilation();
  137.  
  138.   const Driver &getDriver() const { return TheDriver; }
  139.  
  140.   const ToolChain &getDefaultToolChain() const { return DefaultToolChain; }
  141.  
  142.   unsigned isOffloadingHostKind(Action::OffloadKind Kind) const {
  143.     return ActiveOffloadMask & Kind;
  144.   }
  145.  
  146.   unsigned getActiveOffloadKinds() const { return ActiveOffloadMask; }
  147.  
  148.   /// Iterator that visits device toolchains of a given kind.
  149.   using const_offload_toolchains_iterator =
  150.       const std::multimap<Action::OffloadKind,
  151.                           const ToolChain *>::const_iterator;
  152.   using const_offload_toolchains_range =
  153.       std::pair<const_offload_toolchains_iterator,
  154.                 const_offload_toolchains_iterator>;
  155.  
  156.   template <Action::OffloadKind Kind>
  157.   const_offload_toolchains_range getOffloadToolChains() const {
  158.     return OrderedOffloadingToolchains.equal_range(Kind);
  159.   }
  160.  
  161.   const_offload_toolchains_range
  162.   getOffloadToolChains(Action::OffloadKind Kind) const {
  163.     return OrderedOffloadingToolchains.equal_range(Kind);
  164.   }
  165.  
  166.   /// Return true if an offloading tool chain of a given kind exists.
  167.   template <Action::OffloadKind Kind> bool hasOffloadToolChain() const {
  168.     return OrderedOffloadingToolchains.find(Kind) !=
  169.            OrderedOffloadingToolchains.end();
  170.   }
  171.  
  172.   /// Return an offload toolchain of the provided kind. Only one is expected to
  173.   /// exist.
  174.   template <Action::OffloadKind Kind>
  175.   const ToolChain *getSingleOffloadToolChain() const {
  176.     auto TCs = getOffloadToolChains<Kind>();
  177.  
  178.     assert(TCs.first != TCs.second &&
  179.            "No tool chains of the selected kind exist!");
  180.     assert(std::next(TCs.first) == TCs.second &&
  181.            "More than one tool chain of the this kind exist.");
  182.     return TCs.first->second;
  183.   }
  184.  
  185.   void addOffloadDeviceToolChain(const ToolChain *DeviceToolChain,
  186.                                  Action::OffloadKind OffloadKind) {
  187.     assert(OffloadKind != Action::OFK_Host && OffloadKind != Action::OFK_None &&
  188.            "This is not a device tool chain!");
  189.  
  190.     // Update the host offload kind to also contain this kind.
  191.     ActiveOffloadMask |= OffloadKind;
  192.     OrderedOffloadingToolchains.insert(
  193.         std::make_pair(OffloadKind, DeviceToolChain));
  194.   }
  195.  
  196.   const llvm::opt::InputArgList &getInputArgs() const { return *Args; }
  197.  
  198.   const llvm::opt::DerivedArgList &getArgs() const { return *TranslatedArgs; }
  199.  
  200.   llvm::opt::DerivedArgList &getArgs() { return *TranslatedArgs; }
  201.  
  202.   ActionList &getActions() { return Actions; }
  203.   const ActionList &getActions() const { return Actions; }
  204.  
  205.   /// Creates a new Action owned by this Compilation.
  206.   ///
  207.   /// The new Action is *not* added to the list returned by getActions().
  208.   template <typename T, typename... Args> T *MakeAction(Args &&... Arg) {
  209.     T *RawPtr = new T(std::forward<Args>(Arg)...);
  210.     AllActions.push_back(std::unique_ptr<Action>(RawPtr));
  211.     return RawPtr;
  212.   }
  213.  
  214.   JobList &getJobs() { return Jobs; }
  215.   const JobList &getJobs() const { return Jobs; }
  216.  
  217.   void addCommand(std::unique_ptr<Command> C) { Jobs.addJob(std::move(C)); }
  218.  
  219.   llvm::opt::ArgStringList &getTempFiles() { return TempFiles; }
  220.   const llvm::opt::ArgStringList &getTempFiles() const { return TempFiles; }
  221.  
  222.   const ArgStringMap &getResultFiles() const { return ResultFiles; }
  223.  
  224.   const ArgStringMap &getFailureResultFiles() const {
  225.     return FailureResultFiles;
  226.   }
  227.  
  228.   /// Installs a handler that is executed when a compilation job is finished.
  229.   /// The arguments of the callback specify the compilation job as an instance
  230.   /// of class Command and the exit status of the child process executed that
  231.   /// job.
  232.   void setPostCallback(const std::function<void(const Command &, int)> &CB) {
  233.     PostCallback = CB;
  234.   }
  235.  
  236.   /// Returns the sysroot path.
  237.   StringRef getSysRoot() const;
  238.  
  239.   /// getArgsForToolChain - Return the derived argument list for the
  240.   /// tool chain \p TC (or the default tool chain, if TC is not specified).
  241.   /// If a device offloading kind is specified, a translation specific for that
  242.   /// kind is performed, if any.
  243.   ///
  244.   /// \param BoundArch - The bound architecture name, or 0.
  245.   /// \param DeviceOffloadKind - The offload device kind that should be used in
  246.   /// the translation, if any.
  247.   const llvm::opt::DerivedArgList &
  248.   getArgsForToolChain(const ToolChain *TC, StringRef BoundArch,
  249.                       Action::OffloadKind DeviceOffloadKind);
  250.  
  251.   /// addTempFile - Add a file to remove on exit, and returns its
  252.   /// argument.
  253.   const char *addTempFile(const char *Name) {
  254.     TempFiles.push_back(Name);
  255.     return Name;
  256.   }
  257.  
  258.   /// addResultFile - Add a file to remove on failure, and returns its
  259.   /// argument.
  260.   const char *addResultFile(const char *Name, const JobAction *JA) {
  261.     ResultFiles[JA] = Name;
  262.     return Name;
  263.   }
  264.  
  265.   /// addFailureResultFile - Add a file to remove if we crash, and returns its
  266.   /// argument.
  267.   const char *addFailureResultFile(const char *Name, const JobAction *JA) {
  268.     FailureResultFiles[JA] = Name;
  269.     return Name;
  270.   }
  271.  
  272.   /// CleanupFile - Delete a given file.
  273.   ///
  274.   /// \param IssueErrors - Report failures as errors.
  275.   /// \return Whether the file was removed successfully.
  276.   bool CleanupFile(const char *File, bool IssueErrors = false) const;
  277.  
  278.   /// CleanupFileList - Remove the files in the given list.
  279.   ///
  280.   /// \param IssueErrors - Report failures as errors.
  281.   /// \return Whether all files were removed successfully.
  282.   bool CleanupFileList(const llvm::opt::ArgStringList &Files,
  283.                        bool IssueErrors = false) const;
  284.  
  285.   /// CleanupFileMap - Remove the files in the given map.
  286.   ///
  287.   /// \param JA - If specified, only delete the files associated with this
  288.   /// JobAction.  Otherwise, delete all files in the map.
  289.   /// \param IssueErrors - Report failures as errors.
  290.   /// \return Whether all files were removed successfully.
  291.   bool CleanupFileMap(const ArgStringMap &Files,
  292.                       const JobAction *JA,
  293.                       bool IssueErrors = false) const;
  294.  
  295.   /// ExecuteCommand - Execute an actual command.
  296.   ///
  297.   /// \param FailingCommand - For non-zero results, this will be set to the
  298.   /// Command which failed, if any.
  299.   /// \param LogOnly - When true, only tries to log the command, not actually
  300.   /// execute it.
  301.   /// \return The result code of the subprocess.
  302.   int ExecuteCommand(const Command &C, const Command *&FailingCommand,
  303.                      bool LogOnly = false) const;
  304.  
  305.   /// ExecuteJob - Execute a single job.
  306.   ///
  307.   /// \param FailingCommands - For non-zero results, this will be a vector of
  308.   /// failing commands and their associated result code.
  309.   /// \param LogOnly - When true, only tries to log the command, not actually
  310.   /// execute it.
  311.   void
  312.   ExecuteJobs(const JobList &Jobs,
  313.               SmallVectorImpl<std::pair<int, const Command *>> &FailingCommands,
  314.               bool LogOnly = false) const;
  315.  
  316.   /// initCompilationForDiagnostics - Remove stale state and suppress output
  317.   /// so compilation can be reexecuted to generate additional diagnostic
  318.   /// information (e.g., preprocessed source(s)).
  319.   void initCompilationForDiagnostics();
  320.  
  321.   /// Return true if we're compiling for diagnostics.
  322.   bool isForDiagnostics() const { return ForDiagnostics; }
  323.  
  324.   /// Return whether an error during the parsing of the input args.
  325.   bool containsError() const { return ContainsError; }
  326.  
  327.   /// Force driver to fail before toolchain is created. This is necessary when
  328.   /// error happens in action builder.
  329.   void setContainsError() { ContainsError = true; }
  330.  
  331.   /// Redirect - Redirect output of this compilation. Can only be done once.
  332.   ///
  333.   /// \param Redirects - array of optional paths. The array should have a size
  334.   /// of three. The inferior process's stdin(0), stdout(1), and stderr(2) will
  335.   /// be redirected to the corresponding paths, if provided (not std::nullopt).
  336.   void Redirect(ArrayRef<std::optional<StringRef>> Redirects);
  337. };
  338.  
  339. } // namespace driver
  340. } // namespace clang
  341.  
  342. #endif // LLVM_CLANG_DRIVER_COMPILATION_H
  343.