diff options
| author | 2018-04-06 14:26:03 +0000 | |
|---|---|---|
| committer | 2018-04-06 14:26:03 +0000 | |
| commit | bdabc2f19ffb9e20600dad6e8a300842a7bda50e (patch) | |
| tree | c50e7b2e5449b074651bb82a58517a8ebc4a8cf7 /gnu/llvm/tools/clang/lib/Driver/Driver.cpp | |
| parent | Print a 'p' flag for file descriptors that were opened after pledge(2). (diff) | |
| download | wireguard-openbsd-bdabc2f19ffb9e20600dad6e8a300842a7bda50e.tar.xz wireguard-openbsd-bdabc2f19ffb9e20600dad6e8a300842a7bda50e.zip | |
Import LLVM 6.0.1 release including clang, lld and lldb.
"where is the kaboom?" deraadt@
Diffstat (limited to 'gnu/llvm/tools/clang/lib/Driver/Driver.cpp')
| -rw-r--r-- | gnu/llvm/tools/clang/lib/Driver/Driver.cpp | 409 |
1 files changed, 344 insertions, 65 deletions
diff --git a/gnu/llvm/tools/clang/lib/Driver/Driver.cpp b/gnu/llvm/tools/clang/lib/Driver/Driver.cpp index ba4d0e836b4..325b233ac5e 100644 --- a/gnu/llvm/tools/clang/lib/Driver/Driver.cpp +++ b/gnu/llvm/tools/clang/lib/Driver/Driver.cpp @@ -12,7 +12,6 @@ #include "ToolChains/AMDGPU.h" #include "ToolChains/AVR.h" #include "ToolChains/Ananas.h" -#include "ToolChains/Bitrig.h" #include "ToolChains/Clang.h" #include "ToolChains/CloudABI.h" #include "ToolChains/Contiki.h" @@ -63,13 +62,16 @@ #include "llvm/Option/OptSpecifier.h" #include "llvm/Option/OptTable.h" #include "llvm/Option/Option.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Process.h" #include "llvm/Support/Program.h" +#include "llvm/Support/TargetRegistry.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Support/StringSaver.h" #include <map> #include <memory> #include <utility> @@ -87,12 +89,13 @@ Driver::Driver(StringRef ClangExecutable, StringRef DefaultTargetTriple, : Opts(createDriverOptTable()), Diags(Diags), VFS(std::move(VFS)), Mode(GCCMode), SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone), LTOMode(LTOK_None), ClangExecutable(ClangExecutable), - SysRoot(DEFAULT_SYSROOT), UseStdLib(true), + SysRoot(DEFAULT_SYSROOT), DriverTitle("clang LLVM compiler"), CCPrintOptionsFilename(nullptr), CCPrintHeadersFilename(nullptr), CCLogDiagnosticsFilename(nullptr), CCCPrintBindings(false), CCPrintHeaders(false), CCLogDiagnostics(false), CCGenDiagnostics(false), DefaultTargetTriple(DefaultTargetTriple), - CCCGenericGCCName(""), CheckInputsExist(true), CCCUsePCH(true), + CCCGenericGCCName(""), Saver(Alloc), + CheckInputsExist(true), CCCUsePCH(true), GenReproducer(false), SuppressMissingInputWarning(false) { // Provide a sane fallback if no VFS is specified. @@ -103,6 +106,13 @@ Driver::Driver(StringRef ClangExecutable, StringRef DefaultTargetTriple, Dir = llvm::sys::path::parent_path(ClangExecutable); InstalledDir = Dir; // Provide a sensible default installed dir. +#if defined(CLANG_CONFIG_FILE_SYSTEM_DIR) + SystemConfigDir = CLANG_CONFIG_FILE_SYSTEM_DIR; +#endif +#if defined(CLANG_CONFIG_FILE_USER_DIR) + UserConfigDir = CLANG_CONFIG_FILE_USER_DIR; +#endif + // Compute the path to the resource directory. StringRef ClangResourceDir(CLANG_RESOURCE_DIR); SmallString<128> P(Dir); @@ -119,9 +129,8 @@ Driver::Driver(StringRef ClangExecutable, StringRef DefaultTargetTriple, void Driver::ParseDriverMode(StringRef ProgramName, ArrayRef<const char *> Args) { - auto Default = ToolChain::getTargetAndModeFromProgramName(ProgramName); - StringRef DefaultMode(Default.second); - setDriverModeFromOption(DefaultMode); + ClangNameParts = ToolChain::getTargetAndModeFromProgramName(ProgramName); + setDriverModeFromOption(ClangNameParts.DriverMode); for (const char *ArgPtr : Args) { // Ingore nullptrs, they are response file's EOL markers @@ -524,7 +533,7 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C, auto &CudaTC = ToolChains[CudaTriple.str() + "/" + HostTriple.str()]; if (!CudaTC) { CudaTC = llvm::make_unique<toolchains::CudaToolChain>( - *this, CudaTriple, *HostTC, C.getInputArgs()); + *this, CudaTriple, *HostTC, C.getInputArgs(), Action::OFK_Cuda); } C.addOffloadDeviceToolChain(CudaTC.get(), Action::OFK_Cuda); } @@ -579,10 +588,10 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C, C.getSingleOffloadToolChain<Action::OFK_Host>(); assert(HostTC && "Host toolchain should be always defined."); auto &CudaTC = - ToolChains[TT.str() + "/" + HostTC->getTriple().str()]; + ToolChains[TT.str() + "/" + HostTC->getTriple().normalize()]; if (!CudaTC) CudaTC = llvm::make_unique<toolchains::CudaToolChain>( - *this, TT, *HostTC, C.getInputArgs()); + *this, TT, *HostTC, C.getInputArgs(), Action::OFK_OpenMP); TC = CudaTC.get(); } else TC = &getToolChain(C.getInputArgs(), TT); @@ -599,8 +608,216 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C, // // TODO: Add support for other offloading programming models here. // +} + +/// Looks the given directories for the specified file. +/// +/// \param[out] FilePath File path, if the file was found. +/// \param[in] Dirs Directories used for the search. +/// \param[in] FileName Name of the file to search for. +/// \return True if file was found. +/// +/// Looks for file specified by FileName sequentially in directories specified +/// by Dirs. +/// +static bool searchForFile(SmallVectorImpl<char> &FilePath, + ArrayRef<std::string> Dirs, + StringRef FileName) { + SmallString<128> WPath; + for (const StringRef &Dir : Dirs) { + if (Dir.empty()) + continue; + WPath.clear(); + llvm::sys::path::append(WPath, Dir, FileName); + llvm::sys::path::native(WPath); + if (llvm::sys::fs::is_regular_file(WPath)) { + FilePath = std::move(WPath); + return true; + } + } + return false; +} + +bool Driver::readConfigFile(StringRef FileName) { + // Try reading the given file. + SmallVector<const char *, 32> NewCfgArgs; + if (!llvm::cl::readConfigFile(FileName, Saver, NewCfgArgs)) { + Diag(diag::err_drv_cannot_read_config_file) << FileName; + return true; + } + + // Read options from config file. + llvm::SmallString<128> CfgFileName(FileName); + llvm::sys::path::native(CfgFileName); + ConfigFile = CfgFileName.str(); + bool ContainErrors; + CfgOptions = llvm::make_unique<InputArgList>( + ParseArgStrings(NewCfgArgs, ContainErrors)); + if (ContainErrors) { + CfgOptions.reset(); + return true; + } - return; + if (CfgOptions->hasArg(options::OPT_config)) { + CfgOptions.reset(); + Diag(diag::err_drv_nested_config_file); + return true; + } + + // Claim all arguments that come from a configuration file so that the driver + // does not warn on any that is unused. + for (Arg *A : *CfgOptions) + A->claim(); + return false; +} + +bool Driver::loadConfigFile() { + std::string CfgFileName; + bool FileSpecifiedExplicitly = false; + + // Process options that change search path for config files. + if (CLOptions) { + if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) { + SmallString<128> CfgDir; + CfgDir.append( + CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ)); + if (!CfgDir.empty()) { + if (llvm::sys::fs::make_absolute(CfgDir).value() != 0) + SystemConfigDir.clear(); + else + SystemConfigDir = std::string(CfgDir.begin(), CfgDir.end()); + } + } + if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) { + SmallString<128> CfgDir; + CfgDir.append( + CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ)); + if (!CfgDir.empty()) { + if (llvm::sys::fs::make_absolute(CfgDir).value() != 0) + UserConfigDir.clear(); + else + UserConfigDir = std::string(CfgDir.begin(), CfgDir.end()); + } + } + } + + // First try to find config file specified in command line. + if (CLOptions) { + std::vector<std::string> ConfigFiles = + CLOptions->getAllArgValues(options::OPT_config); + if (ConfigFiles.size() > 1) { + Diag(diag::err_drv_duplicate_config); + return true; + } + + if (!ConfigFiles.empty()) { + CfgFileName = ConfigFiles.front(); + assert(!CfgFileName.empty()); + + // If argument contains directory separator, treat it as a path to + // configuration file. + if (llvm::sys::path::has_parent_path(CfgFileName)) { + SmallString<128> CfgFilePath; + if (llvm::sys::path::is_relative(CfgFileName)) + llvm::sys::fs::current_path(CfgFilePath); + llvm::sys::path::append(CfgFilePath, CfgFileName); + if (!llvm::sys::fs::is_regular_file(CfgFilePath)) { + Diag(diag::err_drv_config_file_not_exist) << CfgFilePath; + return true; + } + return readConfigFile(CfgFilePath); + } + + FileSpecifiedExplicitly = true; + } + } + + // If config file is not specified explicitly, try to deduce configuration + // from executable name. For instance, an executable 'armv7l-clang' will + // search for config file 'armv7l-clang.cfg'. + if (CfgFileName.empty() && !ClangNameParts.TargetPrefix.empty()) + CfgFileName = ClangNameParts.TargetPrefix + '-' + ClangNameParts.ModeSuffix; + + if (CfgFileName.empty()) + return false; + + // Determine architecture part of the file name, if it is present. + StringRef CfgFileArch = CfgFileName; + size_t ArchPrefixLen = CfgFileArch.find('-'); + if (ArchPrefixLen == StringRef::npos) + ArchPrefixLen = CfgFileArch.size(); + llvm::Triple CfgTriple; + CfgFileArch = CfgFileArch.take_front(ArchPrefixLen); + CfgTriple = llvm::Triple(llvm::Triple::normalize(CfgFileArch)); + if (CfgTriple.getArch() == llvm::Triple::ArchType::UnknownArch) + ArchPrefixLen = 0; + + if (!StringRef(CfgFileName).endswith(".cfg")) + CfgFileName += ".cfg"; + + // If config file starts with architecture name and command line options + // redefine architecture (with options like -m32 -LE etc), try finding new + // config file with that architecture. + SmallString<128> FixedConfigFile; + size_t FixedArchPrefixLen = 0; + if (ArchPrefixLen) { + // Get architecture name from config file name like 'i386.cfg' or + // 'armv7l-clang.cfg'. + // Check if command line options changes effective triple. + llvm::Triple EffectiveTriple = computeTargetTriple(*this, + CfgTriple.getTriple(), *CLOptions); + if (CfgTriple.getArch() != EffectiveTriple.getArch()) { + FixedConfigFile = EffectiveTriple.getArchName(); + FixedArchPrefixLen = FixedConfigFile.size(); + // Append the rest of original file name so that file name transforms + // like: i386-clang.cfg -> x86_64-clang.cfg. + if (ArchPrefixLen < CfgFileName.size()) + FixedConfigFile += CfgFileName.substr(ArchPrefixLen); + } + } + + // Prepare list of directories where config file is searched for. + SmallVector<std::string, 3> CfgFileSearchDirs; + CfgFileSearchDirs.push_back(UserConfigDir); + CfgFileSearchDirs.push_back(SystemConfigDir); + CfgFileSearchDirs.push_back(Dir); + + // Try to find config file. First try file with corrected architecture. + llvm::SmallString<128> CfgFilePath; + if (!FixedConfigFile.empty()) { + if (searchForFile(CfgFilePath, CfgFileSearchDirs, FixedConfigFile)) + return readConfigFile(CfgFilePath); + // If 'x86_64-clang.cfg' was not found, try 'x86_64.cfg'. + FixedConfigFile.resize(FixedArchPrefixLen); + FixedConfigFile.append(".cfg"); + if (searchForFile(CfgFilePath, CfgFileSearchDirs, FixedConfigFile)) + return readConfigFile(CfgFilePath); + } + + // Then try original file name. + if (searchForFile(CfgFilePath, CfgFileSearchDirs, CfgFileName)) + return readConfigFile(CfgFilePath); + + // Finally try removing driver mode part: 'x86_64-clang.cfg' -> 'x86_64.cfg'. + if (!ClangNameParts.ModeSuffix.empty() && + !ClangNameParts.TargetPrefix.empty()) { + CfgFileName.assign(ClangNameParts.TargetPrefix); + CfgFileName.append(".cfg"); + if (searchForFile(CfgFilePath, CfgFileSearchDirs, CfgFileName)) + return readConfigFile(CfgFilePath); + } + + // Report error but only if config file was specified explicitly, by option + // --config. If it was deduced from executable name, it is not an error. + if (FileSpecifiedExplicitly) { + Diag(diag::err_drv_config_file_not_found) << CfgFileName; + for (const std::string &SearchDir : CfgFileSearchDirs) + if (!SearchDir.empty()) + Diag(diag::note_drv_config_file_searched_in) << SearchDir; + return true; + } + + return false; } Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) { @@ -626,12 +843,35 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) { // FIXME: What are we going to do with -V and -b? + // Arguments specified in command line. + bool ContainsError; + CLOptions = llvm::make_unique<InputArgList>( + ParseArgStrings(ArgList.slice(1), ContainsError)); + + // Try parsing configuration file. + if (!ContainsError) + ContainsError = loadConfigFile(); + bool HasConfigFile = !ContainsError && (CfgOptions.get() != nullptr); + + // All arguments, from both config file and command line. + InputArgList Args = std::move(HasConfigFile ? std::move(*CfgOptions) + : std::move(*CLOptions)); + if (HasConfigFile) + for (auto *Opt : *CLOptions) { + const Arg *BaseArg = &Opt->getBaseArg(); + if (BaseArg == Opt) + BaseArg = nullptr; + Arg *Copy = new llvm::opt::Arg(Opt->getOption(), Opt->getSpelling(), + Args.size(), BaseArg); + Copy->getValues() = Opt->getValues(); + if (Opt->isClaimed()) + Copy->claim(); + Args.append(Copy); + } + // FIXME: This stuff needs to go into the Compilation, not the driver. bool CCCPrintPhases; - bool ContainsError; - InputArgList Args = ParseArgStrings(ArgList.slice(1), ContainsError); - // Silence driver warnings if requested Diags.setIgnoreAllWarnings(Args.hasArg(options::OPT_w)); @@ -664,6 +904,7 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) { T.setOS(llvm::Triple::Win32); T.setVendor(llvm::Triple::PC); T.setEnvironment(llvm::Triple::MSVC); + T.setObjectFormat(llvm::Triple::COFF); DefaultTargetTriple = T.str(); } if (const Arg *A = Args.getLastArg(options::OPT_target)) @@ -678,8 +919,6 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) { SysRoot = A->getValue(); if (const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ)) DyldPrefix = A->getValue(); - if (Args.hasArg(options::OPT_nostdlib)) - UseStdLib = false; if (const Arg *A = Args.getLastArg(options::OPT_resource_dir)) ResourceDir = A->getValue(); @@ -1126,7 +1365,8 @@ void Driver::PrintHelp(bool ShowHidden) const { ExcludedFlagsBitmask |= HelpHidden; getOpts().PrintHelp(llvm::outs(), Name.c_str(), DriverTitle.c_str(), - IncludedFlagsBitmask, ExcludedFlagsBitmask); + IncludedFlagsBitmask, ExcludedFlagsBitmask, + /*ShowAllAliases=*/false); } void Driver::PrintVersion(const Compilation &C, raw_ostream &OS) const { @@ -1147,6 +1387,10 @@ void Driver::PrintVersion(const Compilation &C, raw_ostream &OS) const { // Print out the install directory. OS << "InstalledDir: " << InstalledDir << '\n'; + + // If configuration file was used, print its path. + if (!ConfigFile.empty()) + OS << "Configuration file: " << ConfigFile << '\n'; } /// PrintDiagnosticCategories - Implement the --print-diagnostic-categories @@ -1158,6 +1402,58 @@ static void PrintDiagnosticCategories(raw_ostream &OS) { OS << i << ',' << DiagnosticIDs::getCategoryNameFromID(i) << '\n'; } +void Driver::handleAutocompletions(StringRef PassedFlags) const { + // Print out all options that start with a given argument. This is used for + // shell autocompletion. + std::vector<std::string> SuggestedCompletions; + + unsigned short DisableFlags = + options::NoDriverOption | options::Unsupported | options::Ignored; + // We want to show cc1-only options only when clang is invoked as "clang + // -cc1". When clang is invoked as "clang -cc1", we add "#" to the beginning + // of an --autocomplete option so that the clang driver can distinguish + // whether it is requested to show cc1-only options or not. + if (PassedFlags.size() > 0 && PassedFlags[0] == '#') { + DisableFlags &= ~options::NoDriverOption; + PassedFlags = PassedFlags.substr(1); + } + + if (PassedFlags.find(',') == StringRef::npos) { + // If the flag is in the form of "--autocomplete=-foo", + // we were requested to print out all option names that start with "-foo". + // For example, "--autocomplete=-fsyn" is expanded to "-fsyntax-only". + SuggestedCompletions = Opts->findByPrefix(PassedFlags, DisableFlags); + + // We have to query the -W flags manually as they're not in the OptTable. + // TODO: Find a good way to add them to OptTable instead and them remove + // this code. + for (StringRef S : DiagnosticIDs::getDiagnosticFlags()) + if (S.startswith(PassedFlags)) + SuggestedCompletions.push_back(S); + } else { + // If the flag is in the form of "--autocomplete=foo,bar", we were + // requested to print out all option values for "-foo" that start with + // "bar". For example, + // "--autocomplete=-stdlib=,l" is expanded to "libc++" and "libstdc++". + StringRef Option, Arg; + std::tie(Option, Arg) = PassedFlags.split(','); + SuggestedCompletions = Opts->suggestValueCompletions(Option, Arg); + } + + // Sort the autocomplete candidates so that shells print them out in a + // deterministic order. We could sort in any way, but we chose + // case-insensitive sorting for consistency with the -help option + // which prints out options in the case-insensitive alphabetical order. + std::sort(SuggestedCompletions.begin(), SuggestedCompletions.end(), + [](StringRef A, StringRef B) { + if (int X = A.compare_lower(B)) + return X < 0; + return A.compare(B) > 0; + }); + + llvm::outs() << llvm::join(SuggestedCompletions, "\n") << '\n'; +} + bool Driver::HandleImmediateArgs(const Compilation &C) { // The order these options are handled in gcc is all over the place, but we // don't expect inconsistencies w.r.t. that to matter in practice. @@ -1201,6 +1497,15 @@ bool Driver::HandleImmediateArgs(const Compilation &C) { SuppressMissingInputWarning = true; } + if (C.getArgs().hasArg(options::OPT_v)) { + if (!SystemConfigDir.empty()) + llvm::errs() << "System configuration file directory: " + << SystemConfigDir << "\n"; + if (!UserConfigDir.empty()) + llvm::errs() << "User configuration file directory: " + << UserConfigDir << "\n"; + } + const ToolChain &TC = C.getDefaultToolChain(); if (C.getArgs().hasArg(options::OPT_v)) @@ -1251,55 +1556,15 @@ bool Driver::HandleImmediateArgs(const Compilation &C) { } if (Arg *A = C.getArgs().getLastArg(options::OPT_autocomplete)) { - // Print out all options that start with a given argument. This is used for - // shell autocompletion. StringRef PassedFlags = A->getValue(); - std::vector<std::string> SuggestedCompletions; - - unsigned short DisableFlags = options::NoDriverOption | options::Unsupported | options::Ignored; - // We want to show cc1-only options only when clang is invoked as "clang -cc1". - // When clang is invoked as "clang -cc1", we add "#" to the beginning of an --autocomplete - // option so that the clang driver can distinguish whether it is requested to show cc1-only options or not. - if (PassedFlags[0] == '#') { - DisableFlags &= ~options::NoDriverOption; - PassedFlags = PassedFlags.substr(1); - } - - if (PassedFlags.find(',') == StringRef::npos) { - // If the flag is in the form of "--autocomplete=-foo", - // we were requested to print out all option names that start with "-foo". - // For example, "--autocomplete=-fsyn" is expanded to "-fsyntax-only". - SuggestedCompletions = Opts->findByPrefix(PassedFlags, DisableFlags); - - // We have to query the -W flags manually as they're not in the OptTable. - // TODO: Find a good way to add them to OptTable instead and them remove - // this code. - for (StringRef S : DiagnosticIDs::getDiagnosticFlags()) - if (S.startswith(PassedFlags)) - SuggestedCompletions.push_back(S); - } else { - // If the flag is in the form of "--autocomplete=foo,bar", we were - // requested to print out all option values for "-foo" that start with - // "bar". For example, - // "--autocomplete=-stdlib=,l" is expanded to "libc++" and "libstdc++". - StringRef Option, Arg; - std::tie(Option, Arg) = PassedFlags.split(','); - SuggestedCompletions = Opts->suggestValueCompletions(Option, Arg); - } - - // Sort the autocomplete candidates so that shells print them out in a - // deterministic order. We could sort in any way, but we chose - // case-insensitive sorting for consistency with the -help option - // which prints out options in the case-insensitive alphabetical order. - std::sort(SuggestedCompletions.begin(), SuggestedCompletions.end(), - [](StringRef A, StringRef B) { return A.compare_lower(B) < 0; }); - - llvm::outs() << llvm::join(SuggestedCompletions, "\n") << '\n'; + handleAutocompletions(PassedFlags); return false; } if (C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) { ToolChain::RuntimeLibType RLT = TC.GetRuntimeLibType(C.getArgs()); + const llvm::Triple Triple(TC.ComputeEffectiveClangTriple(C.getArgs())); + RegisterEffectiveTriple TripleRAII(TC, Triple); switch (RLT) { case ToolChain::RLT_CompilerRT: llvm::outs() << TC.getCompilerRT(C.getArgs(), "builtins") << "\n"; @@ -3225,6 +3490,12 @@ InputInfo Driver::BuildJobsForActionNoCache( InputInfoList OffloadDependencesInputInfo; bool BuildingForOffloadDevice = TargetDeviceOffloadKind != Action::OFK_None; if (const OffloadAction *OA = dyn_cast<OffloadAction>(A)) { + // The 'Darwin' toolchain is initialized only when its arguments are + // computed. Get the default arguments for OFK_None to ensure that + // initialization is performed before processing the offload action. + // FIXME: Remove when darwin's toolchain is initialized during construction. + C.getArgsForToolChain(TC, BoundArch, Action::OFK_None); + // The offload action is expected to be used in four different situations. // // a) Set a toolchain/architecture/kind for a host action: @@ -3402,7 +3673,7 @@ InputInfo Driver::BuildJobsForActionNoCache( // Get the unique string identifier for this dependence and cache the // result. CachedResults[{A, GetTriplePlusArchString( - UI.DependentToolChain, UI.DependentBoundArch, + UI.DependentToolChain, BoundArch, UI.DependentOffloadKind)}] = CurI; } @@ -3677,7 +3948,12 @@ std::string Driver::GetFilePath(StringRef Name, const ToolChain &TC) const { return P.str(); } - SmallString<128> P(ResourceDir); + SmallString<128> R(ResourceDir); + llvm::sys::path::append(R, Name); + if (llvm::sys::fs::exists(Twine(R))) + return R.str(); + + SmallString<128> P(TC.getCompilerRTPath()); llvm::sys::path::append(P, Name); if (llvm::sys::fs::exists(Twine(P))) return P.str(); @@ -3810,9 +4086,6 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, case llvm::Triple::OpenBSD: TC = llvm::make_unique<toolchains::OpenBSD>(*this, Target, Args); break; - case llvm::Triple::Bitrig: - TC = llvm::make_unique<toolchains::Bitrig>(*this, Target, Args); - break; case llvm::Triple::NetBSD: TC = llvm::make_unique<toolchains::NetBSD>(*this, Target, Args); break; @@ -3865,7 +4138,13 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, break; case llvm::Triple::MSVC: case llvm::Triple::UnknownEnvironment: - TC = llvm::make_unique<toolchains::MSVCToolChain>(*this, Target, Args); + if (Args.getLastArgValue(options::OPT_fuse_ld_EQ) + .startswith_lower("bfd")) + TC = llvm::make_unique<toolchains::CrossWindowsToolChain>( + *this, Target, Args); + else + TC = + llvm::make_unique<toolchains::MSVCToolChain>(*this, Target, Args); break; } break; |
