48 #include "clang/Config/config.h" 57 #include "llvm/ADT/ArrayRef.h" 58 #include "llvm/ADT/STLExtras.h" 59 #include "llvm/ADT/SmallSet.h" 60 #include "llvm/ADT/StringExtras.h" 61 #include "llvm/ADT/StringSet.h" 62 #include "llvm/ADT/StringSwitch.h" 63 #include "llvm/Config/llvm-config.h" 64 #include "llvm/Option/Arg.h" 65 #include "llvm/Option/ArgList.h" 66 #include "llvm/Option/OptSpecifier.h" 67 #include "llvm/Option/OptTable.h" 68 #include "llvm/Option/Option.h" 69 #include "llvm/Support/CommandLine.h" 70 #include "llvm/Support/ErrorHandling.h" 71 #include "llvm/Support/FileSystem.h" 72 #include "llvm/Support/FormatVariadic.h" 73 #include "llvm/Support/Path.h" 74 #include "llvm/Support/PrettyStackTrace.h" 75 #include "llvm/Support/Process.h" 76 #include "llvm/Support/Program.h" 77 #include "llvm/Support/StringSaver.h" 78 #include "llvm/Support/TargetRegistry.h" 79 #include "llvm/Support/VirtualFileSystem.h" 80 #include "llvm/Support/raw_ostream.h" 90 using namespace clang;
95 StringRef CustomResourceDir) {
101 std::string Dir = llvm::sys::path::parent_path(BinaryPath);
104 if (CustomResourceDir !=
"") {
105 llvm::sys::path::append(P, CustomResourceDir);
112 P = llvm::sys::path::parent_path(Dir);
113 llvm::sys::path::append(P, Twine(
"lib") + CLANG_LIBDIR_SUFFIX,
"clang",
114 CLANG_VERSION_STRING);
124 Mode(GCCMode), SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone),
125 LTOMode(
LTOK_None), ClangExecutable(ClangExecutable),
126 SysRoot(DEFAULT_SYSROOT), DriverTitle(
"clang LLVM compiler"),
127 CCPrintOptionsFilename(nullptr), CCPrintHeadersFilename(nullptr),
128 CCLogDiagnosticsFilename(nullptr), CCCPrintBindings(
false),
130 CCGenDiagnostics(
false), TargetTriple(TargetTriple),
131 CCCGenericGCCName(
""), Saver(Alloc), CheckInputsExist(
true),
132 GenReproducer(
false), SuppressMissingInputWarning(
false) {
136 this->VFS = llvm::vfs::getRealFileSystem();
138 Name = llvm::sys::path::filename(ClangExecutable);
139 Dir = llvm::sys::path::parent_path(ClangExecutable);
142 #if defined(CLANG_CONFIG_FILE_SYSTEM_DIR) 145 #if defined(CLANG_CONFIG_FILE_USER_DIR) 159 for (
const char *ArgPtr : Args) {
161 if (ArgPtr ==
nullptr)
163 const StringRef Arg = ArgPtr;
164 setDriverModeFromOption(Arg);
168 void Driver::setDriverModeFromOption(StringRef Opt) {
169 const std::string OptName =
170 getOpts().getOption(options::OPT_driver_mode).getPrefixedName();
171 if (!Opt.startswith(OptName))
173 StringRef
Value = Opt.drop_front(OptName.size());
176 .Case(
"gcc", GCCMode)
177 .Case(
"g++", GXXMode)
178 .Case(
"cpp", CPPMode)
183 Diag(diag::err_drv_unsupported_option_argument) << OptName <<
Value;
188 bool &ContainsError) {
189 llvm::PrettyStackTraceString CrashInfo(
"Command line argument parsing");
190 ContainsError =
false;
192 unsigned IncludedFlagsBitmask;
193 unsigned ExcludedFlagsBitmask;
194 std::tie(IncludedFlagsBitmask, ExcludedFlagsBitmask) =
195 getIncludeExcludeOptionFlagMasks(IsClCompatMode);
197 unsigned MissingArgIndex, MissingArgCount;
199 getOpts().ParseArgs(ArgStrings, MissingArgIndex, MissingArgCount,
200 IncludedFlagsBitmask, ExcludedFlagsBitmask);
203 if (MissingArgCount) {
204 Diag(diag::err_drv_missing_argument)
205 << Args.getArgString(MissingArgIndex) << MissingArgCount;
212 for (
const Arg *A : Args) {
215 auto ArgString = A->getAsString(Args);
218 ArgString, Nearest, IncludedFlagsBitmask,
220 DiagID = diag::err_drv_unsupported_opt;
221 Diag(DiagID) << ArgString;
223 DiagID = diag::err_drv_unsupported_opt_with_suggestion;
224 Diag(DiagID) << ArgString << Nearest;
232 if (A->getOption().matches(options::OPT_mcpu_EQ) && A->containsValue(
"")) {
233 Diag(diag::warn_drv_empty_joined_argument) << A->getAsString(Args);
235 diag::warn_drv_empty_joined_argument,
240 for (
const Arg *A : Args.filtered(options::OPT_UNKNOWN)) {
242 auto ArgString = A->getAsString(Args);
245 ArgString, Nearest, IncludedFlagsBitmask, ExcludedFlagsBitmask) > 1) {
246 DiagID =
IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl
247 : diag::err_drv_unknown_argument;
248 Diags.
Report(DiagID) << ArgString;
251 ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion
252 : diag::err_drv_unknown_argument_with_suggestion;
253 Diags.
Report(DiagID) << ArgString << Nearest;
265 phases::ID Driver::getFinalPhase(
const DerivedArgList &DAL,
266 Arg **FinalPhaseArg)
const {
267 Arg *PhaseArg =
nullptr;
271 if (
CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) ||
272 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) ||
273 (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) ||
274 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P))) {
278 }
else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile))) {
282 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
283 (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
284 (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
285 (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
286 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
287 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
288 (PhaseArg = DAL.getLastArg(options::OPT__migrate)) ||
289 (PhaseArg = DAL.getLastArg(options::OPT_emit_iterface_stubs)) ||
290 (PhaseArg = DAL.getLastArg(options::OPT__analyze,
291 options::OPT__analyze_auto)) ||
292 (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
296 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_S))) {
300 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_c))) {
308 *FinalPhaseArg = PhaseArg;
314 StringRef
Value,
bool Claim =
true) {
315 Arg *A =
new Arg(Opts.getOption(options::OPT_INPUT),
Value,
316 Args.getBaseArgs().MakeIndex(Value), Value.data());
317 Args.AddSynthesizedArg(A);
323 DerivedArgList *Driver::TranslateInputArgs(
const InputArgList &Args)
const {
324 DerivedArgList *DAL =
new DerivedArgList(Args);
326 bool HasNostdlib = Args.hasArg(options::OPT_nostdlib);
327 bool HasNostdlibxx = Args.hasArg(options::OPT_nostdlibxx);
328 bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs);
329 for (Arg *A : Args) {
336 if ((A->getOption().matches(options::OPT_Wl_COMMA) ||
337 A->getOption().matches(options::OPT_Xlinker)) &&
338 A->containsValue(
"--no-demangle")) {
340 DAL->AddFlagArg(A, Opts->getOption(options::OPT_Z_Xlinker__no_demangle));
343 for (StringRef Val : A->getValues())
344 if (Val !=
"--no-demangle")
345 DAL->AddSeparateArg(A, Opts->getOption(options::OPT_Xlinker), Val);
353 if (A->getOption().matches(options::OPT_Wp_COMMA) &&
354 (A->getValue(0) == StringRef(
"-MD") ||
355 A->getValue(0) == StringRef(
"-MMD"))) {
357 if (A->getValue(0) == StringRef(
"-MD"))
358 DAL->AddFlagArg(A, Opts->getOption(options::OPT_MD));
360 DAL->AddFlagArg(A, Opts->getOption(options::OPT_MMD));
361 if (A->getNumValues() == 2)
362 DAL->AddSeparateArg(A, Opts->getOption(options::OPT_MF),
368 if (A->getOption().matches(options::OPT_l)) {
369 StringRef
Value = A->getValue();
372 if (!HasNostdlib && !HasNodefaultlib && !HasNostdlibxx &&
374 DAL->AddFlagArg(A, Opts->getOption(options::OPT_Z_reserved_lib_stdcxx));
379 if (Value ==
"cc_kext") {
380 DAL->AddFlagArg(A, Opts->getOption(options::OPT_Z_reserved_lib_cckext));
386 if (A->getOption().matches(options::OPT__DASH_DASH)) {
388 for (StringRef Val : A->getValues())
397 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false))
398 DAL->AddFlagArg(0, Opts->getOption(options::OPT_static));
402 #if defined(HOST_LINK_VERSION) 403 if (!Args.hasArg(options::OPT_mlinker_version_EQ) &&
404 strlen(HOST_LINK_VERSION) > 0) {
405 DAL->AddJoinedArg(0, Opts->getOption(options::OPT_mlinker_version_EQ),
407 DAL->getLastArg(options::OPT_mlinker_version_EQ)->claim();
419 StringRef TargetTriple,
421 StringRef DarwinArchName =
"") {
423 if (
const Arg *A = Args.getLastArg(options::OPT_target))
424 TargetTriple = A->getValue();
431 if (TargetTriple.find(
"-unknown-gnu") != StringRef::npos ||
432 TargetTriple.find(
"-pc-gnu") != StringRef::npos)
433 Target.setOSName(
"hurd");
436 if (Target.isOSBinFormatMachO()) {
438 if (!DarwinArchName.empty()) {
444 if (Arg *A = Args.getLastArg(options::OPT_arch)) {
445 StringRef ArchName = A->getValue();
452 if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
453 options::OPT_mbig_endian)) {
454 if (A->getOption().matches(options::OPT_mlittle_endian)) {
455 llvm::Triple LE = Target.getLittleEndianArchVariant();
456 if (LE.getArch() != llvm::Triple::UnknownArch)
457 Target = std::move(LE);
459 llvm::Triple BE = Target.getBigEndianArchVariant();
460 if (BE.getArch() != llvm::Triple::UnknownArch)
461 Target = std::move(BE);
466 if (Target.getArch() == llvm::Triple::tce ||
467 Target.getOS() == llvm::Triple::Minix)
471 Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32,
472 options::OPT_m32, options::OPT_m16);
474 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
476 if (A->getOption().matches(options::OPT_m64)) {
477 AT = Target.get64BitArchVariant().getArch();
478 if (Target.getEnvironment() == llvm::Triple::GNUX32)
479 Target.setEnvironment(llvm::Triple::GNU);
480 }
else if (A->getOption().matches(options::OPT_mx32) &&
481 Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) {
482 AT = llvm::Triple::x86_64;
483 Target.setEnvironment(llvm::Triple::GNUX32);
484 }
else if (A->getOption().matches(options::OPT_m32)) {
485 AT = Target.get32BitArchVariant().getArch();
486 if (Target.getEnvironment() == llvm::Triple::GNUX32)
487 Target.setEnvironment(llvm::Triple::GNU);
488 }
else if (A->getOption().matches(options::OPT_m16) &&
489 Target.get32BitArchVariant().getArch() == llvm::Triple::x86) {
490 AT = llvm::Triple::x86;
491 Target.setEnvironment(llvm::Triple::CODE16);
494 if (AT != llvm::Triple::UnknownArch && AT != Target.getArch())
499 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false)) {
500 if (Target.get32BitArchVariant().getArch() != llvm::Triple::x86)
501 D.
Diag(diag::err_drv_unsupported_opt_for_target) <<
"-miamcu" 504 if (A && !A->getOption().matches(options::OPT_m32))
505 D.
Diag(diag::err_drv_argument_not_allowed_with)
506 <<
"-miamcu" << A->getBaseArg().getAsString(Args);
508 Target.setArch(llvm::Triple::x86);
509 Target.setArchName(
"i586");
510 Target.setEnvironment(llvm::Triple::UnknownEnvironment);
511 Target.setEnvironmentName(
"");
512 Target.setOS(llvm::Triple::ELFIAMCU);
513 Target.setVendor(llvm::Triple::UnknownVendor);
514 Target.setVendorName(
"intel");
519 A = Args.getLastArg(options::OPT_mabi_EQ);
520 if (A && Target.isMIPS()) {
521 StringRef ABIName = A->getValue();
522 if (ABIName ==
"32") {
523 Target = Target.get32BitArchVariant();
524 if (Target.getEnvironment() == llvm::Triple::GNUABI64 ||
525 Target.getEnvironment() == llvm::Triple::GNUABIN32)
526 Target.setEnvironment(llvm::Triple::GNU);
527 }
else if (ABIName ==
"n32") {
528 Target = Target.get64BitArchVariant();
529 if (Target.getEnvironment() == llvm::Triple::GNU ||
530 Target.getEnvironment() == llvm::Triple::GNUABI64)
531 Target.setEnvironment(llvm::Triple::GNUABIN32);
532 }
else if (ABIName ==
"64") {
533 Target = Target.get64BitArchVariant();
534 if (Target.getEnvironment() == llvm::Triple::GNU ||
535 Target.getEnvironment() == llvm::Triple::GNUABIN32)
536 Target.setEnvironment(llvm::Triple::GNUABI64);
545 void Driver::setLTOMode(
const llvm::opt::ArgList &Args) {
547 if (!Args.hasFlag(options::OPT_flto, options::OPT_flto_EQ,
548 options::OPT_fno_lto,
false))
551 StringRef LTOName(
"full");
553 const Arg *A = Args.getLastArg(options::OPT_flto_EQ);
555 LTOName = A->getValue();
557 LTOMode = llvm::StringSwitch<LTOKind>(LTOName)
564 Diag(diag::err_drv_unsupported_option_argument) << A->getOption().getName()
571 StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
573 const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
575 RuntimeName = A->getValue();
577 auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
585 Diag(diag::err_drv_unsupported_option_argument)
586 << A->getOption().getName() << A->getValue();
589 Diag(diag::err_drv_unsupported_opt) <<
"-fopenmp";
604 llvm::any_of(Inputs, [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
609 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
613 if (IsCuda && IsHIP) {
614 Diag(clang::diag::err_drv_mix_cuda_hip);
619 const llvm::Triple &HostTriple = HostTC->
getTriple();
620 StringRef DeviceTripleStr;
623 HostTriple.isArch64Bit() ?
"nvptx64-nvidia-cuda" :
"nvptx-nvidia-cuda";
624 llvm::Triple CudaTriple(DeviceTripleStr);
627 auto &CudaTC = ToolChains[CudaTriple.str() +
"/" + HostTriple.str()];
629 CudaTC = llvm::make_unique<toolchains::CudaToolChain>(
635 const llvm::Triple &HostTriple = HostTC->
getTriple();
636 StringRef DeviceTripleStr;
638 DeviceTripleStr =
"amdgcn-amd-amdhsa";
639 llvm::Triple HIPTriple(DeviceTripleStr);
642 auto &HIPTC = ToolChains[HIPTriple.str() +
"/" + HostTriple.str()];
644 HIPTC = llvm::make_unique<toolchains::HIPToolChain>(
655 if (Arg *OpenMPTargets =
656 C.
getInputArgs().getLastArg(options::OPT_fopenmp_targets_EQ)) {
657 if (OpenMPTargets->getNumValues()) {
662 options::OPT_fopenmp, options::OPT_fopenmp_EQ,
663 options::OPT_fno_openmp,
false);
664 if (HasValidOpenMPRuntime) {
666 HasValidOpenMPRuntime =
670 if (HasValidOpenMPRuntime) {
671 llvm::StringMap<const char *> FoundNormalizedTriples;
672 for (
const char *Val : OpenMPTargets->getValues()) {
673 llvm::Triple TT(Val);
674 std::string NormalizedName = TT.normalize();
677 auto Duplicate = FoundNormalizedTriples.find(NormalizedName);
678 if (Duplicate != FoundNormalizedTriples.end()) {
679 Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
680 << Val << Duplicate->second;
686 FoundNormalizedTriples[NormalizedName] = Val;
689 if (TT.getArch() == llvm::Triple::UnknownArch)
690 Diag(clang::diag::err_drv_invalid_omp_target) << Val;
698 assert(HostTC &&
"Host toolchain should be always defined.");
700 ToolChains[TT.str() +
"/" + HostTC->
getTriple().normalize()];
702 CudaTC = llvm::make_unique<toolchains::CudaToolChain>(
711 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
713 Diag(clang::diag::warn_drv_empty_joined_argument)
734 StringRef FileName) {
736 for (
const StringRef &
Dir : Dirs) {
740 llvm::sys::path::append(WPath,
Dir, FileName);
741 llvm::sys::path::native(WPath);
742 if (llvm::sys::fs::is_regular_file(WPath)) {
743 FilePath = std::move(WPath);
750 bool Driver::readConfigFile(StringRef FileName) {
753 if (!llvm::cl::readConfigFile(FileName, Saver, NewCfgArgs)) {
754 Diag(diag::err_drv_cannot_read_config_file) << FileName;
760 llvm::sys::path::native(CfgFileName);
761 ConfigFile = CfgFileName.str();
763 CfgOptions = llvm::make_unique<InputArgList>(
770 if (CfgOptions->hasArg(options::OPT_config)) {
772 Diag(diag::err_drv_nested_config_file);
778 for (Arg *A : *CfgOptions)
783 bool Driver::loadConfigFile() {
784 std::string CfgFileName;
785 bool FileSpecifiedExplicitly =
false;
789 if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
792 CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
793 if (!CfgDir.empty()) {
794 if (llvm::sys::fs::make_absolute(CfgDir).value() != 0)
800 if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
803 CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ));
804 if (!CfgDir.empty()) {
805 if (llvm::sys::fs::make_absolute(CfgDir).value() != 0)
815 std::vector<std::string> ConfigFiles =
816 CLOptions->getAllArgValues(options::OPT_config);
817 if (ConfigFiles.size() > 1) {
818 Diag(diag::err_drv_duplicate_config);
822 if (!ConfigFiles.empty()) {
823 CfgFileName = ConfigFiles.front();
824 assert(!CfgFileName.empty());
828 if (llvm::sys::path::has_parent_path(CfgFileName)) {
830 if (llvm::sys::path::is_relative(CfgFileName))
831 llvm::sys::fs::current_path(CfgFilePath);
832 llvm::sys::path::append(CfgFilePath, CfgFileName);
833 if (!llvm::sys::fs::is_regular_file(CfgFilePath)) {
834 Diag(diag::err_drv_config_file_not_exist) << CfgFilePath;
837 return readConfigFile(CfgFilePath);
840 FileSpecifiedExplicitly =
true;
850 if (CfgFileName.empty())
854 StringRef CfgFileArch = CfgFileName;
855 size_t ArchPrefixLen = CfgFileArch.find(
'-');
856 if (ArchPrefixLen == StringRef::npos)
857 ArchPrefixLen = CfgFileArch.size();
858 llvm::Triple CfgTriple;
859 CfgFileArch = CfgFileArch.take_front(ArchPrefixLen);
861 if (CfgTriple.getArch() == llvm::Triple::ArchType::UnknownArch)
864 if (!StringRef(CfgFileName).endswith(
".cfg"))
865 CfgFileName +=
".cfg";
871 size_t FixedArchPrefixLen = 0;
877 CfgTriple.getTriple(), *CLOptions);
878 if (CfgTriple.getArch() != EffectiveTriple.getArch()) {
879 FixedConfigFile = EffectiveTriple.getArchName();
880 FixedArchPrefixLen = FixedConfigFile.size();
883 if (ArchPrefixLen < CfgFileName.size())
884 FixedConfigFile += CfgFileName.substr(ArchPrefixLen);
892 CfgFileSearchDirs.push_back(
Dir);
896 if (!FixedConfigFile.empty()) {
897 if (
searchForFile(CfgFilePath, CfgFileSearchDirs, FixedConfigFile))
898 return readConfigFile(CfgFilePath);
900 FixedConfigFile.resize(FixedArchPrefixLen);
901 FixedConfigFile.append(
".cfg");
902 if (
searchForFile(CfgFilePath, CfgFileSearchDirs, FixedConfigFile))
903 return readConfigFile(CfgFilePath);
907 if (
searchForFile(CfgFilePath, CfgFileSearchDirs, CfgFileName))
908 return readConfigFile(CfgFilePath);
914 CfgFileName.append(
".cfg");
915 if (
searchForFile(CfgFilePath, CfgFileSearchDirs, CfgFileName))
916 return readConfigFile(CfgFilePath);
921 if (FileSpecifiedExplicitly) {
922 Diag(diag::err_drv_config_file_not_found) << CfgFileName;
923 for (
const std::string &SearchDir : CfgFileSearchDirs)
924 if (!SearchDir.empty())
925 Diag(diag::note_drv_config_file_searched_in) << SearchDir;
933 llvm::PrettyStackTraceString CrashInfo(
"Compilation construction");
939 llvm::sys::Process::GetEnv(
"COMPILER_PATH")) {
940 StringRef CompilerPath = *CompilerPathValue;
941 while (!CompilerPath.empty()) {
942 std::pair<StringRef, StringRef>
Split =
943 CompilerPath.split(llvm::sys::EnvPathSeparator);
945 CompilerPath = Split.second;
957 CLOptions = llvm::make_unique<InputArgList>(
962 ContainsError = loadConfigFile();
963 bool HasConfigFile = !ContainsError && (CfgOptions.get() !=
nullptr);
966 InputArgList Args = std::move(HasConfigFile ? std::move(*CfgOptions)
967 : std::move(*CLOptions));
972 auto appendOneArg = [&Args](
const Arg *Opt,
const Arg *BaseArg) {
973 unsigned Index = Args.MakeIndex(Opt->getSpelling());
974 Arg *Copy =
new llvm::opt::Arg(Opt->getOption(), Opt->getSpelling(),
976 Copy->getValues() = Opt->getValues();
977 if (Opt->isClaimed())
983 for (
auto *Opt : *CLOptions) {
984 if (Opt->getOption().matches(options::OPT_config))
986 const Arg *BaseArg = &Opt->getBaseArg();
989 appendOneArg(Opt, BaseArg);
995 for (
const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
997 CLModePassThroughArgList.push_back(A->getValue());
1000 if (!CLModePassThroughArgList.empty()) {
1003 auto CLModePassThroughOptions = llvm::make_unique<InputArgList>(
1007 for (
auto *Opt : *CLModePassThroughOptions) {
1008 appendOneArg(Opt,
nullptr);
1014 bool CCCPrintPhases;
1020 Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);
1023 Args.ClaimAllArgs(options::OPT_pipe);
1031 CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
1033 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
1034 CCCGenericGCCName = A->getValue();
1036 options::OPT_fno_crash_diagnostics,
1037 !!::getenv(
"FORCE_CLANG_DIAGNOSTICS_CRASH"));
1042 llvm::Triple T(TargetTriple);
1043 T.setOS(llvm::Triple::Win32);
1044 T.setVendor(llvm::Triple::PC);
1045 T.setEnvironment(llvm::Triple::MSVC);
1046 T.setObjectFormat(llvm::Triple::COFF);
1047 TargetTriple = T.str();
1049 if (
const Arg *A = Args.getLastArg(options::OPT_target))
1050 TargetTriple = A->getValue();
1051 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
1053 for (
const Arg *A : Args.filtered(options::OPT_B)) {
1057 if (
const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1059 if (
const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))
1062 if (
const Arg *A = Args.getLastArg(options::OPT_resource_dir))
1065 if (
const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) {
1066 SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
1067 .Case(
"cwd", SaveTempsCwd)
1068 .Case(
"obj", SaveTempsObj)
1069 .Default(SaveTempsCwd);
1075 if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) {
1076 StringRef
Name = A->getValue();
1077 unsigned Model = llvm::StringSwitch<unsigned>(
Name)
1078 .Case(
"off", EmbedNone)
1079 .Case(
"all", EmbedBitcode)
1080 .Case(
"bitcode", EmbedBitcode)
1081 .Case(
"marker", EmbedMarker)
1084 Diags.
Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1087 BitcodeEmbed =
static_cast<BitcodeEmbedMode
>(Model);
1090 std::unique_ptr<llvm::opt::InputArgList> UArgs =
1091 llvm::make_unique<InputArgList>(std::move(Args));
1094 DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
1116 if (TC.
getTriple().isOSBinFormatMachO())
1121 if (CCCPrintPhases) {
1131 static void printArgList(raw_ostream &OS,
const llvm::opt::ArgList &Args) {
1132 llvm::opt::ArgStringList ASL;
1133 for (
const auto *A : Args)
1134 A->render(Args, ASL);
1136 for (
auto I = ASL.begin(), E = ASL.end(); I != E; ++I) {
1137 if (I != ASL.begin())
1144 bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
1147 assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&
1148 "Only knows about .crash files on Darwin");
1153 path::home_directory(CrashDiagDir);
1154 if (CrashDiagDir.startswith(
"/var/root"))
1156 path::append(CrashDiagDir,
"Library/Logs/DiagnosticReports");
1164 fs::file_status FileStatus;
1165 TimePoint<> LastAccessTime;
1169 for (fs::directory_iterator File(CrashDiagDir, EC), FileEnd;
1170 File != FileEnd && !EC; File.increment(EC)) {
1171 StringRef FileName = path::filename(File->path());
1172 if (!FileName.startswith(
Name))
1174 if (fs::status(File->path(), FileStatus))
1176 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile =
1177 llvm::MemoryBuffer::getFile(File->path());
1182 StringRef Data = CrashFile.get()->getBuffer();
1183 if (!Data.startswith(
"Process:"))
1186 size_t ParentProcPos = Data.find(
"Parent Process:");
1187 if (ParentProcPos == StringRef::npos)
1189 size_t LineEnd = Data.find_first_of(
"\n", ParentProcPos);
1190 if (LineEnd == StringRef::npos)
1192 StringRef ParentProcess = Data.slice(ParentProcPos+15, LineEnd).trim();
1193 int OpenBracket = -1, CloseBracket = -1;
1194 for (
size_t i = 0, e = ParentProcess.size();
i < e; ++
i) {
1195 if (ParentProcess[
i] ==
'[')
1197 if (ParentProcess[
i] ==
']')
1203 if (OpenBracket < 0 || CloseBracket < 0 ||
1204 ParentProcess.slice(OpenBracket + 1, CloseBracket)
1205 .getAsInteger(10, CrashPID) || CrashPID != PID) {
1215 const auto FileAccessTime = FileStatus.getLastModificationTime();
1216 if (FileAccessTime > LastAccessTime) {
1217 CrashFilePath.assign(File->path());
1218 LastAccessTime = FileAccessTime;
1223 if (!CrashFilePath.empty()) {
1224 EC = fs::copy_file(CrashFilePath, ReproCrashFilename);
1239 if (C.
getArgs().hasArg(options::OPT_fno_crash_diagnostics))
1250 Diag(clang::diag::note_drv_command_failed_diag_msg)
1251 <<
"PLEASE submit a bug report to " BUG_REPORT_URL
" and include the " 1252 "crash backtrace, preprocessed source, and associated run script.";
1272 for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
1273 bool IgnoreInput =
false;
1279 }
else if (!strcmp(it->second->getValue(),
"-")) {
1280 Diag(clang::diag::note_drv_command_failed_diag_msg)
1281 <<
"Error generating preprocessed source(s) - " 1282 "ignoring input from stdin.";
1287 it = Inputs.erase(it);
1294 if (Inputs.empty()) {
1295 Diag(clang::diag::note_drv_command_failed_diag_msg)
1296 <<
"Error generating preprocessed source(s) - " 1297 "no preprocessable inputs.";
1303 llvm::StringSet<> ArchNames;
1304 for (
const Arg *A : C.
getArgs()) {
1305 if (A->getOption().matches(options::OPT_arch)) {
1306 StringRef ArchName = A->getValue();
1307 ArchNames.insert(ArchName);
1310 if (ArchNames.size() > 1) {
1311 Diag(clang::diag::note_drv_command_failed_diag_msg)
1312 <<
"Error generating preprocessed source(s) - cannot generate " 1313 "preprocessed source with multiple -arch options.";
1320 if (TC.
getTriple().isOSBinFormatMachO())
1329 Diag(clang::diag::note_drv_command_failed_diag_msg)
1330 <<
"Error generating preprocessed source(s).";
1339 if (!FailingCommands.empty()) {
1340 Diag(clang::diag::note_drv_command_failed_diag_msg)
1341 <<
"Error generating preprocessed source(s).";
1346 if (TempFiles.empty()) {
1347 Diag(clang::diag::note_drv_command_failed_diag_msg)
1348 <<
"Error generating preprocessed source(s).";
1352 Diag(clang::diag::note_drv_command_failed_diag_msg)
1353 <<
"\n********************\n\n" 1354 "PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:\n" 1355 "Preprocessed source(s) and associated run script(s) are located at:";
1359 for (
const char *TempFile : TempFiles) {
1360 Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile;
1363 if (ReproCrashFilename.empty()) {
1364 ReproCrashFilename = TempFile;
1365 llvm::sys::path::replace_extension(ReproCrashFilename,
".crash");
1367 if (StringRef(TempFile).endswith(
".cache")) {
1370 VFS = llvm::sys::path::filename(TempFile);
1371 llvm::sys::path::append(VFS,
"vfs",
"vfs.yaml");
1379 llvm::sys::path::replace_extension(Script,
"sh");
1381 llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew);
1383 Diag(clang::diag::note_drv_command_failed_diag_msg)
1384 <<
"Error generating run script: " << Script <<
" " << EC.message();
1387 <<
"# Driver args: ";
1389 ScriptOS <<
"# Original command: ";
1390 Cmd.
Print(ScriptOS,
"\n",
true);
1391 Cmd.
Print(ScriptOS,
"\n",
true, &CrashInfo);
1392 if (!AdditionalInformation.empty())
1393 ScriptOS <<
"\n# Additional information: " << AdditionalInformation
1397 Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
1401 if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
1403 if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) {
1404 Diag(clang::diag::note_drv_command_failed_diag_msg)
1405 << ReproCrashFilename.str();
1407 llvm::sys::path::append(CrashDiagDir,
Name);
1408 CrashDiagDir +=
"_<YYYY-MM-DD-HHMMSS>_<hostname>.crash";
1409 Diag(clang::diag::note_drv_command_failed_diag_msg)
1410 <<
"Crash backtrace is located in";
1411 Diag(clang::diag::note_drv_command_failed_diag_msg)
1412 << CrashDiagDir.str();
1413 Diag(clang::diag::note_drv_command_failed_diag_msg)
1414 <<
"(choose the .crash file that corresponds to your crash)";
1418 for (
const auto &A : C.
getArgs().filtered(options::OPT_frewrite_map_file,
1419 options::OPT_frewrite_map_file_EQ))
1420 Diag(clang::diag::note_drv_command_failed_diag_msg) << A->getValue();
1422 Diag(clang::diag::note_drv_command_failed_diag_msg)
1423 <<
"\n\n********************";
1432 llvm::sys::commandLineFitsWithinSystemLimits(Cmd.
getExecutable(),
1444 if (C.
getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
1450 if (Diags.hasErrorOccurred())
1455 setUpResponseFiles(C, Job);
1460 if (FailingCommands.empty())
1466 for (
const auto &CmdPair : FailingCommands) {
1467 int CommandRes = CmdPair.first;
1468 const Command *FailingCommand = CmdPair.second;
1483 if (CommandRes == EX_IOERR) {
1501 Diag(clang::diag::err_drv_command_signalled)
1504 Diag(clang::diag::err_drv_command_failed)
1512 unsigned IncludedFlagsBitmask;
1513 unsigned ExcludedFlagsBitmask;
1514 std::tie(IncludedFlagsBitmask, ExcludedFlagsBitmask) =
1515 getIncludeExcludeOptionFlagMasks(
IsCLMode());
1519 ExcludedFlagsBitmask |= HelpHidden;
1521 std::string Usage = llvm::formatv(
"{0} [options] file...",
Name).str();
1523 IncludedFlagsBitmask, ExcludedFlagsBitmask,
1535 if (Arg *A = C.
getArgs().getLastArg(options::OPT_mthread_model)) {
1538 OS <<
"Thread model: " << A->getValue();
1547 if (!ConfigFile.empty())
1548 OS <<
"Configuration file: " << ConfigFile <<
'\n';
1561 if (PassedFlags ==
"")
1565 std::vector<std::string> SuggestedCompletions;
1566 std::vector<std::string> Flags;
1568 unsigned short DisableFlags =
1574 const bool HasSpace = PassedFlags.endswith(
",");
1578 StringRef TargetFlags = PassedFlags;
1579 while (TargetFlags !=
"") {
1581 std::tie(CurFlag, TargetFlags) = TargetFlags.split(
",");
1582 Flags.push_back(std::string(CurFlag));
1587 if (llvm::is_contained(Flags,
"-Xclang") || llvm::is_contained(Flags,
"-cc1"))
1591 Cur = Flags.at(Flags.size() - 1);
1593 if (Flags.size() >= 2) {
1594 Prev = Flags.at(Flags.size() - 2);
1595 SuggestedCompletions = Opts->suggestValueCompletions(Prev, Cur);
1598 if (SuggestedCompletions.empty())
1599 SuggestedCompletions = Opts->suggestValueCompletions(Cur,
"");
1606 if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) {
1607 llvm::outs() <<
'\n';
1613 if (SuggestedCompletions.empty() && !Cur.endswith(
"=")) {
1617 SuggestedCompletions = Opts->findByPrefix(Cur, DisableFlags);
1623 if (S.startswith(Cur))
1624 SuggestedCompletions.push_back(S);
1631 llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) {
1632 if (
int X = A.compare_lower(B))
1634 return A.compare(B) > 0;
1637 llvm::outs() << llvm::join(SuggestedCompletions,
"\n") <<
'\n';
1644 if (C.
getArgs().hasArg(options::OPT_dumpmachine)) {
1649 if (C.
getArgs().hasArg(options::OPT_dumpversion)) {
1652 llvm::outs() << CLANG_VERSION_STRING <<
"\n";
1656 if (C.
getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
1661 if (C.
getArgs().hasArg(options::OPT_help) ||
1662 C.
getArgs().hasArg(options::OPT__help_hidden)) {
1667 if (C.
getArgs().hasArg(options::OPT__version)) {
1673 if (C.
getArgs().hasArg(options::OPT_v) ||
1674 C.
getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
1675 C.
getArgs().hasArg(options::OPT_print_supported_cpus)) {
1677 SuppressMissingInputWarning =
true;
1680 if (C.
getArgs().hasArg(options::OPT_v)) {
1682 llvm::errs() <<
"System configuration file directory: " 1685 llvm::errs() <<
"User configuration file directory: " 1691 if (C.
getArgs().hasArg(options::OPT_v))
1694 if (C.
getArgs().hasArg(options::OPT_print_resource_dir)) {
1699 if (C.
getArgs().hasArg(options::OPT_print_search_dirs)) {
1700 llvm::outs() <<
"programs: =";
1701 bool separator =
false;
1704 llvm::outs() << llvm::sys::EnvPathSeparator;
1705 llvm::outs() << Path;
1708 llvm::outs() <<
"\n";
1715 llvm::outs() << llvm::sys::EnvPathSeparator;
1718 llvm::outs() << sysroot << Path.substr(1);
1720 llvm::outs() << Path;
1722 llvm::outs() <<
"\n";
1728 if (Arg *A = C.
getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
1729 llvm::outs() <<
GetFilePath(A->getValue(), TC) <<
"\n";
1733 if (Arg *A = C.
getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
1734 StringRef ProgName = A->getValue();
1737 if (! ProgName.empty())
1740 llvm::outs() <<
"\n";
1744 if (Arg *A = C.
getArgs().getLastArg(options::OPT_autocomplete)) {
1745 StringRef PassedFlags = A->getValue();
1750 if (C.
getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
1759 llvm::outs() <<
GetFilePath(
"libgcc.a", TC) <<
"\n";
1765 if (C.
getArgs().hasArg(options::OPT_print_multi_lib)) {
1771 if (C.
getArgs().hasArg(options::OPT_print_multi_directory)) {
1774 llvm::outs() <<
".\n";
1777 assert(Suffix.front() ==
'/');
1778 llvm::outs() << Suffix.substr(1) <<
"\n";
1783 if (C.
getArgs().hasArg(options::OPT_print_target_triple)) {
1788 if (C.
getArgs().hasArg(options::OPT_print_effective_triple)) {
1790 llvm::outs() << Triple.getTriple() <<
"\n";
1801 std::map<Action *, unsigned> &Ids) {
1806 llvm::raw_string_ostream os(str);
1810 os <<
"\"" << IA->getInputArg().getValue() <<
"\"";
1812 os <<
'"' << BIA->getArchName() <<
'"' <<
", {" 1814 }
else if (
OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
1815 bool IsFirst =
true;
1816 OA->doOnEachDependence(
1833 os <<
":" << BoundArch;
1843 const char *Prefix =
"{";
1844 for (
Action *PreRequisite : *AL) {
1855 std::string offload_str;
1856 llvm::raw_string_ostream offload_os(offload_str);
1857 if (!isa<OffloadAction>(A)) {
1860 offload_os <<
", (" << S;
1867 unsigned Id = Ids.size();
1869 llvm::errs() << Id <<
": " << os.str() <<
", " 1878 std::map<Action *, unsigned> Ids;
1886 if (isa<CompileJobAction>(A) || isa<BackendJobAction>(A) ||
1887 isa<AssembleJobAction>(A))
1899 DerivedArgList &Args = C.
getArgs();
1901 llvm::PrettyStackTraceString CrashInfo(
"Building universal build actions");
1904 llvm::StringSet<> ArchNames;
1906 for (Arg *A : Args) {
1907 if (A->getOption().matches(options::OPT_arch)) {
1910 llvm::Triple::ArchType Arch =
1912 if (Arch == llvm::Triple::UnknownArch) {
1913 Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
1918 if (ArchNames.insert(A->getValue()).second)
1919 Archs.push_back(A->getValue());
1933 for (
Action* Act : SingleActions) {
1941 Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
1945 for (
unsigned i = 0, e = Archs.size();
i != e; ++
i)
1950 if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
1951 Actions.append(Inputs.begin(), Inputs.end());
1956 Arg *A = Args.getLastArg(options::OPT_g_Group);
1957 if (A && !A->getOption().matches(options::OPT_g0) &&
1958 !A->getOption().matches(options::OPT_gstabs) &&
1965 if (Act->getType() == types::TY_Image) {
1967 Inputs.push_back(Actions.back());
1974 if (Args.hasArg(options::OPT_verify_debug_info)) {
1975 Action* LastAction = Actions.back();
1978 LastAction, types::TY_Nothing));
1994 if (Arg *WorkDir = Args.getLastArg(options::OPT_working_directory)) {
1995 if (!llvm::sys::path::is_absolute(Path)) {
1997 llvm::sys::path::append(Directory, Value);
1998 Path.assign(Directory);
2002 if (
getVFS().exists(Path))
2006 if (!llvm::sys::path::is_absolute(Twine(Path)) &&
2007 llvm::sys::Process::FindInEnvPath(
"LIB", Value))
2010 if (Args.hasArg(options::OPT__SLASH_link) && Ty == types::TY_Object) {
2024 unsigned IncludedFlagsBitmask;
2025 unsigned ExcludedFlagsBitmask;
2026 std::tie(IncludedFlagsBitmask, ExcludedFlagsBitmask) =
2027 getIncludeExcludeOptionFlagMasks(
IsCLMode());
2028 std::string Nearest;
2029 if (
getOpts().findNearest(Value, Nearest, IncludedFlagsBitmask,
2030 ExcludedFlagsBitmask) <= 1) {
2031 Diag(clang::diag::err_drv_no_such_file_with_suggestion)
2037 Diag(clang::diag::err_drv_no_such_file) << Path;
2047 types::ID InputType = types::TY_Nothing;
2048 Arg *InputTypeArg =
nullptr;
2051 if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
2052 options::OPT__SLASH_TP)) {
2053 InputTypeArg = TCTP;
2054 InputType = TCTP->getOption().matches(options::OPT__SLASH_TC)
2059 bool ShowNote =
false;
2061 Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
2063 Diag(clang::diag::warn_drv_overriding_flag_option)
2064 << Previous->getSpelling() << A->getSpelling();
2070 Diag(clang::diag::note_drv_t_option_is_global);
2073 assert(!Args.hasArg(options::OPT_x) &&
"-x and /TC or /TP is not allowed");
2076 for (Arg *A : Args) {
2077 if (A->getOption().getKind() == Option::InputClass) {
2078 const char *
Value = A->getValue();
2082 if (InputType == types::TY_Nothing) {
2085 InputTypeArg->claim();
2088 if (memcmp(Value,
"-", 2) == 0) {
2094 if (!Args.hasArgNoClaim(options::OPT_E) && !
CCCIsCPP())
2095 Diag(
IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
2096 : clang::diag::err_drv_unknown_stdin_type);
2104 if (
const char *Ext = strrchr(Value,
'.'))
2110 else if (
IsCLMode() && Args.hasArgNoClaim(options::OPT_E))
2113 Ty = types::TY_Object;
2123 Diag(clang::diag::warn_drv_treating_input_as_cxx)
2129 if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) &&
2130 Ty == types::TY_Object)
2131 Ty = types::TY_LLVM_BC;
2139 if (Ty != types::TY_Object) {
2140 if (Args.hasArg(options::OPT_ObjC))
2141 Ty = types::TY_ObjC;
2142 else if (Args.hasArg(options::OPT_ObjCXX))
2143 Ty = types::TY_ObjCXX;
2146 assert(InputTypeArg &&
"InputType set w/o InputTypeArg");
2147 if (!InputTypeArg->getOption().matches(options::OPT_x)) {
2150 const char *Ext = strrchr(Value,
'.');
2152 Ty = types::TY_Object;
2156 InputTypeArg->claim();
2161 Inputs.push_back(std::make_pair(Ty, A));
2163 }
else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
2164 StringRef
Value = A->getValue();
2167 Arg *InputArg =
MakeInputArg(Args, *Opts, A->getValue());
2168 Inputs.push_back(std::make_pair(types::TY_C, InputArg));
2171 }
else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
2172 StringRef
Value = A->getValue();
2175 Arg *InputArg =
MakeInputArg(Args, *Opts, A->getValue());
2176 Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
2182 Inputs.push_back(std::make_pair(types::TY_Object, A));
2184 }
else if (A->getOption().matches(options::OPT_x)) {
2193 Diag(clang::diag::err_drv_unknown_language) << A->getValue();
2194 InputType = types::TY_Object;
2196 }
else if (A->getOption().getID() == options::OPT_U) {
2197 assert(A->getNumValues() == 1 &&
"The /U option has one value.");
2198 StringRef Val = A->getValue(0);
2199 if (Val.find_first_of(
"/\\") != StringRef::npos) {
2201 Diag(diag::warn_slash_u_filename) << Val;
2202 Diag(diag::note_use_dashdash);
2206 if (
CCCIsCPP() && Inputs.empty()) {
2210 Inputs.push_back(std::make_pair(types::TY_C, A));
2217 class OffloadingActionBuilder final {
2219 bool IsValid =
false;
2225 std::map<const Arg *, unsigned> InputArgToOffloadKindMap;
2228 class DeviceActionBuilder {
2232 enum ActionBuilderReturnCode {
2251 DerivedArgList &Args;
2260 DeviceActionBuilder(
Compilation &C, DerivedArgList &Args,
2263 : C(C), Args(Args), Inputs(Inputs),
2264 AssociatedOffloadKind(AssociatedOffloadKind) {}
2265 virtual ~DeviceActionBuilder() {}
2270 virtual ActionBuilderReturnCode
2274 return ABRT_Inactive;
2279 virtual ActionBuilderReturnCode addDeviceDepences(
Action *HostAction) {
2280 return ABRT_Inactive;
2285 virtual void appendTopLevelActions(
ActionList &AL) {}
2296 virtual bool canUseBundlerUnbundler()
const {
return false; }
2300 bool isValid() {
return !ToolChains.empty(); }
2304 return AssociatedOffloadKind;
2310 class CudaActionBuilderBase :
public DeviceActionBuilder {
2314 bool CompileHostOnly =
false;
2315 bool CompileDeviceOnly =
false;
2324 Action *CudaFatBinary =
nullptr;
2327 bool IsActive =
false;
2330 bool Relocatable =
false;
2332 CudaActionBuilderBase(
Compilation &C, DerivedArgList &Args,
2335 : DeviceActionBuilder(C, Args, Inputs, OFKind) {}
2337 ActionBuilderReturnCode addDeviceDepences(
Action *HostAction)
override {
2344 if (
auto *IA = dyn_cast<InputAction>(HostAction)) {
2345 assert(!GpuArchList.empty() &&
2346 "We should have at least one GPU architecture.");
2350 if (IA->getType() != types::TY_CUDA &&
2351 IA->getType() != types::TY_HIP) {
2354 return ABRT_Inactive;
2360 if (CompileHostOnly)
2361 return ABRT_Success;
2364 auto Ty = IA->getType() == types::TY_HIP ? types::TY_HIP_DEVICE
2365 : types::TY_CUDA_DEVICE;
2366 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
2367 CudaDeviceActions.push_back(
2371 return ABRT_Success;
2375 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
2380 return ABRT_Inactive;
2382 CudaDeviceActions.clear();
2383 auto *IA = cast<InputAction>(UA->getInputs().back());
2384 std::string FileName = IA->getInputArg().getAsString(Args);
2388 if (IA->getType() == types::TY_Object &&
2389 (!llvm::sys::path::has_extension(FileName) ||
2391 llvm::sys::path::extension(FileName).drop_front()) !=
2393 return ABRT_Inactive;
2395 for (
auto Arch : GpuArchList) {
2396 CudaDeviceActions.push_back(UA);
2398 AssociatedOffloadKind);
2400 return ABRT_Success;
2403 return IsActive ? ABRT_Success : ABRT_Inactive;
2406 void appendTopLevelActions(
ActionList &AL)
override {
2411 AssociatedOffloadKind);
2416 if (CudaFatBinary) {
2418 CudaDeviceActions.clear();
2419 CudaFatBinary =
nullptr;
2423 if (CudaDeviceActions.empty())
2429 assert(CudaDeviceActions.size() == GpuArchList.size() &&
2430 "Expecting one action per GPU architecture.");
2431 assert(ToolChains.size() == 1 &&
2432 "Expecting to have a sing CUDA toolchain.");
2433 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I)
2434 AddTopLevel(CudaDeviceActions[I], GpuArchList[I]);
2436 CudaDeviceActions.clear();
2453 Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
2454 options::OPT_fno_gpu_rdc,
false);
2457 assert(HostTC &&
"No toolchain for host compilation.");
2459 HostTC->
getTriple().getArch() == llvm::Triple::amdgcn) {
2468 ToolChains.push_back(
2473 Arg *PartialCompilationArg = Args.getLastArg(
2474 options::OPT_cuda_host_only, options::OPT_cuda_device_only,
2475 options::OPT_cuda_compile_host_device);
2476 CompileHostOnly = PartialCompilationArg &&
2477 PartialCompilationArg->getOption().matches(
2478 options::OPT_cuda_host_only);
2479 CompileDeviceOnly = PartialCompilationArg &&
2480 PartialCompilationArg->getOption().matches(
2481 options::OPT_cuda_device_only);
2484 std::set<CudaArch> GpuArchs;
2486 for (Arg *A : Args) {
2487 if (!(A->getOption().matches(options::OPT_cuda_gpu_arch_EQ) ||
2488 A->getOption().matches(options::OPT_no_cuda_gpu_arch_EQ)))
2492 const StringRef ArchStr = A->getValue();
2493 if (A->getOption().matches(options::OPT_no_cuda_gpu_arch_EQ) &&
2500 C.
getDriver().
Diag(clang::diag::err_drv_cuda_bad_gpu_arch) << ArchStr;
2502 }
else if (A->getOption().matches(options::OPT_cuda_gpu_arch_EQ))
2503 GpuArchs.insert(Arch);
2504 else if (A->getOption().matches(options::OPT_no_cuda_gpu_arch_EQ))
2505 GpuArchs.erase(Arch);
2507 llvm_unreachable(
"Unexpected option.");
2512 GpuArchList.push_back(Arch);
2517 if (GpuArchList.empty())
2526 class CudaActionBuilder final :
public CudaActionBuilderBase {
2528 CudaActionBuilder(
Compilation &C, DerivedArgList &Args,
2532 ActionBuilderReturnCode
2535 PhasesTy &Phases)
override {
2537 return ABRT_Inactive;
2541 if (CudaDeviceActions.empty())
2542 return ABRT_Success;
2544 assert(CudaDeviceActions.size() == GpuArchList.size() &&
2545 "Expecting one action per GPU architecture.");
2546 assert(!CompileHostOnly &&
2547 "Not expecting CUDA actions in host-only compilation.");
2557 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
2560 for (
auto Ph : Phases) {
2565 if (Ph > FinalPhase)
2578 if (!isa<AssembleJobAction>(CudaDeviceActions[I]) ||
2582 Action *AssembleAction = CudaDeviceActions[I];
2583 assert(AssembleAction->
getType() == types::TY_Object);
2584 assert(AssembleAction->
getInputs().size() == 1);
2587 assert(BackendAction->getType() == types::TY_PP_Asm);
2589 for (
auto &A : {AssembleAction, BackendAction}) {
2593 DeviceActions.push_back(
2599 if (!DeviceActions.empty()) {
2603 if (!CompileDeviceOnly) {
2604 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
2608 CudaFatBinary =
nullptr;
2613 CudaDeviceActions.clear();
2617 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
2622 return ABRT_Success;
2626 "instructions should only occur " 2627 "before the backend phase!");
2630 for (
Action *&A : CudaDeviceActions)
2633 return ABRT_Success;
2638 class HIPActionBuilder final :
public CudaActionBuilderBase {
2643 HIPActionBuilder(
Compilation &C, DerivedArgList &Args,
2647 bool canUseBundlerUnbundler()
const override {
return true; }
2649 ActionBuilderReturnCode
2652 PhasesTy &Phases)
override {
2657 if (CudaDeviceActions.empty() ||
2660 return ABRT_Success;
2663 CudaDeviceActions.size() == GpuArchList.size()) &&
2664 "Expecting one action per GPU architecture.");
2665 assert(!CompileHostOnly &&
2666 "Not expecting CUDA actions in host-only compilation.");
2674 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
2678 AL.push_back(CudaDeviceActions[I]);
2679 CudaDeviceActions[I] =
2689 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(),
2692 DDep, CudaDeviceActions[I]->getType());
2697 types::TY_HIP_FATBIN);
2699 if (!CompileDeviceOnly) {
2700 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
2701 AssociatedOffloadKind);
2704 CudaFatBinary =
nullptr;
2709 CudaDeviceActions.clear();
2711 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
2718 DeviceLinkerInputs.resize(CudaDeviceActions.size());
2719 auto LI = DeviceLinkerInputs.begin();
2720 for (
auto *A : CudaDeviceActions) {
2727 CudaDeviceActions.clear();
2728 return ABRT_Success;
2732 for (
Action *&A : CudaDeviceActions)
2734 AssociatedOffloadKind);
2736 return ABRT_Success;
2742 for (
auto &LI : DeviceLinkerInputs) {
2743 auto *DeviceLinkAction =
2745 DA.
add(*DeviceLinkAction, *ToolChains[0],
2754 class OpenMPActionBuilder final :
public DeviceActionBuilder {
2762 OpenMPActionBuilder(
Compilation &C, DerivedArgList &Args,
2766 ActionBuilderReturnCode
2769 PhasesTy &Phases)
override {
2770 if (OpenMPDeviceActions.empty())
2771 return ABRT_Inactive;
2774 assert(OpenMPDeviceActions.size() == ToolChains.size() &&
2775 "Number of OpenMP actions and toolchains do not match.");
2780 assert(ToolChains.size() == DeviceLinkerInputs.size() &&
2781 "Toolchains and linker inputs sizes do not match.");
2782 auto LI = DeviceLinkerInputs.begin();
2783 for (
auto *A : OpenMPDeviceActions) {
2790 OpenMPDeviceActions.clear();
2791 return ABRT_Success;
2795 for (
Action *&A : OpenMPDeviceActions)
2798 return ABRT_Success;
2801 ActionBuilderReturnCode addDeviceDepences(
Action *HostAction)
override {
2804 if (
auto *IA = dyn_cast<InputAction>(HostAction)) {
2805 OpenMPDeviceActions.clear();
2806 for (
unsigned I = 0; I < ToolChains.size(); ++I)
2807 OpenMPDeviceActions.push_back(
2809 return ABRT_Success;
2813 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
2814 OpenMPDeviceActions.clear();
2815 auto *IA = cast<InputAction>(UA->getInputs().back());
2816 std::string FileName = IA->getInputArg().getAsString(Args);
2820 if (IA->getType() == types::TY_Object &&
2821 (!llvm::sys::path::has_extension(FileName) ||
2823 llvm::sys::path::extension(FileName).drop_front()) !=
2825 return ABRT_Inactive;
2826 for (
unsigned I = 0; I < ToolChains.size(); ++I) {
2827 OpenMPDeviceActions.push_back(UA);
2828 UA->registerDependentActionInfo(
2831 return ABRT_Success;
2838 if (isa<CompileJobAction>(HostAction)) {
2840 assert(ToolChains.size() == OpenMPDeviceActions.size() &&
2841 "Toolchains and device action sizes do not match.");
2845 auto TC = ToolChains.begin();
2846 for (
Action *&A : OpenMPDeviceActions) {
2847 assert(isa<CompileJobAction>(A));
2854 return ABRT_Success;
2857 void appendTopLevelActions(
ActionList &AL)
override {
2858 if (OpenMPDeviceActions.empty())
2862 assert(OpenMPDeviceActions.size() == ToolChains.size() &&
2863 "Number of OpenMP actions and toolchains do not match.");
2866 auto TI = ToolChains.begin();
2867 for (
auto *A : OpenMPDeviceActions) {
2874 OpenMPDeviceActions.clear();
2878 assert(ToolChains.size() == DeviceLinkerInputs.size() &&
2879 "Toolchains and linker inputs sizes do not match.");
2882 auto TC = ToolChains.begin();
2883 for (
auto &LI : DeviceLinkerInputs) {
2884 auto *DeviceLinkAction =
2886 DA.
add(*DeviceLinkAction, **TC,
nullptr,
2896 for (
auto TI = OpenMPTCRange.first, TE = OpenMPTCRange.second; TI != TE;
2898 ToolChains.push_back(TI->second);
2900 DeviceLinkerInputs.resize(ToolChains.size());
2904 bool canUseBundlerUnbundler()
const override {
2921 OffloadingActionBuilder(
Compilation &C, DerivedArgList &Args,
2929 SpecializedBuilders.push_back(
new CudaActionBuilder(C, Args, Inputs));
2932 SpecializedBuilders.push_back(
new HIPActionBuilder(C, Args, Inputs));
2935 SpecializedBuilders.push_back(
new OpenMPActionBuilder(C, Args, Inputs));
2943 unsigned ValidBuilders = 0u;
2944 unsigned ValidBuildersSupportingBundling = 0u;
2945 for (
auto *SB : SpecializedBuilders) {
2946 IsValid = IsValid && !SB->initialize();
2949 if (SB->isValid()) {
2951 if (SB->canUseBundlerUnbundler())
2952 ++ValidBuildersSupportingBundling;
2956 ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling;
2959 ~OffloadingActionBuilder() {
2960 for (
auto *SB : SpecializedBuilders)
2969 addDeviceDependencesToHostAction(
Action *HostAction,
const Arg *InputArg,
2971 DeviceActionBuilder::PhasesTy &Phases) {
2975 if (SpecializedBuilders.empty())
2978 assert(HostAction &&
"Invalid host action!");
2983 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
2984 unsigned InactiveBuilders = 0u;
2985 unsigned IgnoringBuilders = 0u;
2986 for (
auto *SB : SpecializedBuilders) {
2987 if (!SB->isValid()) {
2993 SB->getDeviceDependences(DDeps, CurPhase, FinalPhase, Phases);
2998 if (RetCode == DeviceActionBuilder::ABRT_Ignore_Host)
3003 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
3004 OffloadKind |= SB->getAssociatedOffloadKind();
3009 if (IgnoringBuilders &&
3010 SpecializedBuilders.size() == (InactiveBuilders + IgnoringBuilders))
3027 bool addHostDependenceToDeviceActions(
Action *&HostAction,
3028 const Arg *InputArg) {
3038 if (CanUseBundler && isa<InputAction>(HostAction) &&
3039 InputArg->getOption().getKind() == llvm::opt::Option::InputClass &&
3041 auto UnbundlingHostAction =
3046 HostAction = UnbundlingHostAction;
3049 assert(HostAction &&
"Invalid host action!");
3052 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
3053 for (
auto *SB : SpecializedBuilders) {
3057 auto RetCode = SB->addDeviceDepences(HostAction);
3061 assert(RetCode != DeviceActionBuilder::ABRT_Ignore_Host &&
3062 "Host dependence not expected to be ignored.!");
3066 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
3067 OffloadKind |= SB->getAssociatedOffloadKind();
3072 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction))
3082 const Arg *InputArg) {
3085 for (
auto *SB : SpecializedBuilders) {
3088 SB->appendTopLevelActions(OffloadAL);
3095 if (CanUseBundler && HostAction && !OffloadAL.empty()) {
3097 OffloadAL.push_back(HostAction);
3101 assert(HostAction == AL.back() &&
"Host action not in the list??");
3103 AL.back() = HostAction;
3105 AL.append(OffloadAL.begin(), OffloadAL.end());
3122 for (
auto *SB : SpecializedBuilders) {
3126 SB->appendLinkDependences(DDeps);
3130 unsigned ActiveOffloadKinds = 0u;
3131 for (
auto &I : InputArgToOffloadKindMap)
3132 ActiveOffloadKinds |= I.second;
3149 nullptr, ActiveOffloadKinds);
3157 llvm::PrettyStackTraceString CrashInfo(
"Building compilation actions");
3159 if (!SuppressMissingInputWarning && Inputs.empty()) {
3160 Diag(clang::diag::err_drv_no_input_files);
3165 phases::ID FinalPhase = getFinalPhase(Args, &FinalPhaseArg);
3168 if (Args.hasArg(options::OPT_emit_llvm))
3169 Diag(clang::diag::err_drv_emit_llvm_link);
3171 !Args.getLastArgValue(options::OPT_fuse_ld_EQ).equals_lower(
"lld"))
3172 Diag(clang::diag::err_drv_lto_without_lld);
3177 if (Arg *A = Args.getLastArg(options::OPT_Z_Joined))
3178 Diag(clang::diag::err_drv_use_of_Z_option) << A->getAsString(Args);
3181 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
3182 StringRef
V = A->getValue();
3183 if (Inputs.size() > 1 && !V.empty() &&
3184 !llvm::sys::path::is_separator(V.back())) {
3186 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
3187 << A->getSpelling() <<
V;
3188 Args.eraseArg(options::OPT__SLASH_Fo);
3193 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
3194 StringRef
V = A->getValue();
3195 if (Inputs.size() > 1 && !V.empty() &&
3196 !llvm::sys::path::is_separator(V.back())) {
3198 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
3199 << A->getSpelling() <<
V;
3200 Args.eraseArg(options::OPT__SLASH_Fa);
3205 if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
3206 if (A->getValue()[0] ==
'\0') {
3208 Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
3209 Args.eraseArg(options::OPT__SLASH_o);
3214 Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
3215 Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
3216 if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
3217 Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
3218 Args.eraseArg(options::OPT__SLASH_Yc);
3219 Args.eraseArg(options::OPT__SLASH_Yu);
3220 YcArg = YuArg =
nullptr;
3222 if (YcArg && Inputs.size() > 1) {
3223 Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
3224 Args.eraseArg(options::OPT__SLASH_Yc);
3231 Args.eraseArg(options::OPT__SLASH_Fp);
3232 Args.eraseArg(options::OPT__SLASH_Yc);
3233 Args.eraseArg(options::OPT__SLASH_Yu);
3234 YcArg = YuArg =
nullptr;
3238 OffloadingActionBuilder OffloadBuilder(C, Args, Inputs);
3245 for (
auto &I : Inputs) {
3247 const Arg *InputArg = I.second;
3255 if (InitialPhase > FinalPhase) {
3256 if (InputArg->isClaimed())
3263 if (Args.hasArg(options::OPT_Qunused_arguments))
3269 Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
3270 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase);
3276 Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
3277 << InputArg->getAsString(Args) << !!FinalPhaseArg
3278 << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() :
"");
3280 Diag(clang::diag::warn_drv_input_file_unused)
3281 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase)
3283 << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() :
"");
3299 Actions.push_back(ClangClPch);
3313 if (OffloadBuilder.addHostDependenceToDeviceActions(Current, InputArg))
3321 if (Phase > FinalPhase)
3325 Current = OffloadBuilder.addDeviceDependencesToHostAction(
3326 Current, InputArg, Phase, FinalPhase, PL);
3332 assert((
i + 1) == e &&
"linking must be final compilation step.");
3333 LinkerInputs.push_back(Current);
3355 if (NewCurrent == Current)
3358 if (
auto *HMA = dyn_cast<HeaderModulePrecompileJobAction>(NewCurrent))
3359 HeaderModuleAction = HMA;
3361 Current = NewCurrent;
3365 if (OffloadBuilder.addHostDependenceToDeviceActions(Current, InputArg))
3368 if (Current->
getType() == types::TY_Nothing)
3374 Actions.push_back(Current);
3377 OffloadBuilder.appendTopLevelActions(Actions, Current, InputArg);
3381 if (!LinkerInputs.empty()) {
3383 LA = OffloadBuilder.processHostLinkAction(LA);
3384 Actions.push_back(LA);
3390 Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
3391 Args.ClaimAllArgs(options::OPT_cl_compile_Group);
3396 if (Arg *A = Args.getLastArg(options::OPT_print_supported_cpus)) {
3402 for (
auto &I : Inputs)
3407 Args.ClaimAllArgs(options::OPT_cl_ignored_Group);
3411 Args.ClaimAllArgs(options::OPT_cuda_host_only);
3412 Args.ClaimAllArgs(options::OPT_cuda_compile_host_device);
3418 llvm::PrettyStackTraceString CrashInfo(
"Constructing phase actions");
3429 llvm_unreachable(
"link action invalid here.");
3433 if (Args.hasArg(options::OPT_M, options::OPT_MM)) {
3434 OutputTy = types::TY_Dependencies;
3437 if (!Args.hasFlag(options::OPT_frewrite_includes,
3438 options::OPT_fno_rewrite_includes,
false) &&
3439 !Args.hasFlag(options::OPT_frewrite_imports,
3440 options::OPT_fno_rewrite_imports,
false) &&
3444 "Cannot preprocess this input type!");
3451 "Cannot precompile this input type!");
3455 const char *ModName =
nullptr;
3456 if (OutputTy == types::TY_PCH) {
3457 if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
3458 ModName = A->getValue();
3460 OutputTy = types::TY_ModuleFile;
3463 if (Args.hasArg(options::OPT_fsyntax_only)) {
3465 OutputTy = types::TY_Nothing;
3474 if (Args.hasArg(options::OPT_fsyntax_only))
3476 if (Args.hasArg(options::OPT_rewrite_objc))
3478 if (Args.hasArg(options::OPT_rewrite_legacy_objc))
3480 types::TY_RewrittenLegacyObjC);
3481 if (Args.hasArg(options::OPT__analyze, options::OPT__analyze_auto))
3483 if (Args.hasArg(options::OPT__migrate))
3485 if (Args.hasArg(options::OPT_emit_ast))
3487 if (Args.hasArg(options::OPT_module_file_info))
3489 if (Args.hasArg(options::OPT_verify_pch))
3491 if (Args.hasArg(options::OPT_emit_iterface_stubs))
3498 Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
3501 if (Args.hasArg(options::OPT_emit_llvm)) {
3503 Args.hasArg(options::OPT_S) ? types::TY_LLVM_IR : types::TY_LLVM_BC;
3512 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
3516 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
3518 Arg *FinalOutput = C.
getArgs().getLastArg(options::OPT_o);
3523 unsigned NumOutputs = 0;
3525 if (A->getType() != types::TY_Nothing)
3528 if (NumOutputs > 1) {
3529 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
3530 FinalOutput =
nullptr;
3535 llvm::StringSet<> ArchNames;
3537 for (
const Arg *A : C.
getArgs())
3538 if (A->getOption().matches(options::OPT_arch))
3539 ArchNames.insert(A->getValue());
3542 std::map<std::pair<const Action *, std::string>,
InputInfo> CachedResults;
3550 const char *LinkingOutput =
nullptr;
3551 if (isa<LipoJobAction>(A)) {
3553 LinkingOutput = FinalOutput->getValue();
3561 ArchNames.size() > 1,
3562 LinkingOutput, CachedResults,
3568 if (Diags.hasErrorOccurred() ||
3569 C.
getArgs().hasArg(options::OPT_Qunused_arguments))
3573 (void)C.
getArgs().hasArg(options::OPT__HASH_HASH_HASH);
3576 (void)C.
getArgs().hasArg(options::OPT_driver_mode);
3577 (void)C.
getArgs().hasArg(options::OPT_rsp_quoting);
3583 if (!A->isClaimed()) {
3589 const Option &Opt = A->getOption();
3590 if (Opt.getKind() == Option::FlagClass) {
3591 bool DuplicateClaimed =
false;
3593 for (
const Arg *AA : C.
getArgs().filtered(&Opt)) {
3594 if (AA->isClaimed()) {
3595 DuplicateClaimed =
true;
3600 if (DuplicateClaimed)
3606 if (!
IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN))
3607 Diag(clang::diag::warn_drv_unused_argument)
3608 << A->getAsString(C.
getArgs());
3616 class ToolSelector final {
3627 bool IsHostSelector;
3638 bool CanBeCollapsed =
true) {
3640 if (Inputs.size() != 1)
3643 Action *CurAction = *Inputs.begin();
3644 if (CanBeCollapsed &&
3650 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
3654 if (!IsHostSelector) {
3655 if (OA->hasSingleDeviceDependence(
true)) {
3657 OA->getSingleDeviceDependence(
true);
3658 if (CanBeCollapsed &&
3661 SavedOffloadAction.push_back(OA);
3664 }
else if (OA->hasHostDependence()) {
3665 CurAction = OA->getHostDependence();
3666 if (CanBeCollapsed &&
3669 SavedOffloadAction.push_back(OA);
3679 bool canCollapseAssembleAction()
const {
3680 return TC.useIntegratedAs() && !SaveTemps &&
3681 !C.
getArgs().hasArg(options::OPT_via_file_asm) &&
3682 !C.
getArgs().hasArg(options::OPT__SLASH_FA) &&
3683 !C.
getArgs().hasArg(options::OPT__SLASH_Fa);
3687 bool canCollapsePreprocessorAction()
const {
3688 return !C.
getArgs().hasArg(options::OPT_no_integrated_cpp) &&
3689 !C.
getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
3690 !C.
getArgs().hasArg(options::OPT_rewrite_objc);
3695 struct JobActionInfo final {
3705 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
3707 unsigned ElementNum) {
3708 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
3709 for (
unsigned I = 0; I < ElementNum; ++I)
3710 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
3711 ActionInfo[I].SavedOffloadAction.end());
3727 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
3732 if (!AJ || !BJ || !CJ)
3736 const Tool *T = TC.SelectTool(*CJ);
3743 const Tool *BT = TC.SelectTool(*BJ);
3751 Inputs = CJ->getInputs();
3752 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
3759 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
3768 auto *CJ = getPrevDependentAction(BJ->getInputs(), CompileJobOffloadActions,
3770 if (!AJ || !BJ || !CJ)
3773 assert(isa<CompileJobAction>(CJ) &&
3774 "Expecting compile job preceding backend job.");
3777 const Tool *T = TC.SelectTool(*CJ);
3784 Inputs = BJ->getInputs();
3785 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
3792 if (ActionInfo.size() < 2)
3804 bool InputIsBitcode =
true;
3805 for (
size_t i = 1;
i < ActionInfo.size();
i++)
3806 if (ActionInfo[
i].JA->getType() != types::TY_LLVM_BC &&
3807 ActionInfo[
i].JA->getType() != types::TY_LTO_BC) {
3808 InputIsBitcode =
false;
3811 if (!InputIsBitcode && !canCollapsePreprocessorAction())
3815 const Tool *T = TC.SelectTool(*CJ);
3819 if (T->
canEmitIR() && ((SaveTemps && !InputIsBitcode) || EmbedBitcode))
3822 Inputs = CJ->getInputs();
3823 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
3840 for (
Action *A : Inputs) {
3841 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
3842 if (!PJ || !isa<PreprocessJobAction>(PJ)) {
3843 NewInputs.push_back(A);
3849 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
3850 PreprocessJobOffloadActions.end());
3851 NewInputs.append(PJ->input_begin(), PJ->input_end());
3858 const Compilation &C,
bool SaveTemps,
bool EmbedBitcode)
3859 : TC(TC), C(C), BaseAction(BaseAction), SaveTemps(SaveTemps),
3860 EmbedBitcode(EmbedBitcode) {
3861 assert(BaseAction &&
"Invalid base action.");
3878 ActionChain.back().JA = BaseAction;
3879 while (ActionChain.back().JA) {
3880 const Action *CurAction = ActionChain.back().JA;
3883 ActionChain.resize(ActionChain.size() + 1);
3884 JobActionInfo &AI = ActionChain.back();
3888 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
3892 ActionChain.pop_back();
3900 const Tool *T = combineAssembleBackendCompile(ActionChain, Inputs,
3901 CollapsedOffloadAction);
3903 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
3905 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
3911 combineWithPreprocessor(T, Inputs, CollapsedOffloadAction);
3923 StringRef BoundArch,
3925 std::string TriplePlusArch = TC->
getTriple().normalize();
3926 if (!BoundArch.empty()) {
3927 TriplePlusArch +=
"-";
3928 TriplePlusArch += BoundArch;
3930 TriplePlusArch +=
"-";
3932 return TriplePlusArch;
3937 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
3938 std::map<std::pair<const Action *, std::string>,
InputInfo> &CachedResults,
3940 std::pair<const Action *, std::string> ActionTC = {
3942 auto CachedResult = CachedResults.find(ActionTC);
3943 if (CachedResult != CachedResults.end()) {
3944 return CachedResult->second;
3946 InputInfo Result = BuildJobsForActionNoCache(
3947 C, A, TC, BoundArch, AtTopLevel, MultipleArchs, LinkingOutput,
3948 CachedResults, TargetDeviceOffloadKind);
3949 CachedResults[ActionTC] = Result;
3953 InputInfo Driver::BuildJobsForActionNoCache(
3955 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
3956 std::map<std::pair<const Action *, std::string>,
InputInfo> &CachedResults,
3958 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
3961 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
3993 if (OA->hasSingleDeviceDependence()) {
3995 OA->doOnEachDeviceDependence([&](
Action *DepA,
const ToolChain *DepTC,
3996 const char *DepBoundArch) {
3999 !!DepBoundArch, LinkingOutput,
4009 OA->doOnEachDependence(
4010 BuildingForOffloadDevice,
4013 C, DepA, DepTC, DepBoundArch,
false,
4014 !!DepBoundArch, LinkingOutput, CachedResults,
4018 A = BuildingForOffloadDevice
4019 ? OA->getSingleDeviceDependence(
true)
4020 : OA->getHostDependence();
4023 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
4026 const Arg &Input = IA->getInputArg();
4028 if (Input.getOption().matches(options::OPT_INPUT)) {
4029 const char *
Name = Input.getValue();
4039 if (!ArchName.empty())
4040 TC = &getToolChain(C.
getArgs(),
4047 MultipleArchs, LinkingOutput, CachedResults,
4048 TargetDeviceOffloadKind);
4054 const JobAction *JA = cast<JobAction>(A);
4059 const Tool *T = TS.getTool(Inputs, CollapsedOffloadActions);
4066 for (
const auto *OA : CollapsedOffloadActions)
4067 cast<OffloadAction>(OA)->doOnEachDependence(
4068 BuildingForOffloadDevice,
4071 C, DepA, DepTC, DepBoundArch,
false,
4072 !!DepBoundArch, LinkingOutput, CachedResults,
4078 for (
const Action *Input : Inputs) {
4082 bool SubJobAtTopLevel =
4083 AtTopLevel && (isa<DsymutilJobAction>(A) || isa<VerifyJobAction>(A));
4085 C, Input, TC, BoundArch, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
4090 const char *BaseInput = InputInfos[0].getBaseInput();
4094 if (JA->
getType() == types::TY_dSYM)
4095 BaseInput = InputInfos[0].getFilename();
4098 if (
auto *ModuleJA = dyn_cast<HeaderModulePrecompileJobAction>(JA))
4099 BaseInput = ModuleJA->getModuleName();
4102 if (!OffloadDependencesInputInfo.empty())
4103 InputInfos.append(OffloadDependencesInputInfo.begin(),
4104 OffloadDependencesInputInfo.end());
4107 llvm::Triple EffectiveTriple;
4109 const ArgList &Args =
4111 if (InputInfos.size() != 1) {
4115 EffectiveTriple = llvm::Triple(
4123 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(JA)) {
4127 for (
auto &UI : UA->getDependentActionsInfo()) {
4129 "Unbundling with no offloading??");
4136 UI.DependentOffloadKind,
4137 UI.DependentToolChain->getTriple().normalize(),
4148 UnbundlingResults.push_back(CurI);
4157 Arch = UI.DependentBoundArch;
4162 UI.DependentOffloadKind)}] =
4168 std::pair<const Action *, std::string> ActionTC = {
4170 assert(CachedResults.find(ActionTC) != CachedResults.end() &&
4171 "Result does not exist??");
4172 Result = CachedResults[ActionTC];
4173 }
else if (JA->
getType() == types::TY_Nothing)
4183 AtTopLevel, MultipleArchs,
4190 <<
" - \"" << T->
getName() <<
"\", inputs: [";
4191 for (
unsigned i = 0, e = InputInfos.size();
i != e; ++
i) {
4192 llvm::errs() << InputInfos[
i].getAsString();
4194 llvm::errs() <<
", ";
4196 if (UnbundlingResults.empty())
4197 llvm::errs() <<
"], output: " << Result.
getAsString() <<
"\n";
4199 llvm::errs() <<
"], outputs: [";
4200 for (
unsigned i = 0, e = UnbundlingResults.size();
i != e; ++
i) {
4201 llvm::errs() << UnbundlingResults[
i].getAsString();
4203 llvm::errs() <<
", ";
4205 llvm::errs() <<
"] \n";
4208 if (UnbundlingResults.empty())
4210 C, *JA, Result, InputInfos,
4215 C, *JA, UnbundlingResults, InputInfos,
4224 return Target.isOSWindows() ?
"a.exe" :
"a.out";
4236 if (ArgValue.empty()) {
4238 Filename = BaseName;
4239 }
else if (llvm::sys::path::is_separator(Filename.back())) {
4241 llvm::sys::path::append(Filename, BaseName);
4244 if (!llvm::sys::path::has_extension(ArgValue)) {
4248 if (FileType == types::TY_Image &&
4249 Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
4254 llvm::sys::path::replace_extension(Filename, Extension);
4257 return Args.MakeArgString(Filename.c_str());
4261 const char *BaseInput,
4262 StringRef BoundArch,
bool AtTopLevel,
4264 StringRef OffloadingPrefix)
const {
4265 llvm::PrettyStackTraceString CrashInfo(
"Computing output path");
4267 if (AtTopLevel && !isa<DsymutilJobAction>(JA) && !isa<VerifyJobAction>(JA)) {
4268 if (Arg *FinalOutput = C.
getArgs().getLastArg(options::OPT_o))
4273 if (C.
getArgs().hasArg(options::OPT__SLASH_P)) {
4274 assert(AtTopLevel && isa<PreprocessJobAction>(JA));
4275 StringRef BaseName = llvm::sys::path::filename(BaseInput);
4277 if (Arg *A = C.
getArgs().getLastArg(options::OPT__SLASH_Fi))
4278 NameArg = A->getValue();
4289 if (JA.
getType() == types::TY_PP_Asm &&
4290 (C.
getArgs().hasArg(options::OPT__SLASH_FA) ||
4291 C.
getArgs().hasArg(options::OPT__SLASH_Fa))) {
4293 StringRef BaseName = llvm::sys::path::filename(BaseInput);
4294 StringRef FaValue = C.
getArgs().getLastArgValue(options::OPT__SLASH_Fa);
4302 !C.
getArgs().hasArg(options::OPT__SLASH_Fo)) ||
4304 StringRef
Name = llvm::sys::path::filename(BaseInput);
4305 std::pair<StringRef, StringRef>
Split = Name.split(
'.');
4308 Arg *A = C.
getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
4311 if (!
getVFS().exists(CrashDirectory))
4312 llvm::sys::fs::create_directories(CrashDirectory);
4313 llvm::sys::path::append(CrashDirectory, Split.first);
4314 const char *Middle = Suffix ?
"-%%%%%%." :
"-%%%%%%";
4315 std::error_code EC = llvm::sys::fs::createUniqueFile(
4316 CrashDirectory + Middle + Suffix, TmpName);
4318 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
4331 if (isa<DsymutilJobAction>(JA) || isa<VerifyJobAction>(JA))
4332 BaseName = BasePath;
4334 BaseName = llvm::sys::path::filename(BasePath);
4337 const char *NamedOutput;
4339 if ((JA.
getType() == types::TY_Object || JA.
getType() == types::TY_LTO_BC) &&
4340 C.
getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
4344 .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
4348 }
else if (JA.
getType() == types::TY_Image &&
4349 C.
getArgs().hasArg(options::OPT__SLASH_Fe,
4350 options::OPT__SLASH_o)) {
4354 .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)
4358 }
else if (JA.
getType() == types::TY_Image) {
4365 Output += OffloadingPrefix;
4366 if (MultipleArchs && !BoundArch.empty()) {
4368 Output.append(BoundArch);
4370 NamedOutput = C.
getArgs().MakeArgString(Output.c_str());
4376 assert(Suffix &&
"All types used for output should have a suffix.");
4378 std::string::size_type
End = std::string::npos;
4380 End = BaseName.rfind(
'.');
4382 Suffixed += OffloadingPrefix;
4383 if (MultipleArchs && !BoundArch.empty()) {
4385 Suffixed.append(BoundArch);
4390 if (!AtTopLevel && C.
getArgs().hasArg(options::OPT_emit_llvm) &&
4391 JA.
getType() == types::TY_LLVM_BC)
4395 NamedOutput = C.
getArgs().MakeArgString(Suffixed.c_str());
4400 JA.
getType() != types::TY_PCH) {
4401 Arg *FinalOutput = C.
getArgs().getLastArg(options::OPT_o);
4403 llvm::sys::path::remove_filename(TempPath);
4404 StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
4405 llvm::sys::path::append(TempPath, OutputFileName);
4406 NamedOutput = C.
getArgs().MakeArgString(TempPath.c_str());
4412 bool SameFile =
false;
4414 llvm::sys::fs::current_path(Result);
4415 llvm::sys::path::append(Result, BaseName);
4416 llvm::sys::fs::equivalent(BaseInput, Result.c_str(), SameFile);
4419 StringRef
Name = llvm::sys::path::filename(BaseInput);
4420 std::pair<StringRef, StringRef>
Split = Name.split(
'.');
4429 llvm::sys::path::remove_filename(BasePath);
4430 if (BasePath.empty())
4431 BasePath = NamedOutput;
4433 llvm::sys::path::append(BasePath, NamedOutput);
4446 for (
const auto &
Dir :
P) {
4450 llvm::sys::path::append(P, Name);
4451 if (llvm::sys::fs::exists(Twine(P)))
4452 return P.str().str();
4461 llvm::sys::path::append(R, Name);
4462 if (llvm::sys::fs::exists(Twine(R)))
4466 llvm::sys::path::append(
P, Name);
4467 if (llvm::sys::fs::exists(Twine(
P)))
4471 llvm::sys::path::append(D,
"..", Name);
4472 if (llvm::sys::fs::exists(Twine(D)))
4484 void Driver::generatePrefixedToolNames(
4488 Names.emplace_back((TargetTriple +
"-" +
Tool).str());
4489 Names.emplace_back(
Tool);
4492 std::string DefaultTargetTriple = llvm::sys::getDefaultTargetTriple();
4493 if (DefaultTargetTriple != TargetTriple)
4494 Names.emplace_back((DefaultTargetTriple +
"-" +
Tool).str());
4499 for (
const auto &
Name : Names) {
4500 llvm::sys::path::append(Dir,
Name);
4501 if (llvm::sys::fs::can_execute(Twine(Dir)))
4503 llvm::sys::path::remove_filename(Dir);
4510 generatePrefixedToolNames(Name, TC, TargetSpecificExecutables);
4515 if (llvm::sys::fs::is_directory(PrefixDir)) {
4521 if (llvm::sys::fs::can_execute(Twine(P)))
4527 for (
const auto &Path : List) {
4534 for (
const auto &TargetSpecificExecutable : TargetSpecificExecutables)
4535 if (llvm::ErrorOr<std::string>
P =
4536 llvm::sys::findProgramByName(TargetSpecificExecutable))
4544 std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path);
4546 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
4555 std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix, Path);
4557 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
4566 if (Arg *FpArg = C.
getArgs().getLastArg(options::OPT__SLASH_Fp)) {
4570 Output = FpArg->getValue();
4574 if (!llvm::sys::path::has_extension(Output))
4577 if (Arg *YcArg = C.
getArgs().getLastArg(options::OPT__SLASH_Yc))
4578 Output = YcArg->getValue();
4581 llvm::sys::path::replace_extension(Output,
".pch");
4583 return Output.str();
4586 const ToolChain &Driver::getToolChain(
const ArgList &Args,
4587 const llvm::Triple &
Target)
const {
4589 auto &TC = ToolChains[Target.str()];
4591 switch (Target.getOS()) {
4592 case llvm::Triple::Haiku:
4593 TC = llvm::make_unique<toolchains::Haiku>(*
this, Target, Args);
4595 case llvm::Triple::Ananas:
4596 TC = llvm::make_unique<toolchains::Ananas>(*
this, Target, Args);
4598 case llvm::Triple::CloudABI:
4599 TC = llvm::make_unique<toolchains::CloudABI>(*
this, Target, Args);
4601 case llvm::Triple::Darwin:
4602 case llvm::Triple::MacOSX:
4603 case llvm::Triple::IOS:
4604 case llvm::Triple::TvOS:
4605 case llvm::Triple::WatchOS:
4606 TC = llvm::make_unique<toolchains::DarwinClang>(*
this, Target, Args);
4608 case llvm::Triple::DragonFly:
4609 TC = llvm::make_unique<toolchains::DragonFly>(*
this, Target, Args);
4611 case llvm::Triple::OpenBSD:
4612 TC = llvm::make_unique<toolchains::OpenBSD>(*
this, Target, Args);
4614 case llvm::Triple::NetBSD:
4615 TC = llvm::make_unique<toolchains::NetBSD>(*
this, Target, Args);
4617 case llvm::Triple::FreeBSD:
4618 TC = llvm::make_unique<toolchains::FreeBSD>(*
this, Target, Args);
4620 case llvm::Triple::Minix:
4621 TC = llvm::make_unique<toolchains::Minix>(*
this, Target, Args);
4623 case llvm::Triple::Linux:
4624 case llvm::Triple::ELFIAMCU:
4625 if (Target.getArch() == llvm::Triple::hexagon)
4626 TC = llvm::make_unique<toolchains::HexagonToolChain>(*
this, Target,
4628 else if ((Target.getVendor() == llvm::Triple::MipsTechnologies) &&
4629 !Target.hasEnvironment())
4630 TC = llvm::make_unique<toolchains::MipsLLVMToolChain>(*
this, Target,
4632 else if (Target.getArch() == llvm::Triple::ppc ||
4633 Target.getArch() == llvm::Triple::ppc64 ||
4634 Target.getArch() == llvm::Triple::ppc64le)
4635 TC = llvm::make_unique<toolchains::PPCLinuxToolChain>(*
this, Target,
4638 TC = llvm::make_unique<toolchains::Linux>(*
this, Target, Args);
4640 case llvm::Triple::NaCl:
4641 TC = llvm::make_unique<toolchains::NaClToolChain>(*
this, Target, Args);
4643 case llvm::Triple::Fuchsia:
4644 TC = llvm::make_unique<toolchains::Fuchsia>(*
this, Target, Args);
4646 case llvm::Triple::Solaris:
4647 TC = llvm::make_unique<toolchains::Solaris>(*
this, Target, Args);
4649 case llvm::Triple::AMDHSA:
4650 case llvm::Triple::AMDPAL:
4651 case llvm::Triple::Mesa3D:
4652 TC = llvm::make_unique<toolchains::AMDGPUToolChain>(*
this, Target, Args);
4654 case llvm::Triple::Win32:
4655 switch (Target.getEnvironment()) {
4657 if (Target.isOSBinFormatELF())
4658 TC = llvm::make_unique<toolchains::Generic_ELF>(*
this, Target, Args);
4659 else if (Target.isOSBinFormatMachO())
4660 TC = llvm::make_unique<toolchains::MachO>(*
this, Target, Args);
4662 TC = llvm::make_unique<toolchains::Generic_GCC>(*
this, Target, Args);
4664 case llvm::Triple::GNU:
4665 TC = llvm::make_unique<toolchains::MinGW>(*
this, Target, Args);
4667 case llvm::Triple::Itanium:
4668 TC = llvm::make_unique<toolchains::CrossWindowsToolChain>(*
this, Target,
4671 case llvm::Triple::MSVC:
4672 case llvm::Triple::UnknownEnvironment:
4673 if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
4674 .startswith_lower(
"bfd"))
4675 TC = llvm::make_unique<toolchains::CrossWindowsToolChain>(
4676 *
this, Target, Args);
4679 llvm::make_unique<toolchains::MSVCToolChain>(*
this, Target, Args);
4683 case llvm::Triple::PS4:
4684 TC = llvm::make_unique<toolchains::PS4CPU>(*
this, Target, Args);
4686 case llvm::Triple::Contiki:
4687 TC = llvm::make_unique<toolchains::Contiki>(*
this, Target, Args);
4689 case llvm::Triple::Hurd:
4690 TC = llvm::make_unique<toolchains::Hurd>(*
this, Target, Args);
4695 switch (Target.getArch()) {
4696 case llvm::Triple::tce:
4697 TC = llvm::make_unique<toolchains::TCEToolChain>(*
this, Target, Args);
4699 case llvm::Triple::tcele:
4700 TC = llvm::make_unique<toolchains::TCELEToolChain>(*
this, Target, Args);
4702 case llvm::Triple::hexagon:
4703 TC = llvm::make_unique<toolchains::HexagonToolChain>(*
this, Target,
4706 case llvm::Triple::lanai:
4707 TC = llvm::make_unique<toolchains::LanaiToolChain>(*
this, Target, Args);
4709 case llvm::Triple::xcore:
4710 TC = llvm::make_unique<toolchains::XCoreToolChain>(*
this, Target, Args);
4712 case llvm::Triple::wasm32:
4713 case llvm::Triple::wasm64:
4714 TC = llvm::make_unique<toolchains::WebAssembly>(*
this, Target, Args);
4716 case llvm::Triple::avr:
4717 TC = llvm::make_unique<toolchains::AVRToolChain>(*
this, Target, Args);
4719 case llvm::Triple::msp430:
4721 llvm::make_unique<toolchains::MSP430ToolChain>(*
this, Target, Args);
4723 case llvm::Triple::riscv32:
4724 case llvm::Triple::riscv64:
4725 TC = llvm::make_unique<toolchains::RISCVToolChain>(*
this, Target, Args);
4728 if (Target.getVendor() == llvm::Triple::Myriad)
4729 TC = llvm::make_unique<toolchains::MyriadToolChain>(*
this, Target,
4732 TC = llvm::make_unique<toolchains::BareMetal>(*
this, Target, Args);
4733 else if (Target.isOSBinFormatELF())
4734 TC = llvm::make_unique<toolchains::Generic_ELF>(*
this, Target, Args);
4735 else if (Target.isOSBinFormatMachO())
4736 TC = llvm::make_unique<toolchains::MachO>(*
this, Target, Args);
4738 TC = llvm::make_unique<toolchains::Generic_GCC>(*
this, Target, Args);
4753 if (JA.
size() != 1 ||
4758 if (!isa<PreprocessJobAction>(JA) && !isa<PrecompileJobAction>(JA) &&
4759 !isa<CompileJobAction>(JA) && !isa<BackendJobAction>(JA))
4771 unsigned &Micro,
bool &HadExtra) {
4774 Major = Minor = Micro = 0;
4778 if (Str.consumeInteger(10, Major))
4785 Str = Str.drop_front(1);
4787 if (Str.consumeInteger(10, Minor))
4793 Str = Str.drop_front(1);
4795 if (Str.consumeInteger(10, Micro))
4813 unsigned CurDigit = 0;
4814 while (CurDigit < Digits.size()) {
4816 if (Str.consumeInteger(10, Digit))
4818 Digits[CurDigit] = Digit;
4823 Str = Str.drop_front(1);
4831 std::pair<unsigned, unsigned>
4832 Driver::getIncludeExcludeOptionFlagMasks(
bool IsClCompatMode)
const {
4833 unsigned IncludedFlagsBitmask = 0;
4836 if (IsClCompatMode) {
4844 return std::make_pair(IncludedFlagsBitmask, ExcludedFlagsBitmask);
4848 return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group,
false);
StringRef getSysRoot() const
Returns the sysroot path.
static bool GetReleaseVersion(StringRef Str, unsigned &Major, unsigned &Minor, unsigned &Micro, bool &HadExtra)
GetReleaseVersion - Parse (([0-9]+)(.
ID
ID - Ordered values for successive stages in the compilation process which interact with user options...
static bool ContainsCompileOrAssembleAction(const Action *A)
Check whether the given input tree contains any compilation or assembly actions.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
bool isCollapsingWithNextDependentActionLegal() const
Return true if this function can be collapsed with others.
const llvm::opt::ArgStringList & getTempFiles() const
std::string ModeSuffix
Driver mode part of the executable name, as g++.
const char * CudaArchToString(CudaArch A)
OpenMPRuntimeKind getOpenMPRuntime(const llvm::opt::ArgList &Args) const
Compute the desired OpenMP runtime from the flags provided.
std::string getClangFullVersion()
Retrieves a string representing the complete clang version, which includes the clang version number...
std::string GetTemporaryPath(StringRef Prefix, StringRef Suffix) const
GetTemporaryPath - Return the pathname of a temporary file to use as part of compilation; the file wi...
T * MakeAction(Args &&... Arg)
Creates a new Action owned by this Compilation.
bool canLipoType(ID Id)
canLipoType - Is this type acceptable as the output of a universal build (currently, just the Nothing, Image, and Object types).
Set a ToolChain's effective triple.
const char * getTypeTempSuffix(ID Id, bool CLMode=false)
getTypeTempSuffix - Return the suffix to use when creating a temp file of this type, or null if unspecified.
void BuildInputs(const ToolChain &TC, llvm::opt::DerivedArgList &Args, InputList &Inputs) const
BuildInputs - Construct the list of inputs and their types from the given arguments.
void setResponseFile(const char *FileName)
Set to pass arguments via a response file when launching the command.
bool isUsingLTO() const
Returns true if we are performing any kind of LTO.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
std::string GetProgramPath(StringRef Name, const ToolChain &TC) const
GetProgramPath - Lookup Name in the list of program search paths.
std::string DyldPrefix
Dynamic loader prefix, if present.
static StringRef getCategoryNameFromID(unsigned CategoryID)
Given a category ID, return the name of the category.
DiagnosticBuilder Diag(unsigned DiagID) const
InputInfo BuildJobsForAction(Compilation &C, const Action *A, const ToolChain *TC, StringRef BoundArch, bool AtTopLevel, bool MultipleArchs, const char *LinkingOutput, std::map< std::pair< const Action *, std::string >, InputInfo > &CachedResults, Action::OffloadKind TargetDeviceOffloadKind) const
BuildJobsForAction - Construct the jobs to perform for the action A and return an InputInfo for the r...
CudaArch StringToCudaArch(llvm::StringRef S)
Type used to communicate device actions.
const char * getClassName() const
RAII class that determines when any errors have occurred between the time the instance was created an...
void registerDependentActionInfo(const ToolChain *TC, StringRef BoundArch, OffloadKind Kind)
Register information about a dependent action.
const ArgStringMap & getFailureResultFiles() const
float __ovld __cnfn normalize(float p)
Returns a vector in the same direction as p but with a length of 1.
const llvm::opt::DerivedArgList & getArgsForToolChain(const ToolChain *TC, StringRef BoundArch, Action::OffloadKind DeviceOffloadKind)
getArgsForToolChain - Return the derived argument list for the tool chain TC (or the default tool cha...
void addOffloadDeviceToolChain(const ToolChain *DeviceToolChain, Action::OffloadKind OffloadKind)
Compilation * BuildCompilation(ArrayRef< const char *> Args)
BuildCompilation - Construct a compilation object for a command line argument vector.
std::string TargetPrefix
Target part of the executable name, as i686-linux-android.
Contains the files in the compilation diagnostic report generated by generateCompilationDiagnostics.
static bool ScanDirForExecutable(SmallString< 128 > &Dir, ArrayRef< std::string > Names)
std::string Dir
The path the driver executable was in, as invoked from the command line.
ID lookupCXXTypeForCType(ID Id)
lookupCXXTypeForCType - Lookup CXX input type that corresponds to given C type (used for clang++ emul...
__DEVICE__ int max(int __a, int __b)
const std::string & gccSuffix() const
Get the detected GCC installation path suffix for the multi-arch target variant.
Type used to communicate host actions.
static unsigned getNumberOfCategories()
Return the number of diagnostic categories.
std::string GetClPchPath(Compilation &C, StringRef BaseName) const
Return the pathname of the pch file in clang-cl mode.
Action - Represent an abstract compilation step to perform.
bool HandleImmediateArgs(const Compilation &C)
HandleImmediateArgs - Handle any arguments which should be treated before building actions or binding...
Concrete class used by the front-end to report problems and issues.
types::ID getType() const
bool isOptimizationLevelFast(const llvm::opt::ArgList &Args)
OffloadKind getOffloadingDeviceKind() const
std::unique_ptr< llvm::opt::OptTable > createDriverOptTable()
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
An unknown OpenMP runtime.
const llvm::opt::InputArgList & getInputArgs() const
input_iterator input_begin()
llvm::vfs::FileSystem & getVFS() const
bool isHIP(ID Id)
isHIP - Is this a HIP input.
static Arg * MakeInputArg(DerivedArgList &Args, OptTable &Opts, StringRef Value, bool Claim=true)
bool hasOffloadToolChain() const
Return true if an offloading tool chain of a given kind exists.
ID getPreprocessedType(ID Id)
getPreprocessedType - Get the ID of the type for this input when it has been preprocessed, or INVALID if this input is not preprocessed.
void add(Action &A, const ToolChain &TC, const char *BoundArch, OffloadKind OKind)
Add a action along with the associated toolchain, bound arch, and offload kind.
void PrintActions(const Compilation &C) const
PrintActions - Print the list of actions.
const ToolChain & getDefaultToolChain() const
const ArgStringMap & getResultFiles() const
unsigned GenReproducer
Force clang to emit reproducer for driver invocation.
ID lookupHeaderTypeForSourceType(ID Id)
Lookup header file input type that corresponds to given source file type (used for clang-cl emulation...
const char * getTypeName(ID Id)
getTypeName - Return the name of the type for Id.
ActionClass getKind() const
std::string GetTemporaryDirectory(StringRef Prefix) const
GetTemporaryDirectory - Return the pathname of a temporary directory to use as part of compilation; t...
const char * getPhaseName(ID Id)
const Tool & getCreator() const
getCreator - Return the Tool which caused the creation of this job.
bool isSaveTempsObj() const
Defines version macros and version-related utility functions for Clang.
bool IsCLMode() const
Whether the driver should follow cl.exe like behavior.
static std::string GetResourcesPath(StringRef BinaryPath, StringRef CustomResourceDir="")
Takes the path to a binary that's either in bin/ or lib/ and returns the path to clang's resource dir...
llvm::opt::InputArgList ParseArgStrings(ArrayRef< const char *> Args, bool IsClCompatMode, bool &ContainsError)
ParseArgStrings - Parse the given list of strings into an ArgList.
This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag...
static std::string GetTriplePlusArchString(const ToolChain *TC, StringRef BoundArch, Action::OffloadKind OffloadKind)
Return a string that uniquely identifies the result of a job.
void HandleAutocompletions(StringRef PassedFlags) const
HandleAutocompletions - Handle –autocomplete by searching and printing possible flags, descriptions, and its arguments.
void getCompilationPhases(ID Id, llvm::SmallVectorImpl< phases::ID > &Phases)
getCompilationPhases - Get the list of compilation phases ('Phases') to be done for type 'Id'...
void BuildUniversalActions(Compilation &C, const ToolChain &TC, const InputList &BAInputs) const
BuildUniversalActions - Construct the list of actions to perform for the given arguments, which may require a universal build.
void setCannotBeCollapsedWithNextDependentAction()
Mark this action as not legal to collapse.
Action * ConstructPhaseAction(Compilation &C, const llvm::opt::ArgList &Args, phases::ID Phase, Action *Input, Action::OffloadKind TargetDeviceOffloadKind=Action::OFK_None) const
ConstructAction - Construct the appropriate action to do for Phase on the Input, taking in to account...
const ActionList & getActions() const
Get each of the individual arrays.
const_offload_toolchains_range getOffloadToolChains() const
static void PrintDiagnosticCategories(raw_ostream &OS)
PrintDiagnosticCategories - Implement the –print-diagnostic-categories option.
void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote, CrashReportInfo *CrashInfo=nullptr) const
void PrintHelp(bool ShowHidden) const
PrintHelp - Print the help text.
static void printArg(llvm::raw_ostream &OS, StringRef Arg, bool Quote)
Print a command argument, and optionally quote it.
void generateCompilationDiagnostics(Compilation &C, const Command &FailingCommand, StringRef AdditionalInformation="", CompilationDiagnosticReport *GeneratedReport=nullptr)
generateCompilationDiagnostics - Generate diagnostics information including preprocessed source file(...
static unsigned PrintActions1(const Compilation &C, Action *A, std::map< Action *, unsigned > &Ids)
bool embedBitcodeInObject() const
Encodes a location in the source.
const llvm::opt::DerivedArgList & getArgs() const
bool hasErrorOccurred() const
Determine whether any errors have occurred since this object instance was created.
Command - An executable path/name and argument vector to execute.
bool isCuda(ID Id)
isCuda - Is this a CUDA input.
bool DiagnoseInputExistence(const llvm::opt::DerivedArgList &Args, StringRef Value, types::ID Ty, bool TypoCorrect) const
Check that the file referenced by Value exists.
The legacy name for the LLVM OpenMP runtime from when it was the Intel OpenMP runtime.
std::string InstalledDir
The path to the installed clang directory, if any.
bool CCCIsCXX() const
Whether the driver should follow g++ like behavior.
const char * addResultFile(const char *Name, const JobAction *JA)
addResultFile - Add a file to remove on failure, and returns its argument.
bool isSaveTempsEnabled() const
static std::vector< std::string > getDiagnosticFlags()
Get the string of all diagnostic flags.
std::string UserConfigDir
User directory for config files.
bool isAcceptedByClang(ID Id)
isAcceptedByClang - Can clang handle this input type.
An offload action combines host or/and device actions according to the programming model implementati...
const char * getDefaultImageName() const
Returns the default name for linked images (e.g., "a.out").
void ExecuteJobs(const JobList &Jobs, SmallVectorImpl< std::pair< int, const Command *>> &FailingCommands) const
ExecuteJob - Execute a single job.
void setIgnoreAllWarnings(bool Val)
When set to true, any unmapped warnings are ignored.
static bool searchForFile(SmallVectorImpl< char > &FilePath, ArrayRef< std::string > Dirs, StringRef FileName)
Looks the given directories for the specified file.
unsigned getOffloadingHostActiveKinds() const
void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts, llvm::MemoryBufferRef Buf)
const Action & getSource() const
getSource - Return the Action which caused the creation of this job.
Dataflow Directional Tag Classes.
Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc) const
Based on the way the client configured the DiagnosticsEngine object, classify the specified diagnosti...
const char * getExecutable() const
unsigned CCCPrintBindings
Only print tool bindings, don't build any jobs.
static llvm::Triple computeTargetTriple(const Driver &D, StringRef TargetTriple, const ArgList &Args, StringRef DarwinArchName="")
Compute target triple from args.
const llvm::opt::ArgStringList & getArguments() const
std::string SysRoot
sysroot, if present
std::string Name
The name the driver was invoked as.
llvm::SmallVector< std::string, 4 > TemporaryFiles
int ExecuteCompilation(Compilation &C, SmallVectorImpl< std::pair< int, const Command *> > &FailingCommands)
ExecuteCompilation - Execute the compilation according to the command line arguments and return an ap...
ActionList & getActions()
ParsedClangName ClangNameParts
Target and driver mode components extracted from clang executable name.
bool getCheckInputsExist() const
std::string ClangExecutable
The original path to the clang executable.
void BuildJobs(Compilation &C) const
BuildJobs - Bind actions to concrete tools and translate arguments to form the list of jobs to run...
ID getPrecompiledType(ID Id)
getPrecompiledType - Get the ID of the type for this input when it has been precompiled, or INVALID if this input is not precompiled.
bool ShouldUseClangCompiler(const JobAction &JA) const
ShouldUseClangCompiler - Should the clang compiler be used to handle this action. ...
Compilation - A set of tasks to perform for a single driver invocation.
void BuildActions(Compilation &C, llvm::opt::DerivedArgList &Args, const InputList &Inputs, ActionList &Actions) const
BuildActions - Construct the list of actions to perform for the given arguments, which are only done ...
const Driver & getDriver() const
static StringRef GetOffloadKindName(OffloadKind Kind)
Return a string containing a offload kind name.
std::string GetFilePath(StringRef Name, const ToolChain &TC) const
GetFilePath - Lookup Name in the list of file search paths.
static void printArgList(raw_ostream &OS, const llvm::opt::ArgList &Args)
ID lookupTypeForExtension(llvm::StringRef Ext)
lookupTypeForExtension - Lookup the type to use for the file extension Ext.
bool CleanupFileMap(const ArgStringMap &Files, const JobAction *JA, bool IssueErrors=false) const
CleanupFileMap - Remove the files in the given map.
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
Driver(StringRef ClangExecutable, StringRef TargetTriple, DiagnosticsEngine &Diags, IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS=nullptr)
void propagateHostOffloadInfo(unsigned OKinds, const char *OArch)
Append the host offload info of this action and propagate it to its dependences.
static std::string GetOffloadingFileNamePrefix(OffloadKind Kind, StringRef NormalizedTriple, bool CreatePrefixForHost=false)
Return a string that can be used as prefix in order to generate unique files for each offloading kind...
void ParseDriverMode(StringRef ProgramName, ArrayRef< const char *> Args)
ParseDriverMode - Look for and handle the driver mode option in Args.
const llvm::opt::OptTable & getOpts() const
const char * addTempFile(const char *Name)
addTempFile - Add a file to remove on exit, and returns its argument.
std::string getOffloadingKindPrefix() const
Return a string containing the offload kind of the action.
const ToolChain * getSingleOffloadToolChain() const
Return an offload toolchain of the provided kind.
std::string DriverTitle
Driver title to use with help.
static const char * MakeCLOutputFilename(const ArgList &Args, StringRef ArgValue, StringRef BaseName, types::ID FileType)
Create output filename based on ArgValue, which could either be a full filename, filename without ext...
void initialize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)
bool CCCIsCPP() const
Whether the driver is just the preprocessor.
void PrintVersion(const Compilation &C, raw_ostream &OS) const
PrintVersion - Print the driver version.
void CreateOffloadingDeviceToolChains(Compilation &C, InputList &Inputs)
CreateOffloadingDeviceToolChains - create all the toolchains required to support offloading devices g...
bool appendSuffixForType(ID Id)
appendSuffixForType - When generating outputs of this type, should the suffix be appended (instead of...
ID lookupTypeForTypeSpecifier(const char *Name)
lookupTypeForTypSpecifier - Lookup the type to use for a user specified type name.
const char * GetNamedOutputPath(Compilation &C, const JobAction &JA, const char *BaseInput, StringRef BoundArch, bool AtTopLevel, bool MultipleArchs, StringRef NormalizedTriple) const
GetNamedOutputPath - Return the name to use for the output of the action JA.
void initCompilationForDiagnostics()
initCompilationForDiagnostics - Remove stale state and suppress output so compilation can be reexecut...
bool isSrcFile(ID Id)
isSrcFile - Is this a source file, i.e.
const char * DriverMode
Corresponding driver mode argument, as '–driver-mode=g++'.
const char * getOffloadingArch() const
virtual void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote, CrashReportInfo *CrashInfo=nullptr) const
unsigned CCGenDiagnostics
Whether the driver is generating diagnostics for debugging purposes.
std::string SystemConfigDir
System directory for config files.
std::string ResourceDir
The path to the compiler resource directory.