• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===--- Compilation.h - Compilation Task Data Structure --------*- C++ -*-===//
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 
10 #ifndef LLVM_CLANG_DRIVER_COMPILATION_H
11 #define LLVM_CLANG_DRIVER_COMPILATION_H
12 
13 #include "clang/Driver/Action.h"
14 #include "clang/Driver/Job.h"
15 #include "clang/Driver/Util.h"
16 #include "llvm/ADT/DenseMap.h"
17 #include "llvm/Support/Path.h"
18 #include <map>
19 
20 namespace llvm {
21 namespace opt {
22   class DerivedArgList;
23   class InputArgList;
24 }
25 }
26 
27 namespace clang {
28 namespace driver {
29   class Driver;
30   class JobList;
31   class ToolChain;
32 
33 /// Compilation - A set of tasks to perform for a single driver
34 /// invocation.
35 class Compilation {
36   /// The driver we were created by.
37   const Driver &TheDriver;
38 
39   /// The default tool chain.
40   const ToolChain &DefaultToolChain;
41 
42   /// A mask of all the programming models the host has to support in the
43   /// current compilation.
44   unsigned ActiveOffloadMask;
45 
46   /// Array with the toolchains of offloading host and devices in the order they
47   /// were requested by the user. We are preserving that order in case the code
48   /// generation needs to derive a programming-model-specific semantic out of
49   /// it.
50   std::multimap<Action::OffloadKind, const ToolChain *>
51       OrderedOffloadingToolchains;
52 
53   /// The original (untranslated) input argument list.
54   llvm::opt::InputArgList *Args;
55 
56   /// The driver translated arguments. Note that toolchains may perform their
57   /// own argument translation.
58   llvm::opt::DerivedArgList *TranslatedArgs;
59 
60   /// The list of actions we've created via MakeAction.  This is not accessible
61   /// to consumers; it's here just to manage ownership.
62   std::vector<std::unique_ptr<Action>> AllActions;
63 
64   /// The list of actions.  This is maintained and modified by consumers, via
65   /// getActions().
66   ActionList Actions;
67 
68   /// The root list of jobs.
69   JobList Jobs;
70 
71   /// Cache of translated arguments for a particular tool chain and bound
72   /// architecture.
73   llvm::DenseMap<std::pair<const ToolChain *, const char *>,
74                  llvm::opt::DerivedArgList *> TCArgs;
75 
76   /// Temporary files which should be removed on exit.
77   llvm::opt::ArgStringList TempFiles;
78 
79   /// Result files which should be removed on failure.
80   ArgStringMap ResultFiles;
81 
82   /// Result files which are generated correctly on failure, and which should
83   /// only be removed if we crash.
84   ArgStringMap FailureResultFiles;
85 
86   /// Redirection for stdout, stderr, etc.
87   const StringRef **Redirects;
88 
89   /// Whether we're compiling for diagnostic purposes.
90   bool ForDiagnostics;
91 
92 public:
93   Compilation(const Driver &D, const ToolChain &DefaultToolChain,
94               llvm::opt::InputArgList *Args,
95               llvm::opt::DerivedArgList *TranslatedArgs);
96   ~Compilation();
97 
getDriver()98   const Driver &getDriver() const { return TheDriver; }
99 
getDefaultToolChain()100   const ToolChain &getDefaultToolChain() const { return DefaultToolChain; }
getOffloadingHostToolChain()101   const ToolChain *getOffloadingHostToolChain() const {
102     auto It = OrderedOffloadingToolchains.find(Action::OFK_Host);
103     if (It != OrderedOffloadingToolchains.end())
104       return It->second;
105     return nullptr;
106   }
isOffloadingHostKind(Action::OffloadKind Kind)107   unsigned isOffloadingHostKind(Action::OffloadKind Kind) const {
108     return ActiveOffloadMask & Kind;
109   }
110 
111   /// Iterator that visits device toolchains of a given kind.
112   typedef const std::multimap<Action::OffloadKind,
113                               const ToolChain *>::const_iterator
114       const_offload_toolchains_iterator;
115   typedef std::pair<const_offload_toolchains_iterator,
116                     const_offload_toolchains_iterator>
117       const_offload_toolchains_range;
118 
119   template <Action::OffloadKind Kind>
getOffloadToolChains()120   const_offload_toolchains_range getOffloadToolChains() const {
121     return OrderedOffloadingToolchains.equal_range(Kind);
122   }
123 
124   // Return an offload toolchain of the provided kind. Only one is expected to
125   // exist.
126   template <Action::OffloadKind Kind>
getSingleOffloadToolChain()127   const ToolChain *getSingleOffloadToolChain() const {
128     auto TCs = getOffloadToolChains<Kind>();
129 
130     assert(TCs.first != TCs.second &&
131            "No tool chains of the selected kind exist!");
132     assert(std::next(TCs.first) == TCs.second &&
133            "More than one tool chain of the this kind exist.");
134     return TCs.first->second;
135   }
136 
addOffloadDeviceToolChain(const ToolChain * DeviceToolChain,Action::OffloadKind OffloadKind)137   void addOffloadDeviceToolChain(const ToolChain *DeviceToolChain,
138                                  Action::OffloadKind OffloadKind) {
139     assert(OffloadKind != Action::OFK_Host && OffloadKind != Action::OFK_None &&
140            "This is not a device tool chain!");
141 
142     // Update the host offload kind to also contain this kind.
143     ActiveOffloadMask |= OffloadKind;
144     OrderedOffloadingToolchains.insert(
145         std::make_pair(OffloadKind, DeviceToolChain));
146   }
147 
getInputArgs()148   const llvm::opt::InputArgList &getInputArgs() const { return *Args; }
149 
getArgs()150   const llvm::opt::DerivedArgList &getArgs() const { return *TranslatedArgs; }
151 
getArgs()152   llvm::opt::DerivedArgList &getArgs() { return *TranslatedArgs; }
153 
getActions()154   ActionList &getActions() { return Actions; }
getActions()155   const ActionList &getActions() const { return Actions; }
156 
157   /// Creates a new Action owned by this Compilation.
158   ///
159   /// The new Action is *not* added to the list returned by getActions().
MakeAction(Args &&...Arg)160   template <typename T, typename... Args> T *MakeAction(Args &&... Arg) {
161     T *RawPtr = new T(std::forward<Args>(Arg)...);
162     AllActions.push_back(std::unique_ptr<Action>(RawPtr));
163     return RawPtr;
164   }
165 
getJobs()166   JobList &getJobs() { return Jobs; }
getJobs()167   const JobList &getJobs() const { return Jobs; }
168 
addCommand(std::unique_ptr<Command> C)169   void addCommand(std::unique_ptr<Command> C) { Jobs.addJob(std::move(C)); }
170 
getTempFiles()171   const llvm::opt::ArgStringList &getTempFiles() const { return TempFiles; }
172 
getResultFiles()173   const ArgStringMap &getResultFiles() const { return ResultFiles; }
174 
getFailureResultFiles()175   const ArgStringMap &getFailureResultFiles() const {
176     return FailureResultFiles;
177   }
178 
179   /// Returns the sysroot path.
180   StringRef getSysRoot() const;
181 
182   /// getArgsForToolChain - Return the derived argument list for the
183   /// tool chain \p TC (or the default tool chain, if TC is not specified).
184   ///
185   /// \param BoundArch - The bound architecture name, or 0.
186   const llvm::opt::DerivedArgList &getArgsForToolChain(const ToolChain *TC,
187                                                        const char *BoundArch);
188 
189   /// addTempFile - Add a file to remove on exit, and returns its
190   /// argument.
addTempFile(const char * Name)191   const char *addTempFile(const char *Name) {
192     TempFiles.push_back(Name);
193     return Name;
194   }
195 
196   /// addResultFile - Add a file to remove on failure, and returns its
197   /// argument.
addResultFile(const char * Name,const JobAction * JA)198   const char *addResultFile(const char *Name, const JobAction *JA) {
199     ResultFiles[JA] = Name;
200     return Name;
201   }
202 
203   /// addFailureResultFile - Add a file to remove if we crash, and returns its
204   /// argument.
addFailureResultFile(const char * Name,const JobAction * JA)205   const char *addFailureResultFile(const char *Name, const JobAction *JA) {
206     FailureResultFiles[JA] = Name;
207     return Name;
208   }
209 
210   /// CleanupFile - Delete a given file.
211   ///
212   /// \param IssueErrors - Report failures as errors.
213   /// \return Whether the file was removed successfully.
214   bool CleanupFile(const char *File, bool IssueErrors = false) const;
215 
216   /// CleanupFileList - Remove the files in the given list.
217   ///
218   /// \param IssueErrors - Report failures as errors.
219   /// \return Whether all files were removed successfully.
220   bool CleanupFileList(const llvm::opt::ArgStringList &Files,
221                        bool IssueErrors = false) const;
222 
223   /// CleanupFileMap - Remove the files in the given map.
224   ///
225   /// \param JA - If specified, only delete the files associated with this
226   /// JobAction.  Otherwise, delete all files in the map.
227   /// \param IssueErrors - Report failures as errors.
228   /// \return Whether all files were removed successfully.
229   bool CleanupFileMap(const ArgStringMap &Files,
230                       const JobAction *JA,
231                       bool IssueErrors = false) const;
232 
233   /// ExecuteCommand - Execute an actual command.
234   ///
235   /// \param FailingCommand - For non-zero results, this will be set to the
236   /// Command which failed, if any.
237   /// \return The result code of the subprocess.
238   int ExecuteCommand(const Command &C, const Command *&FailingCommand) const;
239 
240   /// ExecuteJob - Execute a single job.
241   ///
242   /// \param FailingCommands - For non-zero results, this will be a vector of
243   /// failing commands and their associated result code.
244   void ExecuteJobs(
245       const JobList &Jobs,
246       SmallVectorImpl<std::pair<int, const Command *>> &FailingCommands) const;
247 
248   /// initCompilationForDiagnostics - Remove stale state and suppress output
249   /// so compilation can be reexecuted to generate additional diagnostic
250   /// information (e.g., preprocessed source(s)).
251   void initCompilationForDiagnostics();
252 
253   /// Return true if we're compiling for diagnostics.
isForDiagnostics()254   bool isForDiagnostics() const { return ForDiagnostics; }
255 
256   /// Redirect - Redirect output of this compilation. Can only be done once.
257   ///
258   /// \param Redirects - array of pointers to paths. The array
259   /// should have a size of three. The inferior process's
260   /// stdin(0), stdout(1), and stderr(2) will be redirected to the
261   /// corresponding paths. This compilation instance becomes
262   /// the owner of Redirects and will delete the array and StringRef's.
263   void Redirect(const StringRef** Redirects);
264 };
265 
266 } // end namespace driver
267 } // end namespace clang
268 
269 #endif
270