File indexing completed on 2026-05-10 08:36:52
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_CLANG_DRIVER_COMPILATION_H
0010 #define LLVM_CLANG_DRIVER_COMPILATION_H
0011
0012 #include "clang/Basic/LLVM.h"
0013 #include "clang/Driver/Action.h"
0014 #include "clang/Driver/Job.h"
0015 #include "clang/Driver/Util.h"
0016 #include "llvm/ADT/ArrayRef.h"
0017 #include "llvm/ADT/DenseMap.h"
0018 #include "llvm/ADT/StringRef.h"
0019 #include "llvm/Option/Option.h"
0020 #include <cassert>
0021 #include <iterator>
0022 #include <map>
0023 #include <memory>
0024 #include <optional>
0025 #include <utility>
0026 #include <vector>
0027
0028 namespace llvm {
0029 namespace opt {
0030
0031 class DerivedArgList;
0032 class InputArgList;
0033
0034 }
0035 }
0036
0037 namespace clang {
0038 namespace driver {
0039
0040 class Driver;
0041 class ToolChain;
0042
0043
0044
0045 class Compilation {
0046
0047 const Driver &TheDriver;
0048
0049
0050 const ToolChain &DefaultToolChain;
0051
0052
0053
0054 unsigned ActiveOffloadMask = 0;
0055
0056
0057
0058
0059
0060 std::multimap<Action::OffloadKind, const ToolChain *>
0061 OrderedOffloadingToolchains;
0062
0063
0064 llvm::opt::InputArgList *Args;
0065
0066
0067
0068 llvm::opt::DerivedArgList *TranslatedArgs;
0069
0070
0071
0072 std::vector<std::unique_ptr<Action>> AllActions;
0073
0074
0075
0076 ActionList Actions;
0077
0078
0079 JobList Jobs;
0080
0081
0082
0083 struct TCArgsKey final {
0084 const ToolChain *TC = nullptr;
0085 StringRef BoundArch;
0086 Action::OffloadKind DeviceOffloadKind = Action::OFK_None;
0087
0088 TCArgsKey(const ToolChain *TC, StringRef BoundArch,
0089 Action::OffloadKind DeviceOffloadKind)
0090 : TC(TC), BoundArch(BoundArch), DeviceOffloadKind(DeviceOffloadKind) {}
0091
0092 bool operator<(const TCArgsKey &K) const {
0093 if (TC < K.TC)
0094 return true;
0095 else if (TC == K.TC && BoundArch < K.BoundArch)
0096 return true;
0097 else if (TC == K.TC && BoundArch == K.BoundArch &&
0098 DeviceOffloadKind < K.DeviceOffloadKind)
0099 return true;
0100 return false;
0101 }
0102 };
0103 std::map<TCArgsKey, llvm::opt::DerivedArgList *> TCArgs;
0104
0105
0106 llvm::opt::ArgStringList TempFiles;
0107
0108
0109 ArgStringMap ResultFiles;
0110
0111
0112
0113 ArgStringMap FailureResultFiles;
0114
0115
0116 ArgStringMap TimeTraceFiles;
0117
0118
0119 std::vector<std::optional<StringRef>> Redirects;
0120
0121
0122
0123
0124 std::function<void(const Command &, int)> PostCallback;
0125
0126
0127 bool ForDiagnostics = false;
0128
0129
0130 bool ContainsError;
0131
0132
0133 bool ForceKeepTempFiles = false;
0134
0135 public:
0136 Compilation(const Driver &D, const ToolChain &DefaultToolChain,
0137 llvm::opt::InputArgList *Args,
0138 llvm::opt::DerivedArgList *TranslatedArgs, bool ContainsError);
0139 ~Compilation();
0140
0141 const Driver &getDriver() const { return TheDriver; }
0142
0143 const ToolChain &getDefaultToolChain() const { return DefaultToolChain; }
0144
0145 unsigned isOffloadingHostKind(Action::OffloadKind Kind) const {
0146 return ActiveOffloadMask & Kind;
0147 }
0148
0149 unsigned getActiveOffloadKinds() const { return ActiveOffloadMask; }
0150
0151
0152 using const_offload_toolchains_iterator =
0153 const std::multimap<Action::OffloadKind,
0154 const ToolChain *>::const_iterator;
0155 using const_offload_toolchains_range =
0156 std::pair<const_offload_toolchains_iterator,
0157 const_offload_toolchains_iterator>;
0158
0159 template <Action::OffloadKind Kind>
0160 const_offload_toolchains_range getOffloadToolChains() const {
0161 return OrderedOffloadingToolchains.equal_range(Kind);
0162 }
0163
0164 const_offload_toolchains_range
0165 getOffloadToolChains(Action::OffloadKind Kind) const {
0166 return OrderedOffloadingToolchains.equal_range(Kind);
0167 }
0168
0169
0170 template <Action::OffloadKind Kind> bool hasOffloadToolChain() const {
0171 return OrderedOffloadingToolchains.find(Kind) !=
0172 OrderedOffloadingToolchains.end();
0173 }
0174
0175
0176
0177 template <Action::OffloadKind Kind>
0178 const ToolChain *getSingleOffloadToolChain() const {
0179 auto TCs = getOffloadToolChains<Kind>();
0180
0181 assert(TCs.first != TCs.second &&
0182 "No tool chains of the selected kind exist!");
0183 assert(std::next(TCs.first) == TCs.second &&
0184 "More than one tool chain of the this kind exist.");
0185 return TCs.first->second;
0186 }
0187
0188 void addOffloadDeviceToolChain(const ToolChain *DeviceToolChain,
0189 Action::OffloadKind OffloadKind) {
0190 assert(OffloadKind != Action::OFK_Host && OffloadKind != Action::OFK_None &&
0191 "This is not a device tool chain!");
0192
0193
0194 ActiveOffloadMask |= OffloadKind;
0195 OrderedOffloadingToolchains.insert(
0196 std::make_pair(OffloadKind, DeviceToolChain));
0197 }
0198
0199 const llvm::opt::InputArgList &getInputArgs() const { return *Args; }
0200
0201 const llvm::opt::DerivedArgList &getArgs() const { return *TranslatedArgs; }
0202
0203 llvm::opt::DerivedArgList &getArgs() { return *TranslatedArgs; }
0204
0205 ActionList &getActions() { return Actions; }
0206 const ActionList &getActions() const { return Actions; }
0207
0208
0209
0210
0211 template <typename T, typename... Args> T *MakeAction(Args &&... Arg) {
0212 T *RawPtr = new T(std::forward<Args>(Arg)...);
0213 AllActions.push_back(std::unique_ptr<Action>(RawPtr));
0214 return RawPtr;
0215 }
0216
0217 JobList &getJobs() { return Jobs; }
0218 const JobList &getJobs() const { return Jobs; }
0219
0220 void addCommand(std::unique_ptr<Command> C) { Jobs.addJob(std::move(C)); }
0221
0222 llvm::opt::ArgStringList &getTempFiles() { return TempFiles; }
0223 const llvm::opt::ArgStringList &getTempFiles() const { return TempFiles; }
0224
0225 const ArgStringMap &getResultFiles() const { return ResultFiles; }
0226
0227 const ArgStringMap &getFailureResultFiles() const {
0228 return FailureResultFiles;
0229 }
0230
0231
0232
0233
0234
0235 void setPostCallback(const std::function<void(const Command &, int)> &CB) {
0236 PostCallback = CB;
0237 }
0238
0239
0240 StringRef getSysRoot() const;
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250 const llvm::opt::DerivedArgList &
0251 getArgsForToolChain(const ToolChain *TC, StringRef BoundArch,
0252 Action::OffloadKind DeviceOffloadKind);
0253
0254
0255
0256 const char *addTempFile(const char *Name) {
0257 TempFiles.push_back(Name);
0258 return Name;
0259 }
0260
0261
0262
0263 const char *addResultFile(const char *Name, const JobAction *JA) {
0264 ResultFiles[JA] = Name;
0265 return Name;
0266 }
0267
0268
0269
0270 const char *addFailureResultFile(const char *Name, const JobAction *JA) {
0271 FailureResultFiles[JA] = Name;
0272 return Name;
0273 }
0274
0275 const char *getTimeTraceFile(const JobAction *JA) const {
0276 return TimeTraceFiles.lookup(JA);
0277 }
0278 void addTimeTraceFile(const char *Name, const JobAction *JA) {
0279 assert(!TimeTraceFiles.contains(JA));
0280 TimeTraceFiles[JA] = Name;
0281 }
0282
0283
0284
0285
0286
0287 bool CleanupFile(const char *File, bool IssueErrors = false) const;
0288
0289
0290
0291
0292
0293 bool CleanupFileList(const llvm::opt::ArgStringList &Files,
0294 bool IssueErrors = false) const;
0295
0296
0297
0298
0299
0300
0301
0302 bool CleanupFileMap(const ArgStringMap &Files,
0303 const JobAction *JA,
0304 bool IssueErrors = false) const;
0305
0306
0307
0308
0309
0310
0311
0312
0313 int ExecuteCommand(const Command &C, const Command *&FailingCommand,
0314 bool LogOnly = false) const;
0315
0316
0317
0318
0319
0320
0321
0322 void
0323 ExecuteJobs(const JobList &Jobs,
0324 SmallVectorImpl<std::pair<int, const Command *>> &FailingCommands,
0325 bool LogOnly = false) const;
0326
0327
0328
0329
0330 void initCompilationForDiagnostics();
0331
0332
0333 bool isForDiagnostics() const { return ForDiagnostics; }
0334
0335
0336 bool containsError() const { return ContainsError; }
0337
0338
0339
0340 void setContainsError() { ContainsError = true; }
0341
0342
0343
0344
0345
0346
0347 void Redirect(ArrayRef<std::optional<StringRef>> Redirects);
0348 };
0349
0350 }
0351 }
0352
0353 #endif