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