Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:52

0001 //===- Job.h - Commands to Execute ------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_CLANG_DRIVER_JOB_H
0010 #define LLVM_CLANG_DRIVER_JOB_H
0011 
0012 #include "clang/Basic/LLVM.h"
0013 #include "clang/Driver/InputInfo.h"
0014 #include "llvm/ADT/ArrayRef.h"
0015 #include "llvm/ADT/SmallVector.h"
0016 #include "llvm/ADT/StringRef.h"
0017 #include "llvm/ADT/iterator.h"
0018 #include "llvm/Option/Option.h"
0019 #include "llvm/Support/Program.h"
0020 #include <memory>
0021 #include <optional>
0022 #include <string>
0023 #include <utility>
0024 #include <vector>
0025 
0026 namespace clang {
0027 namespace driver {
0028 
0029 class Action;
0030 class InputInfo;
0031 class Tool;
0032 
0033 struct CrashReportInfo {
0034   StringRef Filename;
0035   StringRef VFSPath;
0036 
0037   CrashReportInfo(StringRef Filename, StringRef VFSPath)
0038       : Filename(Filename), VFSPath(VFSPath) {}
0039 };
0040 
0041 // Encodes the kind of response file supported for a command invocation.
0042 // Response files are necessary if the command line gets too large, requiring
0043 // the arguments to be transferred to a file.
0044 struct ResponseFileSupport {
0045   enum ResponseFileKind {
0046     // Provides full support for response files, which means we can transfer
0047     // all tool input arguments to a file.
0048     RF_Full,
0049     // Input file names can live in a file, but flags can't. This is a special
0050     // case for old versions of Apple's ld64.
0051     RF_FileList,
0052     // Does not support response files: all arguments must be passed via
0053     // command line.
0054     RF_None
0055   };
0056   /// The level of support for response files.
0057   ResponseFileKind ResponseKind;
0058 
0059   /// The encoding to use when writing response files on Windows. Ignored on
0060   /// other host OSes.
0061   ///
0062   /// Windows use cases: - GCC and Binutils on mingw only accept ANSI response
0063   /// files encoded with the system current code page.
0064   /// - MSVC's CL.exe and LINK.exe accept UTF16 on Windows.
0065   /// - Clang accepts both UTF8 and UTF16.
0066   ///
0067   /// FIXME: When GNU tools learn how to parse UTF16 on Windows, we should
0068   /// always use UTF16 for Windows, which is the Windows official encoding for
0069   /// international characters.
0070   llvm::sys::WindowsEncodingMethod ResponseEncoding;
0071 
0072   /// What prefix to use for the command-line argument when passing a response
0073   /// file.
0074   const char *ResponseFlag;
0075 
0076   /// Returns a ResponseFileSupport indicating that response files are not
0077   /// supported.
0078   static constexpr ResponseFileSupport None() {
0079     return {RF_None, llvm::sys::WEM_UTF8, nullptr};
0080   }
0081 
0082   /// Returns a ResponseFileSupport indicating that response files are
0083   /// supported, using the @file syntax. On windows, the file is written in the
0084   /// UTF8 encoding. On other OSes, no re-encoding occurs.
0085   static constexpr ResponseFileSupport AtFileUTF8() {
0086     return {RF_Full, llvm::sys::WEM_UTF8, "@"};
0087   }
0088 
0089   /// Returns a ResponseFileSupport indicating that response files are
0090   /// supported, using the @file syntax. On windows, the file is written in the
0091   /// current ANSI code-page encoding. On other OSes, no re-encoding occurs.
0092   static constexpr ResponseFileSupport AtFileCurCP() {
0093     return {RF_Full, llvm::sys::WEM_CurrentCodePage, "@"};
0094   }
0095 
0096   /// Returns a ResponseFileSupport indicating that response files are
0097   /// supported, using the @file syntax. On windows, the file is written in the
0098   /// UTF-16 encoding. On other OSes, no re-encoding occurs.
0099   static constexpr ResponseFileSupport AtFileUTF16() {
0100     return {RF_Full, llvm::sys::WEM_UTF16, "@"};
0101   }
0102 };
0103 
0104 /// Command - An executable path/name and argument vector to
0105 /// execute.
0106 class Command {
0107   /// Source - The action which caused the creation of this job.
0108   const Action &Source;
0109 
0110   /// Tool - The tool which caused the creation of this job.
0111   const Tool &Creator;
0112 
0113   /// Whether and how to generate response files if the arguments are too long.
0114   ResponseFileSupport ResponseSupport;
0115 
0116   /// The executable to run.
0117   const char *Executable;
0118 
0119   /// Optional argument to prepend.
0120   const char *PrependArg;
0121 
0122   /// The list of program arguments (not including the implicit first
0123   /// argument, which will be the executable).
0124   llvm::opt::ArgStringList Arguments;
0125 
0126   /// The list of program inputs.
0127   std::vector<InputInfo> InputInfoList;
0128 
0129   /// The list of program arguments which are outputs. May be empty.
0130   std::vector<std::string> OutputFilenames;
0131 
0132   /// Response file name, if this command is set to use one, or nullptr
0133   /// otherwise
0134   const char *ResponseFile = nullptr;
0135 
0136   /// The input file list in case we need to emit a file list instead of a
0137   /// proper response file
0138   llvm::opt::ArgStringList InputFileList;
0139 
0140   /// String storage if we need to create a new argument to specify a response
0141   /// file
0142   std::string ResponseFileFlag;
0143 
0144   /// See Command::setEnvironment
0145   std::vector<const char *> Environment;
0146 
0147   /// Optional redirection for stdin, stdout, stderr.
0148   std::vector<std::optional<std::string>> RedirectFiles;
0149 
0150   /// Information on executable run provided by OS.
0151   mutable std::optional<llvm::sys::ProcessStatistics> ProcStat;
0152 
0153   /// When a response file is needed, we try to put most arguments in an
0154   /// exclusive file, while others remains as regular command line arguments.
0155   /// This functions fills a vector with the regular command line arguments,
0156   /// argv, excluding the ones passed in a response file.
0157   void buildArgvForResponseFile(llvm::SmallVectorImpl<const char *> &Out) const;
0158 
0159   /// Encodes an array of C strings into a single string separated by whitespace.
0160   /// This function will also put in quotes arguments that have whitespaces and
0161   /// will escape the regular backslashes (used in Windows paths) and quotes.
0162   /// The results are the contents of a response file, written into a raw_ostream.
0163   void writeResponseFile(raw_ostream &OS) const;
0164 
0165 public:
0166   /// Whether to print the input filenames when executing.
0167   bool PrintInputFilenames = false;
0168 
0169   /// Whether the command will be executed in this process or not.
0170   bool InProcess = false;
0171 
0172   Command(const Action &Source, const Tool &Creator,
0173           ResponseFileSupport ResponseSupport, const char *Executable,
0174           const llvm::opt::ArgStringList &Arguments, ArrayRef<InputInfo> Inputs,
0175           ArrayRef<InputInfo> Outputs = {}, const char *PrependArg = nullptr);
0176   // FIXME: This really shouldn't be copyable, but is currently copied in some
0177   // error handling in Driver::generateCompilationDiagnostics.
0178   Command(const Command &) = default;
0179   virtual ~Command() = default;
0180 
0181   virtual void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
0182                      CrashReportInfo *CrashInfo = nullptr) const;
0183 
0184   virtual int Execute(ArrayRef<std::optional<StringRef>> Redirects,
0185                       std::string *ErrMsg, bool *ExecutionFailed) const;
0186 
0187   /// getSource - Return the Action which caused the creation of this job.
0188   const Action &getSource() const { return Source; }
0189 
0190   /// getCreator - Return the Tool which caused the creation of this job.
0191   const Tool &getCreator() const { return Creator; }
0192 
0193   /// Returns the kind of response file supported by the current invocation.
0194   const ResponseFileSupport &getResponseFileSupport() {
0195     return ResponseSupport;
0196   }
0197 
0198   /// Set to pass arguments via a response file when launching the command
0199   void setResponseFile(const char *FileName);
0200 
0201   /// Set an input file list, necessary if you specified an RF_FileList response
0202   /// file support.
0203   void setInputFileList(llvm::opt::ArgStringList List) {
0204     InputFileList = std::move(List);
0205   }
0206 
0207   /// Sets the environment to be used by the new process.
0208   /// \param NewEnvironment An array of environment variables.
0209   /// \remark If the environment remains unset, then the environment
0210   ///         from the parent process will be used.
0211   virtual void setEnvironment(llvm::ArrayRef<const char *> NewEnvironment);
0212 
0213   void
0214   setRedirectFiles(const std::vector<std::optional<std::string>> &Redirects);
0215 
0216   void replaceArguments(llvm::opt::ArgStringList List) {
0217     Arguments = std::move(List);
0218   }
0219 
0220   void replaceExecutable(const char *Exe) { Executable = Exe; }
0221 
0222   const char *getExecutable() const { return Executable; }
0223 
0224   const llvm::opt::ArgStringList &getArguments() const { return Arguments; }
0225 
0226   const std::vector<InputInfo> &getInputInfos() const { return InputInfoList; }
0227 
0228   const std::vector<std::string> &getOutputFilenames() const {
0229     return OutputFilenames;
0230   }
0231 
0232   std::optional<llvm::sys::ProcessStatistics> getProcessStatistics() const {
0233     return ProcStat;
0234   }
0235 
0236 protected:
0237   /// Optionally print the filenames to be compiled
0238   void PrintFileNames() const;
0239 };
0240 
0241 /// Use the CC1 tool callback when available, to avoid creating a new process
0242 class CC1Command : public Command {
0243 public:
0244   CC1Command(const Action &Source, const Tool &Creator,
0245              ResponseFileSupport ResponseSupport, const char *Executable,
0246              const llvm::opt::ArgStringList &Arguments,
0247              ArrayRef<InputInfo> Inputs, ArrayRef<InputInfo> Outputs = {},
0248              const char *PrependArg = nullptr);
0249 
0250   void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
0251              CrashReportInfo *CrashInfo = nullptr) const override;
0252 
0253   int Execute(ArrayRef<std::optional<StringRef>> Redirects, std::string *ErrMsg,
0254               bool *ExecutionFailed) const override;
0255 
0256   void setEnvironment(llvm::ArrayRef<const char *> NewEnvironment) override;
0257 };
0258 
0259 /// JobList - A sequence of jobs to perform.
0260 class JobList {
0261 public:
0262   using list_type = SmallVector<std::unique_ptr<Command>, 4>;
0263   using size_type = list_type::size_type;
0264   using iterator = llvm::pointee_iterator<list_type::iterator>;
0265   using const_iterator = llvm::pointee_iterator<list_type::const_iterator>;
0266 
0267 private:
0268   list_type Jobs;
0269 
0270 public:
0271   void Print(llvm::raw_ostream &OS, const char *Terminator,
0272              bool Quote, CrashReportInfo *CrashInfo = nullptr) const;
0273 
0274   /// Add a job to the list (taking ownership).
0275   void addJob(std::unique_ptr<Command> J) { Jobs.push_back(std::move(J)); }
0276 
0277   /// Clear the job list.
0278   void clear();
0279 
0280   const list_type &getJobs() const { return Jobs; }
0281 
0282   bool empty() const { return Jobs.empty(); }
0283   size_type size() const { return Jobs.size(); }
0284   iterator begin() { return Jobs.begin(); }
0285   const_iterator begin() const { return Jobs.begin(); }
0286   iterator end() { return Jobs.end(); }
0287   const_iterator end() const { return Jobs.end(); }
0288 };
0289 
0290 } // namespace driver
0291 } // namespace clang
0292 
0293 #endif // LLVM_CLANG_DRIVER_JOB_H