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 /// Redirection for stdout, stderr, etc. 103 const StringRef **Redirects; 104 105 /// Whether we're compiling for diagnostic purposes. 106 bool ForDiagnostics; 107 108public: 109 Compilation(const Driver &D, const ToolChain &DefaultToolChain, 110 llvm::opt::InputArgList *Args, 111 llvm::opt::DerivedArgList *TranslatedArgs); 112 ~Compilation(); 113 114 const Driver &getDriver() const { return TheDriver; } 115 116 const ToolChain &getDefaultToolChain() const { return DefaultToolChain; } 117 118 unsigned isOffloadingHostKind(Action::OffloadKind Kind) const { 119 return ActiveOffloadMask & Kind; 120 } 121 122 /// Iterator that visits device toolchains of a given kind. 123 typedef const std::multimap<Action::OffloadKind, 124 const ToolChain *>::const_iterator 125 const_offload_toolchains_iterator; 126 typedef std::pair<const_offload_toolchains_iterator, 127 const_offload_toolchains_iterator> 128 const_offload_toolchains_range; 129 130 template <Action::OffloadKind Kind> 131 const_offload_toolchains_range getOffloadToolChains() const { 132 return OrderedOffloadingToolchains.equal_range(Kind); 133 } 134 135 /// Return true if an offloading tool chain of a given kind exists. 136 template <Action::OffloadKind Kind> bool hasOffloadToolChain() const { 137 return OrderedOffloadingToolchains.find(Kind) != 138 OrderedOffloadingToolchains.end(); 139 } 140 141 /// Return an offload toolchain of the provided kind. Only one is expected to 142 /// exist. 143 template <Action::OffloadKind Kind> 144 const ToolChain *getSingleOffloadToolChain() const { 145 auto TCs = getOffloadToolChains<Kind>(); 146 147 assert(TCs.first != TCs.second && 148 "No tool chains of the selected kind exist!"); 149 assert(std::next(TCs.first) == TCs.second && 150 "More than one tool chain of the this kind exist."); 151 return TCs.first->second; 152 } 153 154 void addOffloadDeviceToolChain(const ToolChain *DeviceToolChain, 155 Action::OffloadKind OffloadKind) { 156 assert(OffloadKind != Action::OFK_Host && OffloadKind != Action::OFK_None && 157 "This is not a device tool chain!"); 158 159 // Update the host offload kind to also contain this kind. 160 ActiveOffloadMask |= OffloadKind; 161 OrderedOffloadingToolchains.insert( 162 std::make_pair(OffloadKind, DeviceToolChain)); 163 } 164 165 const llvm::opt::InputArgList &getInputArgs() const { return *Args; } 166 167 const llvm::opt::DerivedArgList &getArgs() const { return *TranslatedArgs; } 168 169 llvm::opt::DerivedArgList &getArgs() { return *TranslatedArgs; } 170 171 ActionList &getActions() { return Actions; } 172 const ActionList &getActions() const { return Actions; } 173 174 /// Creates a new Action owned by this Compilation. 175 /// 176 /// The new Action is *not* added to the list returned by getActions(). 177 template <typename T, typename... Args> T *MakeAction(Args &&... Arg) { 178 T *RawPtr = new T(std::forward<Args>(Arg)...); 179 AllActions.push_back(std::unique_ptr<Action>(RawPtr)); 180 return RawPtr; 181 } 182 183 JobList &getJobs() { return Jobs; } 184 const JobList &getJobs() const { return Jobs; } 185 186 void addCommand(std::unique_ptr<Command> C) { Jobs.addJob(std::move(C)); } 187 188 const llvm::opt::ArgStringList &getTempFiles() const { return TempFiles; } 189 190 const ArgStringMap &getResultFiles() const { return ResultFiles; } 191 192 const ArgStringMap &getFailureResultFiles() const { 193 return FailureResultFiles; 194 } 195 196 /// Returns the sysroot path. 197 StringRef getSysRoot() const; 198 199 /// getArgsForToolChain - Return the derived argument list for the 200 /// tool chain \p TC (or the default tool chain, if TC is not specified). 201 /// If a device offloading kind is specified, a translation specific for that 202 /// kind is performed, if any. 203 /// 204 /// \param BoundArch - The bound architecture name, or 0. 205 /// \param DeviceOffloadKind - The offload device kind that should be used in 206 /// the translation, if any. 207 const llvm::opt::DerivedArgList & 208 getArgsForToolChain(const ToolChain *TC, StringRef BoundArch, 209 Action::OffloadKind DeviceOffloadKind); 210 211 /// addTempFile - Add a file to remove on exit, and returns its 212 /// argument. 213 const char *addTempFile(const char *Name) { 214 TempFiles.push_back(Name); 215 return Name; 216 } 217 218 /// addResultFile - Add a file to remove on failure, and returns its 219 /// argument. 220 const char *addResultFile(const char *Name, const JobAction *JA) { 221 ResultFiles[JA] = Name; 222 return Name; 223 } 224 225 /// addFailureResultFile - Add a file to remove if we crash, and returns its 226 /// argument. 227 const char *addFailureResultFile(const char *Name, const JobAction *JA) { 228 FailureResultFiles[JA] = Name; 229 return Name; 230 } 231 232 /// CleanupFile - Delete a given file. 233 /// 234 /// \param IssueErrors - Report failures as errors. 235 /// \return Whether the file was removed successfully. 236 bool CleanupFile(const char *File, bool IssueErrors = false) const; 237 238 /// CleanupFileList - Remove the files in the given list. 239 /// 240 /// \param IssueErrors - Report failures as errors. 241 /// \return Whether all files were removed successfully. 242 bool CleanupFileList(const llvm::opt::ArgStringList &Files, 243 bool IssueErrors = false) const; 244 245 /// CleanupFileMap - Remove the files in the given map. 246 /// 247 /// \param JA - If specified, only delete the files associated with this 248 /// JobAction. Otherwise, delete all files in the map. 249 /// \param IssueErrors - Report failures as errors. 250 /// \return Whether all files were removed successfully. 251 bool CleanupFileMap(const ArgStringMap &Files, 252 const JobAction *JA, 253 bool IssueErrors = false) const; 254 255 /// ExecuteCommand - Execute an actual command. 256 /// 257 /// \param FailingCommand - For non-zero results, this will be set to the 258 /// Command which failed, if any. 259 /// \return The result code of the subprocess. 260 int ExecuteCommand(const Command &C, const Command *&FailingCommand) const; 261 262 /// ExecuteJob - Execute a single job. 263 /// 264 /// \param FailingCommands - For non-zero results, this will be a vector of 265 /// failing commands and their associated result code. 266 void ExecuteJobs( 267 const JobList &Jobs, 268 SmallVectorImpl<std::pair<int, const Command *>> &FailingCommands) const; 269 270 /// initCompilationForDiagnostics - Remove stale state and suppress output 271 /// so compilation can be reexecuted to generate additional diagnostic 272 /// information (e.g., preprocessed source(s)). 273 void initCompilationForDiagnostics(); 274 275 /// Return true if we're compiling for diagnostics. 276 bool isForDiagnostics() const { return ForDiagnostics; } 277 278 /// Redirect - Redirect output of this compilation. Can only be done once. 279 /// 280 /// \param Redirects - array of pointers to paths. The array 281 /// should have a size of three. The inferior process's 282 /// stdin(0), stdout(1), and stderr(2) will be redirected to the 283 /// corresponding paths. This compilation instance becomes 284 /// the owner of Redirects and will delete the array and StringRef's. 285 void Redirect(const StringRef** Redirects); 286}; 287 288} // end namespace driver 289} // end namespace clang 290 291#endif 292