49 #include "clang/Config/config.h" 58 #include "llvm/ADT/ArrayRef.h" 59 #include "llvm/ADT/STLExtras.h" 60 #include "llvm/ADT/SmallSet.h" 61 #include "llvm/ADT/StringExtras.h" 62 #include "llvm/ADT/StringSet.h" 63 #include "llvm/ADT/StringSwitch.h" 64 #include "llvm/Config/llvm-config.h" 65 #include "llvm/Option/Arg.h" 66 #include "llvm/Option/ArgList.h" 67 #include "llvm/Option/OptSpecifier.h" 68 #include "llvm/Option/OptTable.h" 69 #include "llvm/Option/Option.h" 70 #include "llvm/Support/CommandLine.h" 71 #include "llvm/Support/ErrorHandling.h" 72 #include "llvm/Support/FileSystem.h" 73 #include "llvm/Support/FormatVariadic.h" 74 #include "llvm/Support/Path.h" 75 #include "llvm/Support/PrettyStackTrace.h" 76 #include "llvm/Support/Process.h" 77 #include "llvm/Support/Program.h" 78 #include "llvm/Support/StringSaver.h" 79 #include "llvm/Support/TargetRegistry.h" 80 #include "llvm/Support/VirtualFileSystem.h" 81 #include "llvm/Support/raw_ostream.h" 91 using namespace clang;
96 StringRef CustomResourceDir) {
102 std::string Dir = llvm::sys::path::parent_path(BinaryPath);
105 if (CustomResourceDir !=
"") {
106 llvm::sys::path::append(P, CustomResourceDir);
113 P = llvm::sys::path::parent_path(Dir);
114 llvm::sys::path::append(P, Twine(
"lib") + CLANG_LIBDIR_SUFFIX,
"clang",
115 CLANG_VERSION_STRING);
124 : Diags(Diags), VFS(
std::move(VFS)), Mode(GCCMode),
125 SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone), LTOMode(
LTOK_None),
126 ClangExecutable(ClangExecutable), SysRoot(DEFAULT_SYSROOT),
127 DriverTitle(
"clang LLVM compiler"), CCPrintOptionsFilename(nullptr),
128 CCPrintHeadersFilename(nullptr), CCLogDiagnosticsFilename(nullptr),
130 CCLogDiagnostics(
false), CCGenDiagnostics(
false),
131 TargetTriple(TargetTriple), CCCGenericGCCName(
""), Saver(Alloc),
132 CheckInputsExist(
true), GenReproducer(
false),
133 SuppressMissingInputWarning(
false) {
137 this->VFS = llvm::vfs::getRealFileSystem();
139 Name = llvm::sys::path::filename(ClangExecutable);
140 Dir = llvm::sys::path::parent_path(ClangExecutable);
143 #if defined(CLANG_CONFIG_FILE_SYSTEM_DIR) 146 #if defined(CLANG_CONFIG_FILE_USER_DIR) 160 for (
const char *ArgPtr : Args) {
162 if (ArgPtr ==
nullptr)
164 const StringRef Arg = ArgPtr;
165 setDriverModeFromOption(Arg);
169 void Driver::setDriverModeFromOption(StringRef Opt) {
170 const std::string OptName =
171 getOpts().getOption(options::OPT_driver_mode).getPrefixedName();
172 if (!Opt.startswith(OptName))
174 StringRef
Value = Opt.drop_front(OptName.size());
177 .Case(
"gcc", GCCMode)
178 .Case(
"g++", GXXMode)
179 .Case(
"cpp", CPPMode)
181 .Case(
"flang", FlangMode)
185 Diag(diag::err_drv_unsupported_option_argument) << OptName <<
Value;
190 bool &ContainsError) {
191 llvm::PrettyStackTraceString CrashInfo(
"Command line argument parsing");
192 ContainsError =
false;
194 unsigned IncludedFlagsBitmask;
195 unsigned ExcludedFlagsBitmask;
196 std::tie(IncludedFlagsBitmask, ExcludedFlagsBitmask) =
197 getIncludeExcludeOptionFlagMasks(IsClCompatMode);
199 unsigned MissingArgIndex, MissingArgCount;
201 getOpts().ParseArgs(ArgStrings, MissingArgIndex, MissingArgCount,
202 IncludedFlagsBitmask, ExcludedFlagsBitmask);
205 if (MissingArgCount) {
206 Diag(diag::err_drv_missing_argument)
207 << Args.getArgString(MissingArgIndex) << MissingArgCount;
214 for (
const Arg *A : Args) {
217 auto ArgString = A->getAsString(Args);
220 ArgString, Nearest, IncludedFlagsBitmask,
222 DiagID = diag::err_drv_unsupported_opt;
223 Diag(DiagID) << ArgString;
225 DiagID = diag::err_drv_unsupported_opt_with_suggestion;
226 Diag(DiagID) << ArgString << Nearest;
234 if (A->getOption().matches(options::OPT_mcpu_EQ) && A->containsValue(
"")) {
235 Diag(diag::warn_drv_empty_joined_argument) << A->getAsString(Args);
237 diag::warn_drv_empty_joined_argument,
242 for (
const Arg *A : Args.filtered(options::OPT_UNKNOWN)) {
244 auto ArgString = A->getAsString(Args);
247 ArgString, Nearest, IncludedFlagsBitmask, ExcludedFlagsBitmask) > 1) {
248 DiagID =
IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl
249 : diag::err_drv_unknown_argument;
250 Diags.
Report(DiagID) << ArgString;
253 ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion
254 : diag::err_drv_unknown_argument_with_suggestion;
255 Diags.
Report(DiagID) << ArgString << Nearest;
267 phases::ID Driver::getFinalPhase(
const DerivedArgList &DAL,
268 Arg **FinalPhaseArg)
const {
269 Arg *PhaseArg =
nullptr;
273 if (
CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) ||
274 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) ||
275 (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) ||
276 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P))) {
280 }
else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile))) {
284 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
285 (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
286 (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
287 (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
288 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
289 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
290 (PhaseArg = DAL.getLastArg(options::OPT__migrate)) ||
291 (PhaseArg = DAL.getLastArg(options::OPT__analyze)) ||
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 const llvm::opt::OptTable &Opts =
getOpts();
325 DerivedArgList *DAL =
new DerivedArgList(Args);
327 bool HasNostdlib = Args.hasArg(options::OPT_nostdlib);
328 bool HasNostdlibxx = Args.hasArg(options::OPT_nostdlibxx);
329 bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs);
330 for (Arg *A : Args) {
337 if ((A->getOption().matches(options::OPT_Wl_COMMA) ||
338 A->getOption().matches(options::OPT_Xlinker)) &&
339 A->containsValue(
"--no-demangle")) {
341 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_Xlinker__no_demangle));
344 for (StringRef Val : A->getValues())
345 if (Val !=
"--no-demangle")
346 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_Xlinker), Val);
354 if (A->getOption().matches(options::OPT_Wp_COMMA) &&
355 (A->getValue(0) == StringRef(
"-MD") ||
356 A->getValue(0) == StringRef(
"-MMD"))) {
358 if (A->getValue(0) == StringRef(
"-MD"))
359 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MD));
361 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MMD));
362 if (A->getNumValues() == 2)
363 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue(1));
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);
542 A = Args.getLastArg(options::OPT_march_EQ);
543 if (A && Target.isRISCV()) {
544 StringRef ArchName = A->getValue();
545 if (ArchName.startswith_lower(
"rv32"))
546 Target.setArch(llvm::Triple::riscv32);
547 else if (ArchName.startswith_lower(
"rv64"))
548 Target.setArch(llvm::Triple::riscv64);
556 void Driver::setLTOMode(
const llvm::opt::ArgList &Args) {
558 if (!Args.hasFlag(options::OPT_flto, options::OPT_flto_EQ,
559 options::OPT_fno_lto,
false))
562 StringRef LTOName(
"full");
564 const Arg *A = Args.getLastArg(options::OPT_flto_EQ);
566 LTOName = A->getValue();
568 LTOMode = llvm::StringSwitch<LTOKind>(LTOName)
575 Diag(diag::err_drv_unsupported_option_argument) << A->getOption().getName()
582 StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
584 const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
586 RuntimeName = A->getValue();
588 auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
596 Diag(diag::err_drv_unsupported_option_argument)
597 << A->getOption().getName() << A->getValue();
600 Diag(diag::err_drv_unsupported_opt) <<
"-fopenmp";
615 llvm::any_of(Inputs, [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
620 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
624 if (IsCuda && IsHIP) {
625 Diag(clang::diag::err_drv_mix_cuda_hip);
630 const llvm::Triple &HostTriple = HostTC->
getTriple();
631 StringRef DeviceTripleStr;
634 HostTriple.isArch64Bit() ?
"nvptx64-nvidia-cuda" :
"nvptx-nvidia-cuda";
635 llvm::Triple CudaTriple(DeviceTripleStr);
638 auto &CudaTC = ToolChains[CudaTriple.str() +
"/" + HostTriple.str()];
640 CudaTC = std::make_unique<toolchains::CudaToolChain>(
646 const llvm::Triple &HostTriple = HostTC->
getTriple();
647 StringRef DeviceTripleStr;
649 DeviceTripleStr =
"amdgcn-amd-amdhsa";
650 llvm::Triple HIPTriple(DeviceTripleStr);
653 auto &HIPTC = ToolChains[HIPTriple.str() +
"/" + HostTriple.str()];
655 HIPTC = std::make_unique<toolchains::HIPToolChain>(
666 if (Arg *OpenMPTargets =
667 C.
getInputArgs().getLastArg(options::OPT_fopenmp_targets_EQ)) {
668 if (OpenMPTargets->getNumValues()) {
673 options::OPT_fopenmp, options::OPT_fopenmp_EQ,
674 options::OPT_fno_openmp,
false);
675 if (HasValidOpenMPRuntime) {
677 HasValidOpenMPRuntime =
681 if (HasValidOpenMPRuntime) {
682 llvm::StringMap<const char *> FoundNormalizedTriples;
683 for (
const char *Val : OpenMPTargets->getValues()) {
684 llvm::Triple TT(Val);
685 std::string NormalizedName = TT.normalize();
688 auto Duplicate = FoundNormalizedTriples.find(NormalizedName);
689 if (Duplicate != FoundNormalizedTriples.end()) {
690 Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
691 << Val << Duplicate->second;
697 FoundNormalizedTriples[NormalizedName] = Val;
700 if (TT.getArch() == llvm::Triple::UnknownArch)
701 Diag(clang::diag::err_drv_invalid_omp_target) << Val;
709 assert(HostTC &&
"Host toolchain should be always defined.");
711 ToolChains[TT.str() +
"/" + HostTC->
getTriple().normalize()];
713 CudaTC = std::make_unique<toolchains::CudaToolChain>(
722 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
724 Diag(clang::diag::warn_drv_empty_joined_argument)
745 StringRef FileName) {
747 for (
const std::string &
Dir : Dirs) {
751 llvm::sys::path::append(WPath,
Dir, FileName);
752 llvm::sys::path::native(WPath);
753 if (llvm::sys::fs::is_regular_file(WPath)) {
754 FilePath = std::move(WPath);
761 bool Driver::readConfigFile(StringRef FileName) {
764 if (!llvm::cl::readConfigFile(FileName, Saver, NewCfgArgs)) {
765 Diag(diag::err_drv_cannot_read_config_file) << FileName;
771 llvm::sys::path::native(CfgFileName);
772 ConfigFile = CfgFileName.str();
774 CfgOptions = std::make_unique<InputArgList>(
781 if (CfgOptions->hasArg(options::OPT_config)) {
783 Diag(diag::err_drv_nested_config_file);
789 for (Arg *A : *CfgOptions)
794 bool Driver::loadConfigFile() {
795 std::string CfgFileName;
796 bool FileSpecifiedExplicitly =
false;
800 if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
803 CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
804 if (!CfgDir.empty()) {
805 if (llvm::sys::fs::make_absolute(CfgDir).value() != 0)
811 if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
814 CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ));
815 if (!CfgDir.empty()) {
816 if (llvm::sys::fs::make_absolute(CfgDir).value() != 0)
826 std::vector<std::string> ConfigFiles =
827 CLOptions->getAllArgValues(options::OPT_config);
828 if (ConfigFiles.size() > 1) {
829 Diag(diag::err_drv_duplicate_config);
833 if (!ConfigFiles.empty()) {
834 CfgFileName = ConfigFiles.front();
835 assert(!CfgFileName.empty());
839 if (llvm::sys::path::has_parent_path(CfgFileName)) {
841 if (llvm::sys::path::is_relative(CfgFileName))
842 llvm::sys::fs::current_path(CfgFilePath);
843 llvm::sys::path::append(CfgFilePath, CfgFileName);
844 if (!llvm::sys::fs::is_regular_file(CfgFilePath)) {
845 Diag(diag::err_drv_config_file_not_exist) << CfgFilePath;
848 return readConfigFile(CfgFilePath);
851 FileSpecifiedExplicitly =
true;
861 if (CfgFileName.empty())
865 StringRef CfgFileArch = CfgFileName;
866 size_t ArchPrefixLen = CfgFileArch.find(
'-');
867 if (ArchPrefixLen == StringRef::npos)
868 ArchPrefixLen = CfgFileArch.size();
869 llvm::Triple CfgTriple;
870 CfgFileArch = CfgFileArch.take_front(ArchPrefixLen);
872 if (CfgTriple.getArch() == llvm::Triple::ArchType::UnknownArch)
875 if (!StringRef(CfgFileName).endswith(
".cfg"))
876 CfgFileName +=
".cfg";
882 size_t FixedArchPrefixLen = 0;
888 CfgTriple.getTriple(), *CLOptions);
889 if (CfgTriple.getArch() != EffectiveTriple.getArch()) {
890 FixedConfigFile = EffectiveTriple.getArchName();
891 FixedArchPrefixLen = FixedConfigFile.size();
894 if (ArchPrefixLen < CfgFileName.size())
895 FixedConfigFile += CfgFileName.substr(ArchPrefixLen);
903 CfgFileSearchDirs.push_back(
Dir);
907 if (!FixedConfigFile.empty()) {
908 if (
searchForFile(CfgFilePath, CfgFileSearchDirs, FixedConfigFile))
909 return readConfigFile(CfgFilePath);
911 FixedConfigFile.resize(FixedArchPrefixLen);
912 FixedConfigFile.append(
".cfg");
913 if (
searchForFile(CfgFilePath, CfgFileSearchDirs, FixedConfigFile))
914 return readConfigFile(CfgFilePath);
918 if (
searchForFile(CfgFilePath, CfgFileSearchDirs, CfgFileName))
919 return readConfigFile(CfgFilePath);
925 CfgFileName.append(
".cfg");
926 if (
searchForFile(CfgFilePath, CfgFileSearchDirs, CfgFileName))
927 return readConfigFile(CfgFilePath);
932 if (FileSpecifiedExplicitly) {
933 Diag(diag::err_drv_config_file_not_found) << CfgFileName;
934 for (
const std::string &SearchDir : CfgFileSearchDirs)
935 if (!SearchDir.empty())
936 Diag(diag::note_drv_config_file_searched_in) << SearchDir;
944 llvm::PrettyStackTraceString CrashInfo(
"Compilation construction");
950 llvm::sys::Process::GetEnv(
"COMPILER_PATH")) {
951 StringRef CompilerPath = *CompilerPathValue;
952 while (!CompilerPath.empty()) {
953 std::pair<StringRef, StringRef>
Split =
954 CompilerPath.split(llvm::sys::EnvPathSeparator);
956 CompilerPath = Split.second;
968 CLOptions = std::make_unique<InputArgList>(
973 ContainsError = loadConfigFile();
974 bool HasConfigFile = !ContainsError && (CfgOptions.get() !=
nullptr);
977 InputArgList Args = std::move(HasConfigFile ? std::move(*CfgOptions)
978 : std::move(*CLOptions));
983 auto appendOneArg = [&Args](
const Arg *Opt,
const Arg *BaseArg) {
984 unsigned Index = Args.MakeIndex(Opt->getSpelling());
985 Arg *Copy =
new llvm::opt::Arg(Opt->getOption(), Opt->getSpelling(),
987 Copy->getValues() = Opt->getValues();
988 if (Opt->isClaimed())
994 for (
auto *Opt : *CLOptions) {
995 if (Opt->getOption().matches(options::OPT_config))
997 const Arg *BaseArg = &Opt->getBaseArg();
1000 appendOneArg(Opt, BaseArg);
1004 if (
IsCLMode() && !ContainsError) {
1006 for (
const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
1008 CLModePassThroughArgList.push_back(A->getValue());
1011 if (!CLModePassThroughArgList.empty()) {
1014 auto CLModePassThroughOptions = std::make_unique<InputArgList>(
1018 for (
auto *Opt : *CLModePassThroughOptions) {
1019 appendOneArg(Opt,
nullptr);
1025 if (Arg *WD = Args.getLastArg(options::OPT_working_directory))
1026 if (VFS->setCurrentWorkingDirectory(WD->getValue()))
1027 Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue();
1030 bool CCCPrintPhases;
1036 Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);
1039 Args.ClaimAllArgs(options::OPT_fintegrated_cc1);
1040 Args.ClaimAllArgs(options::OPT_fno_integrated_cc1);
1043 Args.ClaimAllArgs(options::OPT_pipe);
1051 CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
1053 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
1054 CCCGenericGCCName = A->getValue();
1056 options::OPT_fno_crash_diagnostics,
1057 !!::getenv(
"FORCE_CLANG_DIAGNOSTICS_CRASH"));
1062 llvm::Triple T(TargetTriple);
1063 T.setOS(llvm::Triple::Win32);
1064 T.setVendor(llvm::Triple::PC);
1065 T.setEnvironment(llvm::Triple::MSVC);
1066 T.setObjectFormat(llvm::Triple::COFF);
1067 TargetTriple = T.str();
1069 if (
const Arg *A = Args.getLastArg(options::OPT_target))
1070 TargetTriple = A->getValue();
1071 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
1073 for (
const Arg *A : Args.filtered(options::OPT_B)) {
1077 if (
const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1079 if (
const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))
1082 if (
const Arg *A = Args.getLastArg(options::OPT_resource_dir))
1085 if (
const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) {
1086 SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
1087 .Case(
"cwd", SaveTempsCwd)
1088 .Case(
"obj", SaveTempsObj)
1089 .Default(SaveTempsCwd);
1095 if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) {
1096 StringRef
Name = A->getValue();
1097 unsigned Model = llvm::StringSwitch<unsigned>(
Name)
1098 .Case(
"off", EmbedNone)
1099 .Case(
"all", EmbedBitcode)
1100 .Case(
"bitcode", EmbedBitcode)
1101 .Case(
"marker", EmbedMarker)
1104 Diags.
Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1107 BitcodeEmbed =
static_cast<BitcodeEmbedMode
>(Model);
1110 std::unique_ptr<llvm::opt::InputArgList> UArgs =
1111 std::make_unique<InputArgList>(std::move(Args));
1114 DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
1136 if (TC.
getTriple().isOSBinFormatMachO())
1141 if (CCCPrintPhases) {
1151 static void printArgList(raw_ostream &OS,
const llvm::opt::ArgList &Args) {
1152 llvm::opt::ArgStringList ASL;
1153 for (
const auto *A : Args)
1154 A->render(Args, ASL);
1156 for (
auto I = ASL.begin(), E = ASL.end(); I != E; ++I) {
1157 if (I != ASL.begin())
1164 bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
1167 assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&
1168 "Only knows about .crash files on Darwin");
1173 path::home_directory(CrashDiagDir);
1174 if (CrashDiagDir.startswith(
"/var/root"))
1176 path::append(CrashDiagDir,
"Library/Logs/DiagnosticReports");
1184 fs::file_status FileStatus;
1185 TimePoint<> LastAccessTime;
1189 for (fs::directory_iterator File(CrashDiagDir, EC), FileEnd;
1190 File != FileEnd && !EC; File.increment(EC)) {
1191 StringRef FileName = path::filename(File->path());
1192 if (!FileName.startswith(
Name))
1194 if (fs::status(File->path(), FileStatus))
1196 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile =
1197 llvm::MemoryBuffer::getFile(File->path());
1202 StringRef Data = CrashFile.get()->getBuffer();
1203 if (!Data.startswith(
"Process:"))
1206 size_t ParentProcPos = Data.find(
"Parent Process:");
1207 if (ParentProcPos == StringRef::npos)
1209 size_t LineEnd = Data.find_first_of(
"\n", ParentProcPos);
1210 if (LineEnd == StringRef::npos)
1212 StringRef ParentProcess = Data.slice(ParentProcPos+15, LineEnd).trim();
1213 int OpenBracket = -1, CloseBracket = -1;
1214 for (
size_t i = 0, e = ParentProcess.size(); i < e; ++i) {
1215 if (ParentProcess[i] ==
'[')
1217 if (ParentProcess[i] ==
']')
1223 if (OpenBracket < 0 || CloseBracket < 0 ||
1224 ParentProcess.slice(OpenBracket + 1, CloseBracket)
1225 .getAsInteger(10, CrashPID) || CrashPID != PID) {
1235 const auto FileAccessTime = FileStatus.getLastModificationTime();
1236 if (FileAccessTime > LastAccessTime) {
1237 CrashFilePath.assign(File->path());
1238 LastAccessTime = FileAccessTime;
1243 if (!CrashFilePath.empty()) {
1244 EC = fs::copy_file(CrashFilePath, ReproCrashFilename);
1259 if (C.
getArgs().hasArg(options::OPT_fno_crash_diagnostics))
1270 Diag(clang::diag::note_drv_command_failed_diag_msg)
1271 <<
"PLEASE submit a bug report to " BUG_REPORT_URL
" and include the " 1272 "crash backtrace, preprocessed source, and associated run script.";
1292 for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
1293 bool IgnoreInput =
false;
1299 }
else if (!strcmp(it->second->getValue(),
"-")) {
1300 Diag(clang::diag::note_drv_command_failed_diag_msg)
1301 <<
"Error generating preprocessed source(s) - " 1302 "ignoring input from stdin.";
1307 it = Inputs.erase(it);
1314 if (Inputs.empty()) {
1315 Diag(clang::diag::note_drv_command_failed_diag_msg)
1316 <<
"Error generating preprocessed source(s) - " 1317 "no preprocessable inputs.";
1323 llvm::StringSet<> ArchNames;
1324 for (
const Arg *A : C.
getArgs()) {
1325 if (A->getOption().matches(options::OPT_arch)) {
1326 StringRef ArchName = A->getValue();
1327 ArchNames.insert(ArchName);
1330 if (ArchNames.size() > 1) {
1331 Diag(clang::diag::note_drv_command_failed_diag_msg)
1332 <<
"Error generating preprocessed source(s) - cannot generate " 1333 "preprocessed source with multiple -arch options.";
1340 if (TC.
getTriple().isOSBinFormatMachO())
1349 Diag(clang::diag::note_drv_command_failed_diag_msg)
1350 <<
"Error generating preprocessed source(s).";
1359 if (!FailingCommands.empty()) {
1360 Diag(clang::diag::note_drv_command_failed_diag_msg)
1361 <<
"Error generating preprocessed source(s).";
1366 if (TempFiles.empty()) {
1367 Diag(clang::diag::note_drv_command_failed_diag_msg)
1368 <<
"Error generating preprocessed source(s).";
1372 Diag(clang::diag::note_drv_command_failed_diag_msg)
1373 <<
"\n********************\n\n" 1374 "PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:\n" 1375 "Preprocessed source(s) and associated run script(s) are located at:";
1379 for (
const char *TempFile : TempFiles) {
1380 Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile;
1383 if (ReproCrashFilename.empty()) {
1384 ReproCrashFilename = TempFile;
1385 llvm::sys::path::replace_extension(ReproCrashFilename,
".crash");
1387 if (StringRef(TempFile).endswith(
".cache")) {
1390 VFS = llvm::sys::path::filename(TempFile);
1391 llvm::sys::path::append(VFS,
"vfs",
"vfs.yaml");
1399 llvm::sys::path::replace_extension(Script,
"sh");
1401 llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew);
1403 Diag(clang::diag::note_drv_command_failed_diag_msg)
1404 <<
"Error generating run script: " << Script <<
" " << EC.message();
1407 <<
"# Driver args: ";
1409 ScriptOS <<
"# Original command: ";
1410 Cmd.
Print(ScriptOS,
"\n",
true);
1411 Cmd.
Print(ScriptOS,
"\n",
true, &CrashInfo);
1412 if (!AdditionalInformation.empty())
1413 ScriptOS <<
"\n# Additional information: " << AdditionalInformation
1417 Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
1421 if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
1423 if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) {
1424 Diag(clang::diag::note_drv_command_failed_diag_msg)
1425 << ReproCrashFilename.str();
1427 llvm::sys::path::append(CrashDiagDir,
Name);
1428 CrashDiagDir +=
"_<YYYY-MM-DD-HHMMSS>_<hostname>.crash";
1429 Diag(clang::diag::note_drv_command_failed_diag_msg)
1430 <<
"Crash backtrace is located in";
1431 Diag(clang::diag::note_drv_command_failed_diag_msg)
1432 << CrashDiagDir.str();
1433 Diag(clang::diag::note_drv_command_failed_diag_msg)
1434 <<
"(choose the .crash file that corresponds to your crash)";
1438 for (
const auto &A : C.
getArgs().filtered(options::OPT_frewrite_map_file,
1439 options::OPT_frewrite_map_file_EQ))
1440 Diag(clang::diag::note_drv_command_failed_diag_msg) << A->getValue();
1442 Diag(clang::diag::note_drv_command_failed_diag_msg)
1443 <<
"\n\n********************";
1452 llvm::sys::commandLineFitsWithinSystemLimits(Cmd.
getExecutable(),
1464 if (C.
getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
1470 if (Diags.hasErrorOccurred())
1475 setUpResponseFiles(C, Job);
1480 if (FailingCommands.empty())
1486 for (
const auto &CmdPair : FailingCommands) {
1487 int CommandRes = CmdPair.first;
1488 const Command *FailingCommand = CmdPair.second;
1503 if (CommandRes == EX_IOERR) {
1521 Diag(clang::diag::err_drv_command_signalled)
1524 Diag(clang::diag::err_drv_command_failed)
1532 unsigned IncludedFlagsBitmask;
1533 unsigned ExcludedFlagsBitmask;
1534 std::tie(IncludedFlagsBitmask, ExcludedFlagsBitmask) =
1535 getIncludeExcludeOptionFlagMasks(
IsCLMode());
1539 ExcludedFlagsBitmask |= HelpHidden;
1541 std::string Usage = llvm::formatv(
"{0} [options] file...",
Name).str();
1543 IncludedFlagsBitmask, ExcludedFlagsBitmask,
1555 if (Arg *A = C.
getArgs().getLastArg(options::OPT_mthread_model)) {
1558 OS <<
"Thread model: " << A->getValue();
1567 if (!ConfigFile.empty())
1568 OS <<
"Configuration file: " << ConfigFile <<
'\n';
1581 if (PassedFlags ==
"")
1585 std::vector<std::string> SuggestedCompletions;
1586 std::vector<std::string> Flags;
1588 unsigned short DisableFlags =
1594 const bool HasSpace = PassedFlags.endswith(
",");
1598 StringRef TargetFlags = PassedFlags;
1599 while (TargetFlags !=
"") {
1601 std::tie(CurFlag, TargetFlags) = TargetFlags.split(
",");
1602 Flags.push_back(std::string(CurFlag));
1607 if (llvm::is_contained(Flags,
"-Xclang") || llvm::is_contained(Flags,
"-cc1"))
1610 const llvm::opt::OptTable &Opts =
getOpts();
1612 Cur = Flags.at(Flags.size() - 1);
1614 if (Flags.size() >= 2) {
1615 Prev = Flags.at(Flags.size() - 2);
1616 SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur);
1619 if (SuggestedCompletions.empty())
1620 SuggestedCompletions = Opts.suggestValueCompletions(Cur,
"");
1627 if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) {
1628 llvm::outs() <<
'\n';
1634 if (SuggestedCompletions.empty() && !Cur.endswith(
"=")) {
1638 SuggestedCompletions = Opts.findByPrefix(Cur, DisableFlags);
1644 if (S.startswith(Cur))
1645 SuggestedCompletions.push_back(S);
1652 llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) {
1653 if (
int X = A.compare_lower(B))
1655 return A.compare(B) > 0;
1658 llvm::outs() << llvm::join(SuggestedCompletions,
"\n") <<
'\n';
1665 if (C.
getArgs().hasArg(options::OPT_dumpmachine)) {
1670 if (C.
getArgs().hasArg(options::OPT_dumpversion)) {
1673 llvm::outs() << CLANG_VERSION_STRING <<
"\n";
1677 if (C.
getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
1682 if (C.
getArgs().hasArg(options::OPT_help) ||
1683 C.
getArgs().hasArg(options::OPT__help_hidden)) {
1688 if (C.
getArgs().hasArg(options::OPT__version)) {
1694 if (C.
getArgs().hasArg(options::OPT_v) ||
1695 C.
getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
1696 C.
getArgs().hasArg(options::OPT_print_supported_cpus)) {
1698 SuppressMissingInputWarning =
true;
1701 if (C.
getArgs().hasArg(options::OPT_v)) {
1703 llvm::errs() <<
"System configuration file directory: " 1706 llvm::errs() <<
"User configuration file directory: " 1712 if (C.
getArgs().hasArg(options::OPT_v))
1715 if (C.
getArgs().hasArg(options::OPT_print_resource_dir)) {
1720 if (C.
getArgs().hasArg(options::OPT_print_search_dirs)) {
1721 llvm::outs() <<
"programs: =";
1722 bool separator =
false;
1725 llvm::outs() << llvm::sys::EnvPathSeparator;
1726 llvm::outs() << Path;
1729 llvm::outs() <<
"\n";
1736 llvm::outs() << llvm::sys::EnvPathSeparator;
1739 llvm::outs() << sysroot << Path.substr(1);
1741 llvm::outs() << Path;
1743 llvm::outs() <<
"\n";
1749 if (Arg *A = C.
getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
1750 llvm::outs() <<
GetFilePath(A->getValue(), TC) <<
"\n";
1754 if (Arg *A = C.
getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
1755 StringRef ProgName = A->getValue();
1758 if (! ProgName.empty())
1761 llvm::outs() <<
"\n";
1765 if (Arg *A = C.
getArgs().getLastArg(options::OPT_autocomplete)) {
1766 StringRef PassedFlags = A->getValue();
1771 if (C.
getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
1780 llvm::outs() <<
GetFilePath(
"libgcc.a", TC) <<
"\n";
1786 if (C.
getArgs().hasArg(options::OPT_print_multi_lib)) {
1792 if (C.
getArgs().hasArg(options::OPT_print_multi_directory)) {
1795 llvm::outs() <<
".\n";
1798 assert(Suffix.front() ==
'/');
1799 llvm::outs() << Suffix.substr(1) <<
"\n";
1804 if (C.
getArgs().hasArg(options::OPT_print_target_triple)) {
1809 if (C.
getArgs().hasArg(options::OPT_print_effective_triple)) {
1811 llvm::outs() << Triple.getTriple() <<
"\n";
1828 std::map<Action *, unsigned> &Ids,
1834 llvm::raw_string_ostream os(str);
1836 auto getSibIndent = [](
int K) -> Twine {
1840 Twine SibIndent =
Indent + getSibIndent(Kind);
1844 os <<
"\"" << IA->getInputArg().getValue() <<
"\"";
1846 os <<
'"' << BIA->getArchName() <<
'"' <<
", {" 1847 <<
PrintActions1(C, *BIA->input_begin(), Ids, SibIndent, SibKind) <<
"}";
1848 }
else if (
OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
1849 bool IsFirst =
true;
1850 OA->doOnEachDependence(
1867 os <<
":" << BoundArch;
1870 os <<
" {" <<
PrintActions1(C, A, Ids, SibIndent, SibKind) <<
"}";
1878 const char *Prefix =
"{";
1879 for (
Action *PreRequisite : *AL) {
1880 os << Prefix <<
PrintActions1(C, PreRequisite, Ids, SibIndent, SibKind);
1891 std::string offload_str;
1892 llvm::raw_string_ostream offload_os(offload_str);
1893 if (!isa<OffloadAction>(A)) {
1896 offload_os <<
", (" << S;
1903 auto getSelfIndent = [](
int K) -> Twine {
1907 unsigned Id = Ids.size();
1909 llvm::errs() <<
Indent + getSelfIndent(Kind) << Id <<
": " << os.str() <<
", " 1918 std::map<Action *, unsigned> Ids;
1926 if (isa<CompileJobAction>(A) || isa<BackendJobAction>(A) ||
1927 isa<AssembleJobAction>(A))
1939 DerivedArgList &Args = C.
getArgs();
1941 llvm::PrettyStackTraceString CrashInfo(
"Building universal build actions");
1944 llvm::StringSet<> ArchNames;
1946 for (Arg *A : Args) {
1947 if (A->getOption().matches(options::OPT_arch)) {
1950 llvm::Triple::ArchType Arch =
1952 if (Arch == llvm::Triple::UnknownArch) {
1953 Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
1958 if (ArchNames.insert(A->getValue()).second)
1959 Archs.push_back(A->getValue());
1973 for (
Action* Act : SingleActions) {
1981 Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
1985 for (
unsigned i = 0, e = Archs.size(); i != e; ++i)
1990 if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
1991 Actions.append(Inputs.begin(), Inputs.end());
1996 Arg *A = Args.getLastArg(options::OPT_g_Group);
1997 bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) &&
1998 !A->getOption().matches(options::OPT_gstabs);
2006 if (Act->getType() == types::TY_Image) {
2008 Inputs.push_back(Actions.back());
2015 if (Args.hasArg(options::OPT_verify_debug_info)) {
2016 Action* LastAction = Actions.back();
2019 LastAction, types::TY_Nothing));
2034 if (
getVFS().exists(Value))
2038 if (!llvm::sys::path::is_absolute(Twine(Value)) &&
2039 llvm::sys::Process::FindInEnvPath(
"LIB", Value))
2042 if (Args.hasArg(options::OPT__SLASH_link) && Ty == types::TY_Object) {
2056 unsigned IncludedFlagsBitmask;
2057 unsigned ExcludedFlagsBitmask;
2058 std::tie(IncludedFlagsBitmask, ExcludedFlagsBitmask) =
2059 getIncludeExcludeOptionFlagMasks(
IsCLMode());
2060 std::string Nearest;
2061 if (
getOpts().findNearest(Value, Nearest, IncludedFlagsBitmask,
2062 ExcludedFlagsBitmask) <= 1) {
2063 Diag(clang::diag::err_drv_no_such_file_with_suggestion)
2064 << Value << Nearest;
2069 Diag(clang::diag::err_drv_no_such_file) <<
Value;
2076 const llvm::opt::OptTable &Opts =
getOpts();
2080 types::ID InputType = types::TY_Nothing;
2081 Arg *InputTypeArg =
nullptr;
2084 if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
2085 options::OPT__SLASH_TP)) {
2086 InputTypeArg = TCTP;
2087 InputType = TCTP->getOption().matches(options::OPT__SLASH_TC)
2092 bool ShowNote =
false;
2094 Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
2096 Diag(clang::diag::warn_drv_overriding_flag_option)
2097 << Previous->getSpelling() << A->getSpelling();
2103 Diag(clang::diag::note_drv_t_option_is_global);
2106 assert(!Args.hasArg(options::OPT_x) &&
"-x and /TC or /TP is not allowed");
2109 for (Arg *A : Args) {
2110 if (A->getOption().
getKind() == Option::InputClass) {
2111 const char *
Value = A->getValue();
2115 if (InputType == types::TY_Nothing) {
2118 InputTypeArg->claim();
2121 if (memcmp(Value,
"-", 2) == 0) {
2127 if (!Args.hasArgNoClaim(options::OPT_E) && !
CCCIsCPP())
2128 Diag(
IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
2129 : clang::diag::err_drv_unknown_stdin_type);
2137 if (
const char *Ext = strrchr(Value,
'.'))
2143 else if (
IsCLMode() && Args.hasArgNoClaim(options::OPT_E))
2146 Ty = types::TY_Object;
2156 Diag(clang::diag::warn_drv_treating_input_as_cxx)
2162 if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) &&
2163 Ty == types::TY_Object)
2164 Ty = types::TY_LLVM_BC;
2172 if (Ty != types::TY_Object) {
2173 if (Args.hasArg(options::OPT_ObjC))
2174 Ty = types::TY_ObjC;
2175 else if (Args.hasArg(options::OPT_ObjCXX))
2176 Ty = types::TY_ObjCXX;
2179 assert(InputTypeArg &&
"InputType set w/o InputTypeArg");
2180 if (!InputTypeArg->getOption().matches(options::OPT_x)) {
2183 const char *Ext = strrchr(Value,
'.');
2185 Ty = types::TY_Object;
2189 InputTypeArg->claim();
2194 Inputs.push_back(std::make_pair(Ty, A));
2196 }
else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
2197 StringRef
Value = A->getValue();
2200 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
2201 Inputs.push_back(std::make_pair(types::TY_C, InputArg));
2204 }
else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
2205 StringRef
Value = A->getValue();
2208 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
2209 Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
2215 Inputs.push_back(std::make_pair(types::TY_Object, A));
2217 }
else if (A->getOption().matches(options::OPT_x)) {
2226 Diag(clang::diag::err_drv_unknown_language) << A->getValue();
2227 InputType = types::TY_Object;
2229 }
else if (A->getOption().getID() == options::OPT_U) {
2230 assert(A->getNumValues() == 1 &&
"The /U option has one value.");
2231 StringRef Val = A->getValue(0);
2232 if (Val.find_first_of(
"/\\") != StringRef::npos) {
2234 Diag(diag::warn_slash_u_filename) << Val;
2235 Diag(diag::note_use_dashdash);
2239 if (
CCCIsCPP() && Inputs.empty()) {
2243 Inputs.push_back(std::make_pair(types::TY_C, A));
2250 class OffloadingActionBuilder final {
2252 bool IsValid =
false;
2258 std::map<const Arg *, unsigned> InputArgToOffloadKindMap;
2261 class DeviceActionBuilder {
2265 enum ActionBuilderReturnCode {
2284 DerivedArgList &Args;
2293 DeviceActionBuilder(
Compilation &C, DerivedArgList &Args,
2296 : C(C), Args(Args), Inputs(Inputs),
2297 AssociatedOffloadKind(AssociatedOffloadKind) {}
2298 virtual ~DeviceActionBuilder() {}
2303 virtual ActionBuilderReturnCode
2307 return ABRT_Inactive;
2312 virtual ActionBuilderReturnCode addDeviceDepences(
Action *HostAction) {
2313 return ABRT_Inactive;
2317 virtual void appendTopLevelActions(
ActionList &AL) {}
2320 virtual void appendLinkActions(
ActionList &AL) {}
2330 virtual bool canUseBundlerUnbundler()
const {
return false; }
2334 bool isValid() {
return !ToolChains.empty(); }
2338 return AssociatedOffloadKind;
2344 class CudaActionBuilderBase :
public DeviceActionBuilder {
2348 bool CompileHostOnly =
false;
2349 bool CompileDeviceOnly =
false;
2351 bool EmitAsm =
false;
2360 Action *CudaFatBinary =
nullptr;
2363 bool IsActive =
false;
2366 bool Relocatable =
false;
2372 CudaActionBuilderBase(
Compilation &C, DerivedArgList &Args,
2375 : DeviceActionBuilder(C, Args, Inputs, OFKind) {}
2377 ActionBuilderReturnCode addDeviceDepences(
Action *HostAction)
override {
2384 if (
auto *IA = dyn_cast<InputAction>(HostAction)) {
2385 assert(!GpuArchList.empty() &&
2386 "We should have at least one GPU architecture.");
2390 if (IA->getType() != types::TY_CUDA &&
2391 IA->getType() != types::TY_HIP) {
2394 return ABRT_Inactive;
2400 if (CompileHostOnly)
2401 return ABRT_Success;
2404 auto Ty = IA->getType() == types::TY_HIP ? types::TY_HIP_DEVICE
2405 : types::TY_CUDA_DEVICE;
2406 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
2407 CudaDeviceActions.push_back(
2411 return ABRT_Success;
2415 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
2420 return ABRT_Inactive;
2422 CudaDeviceActions.clear();
2423 auto *IA = cast<InputAction>(UA->getInputs().back());
2424 std::string FileName = IA->getInputArg().getAsString(Args);
2428 if (IA->getType() == types::TY_Object &&
2429 (!llvm::sys::path::has_extension(FileName) ||
2431 llvm::sys::path::extension(FileName).drop_front()) !=
2433 return ABRT_Inactive;
2435 for (
auto Arch : GpuArchList) {
2436 CudaDeviceActions.push_back(UA);
2438 AssociatedOffloadKind);
2440 return ABRT_Success;
2443 return IsActive ? ABRT_Success : ABRT_Inactive;
2446 void appendTopLevelActions(
ActionList &AL)
override {
2451 AssociatedOffloadKind);
2456 if (CudaFatBinary) {
2458 CudaDeviceActions.clear();
2459 CudaFatBinary =
nullptr;
2463 if (CudaDeviceActions.empty())
2469 assert(CudaDeviceActions.size() == GpuArchList.size() &&
2470 "Expecting one action per GPU architecture.");
2471 assert(ToolChains.size() == 1 &&
2472 "Expecting to have a sing CUDA toolchain.");
2473 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I)
2474 AddTopLevel(CudaDeviceActions[I], GpuArchList[I]);
2476 CudaDeviceActions.clear();
2493 Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
2494 options::OPT_fno_gpu_rdc,
false);
2497 assert(HostTC &&
"No toolchain for host compilation.");
2499 HostTC->
getTriple().getArch() == llvm::Triple::amdgcn) {
2508 ToolChains.push_back(
2513 Arg *PartialCompilationArg = Args.getLastArg(
2514 options::OPT_cuda_host_only, options::OPT_cuda_device_only,
2515 options::OPT_cuda_compile_host_device);
2516 CompileHostOnly = PartialCompilationArg &&
2517 PartialCompilationArg->getOption().matches(
2518 options::OPT_cuda_host_only);
2519 CompileDeviceOnly = PartialCompilationArg &&
2520 PartialCompilationArg->getOption().matches(
2521 options::OPT_cuda_device_only);
2522 EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
2523 EmitAsm = Args.getLastArg(options::OPT_S);
2526 std::set<CudaArch> GpuArchs;
2528 for (Arg *A : Args) {
2529 if (!(A->getOption().matches(options::OPT_cuda_gpu_arch_EQ) ||
2530 A->getOption().matches(options::OPT_no_cuda_gpu_arch_EQ)))
2534 const StringRef ArchStr = A->getValue();
2535 if (A->getOption().matches(options::OPT_no_cuda_gpu_arch_EQ) &&
2542 C.
getDriver().
Diag(clang::diag::err_drv_cuda_bad_gpu_arch) << ArchStr;
2544 }
else if (A->getOption().matches(options::OPT_cuda_gpu_arch_EQ))
2545 GpuArchs.insert(Arch);
2546 else if (A->getOption().matches(options::OPT_no_cuda_gpu_arch_EQ))
2547 GpuArchs.erase(Arch);
2549 llvm_unreachable(
"Unexpected option.");
2554 GpuArchList.push_back(Arch);
2559 if (GpuArchList.empty())
2560 GpuArchList.push_back(DefaultCudaArch);
2568 class CudaActionBuilder final :
public CudaActionBuilderBase {
2570 CudaActionBuilder(
Compilation &C, DerivedArgList &Args,
2576 ActionBuilderReturnCode
2579 PhasesTy &Phases)
override {
2581 return ABRT_Inactive;
2585 if (CudaDeviceActions.empty())
2586 return ABRT_Success;
2588 assert(CudaDeviceActions.size() == GpuArchList.size() &&
2589 "Expecting one action per GPU architecture.");
2590 assert(!CompileHostOnly &&
2591 "Not expecting CUDA actions in host-only compilation.");
2601 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
2604 for (
auto Ph : Phases) {
2609 if (Ph > FinalPhase)
2622 if (!isa<AssembleJobAction>(CudaDeviceActions[I]) ||
2626 Action *AssembleAction = CudaDeviceActions[I];
2627 assert(AssembleAction->
getType() == types::TY_Object);
2628 assert(AssembleAction->
getInputs().size() == 1);
2631 assert(BackendAction->getType() == types::TY_PP_Asm);
2633 for (
auto &A : {AssembleAction, BackendAction}) {
2637 DeviceActions.push_back(
2643 if (!DeviceActions.empty()) {
2647 if (!CompileDeviceOnly) {
2648 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
2652 CudaFatBinary =
nullptr;
2657 CudaDeviceActions.clear();
2661 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
2666 return ABRT_Success;
2670 "instructions should only occur " 2671 "before the backend phase!");
2674 for (
Action *&A : CudaDeviceActions)
2677 return ABRT_Success;
2682 class HIPActionBuilder final :
public CudaActionBuilderBase {
2687 HIPActionBuilder(
Compilation &C, DerivedArgList &Args,
2693 bool canUseBundlerUnbundler()
const override {
return true; }
2695 ActionBuilderReturnCode
2698 PhasesTy &Phases)
override {
2703 if (CudaDeviceActions.empty() ||
2706 return ABRT_Success;
2709 CudaDeviceActions.size() == GpuArchList.size()) &&
2710 "Expecting one action per GPU architecture.");
2711 assert(!CompileHostOnly &&
2712 "Not expecting CUDA actions in host-only compilation.");
2721 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
2725 AL.push_back(CudaDeviceActions[I]);
2726 CudaDeviceActions[I] =
2736 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(),
2739 DDep, CudaDeviceActions[I]->getType());
2744 types::TY_HIP_FATBIN);
2746 if (!CompileDeviceOnly) {
2747 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
2748 AssociatedOffloadKind);
2751 CudaFatBinary =
nullptr;
2756 CudaDeviceActions.clear();
2758 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
2765 DeviceLinkerInputs.resize(CudaDeviceActions.size());
2766 auto LI = DeviceLinkerInputs.begin();
2767 for (
auto *A : CudaDeviceActions) {
2774 CudaDeviceActions.clear();
2775 return ABRT_Success;
2779 for (
Action *&A : CudaDeviceActions)
2781 AssociatedOffloadKind);
2783 return (CompileDeviceOnly && CurPhase == FinalPhase) ? ABRT_Ignore_Host
2790 for (
auto &LI : DeviceLinkerInputs) {
2791 auto *DeviceLinkAction =
2793 DA.
add(*DeviceLinkAction, *ToolChains[0],
2802 class OpenMPActionBuilder final :
public DeviceActionBuilder {
2810 OpenMPActionBuilder(
Compilation &C, DerivedArgList &Args,
2814 ActionBuilderReturnCode
2817 PhasesTy &Phases)
override {
2818 if (OpenMPDeviceActions.empty())
2819 return ABRT_Inactive;
2822 assert(OpenMPDeviceActions.size() == ToolChains.size() &&
2823 "Number of OpenMP actions and toolchains do not match.");
2828 assert(ToolChains.size() == DeviceLinkerInputs.size() &&
2829 "Toolchains and linker inputs sizes do not match.");
2830 auto LI = DeviceLinkerInputs.begin();
2831 for (
auto *A : OpenMPDeviceActions) {
2838 OpenMPDeviceActions.clear();
2839 return ABRT_Success;
2843 for (
Action *&A : OpenMPDeviceActions)
2846 return ABRT_Success;
2849 ActionBuilderReturnCode addDeviceDepences(
Action *HostAction)
override {
2852 if (
auto *IA = dyn_cast<InputAction>(HostAction)) {
2853 OpenMPDeviceActions.clear();
2854 for (
unsigned I = 0; I < ToolChains.size(); ++I)
2855 OpenMPDeviceActions.push_back(
2857 return ABRT_Success;
2861 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
2862 OpenMPDeviceActions.clear();
2863 auto *IA = cast<InputAction>(UA->getInputs().back());
2864 std::string FileName = IA->getInputArg().getAsString(Args);
2868 if (IA->getType() == types::TY_Object &&
2869 (!llvm::sys::path::has_extension(FileName) ||
2871 llvm::sys::path::extension(FileName).drop_front()) !=
2873 return ABRT_Inactive;
2874 for (
unsigned I = 0; I < ToolChains.size(); ++I) {
2875 OpenMPDeviceActions.push_back(UA);
2876 UA->registerDependentActionInfo(
2879 return ABRT_Success;
2886 if (isa<CompileJobAction>(HostAction)) {
2888 assert(ToolChains.size() == OpenMPDeviceActions.size() &&
2889 "Toolchains and device action sizes do not match.");
2893 auto TC = ToolChains.begin();
2894 for (
Action *&A : OpenMPDeviceActions) {
2895 assert(isa<CompileJobAction>(A));
2902 return ABRT_Success;
2905 void appendTopLevelActions(
ActionList &AL)
override {
2906 if (OpenMPDeviceActions.empty())
2910 assert(OpenMPDeviceActions.size() == ToolChains.size() &&
2911 "Number of OpenMP actions and toolchains do not match.");
2914 auto TI = ToolChains.begin();
2915 for (
auto *A : OpenMPDeviceActions) {
2922 OpenMPDeviceActions.clear();
2925 void appendLinkActions(
ActionList &AL)
override {
2926 assert(ToolChains.size() == DeviceLinkerInputs.size() &&
2927 "Toolchains and linker inputs sizes do not match.");
2930 auto TC = ToolChains.begin();
2931 for (
auto &LI : DeviceLinkerInputs) {
2932 auto *DeviceLinkAction =
2935 DeviceLinkDeps.
add(*DeviceLinkAction, **TC,
nullptr,
2938 DeviceLinkAction->getType()));
2941 DeviceLinkerInputs.clear();
2950 for (
auto TI = OpenMPTCRange.first, TE = OpenMPTCRange.second; TI != TE;
2952 ToolChains.push_back(TI->second);
2954 DeviceLinkerInputs.resize(ToolChains.size());
2958 bool canUseBundlerUnbundler()
const override {
2975 OffloadingActionBuilder(
Compilation &C, DerivedArgList &Args,
2983 SpecializedBuilders.push_back(
new CudaActionBuilder(C, Args, Inputs));
2986 SpecializedBuilders.push_back(
new HIPActionBuilder(C, Args, Inputs));
2989 SpecializedBuilders.push_back(
new OpenMPActionBuilder(C, Args, Inputs));
2997 unsigned ValidBuilders = 0u;
2998 unsigned ValidBuildersSupportingBundling = 0u;
2999 for (
auto *SB : SpecializedBuilders) {
3000 IsValid = IsValid && !SB->initialize();
3003 if (SB->isValid()) {
3005 if (SB->canUseBundlerUnbundler())
3006 ++ValidBuildersSupportingBundling;
3010 ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling;
3013 ~OffloadingActionBuilder() {
3014 for (
auto *SB : SpecializedBuilders)
3023 addDeviceDependencesToHostAction(
Action *HostAction,
const Arg *InputArg,
3025 DeviceActionBuilder::PhasesTy &Phases) {
3029 if (SpecializedBuilders.empty())
3032 assert(HostAction &&
"Invalid host action!");
3037 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
3038 unsigned InactiveBuilders = 0u;
3039 unsigned IgnoringBuilders = 0u;
3040 for (
auto *SB : SpecializedBuilders) {
3041 if (!SB->isValid()) {
3047 SB->getDeviceDependences(DDeps, CurPhase, FinalPhase, Phases);
3052 if (RetCode == DeviceActionBuilder::ABRT_Ignore_Host)
3057 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
3058 OffloadKind |= SB->getAssociatedOffloadKind();
3063 if (IgnoringBuilders &&
3064 SpecializedBuilders.size() == (InactiveBuilders + IgnoringBuilders))
3081 bool addHostDependenceToDeviceActions(
Action *&HostAction,
3082 const Arg *InputArg) {
3092 if (CanUseBundler && isa<InputAction>(HostAction) &&
3093 InputArg->getOption().getKind() == llvm::opt::Option::InputClass &&
3095 auto UnbundlingHostAction =
3100 HostAction = UnbundlingHostAction;
3103 assert(HostAction &&
"Invalid host action!");
3106 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
3107 for (
auto *SB : SpecializedBuilders) {
3111 auto RetCode = SB->addDeviceDepences(HostAction);
3115 assert(RetCode != DeviceActionBuilder::ABRT_Ignore_Host &&
3116 "Host dependence not expected to be ignored.!");
3120 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
3121 OffloadKind |= SB->getAssociatedOffloadKind();
3126 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction))
3136 const Arg *InputArg) {
3139 for (
auto *SB : SpecializedBuilders) {
3142 SB->appendTopLevelActions(OffloadAL);
3149 if (CanUseBundler && HostAction &&
3150 HostAction->
getType() != types::TY_Nothing && !OffloadAL.empty()) {
3152 OffloadAL.push_back(HostAction);
3156 assert(HostAction == AL.back() &&
"Host action not in the list??");
3158 AL.back() = HostAction;
3160 AL.append(OffloadAL.begin(), OffloadAL.end());
3170 Action* makeHostLinkAction() {
3173 for (DeviceActionBuilder *SB : SpecializedBuilders) {
3176 SB->appendLinkActions(DeviceAL);
3179 if (DeviceAL.empty())
3196 for (
auto *SB : SpecializedBuilders) {
3200 SB->appendLinkDependences(DDeps);
3204 unsigned ActiveOffloadKinds = 0u;
3205 for (
auto &I : InputArgToOffloadKindMap)
3206 ActiveOffloadKinds |= I.second;
3223 nullptr, ActiveOffloadKinds);
3229 void Driver::handleArguments(
Compilation &C, DerivedArgList &Args,
3234 Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
3235 Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
3236 if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
3237 Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
3238 Args.eraseArg(options::OPT__SLASH_Yc);
3239 Args.eraseArg(options::OPT__SLASH_Yu);
3240 YcArg = YuArg =
nullptr;
3242 if (YcArg && Inputs.size() > 1) {
3243 Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
3244 Args.eraseArg(options::OPT__SLASH_Yc);
3249 phases::ID FinalPhase = getFinalPhase(Args, &FinalPhaseArg);
3252 if (Args.hasArg(options::OPT_emit_llvm))
3253 Diag(clang::diag::err_drv_emit_llvm_link);
3255 !Args.getLastArgValue(options::OPT_fuse_ld_EQ).equals_lower(
"lld"))
3256 Diag(clang::diag::err_drv_lto_without_lld);
3263 Args.eraseArg(options::OPT__SLASH_Fp);
3264 Args.eraseArg(options::OPT__SLASH_Yc);
3265 Args.eraseArg(options::OPT__SLASH_Yu);
3266 YcArg = YuArg =
nullptr;
3269 unsigned LastPLSize = 0;
3270 for (
auto &I : Inputs) {
3272 const Arg *InputArg = I.second;
3276 LastPLSize = PL.size();
3281 if (InitialPhase > FinalPhase) {
3282 if (InputArg->isClaimed())
3289 if (Args.hasArg(options::OPT_Qunused_arguments))
3295 Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
3296 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase);
3300 (Args.getLastArg(options::OPT__SLASH_EP,
3301 options::OPT__SLASH_P) ||
3302 Args.getLastArg(options::OPT_E) ||
3303 Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
3305 Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
3306 << InputArg->getAsString(Args) << !!FinalPhaseArg
3307 << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() :
"");
3309 Diag(clang::diag::warn_drv_input_file_unused)
3310 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase)
3312 << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() :
"");
3327 Actions.push_back(ClangClPch);
3341 Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
3342 Args.ClaimAllArgs(options::OPT_cl_compile_Group);
3348 llvm::PrettyStackTraceString CrashInfo(
"Building compilation actions");
3350 if (!SuppressMissingInputWarning && Inputs.empty()) {
3351 Diag(clang::diag::err_drv_no_input_files);
3357 if (Arg *A = Args.getLastArg(options::OPT_Z_Joined))
3358 Diag(clang::diag::err_drv_use_of_Z_option) << A->getAsString(Args);
3361 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
3362 StringRef
V = A->getValue();
3363 if (Inputs.size() > 1 && !V.empty() &&
3364 !llvm::sys::path::is_separator(V.back())) {
3366 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
3367 << A->getSpelling() <<
V;
3368 Args.eraseArg(options::OPT__SLASH_Fo);
3373 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
3374 StringRef
V = A->getValue();
3375 if (Inputs.size() > 1 && !V.empty() &&
3376 !llvm::sys::path::is_separator(V.back())) {
3378 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
3379 << A->getSpelling() <<
V;
3380 Args.eraseArg(options::OPT__SLASH_Fa);
3385 if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
3386 if (A->getValue()[0] ==
'\0') {
3388 Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
3389 Args.eraseArg(options::OPT__SLASH_o);
3393 handleArguments(C, Args, Inputs, Actions);
3396 OffloadingActionBuilder OffloadBuilder(C, Args, Inputs);
3403 for (
auto &I : Inputs) {
3405 const Arg *InputArg = I.second;
3420 if (OffloadBuilder.addHostDependenceToDeviceActions(Current, InputArg))
3426 Current = OffloadBuilder.addDeviceDependencesToHostAction(
3427 Current, InputArg, Phase, PL.back(), FullPL);
3433 assert(Phase == PL.back() &&
"linking must be final compilation step.");
3434 LinkerInputs.push_back(Current);
3444 assert(Phase == PL.back() &&
"merging must be final compilation step.");
3445 MergerInputs.push_back(Current);
3467 if (NewCurrent == Current)
3470 if (
auto *HMA = dyn_cast<HeaderModulePrecompileJobAction>(NewCurrent))
3471 HeaderModuleAction = HMA;
3473 Current = NewCurrent;
3477 if (OffloadBuilder.addHostDependenceToDeviceActions(Current, InputArg))
3480 if (Current->
getType() == types::TY_Nothing)
3486 Actions.push_back(Current);
3489 OffloadBuilder.appendTopLevelActions(Actions, Current, InputArg);
3493 if (!LinkerInputs.empty()) {
3494 if (
Action *Wrapper = OffloadBuilder.makeHostLinkAction())
3495 LinkerInputs.push_back(Wrapper);
3497 LA = OffloadBuilder.processHostLinkAction(LA);
3498 Actions.push_back(LA);
3502 if (!MergerInputs.empty())
3506 if (Args.hasArg(options::OPT_emit_interface_stubs)) {
3508 if (Args.hasArg(options::OPT_c)) {
3511 llvm::copy_if(CompilePhaseList, std::back_inserter(PhaseList),
3519 for (
auto &I : Inputs) {
3521 const Arg *InputArg = I.second;
3526 if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||
3527 InputType == types::TY_Asm)
3532 for (
auto Phase : PhaseList) {
3536 "IFS Pipeline can only consist of Compile followed by IfsMerge.");
3541 if (InputType == types::TY_Object)
3548 assert(Phase == PhaseList.back() &&
3549 "merging must be final compilation step.");
3550 MergerInputs.push_back(Current);
3559 Actions.push_back(Current);
3563 if (!MergerInputs.empty())
3570 if (Arg *A = Args.getLastArg(options::OPT_print_supported_cpus)) {
3576 for (
auto &I : Inputs)
3581 Args.ClaimAllArgs(options::OPT_cl_ignored_Group);
3585 Args.ClaimAllArgs(options::OPT_cuda_host_only);
3586 Args.ClaimAllArgs(options::OPT_cuda_compile_host_device);
3592 llvm::PrettyStackTraceString CrashInfo(
"Constructing phase actions");
3603 llvm_unreachable(
"link action invalid here.");
3605 llvm_unreachable(
"ifsmerge action invalid here.");
3610 if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
3611 !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
3612 OutputTy = types::TY_Dependencies;
3615 if (!Args.hasFlag(options::OPT_frewrite_includes,
3616 options::OPT_fno_rewrite_includes,
false) &&
3617 !Args.hasFlag(options::OPT_frewrite_imports,
3618 options::OPT_fno_rewrite_imports,
false) &&
3622 "Cannot preprocess this input type!");
3629 "Cannot precompile this input type!");
3633 const char *ModName =
nullptr;
3634 if (OutputTy == types::TY_PCH) {
3635 if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
3636 ModName = A->getValue();
3638 OutputTy = types::TY_ModuleFile;
3641 if (Args.hasArg(options::OPT_fsyntax_only)) {
3643 OutputTy = types::TY_Nothing;
3652 if (Args.hasArg(options::OPT_fsyntax_only))
3654 if (Args.hasArg(options::OPT_rewrite_objc))
3656 if (Args.hasArg(options::OPT_rewrite_legacy_objc))
3658 types::TY_RewrittenLegacyObjC);
3659 if (Args.hasArg(options::OPT__analyze))
3661 if (Args.hasArg(options::OPT__migrate))
3663 if (Args.hasArg(options::OPT_emit_ast))
3665 if (Args.hasArg(options::OPT_module_file_info))
3667 if (Args.hasArg(options::OPT_verify_pch))
3674 Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
3677 if (Args.hasArg(options::OPT_emit_llvm)) {
3679 Args.hasArg(options::OPT_S) ? types::TY_LLVM_IR : types::TY_LLVM_BC;
3688 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
3692 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
3694 Arg *FinalOutput = C.
getArgs().getLastArg(options::OPT_o);
3710 unsigned NumOutputs = 0;
3711 unsigned NumIfsOutputs = 0;
3713 if (A->
getType() != types::TY_Nothing &&
3715 (A->
getType() == clang::driver::types::TY_IFS_CPP &&
3717 0 == NumIfsOutputs++) ||
3722 if (NumOutputs > 1) {
3723 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
3724 FinalOutput =
nullptr;
3729 llvm::StringSet<> ArchNames;
3731 for (
const Arg *A : C.
getArgs())
3732 if (A->getOption().matches(options::OPT_arch))
3733 ArchNames.insert(A->getValue());
3736 std::map<std::pair<const Action *, std::string>,
InputInfo> CachedResults;
3744 const char *LinkingOutput =
nullptr;
3745 if (isa<LipoJobAction>(A)) {
3747 LinkingOutput = FinalOutput->getValue();
3755 ArchNames.size() > 1,
3756 LinkingOutput, CachedResults,
3763 J.InProcess =
false;
3767 if (Diags.hasErrorOccurred() ||
3768 C.
getArgs().hasArg(options::OPT_Qunused_arguments))
3772 (void)C.
getArgs().hasArg(options::OPT__HASH_HASH_HASH);
3775 (void)C.
getArgs().hasArg(options::OPT_driver_mode);
3776 (void)C.
getArgs().hasArg(options::OPT_rsp_quoting);
3782 if (!A->isClaimed()) {
3788 const Option &Opt = A->getOption();
3789 if (Opt.getKind() == Option::FlagClass) {
3790 bool DuplicateClaimed =
false;
3792 for (
const Arg *AA : C.
getArgs().filtered(&Opt)) {
3793 if (AA->isClaimed()) {
3794 DuplicateClaimed =
true;
3799 if (DuplicateClaimed)
3805 if (!
IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN))
3806 Diag(clang::diag::warn_drv_unused_argument)
3807 << A->getAsString(C.
getArgs());
3815 class ToolSelector final {
3826 bool IsHostSelector;
3837 bool CanBeCollapsed =
true) {
3839 if (Inputs.size() != 1)
3842 Action *CurAction = *Inputs.begin();
3843 if (CanBeCollapsed &&
3849 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
3853 if (!IsHostSelector) {
3854 if (OA->hasSingleDeviceDependence(
true)) {
3856 OA->getSingleDeviceDependence(
true);
3857 if (CanBeCollapsed &&
3860 SavedOffloadAction.push_back(OA);
3863 }
else if (OA->hasHostDependence()) {
3864 CurAction = OA->getHostDependence();
3865 if (CanBeCollapsed &&
3868 SavedOffloadAction.push_back(OA);
3878 bool canCollapseAssembleAction()
const {
3879 return TC.useIntegratedAs() && !SaveTemps &&
3880 !C.
getArgs().hasArg(options::OPT_via_file_asm) &&
3881 !C.
getArgs().hasArg(options::OPT__SLASH_FA) &&
3882 !C.
getArgs().hasArg(options::OPT__SLASH_Fa);
3886 bool canCollapsePreprocessorAction()
const {
3887 return !C.
getArgs().hasArg(options::OPT_no_integrated_cpp) &&
3888 !C.
getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
3889 !C.
getArgs().hasArg(options::OPT_rewrite_objc);
3894 struct JobActionInfo final {
3904 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
3906 unsigned ElementNum) {
3907 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
3908 for (
unsigned I = 0; I < ElementNum; ++I)
3909 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
3910 ActionInfo[I].SavedOffloadAction.end());
3926 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
3931 if (!AJ || !BJ || !CJ)
3935 const Tool *T = TC.SelectTool(*CJ);
3942 const Tool *BT = TC.SelectTool(*BJ);
3950 Inputs = CJ->getInputs();
3951 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
3958 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
3966 const Tool *T = TC.SelectTool(*BJ);
3973 Inputs = BJ->getInputs();
3974 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
3981 if (ActionInfo.size() < 2)
3993 bool InputIsBitcode =
true;
3994 for (
size_t i = 1; i < ActionInfo.size(); i++)
3995 if (ActionInfo[i].JA->getType() != types::TY_LLVM_BC &&
3996 ActionInfo[i].JA->getType() != types::TY_LTO_BC) {
3997 InputIsBitcode =
false;
4000 if (!InputIsBitcode && !canCollapsePreprocessorAction())
4004 const Tool *T = TC.SelectTool(*CJ);
4008 if (T->
canEmitIR() && ((SaveTemps && !InputIsBitcode) || EmbedBitcode))
4011 Inputs = CJ->getInputs();
4012 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
4029 for (
Action *A : Inputs) {
4030 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
4031 if (!PJ || !isa<PreprocessJobAction>(PJ)) {
4032 NewInputs.push_back(A);
4038 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
4039 PreprocessJobOffloadActions.end());
4040 NewInputs.append(PJ->input_begin(), PJ->input_end());
4047 const Compilation &C,
bool SaveTemps,
bool EmbedBitcode)
4048 : TC(TC), C(C), BaseAction(BaseAction), SaveTemps(SaveTemps),
4049 EmbedBitcode(EmbedBitcode) {
4050 assert(BaseAction &&
"Invalid base action.");
4067 ActionChain.back().JA = BaseAction;
4068 while (ActionChain.back().JA) {
4069 const Action *CurAction = ActionChain.back().JA;
4072 ActionChain.resize(ActionChain.size() + 1);
4073 JobActionInfo &AI = ActionChain.back();
4077 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
4081 ActionChain.pop_back();
4089 const Tool *T = combineAssembleBackendCompile(ActionChain, Inputs,
4090 CollapsedOffloadAction);
4092 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
4094 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
4100 combineWithPreprocessor(T, Inputs, CollapsedOffloadAction);
4112 StringRef BoundArch,
4114 std::string TriplePlusArch = TC->
getTriple().normalize();
4115 if (!BoundArch.empty()) {
4116 TriplePlusArch +=
"-";
4117 TriplePlusArch += BoundArch;
4119 TriplePlusArch +=
"-";
4121 return TriplePlusArch;
4126 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
4127 std::map<std::pair<const Action *, std::string>,
InputInfo> &CachedResults,
4129 std::pair<const Action *, std::string> ActionTC = {
4131 auto CachedResult = CachedResults.find(ActionTC);
4132 if (CachedResult != CachedResults.end()) {
4133 return CachedResult->second;
4135 InputInfo Result = BuildJobsForActionNoCache(
4136 C, A, TC, BoundArch, AtTopLevel, MultipleArchs, LinkingOutput,
4137 CachedResults, TargetDeviceOffloadKind);
4138 CachedResults[ActionTC] = Result;
4142 InputInfo Driver::BuildJobsForActionNoCache(
4144 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
4145 std::map<std::pair<const Action *, std::string>,
InputInfo> &CachedResults,
4147 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
4150 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
4182 if (OA->hasSingleDeviceDependence()) {
4184 OA->doOnEachDeviceDependence([&](
Action *DepA,
const ToolChain *DepTC,
4185 const char *DepBoundArch) {
4188 !!DepBoundArch, LinkingOutput,
4198 OA->doOnEachDependence(
4199 BuildingForOffloadDevice,
4202 C, DepA, DepTC, DepBoundArch,
false,
4203 !!DepBoundArch, LinkingOutput, CachedResults,
4207 A = BuildingForOffloadDevice
4208 ? OA->getSingleDeviceDependence(
true)
4209 : OA->getHostDependence();
4212 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
4215 const Arg &Input = IA->getInputArg();
4217 if (Input.getOption().matches(options::OPT_INPUT)) {
4218 const char *
Name = Input.getValue();
4228 if (!ArchName.empty())
4229 TC = &getToolChain(C.
getArgs(),
4236 MultipleArchs, LinkingOutput, CachedResults,
4237 TargetDeviceOffloadKind);
4243 const JobAction *JA = cast<JobAction>(A);
4248 const Tool *T = TS.getTool(Inputs, CollapsedOffloadActions);
4255 for (
const auto *OA : CollapsedOffloadActions)
4256 cast<OffloadAction>(OA)->doOnEachDependence(
4257 BuildingForOffloadDevice,
4260 C, DepA, DepTC, DepBoundArch,
false,
4261 !!DepBoundArch, LinkingOutput, CachedResults,
4267 for (
const Action *Input : Inputs) {
4271 bool SubJobAtTopLevel =
4272 AtTopLevel && (isa<DsymutilJobAction>(A) || isa<VerifyJobAction>(A));
4274 C, Input, TC, BoundArch, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
4279 const char *BaseInput = InputInfos[0].getBaseInput();
4283 if (JA->
getType() == types::TY_dSYM)
4284 BaseInput = InputInfos[0].getFilename();
4287 if (
auto *ModuleJA = dyn_cast<HeaderModulePrecompileJobAction>(JA))
4288 BaseInput = ModuleJA->getModuleName();
4291 if (!OffloadDependencesInputInfo.empty())
4292 InputInfos.append(OffloadDependencesInputInfo.begin(),
4293 OffloadDependencesInputInfo.end());
4296 llvm::Triple EffectiveTriple;
4298 const ArgList &Args =
4300 if (InputInfos.size() != 1) {
4304 EffectiveTriple = llvm::Triple(
4312 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(JA)) {
4316 for (
auto &UI : UA->getDependentActionsInfo()) {
4318 "Unbundling with no offloading??");
4325 UI.DependentOffloadKind,
4326 UI.DependentToolChain->getTriple().normalize(),
4337 UnbundlingResults.push_back(CurI);
4346 Arch = UI.DependentBoundArch;
4351 UI.DependentOffloadKind)}] =
4357 std::pair<const Action *, std::string> ActionTC = {
4359 assert(CachedResults.find(ActionTC) != CachedResults.end() &&
4360 "Result does not exist??");
4361 Result = CachedResults[ActionTC];
4362 }
else if (JA->
getType() == types::TY_Nothing)
4371 if (isa<OffloadWrapperJobAction>(JA)) {
4372 OffloadingPrefix +=
"-wrapper";
4373 if (Arg *FinalOutput = C.
getArgs().getLastArg(options::OPT_o))
4374 BaseInput = FinalOutput->getValue();
4379 AtTopLevel, MultipleArchs,
4386 <<
" - \"" << T->
getName() <<
"\", inputs: [";
4387 for (
unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
4388 llvm::errs() << InputInfos[i].getAsString();
4390 llvm::errs() <<
", ";
4392 if (UnbundlingResults.empty())
4393 llvm::errs() <<
"], output: " << Result.
getAsString() <<
"\n";
4395 llvm::errs() <<
"], outputs: [";
4396 for (
unsigned i = 0, e = UnbundlingResults.size(); i != e; ++i) {
4397 llvm::errs() << UnbundlingResults[i].getAsString();
4399 llvm::errs() <<
", ";
4401 llvm::errs() <<
"] \n";
4404 if (UnbundlingResults.empty())
4406 C, *JA, Result, InputInfos,
4411 C, *JA, UnbundlingResults, InputInfos,
4420 return Target.isOSWindows() ?
"a.exe" :
"a.out";
4432 if (ArgValue.empty()) {
4434 Filename = BaseName;
4435 }
else if (llvm::sys::path::is_separator(Filename.back())) {
4437 llvm::sys::path::append(Filename, BaseName);
4440 if (!llvm::sys::path::has_extension(ArgValue)) {
4444 if (FileType == types::TY_Image &&
4445 Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
4450 llvm::sys::path::replace_extension(Filename, Extension);
4453 return Args.MakeArgString(Filename.c_str());
4457 const char *BaseInput,
4458 StringRef BoundArch,
bool AtTopLevel,
4460 StringRef OffloadingPrefix)
const {
4461 llvm::PrettyStackTraceString CrashInfo(
"Computing output path");
4463 if (AtTopLevel && !isa<DsymutilJobAction>(JA) && !isa<VerifyJobAction>(JA)) {
4464 if (Arg *FinalOutput = C.
getArgs().getLastArg(options::OPT_o))
4469 if (C.
getArgs().hasArg(options::OPT__SLASH_P)) {
4470 assert(AtTopLevel && isa<PreprocessJobAction>(JA));
4471 StringRef BaseName = llvm::sys::path::filename(BaseInput);
4473 if (Arg *A = C.
getArgs().getLastArg(options::OPT__SLASH_Fi))
4474 NameArg = A->getValue();
4485 if (JA.
getType() == types::TY_PP_Asm &&
4486 (C.
getArgs().hasArg(options::OPT__SLASH_FA) ||
4487 C.
getArgs().hasArg(options::OPT__SLASH_Fa))) {
4489 StringRef BaseName = llvm::sys::path::filename(BaseInput);
4490 StringRef FaValue = C.
getArgs().getLastArgValue(options::OPT__SLASH_Fa);
4498 !C.
getArgs().hasArg(options::OPT__SLASH_Fo)) ||
4500 StringRef
Name = llvm::sys::path::filename(BaseInput);
4501 std::pair<StringRef, StringRef>
Split = Name.split(
'.');
4504 Arg *A = C.
getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
4507 if (!
getVFS().exists(CrashDirectory))
4508 llvm::sys::fs::create_directories(CrashDirectory);
4509 llvm::sys::path::append(CrashDirectory, Split.first);
4510 const char *Middle = Suffix ?
"-%%%%%%." :
"-%%%%%%";
4511 std::error_code EC = llvm::sys::fs::createUniqueFile(
4512 CrashDirectory + Middle + Suffix, TmpName);
4514 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
4527 if (isa<DsymutilJobAction>(JA) || isa<VerifyJobAction>(JA))
4528 BaseName = BasePath;
4530 BaseName = llvm::sys::path::filename(BasePath);
4533 const char *NamedOutput;
4535 if ((JA.
getType() == types::TY_Object || JA.
getType() == types::TY_LTO_BC) &&
4536 C.
getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
4540 .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
4544 }
else if (JA.
getType() == types::TY_Image &&
4545 C.
getArgs().hasArg(options::OPT__SLASH_Fe,
4546 options::OPT__SLASH_o)) {
4550 .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)
4554 }
else if (JA.
getType() == types::TY_Image) {
4564 !C.
getArgs().hasFlag(options::OPT_fgpu_rdc,
4565 options::OPT_fno_gpu_rdc,
false);
4568 llvm::sys::path::replace_extension(Output,
"");
4570 Output += OffloadingPrefix;
4571 if (MultipleArchs && !BoundArch.empty()) {
4573 Output.append(BoundArch);
4577 NamedOutput = C.
getArgs().MakeArgString(Output.c_str());
4583 assert(Suffix &&
"All types used for output should have a suffix.");
4585 std::string::size_type
End = std::string::npos;
4587 End = BaseName.rfind(
'.');
4589 Suffixed += OffloadingPrefix;
4590 if (MultipleArchs && !BoundArch.empty()) {
4592 Suffixed.append(BoundArch);
4597 if (!AtTopLevel && C.
getArgs().hasArg(options::OPT_emit_llvm) &&
4598 JA.
getType() == types::TY_LLVM_BC)
4602 NamedOutput = C.
getArgs().MakeArgString(Suffixed.c_str());
4607 JA.
getType() != types::TY_PCH) {
4608 Arg *FinalOutput = C.
getArgs().getLastArg(options::OPT_o);
4610 llvm::sys::path::remove_filename(TempPath);
4611 StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
4612 llvm::sys::path::append(TempPath, OutputFileName);
4613 NamedOutput = C.
getArgs().MakeArgString(TempPath.c_str());
4619 bool SameFile =
false;
4621 llvm::sys::fs::current_path(Result);
4622 llvm::sys::path::append(Result, BaseName);
4623 llvm::sys::fs::equivalent(BaseInput, Result.c_str(), SameFile);
4626 StringRef
Name = llvm::sys::path::filename(BaseInput);
4627 std::pair<StringRef, StringRef>
Split = Name.split(
'.');
4636 llvm::sys::path::remove_filename(BasePath);
4637 if (BasePath.empty())
4638 BasePath = NamedOutput;
4640 llvm::sys::path::append(BasePath, NamedOutput);
4653 for (
const auto &
Dir :
P) {
4657 llvm::sys::path::append(P, Name);
4658 if (llvm::sys::fs::exists(Twine(P)))
4659 return P.str().str();
4668 llvm::sys::path::append(R, Name);
4669 if (llvm::sys::fs::exists(Twine(R)))
4673 llvm::sys::path::append(
P, Name);
4674 if (llvm::sys::fs::exists(Twine(
P)))
4678 llvm::sys::path::append(D,
"..", Name);
4679 if (llvm::sys::fs::exists(Twine(D)))
4691 void Driver::generatePrefixedToolNames(
4695 Names.emplace_back((TargetTriple +
"-" + Tool).str());
4696 Names.emplace_back(Tool);
4699 std::string DefaultTargetTriple = llvm::sys::getDefaultTargetTriple();
4700 if (DefaultTargetTriple != TargetTriple)
4701 Names.emplace_back((DefaultTargetTriple +
"-" + Tool).str());
4706 for (
const auto &
Name : Names) {
4707 llvm::sys::path::append(Dir,
Name);
4708 if (llvm::sys::fs::can_execute(Twine(Dir)))
4710 llvm::sys::path::remove_filename(Dir);
4717 generatePrefixedToolNames(Name, TC, TargetSpecificExecutables);
4722 if (llvm::sys::fs::is_directory(PrefixDir)) {
4728 if (llvm::sys::fs::can_execute(Twine(P)))
4734 for (
const auto &Path : List) {
4741 for (
const auto &TargetSpecificExecutable : TargetSpecificExecutables)
4742 if (llvm::ErrorOr<std::string>
P =
4743 llvm::sys::findProgramByName(TargetSpecificExecutable))
4751 std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path);
4753 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
4762 std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix, Path);
4764 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
4773 if (Arg *FpArg = C.
getArgs().getLastArg(options::OPT__SLASH_Fp)) {
4777 Output = FpArg->getValue();
4781 if (!llvm::sys::path::has_extension(Output))
4784 if (Arg *YcArg = C.
getArgs().getLastArg(options::OPT__SLASH_Yc))
4785 Output = YcArg->getValue();
4788 llvm::sys::path::replace_extension(Output,
".pch");
4790 return Output.str();
4793 const ToolChain &Driver::getToolChain(
const ArgList &Args,
4794 const llvm::Triple &
Target)
const {
4796 auto &TC = ToolChains[Target.str()];
4798 switch (Target.getOS()) {
4800 TC = std::make_unique<toolchains::AIX>(*
this, Target, Args);
4802 case llvm::Triple::Haiku:
4803 TC = std::make_unique<toolchains::Haiku>(*
this, Target, Args);
4805 case llvm::Triple::Ananas:
4806 TC = std::make_unique<toolchains::Ananas>(*
this, Target, Args);
4808 case llvm::Triple::CloudABI:
4809 TC = std::make_unique<toolchains::CloudABI>(*
this, Target, Args);
4811 case llvm::Triple::Darwin:
4812 case llvm::Triple::MacOSX:
4813 case llvm::Triple::IOS:
4814 case llvm::Triple::TvOS:
4815 case llvm::Triple::WatchOS:
4816 TC = std::make_unique<toolchains::DarwinClang>(*
this, Target, Args);
4818 case llvm::Triple::DragonFly:
4819 TC = std::make_unique<toolchains::DragonFly>(*
this, Target, Args);
4821 case llvm::Triple::OpenBSD:
4822 TC = std::make_unique<toolchains::OpenBSD>(*
this, Target, Args);
4824 case llvm::Triple::NetBSD:
4825 TC = std::make_unique<toolchains::NetBSD>(*
this, Target, Args);
4827 case llvm::Triple::FreeBSD:
4828 TC = std::make_unique<toolchains::FreeBSD>(*
this, Target, Args);
4830 case llvm::Triple::Minix:
4831 TC = std::make_unique<toolchains::Minix>(*
this, Target, Args);
4833 case llvm::Triple::Linux:
4834 case llvm::Triple::ELFIAMCU:
4835 if (Target.getArch() == llvm::Triple::hexagon)
4836 TC = std::make_unique<toolchains::HexagonToolChain>(*
this, Target,
4838 else if ((Target.getVendor() == llvm::Triple::MipsTechnologies) &&
4839 !Target.hasEnvironment())
4840 TC = std::make_unique<toolchains::MipsLLVMToolChain>(*
this, Target,
4842 else if (Target.getArch() == llvm::Triple::ppc ||
4843 Target.getArch() == llvm::Triple::ppc64 ||
4844 Target.getArch() == llvm::Triple::ppc64le)
4845 TC = std::make_unique<toolchains::PPCLinuxToolChain>(*
this, Target,
4848 TC = std::make_unique<toolchains::Linux>(*
this, Target, Args);
4850 case llvm::Triple::NaCl:
4851 TC = std::make_unique<toolchains::NaClToolChain>(*
this, Target, Args);
4853 case llvm::Triple::Fuchsia:
4854 TC = std::make_unique<toolchains::Fuchsia>(*
this, Target, Args);
4856 case llvm::Triple::Solaris:
4857 TC = std::make_unique<toolchains::Solaris>(*
this, Target, Args);
4859 case llvm::Triple::AMDHSA:
4860 case llvm::Triple::AMDPAL:
4861 case llvm::Triple::Mesa3D:
4862 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this, Target, Args);
4864 case llvm::Triple::Win32:
4865 switch (Target.getEnvironment()) {
4867 if (Target.isOSBinFormatELF())
4868 TC = std::make_unique<toolchains::Generic_ELF>(*
this, Target, Args);
4869 else if (Target.isOSBinFormatMachO())
4870 TC = std::make_unique<toolchains::MachO>(*
this, Target, Args);
4872 TC = std::make_unique<toolchains::Generic_GCC>(*
this, Target, Args);
4874 case llvm::Triple::GNU:
4875 TC = std::make_unique<toolchains::MinGW>(*
this, Target, Args);
4877 case llvm::Triple::Itanium:
4878 TC = std::make_unique<toolchains::CrossWindowsToolChain>(*
this, Target,
4881 case llvm::Triple::MSVC:
4882 case llvm::Triple::UnknownEnvironment:
4883 if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
4884 .startswith_lower(
"bfd"))
4885 TC = std::make_unique<toolchains::CrossWindowsToolChain>(
4886 *
this, Target, Args);
4889 std::make_unique<toolchains::MSVCToolChain>(*
this, Target, Args);
4893 case llvm::Triple::PS4:
4894 TC = std::make_unique<toolchains::PS4CPU>(*
this, Target, Args);
4896 case llvm::Triple::Contiki:
4897 TC = std::make_unique<toolchains::Contiki>(*
this, Target, Args);
4899 case llvm::Triple::Hurd:
4900 TC = std::make_unique<toolchains::Hurd>(*
this, Target, Args);
4905 switch (Target.getArch()) {
4906 case llvm::Triple::tce:
4907 TC = std::make_unique<toolchains::TCEToolChain>(*
this, Target, Args);
4909 case llvm::Triple::tcele:
4910 TC = std::make_unique<toolchains::TCELEToolChain>(*
this, Target, Args);
4912 case llvm::Triple::hexagon:
4913 TC = std::make_unique<toolchains::HexagonToolChain>(*
this, Target,
4916 case llvm::Triple::lanai:
4917 TC = std::make_unique<toolchains::LanaiToolChain>(*
this, Target, Args);
4919 case llvm::Triple::xcore:
4920 TC = std::make_unique<toolchains::XCoreToolChain>(*
this, Target, Args);
4922 case llvm::Triple::wasm32:
4923 case llvm::Triple::wasm64:
4924 TC = std::make_unique<toolchains::WebAssembly>(*
this, Target, Args);
4926 case llvm::Triple::avr:
4927 TC = std::make_unique<toolchains::AVRToolChain>(*
this, Target, Args);
4929 case llvm::Triple::msp430:
4931 std::make_unique<toolchains::MSP430ToolChain>(*
this, Target, Args);
4933 case llvm::Triple::riscv32:
4934 case llvm::Triple::riscv64:
4935 TC = std::make_unique<toolchains::RISCVToolChain>(*
this, Target, Args);
4938 if (Target.getVendor() == llvm::Triple::Myriad)
4939 TC = std::make_unique<toolchains::MyriadToolChain>(*
this, Target,
4942 TC = std::make_unique<toolchains::BareMetal>(*
this, Target, Args);
4943 else if (Target.isOSBinFormatELF())
4944 TC = std::make_unique<toolchains::Generic_ELF>(*
this, Target, Args);
4945 else if (Target.isOSBinFormatMachO())
4946 TC = std::make_unique<toolchains::MachO>(*
this, Target, Args);
4948 TC = std::make_unique<toolchains::Generic_GCC>(*
this, Target, Args);
4963 if (JA.
size() != 1 ||
4968 if (!isa<PreprocessJobAction>(JA) && !isa<PrecompileJobAction>(JA) &&
4969 !isa<CompileJobAction>(JA) && !isa<BackendJobAction>(JA))
4977 if (JA.
size() != 1 ||
4982 if (!isa<PreprocessJobAction>(JA) && !isa<CompileJobAction>(JA) && !isa<BackendJobAction>(JA))
4994 unsigned &Micro,
bool &HadExtra) {
4997 Major = Minor = Micro = 0;
5001 if (Str.consumeInteger(10, Major))
5008 Str = Str.drop_front(1);
5010 if (Str.consumeInteger(10, Minor))
5016 Str = Str.drop_front(1);
5018 if (Str.consumeInteger(10, Micro))
5036 unsigned CurDigit = 0;
5037 while (CurDigit < Digits.size()) {
5039 if (Str.consumeInteger(10, Digit))
5041 Digits[CurDigit] = Digit;
5046 Str = Str.drop_front(1);
5054 std::pair<unsigned, unsigned>
5055 Driver::getIncludeExcludeOptionFlagMasks(
bool IsClCompatMode)
const {
5056 unsigned IncludedFlagsBitmask = 0;
5059 if (IsClCompatMode) {
5067 return std::make_pair(IncludedFlagsBitmask, ExcludedFlagsBitmask);
5071 return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group,
false);
5076 if (Args.hasFlag(options::OPT_fsave_optimization_record,
5077 options::OPT_fno_save_optimization_record,
false))
5081 if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ,
5082 options::OPT_fno_save_optimization_record,
false))
5086 if (Args.hasFlag(options::OPT_foptimization_record_file_EQ,
5087 options::OPT_fno_save_optimization_record,
false))
5091 if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
5092 options::OPT_fno_save_optimization_record,
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.
bool ShouldUseFlangCompiler(const JobAction &JA) const
ShouldUseFlangCompiler - Should the flang compiler be used to handle this action. ...
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.
static unsigned PrintActions1(const Compilation &C, Action *A, std::map< Action *, unsigned > &Ids, Twine Indent={}, int Kind=TopLevelAction)
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
static Arg * MakeInputArg(DerivedArgList &Args, const OptTable &Opts, StringRef Value, bool Claim=true)
bool isOptimizationLevelFast(const llvm::opt::ArgList &Args)
OffloadKind getOffloadingDeviceKind() const
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.
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(...
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.
clang::driver::toolchains::AIX AIX
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 ...
bool willEmitRemarks(const llvm::opt::ArgList &Args)
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.
bool LE(InterpState &S, CodePtr OpPC)
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.
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
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.
bool isFortran(ID Id)
isFortran - Is this a Fortran input.
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.