https://github.com/AdityaSinha149 updated https://github.com/llvm/llvm-project/pull/238477
>From 332d86e7cda0036804e6bd883b335efaef48a76c Mon Sep 17 00:00:00 2001 From: AdityaSinha149 <[email protected]> Date: Tue, 3 Nov 2026 23:40:49 +0530 Subject: [PATCH] [clang][Driver] NFC: Share -B and --ld-path lookup helpers --- clang/include/clang/Driver/CommonArgs.h | 16 ++++++++ clang/lib/Driver/Driver.cpp | 29 ++------------ clang/lib/Driver/ToolChain.cpp | 17 ++++---- clang/lib/Driver/ToolChains/CommonArgs.cpp | 45 ++++++++++++++++++++++ 4 files changed, 73 insertions(+), 34 deletions(-) diff --git a/clang/include/clang/Driver/CommonArgs.h b/clang/include/clang/Driver/CommonArgs.h index 138e18f8641b90..c7b648f0001fcc 100644 --- a/clang/include/clang/Driver/CommonArgs.h +++ b/clang/include/clang/Driver/CommonArgs.h @@ -19,6 +19,7 @@ #include "llvm/Option/Arg.h" #include "llvm/Option/ArgList.h" #include "llvm/Support/CodeGen.h" +#include <optional> namespace clang { namespace driver { @@ -40,6 +41,21 @@ OffloadJobsOpt parseOffloadJobs(const llvm::opt::ArgList &Args); void addPathIfExists(const Driver &D, const Twine &Path, ToolChain::path_list &Paths); +/// Appends the -B prefixes and then the COMPILER_PATH entries to +/// \p PrefixDirs. +void addPrefixDirs(const llvm::opt::ArgList &Args, + SmallVectorImpl<std::string> &PrefixDirs); + +/// Looks for the program \p Name in \p PrefixDirs. \p Name is looked up in a +/// prefix that is a directory and appended to any other prefix. +std::optional<std::string> +findProgramInPrefixDirs(StringRef Name, ArrayRef<std::string> PrefixDirs); + +/// Resolves the --ld-path= value \p LdPath. \p FoundPath is where the caller's +/// program search found \p LdPath by name; it is used only when \p LdPath has +/// no directory part. Returns std::nullopt if the result is not executable. +std::optional<std::string> resolveLdPath(StringRef LdPath, StringRef FoundPath); + void AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, const JobAction &JA); diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 37fb69baf6a3eb..fe861454b5ad68 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -1697,20 +1697,7 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) { TargetTriple = A->getValue(); if (const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir)) Dir = A->getValue(); - for (const Arg *A : Args.filtered(options::OPT_B)) { - A->claim(); - PrefixDirs.push_back(A->getValue(0)); - } - if (std::optional<std::string> CompilerPathValue = - llvm::sys::Process::GetEnv("COMPILER_PATH")) { - StringRef CompilerPath = *CompilerPathValue; - while (!CompilerPath.empty()) { - std::pair<StringRef, StringRef> Split = - CompilerPath.split(llvm::sys::EnvPathSeparator); - PrefixDirs.push_back(std::string(Split.first)); - CompilerPath = Split.second; - } - } + tools::addPrefixDirs(Args, PrefixDirs); if (const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ)) SysRoot = A->getValue(); if (const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ)) @@ -5985,17 +5972,9 @@ std::string Driver::GetProgramPath(StringRef Name, const ToolChain &TC) const { // Respect a limited subset of the '-Bprefix' functionality in GCC by // attempting to use this prefix when looking for program paths. - for (const auto &PrefixDir : PrefixDirs) { - if (llvm::sys::fs::is_directory(PrefixDir)) { - SmallString<128> P(PrefixDir); - if (ScanDirForExecutable(P, Name)) - return std::string(P); - } else { - SmallString<128> P((PrefixDir + Name).str()); - if (llvm::sys::fs::can_execute(Twine(P))) - return std::string(P); - } - } + if (std::optional<std::string> P = + tools::findProgramInPrefixDirs(Name, PrefixDirs)) + return *P; const ToolChain::path_list &List = TC.getProgramPaths(); for (const auto &TargetSpecificExecutable : TargetSpecificExecutables) { diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index b3e7043a64fe56..46e5ad52f28bdf 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -1321,15 +1321,14 @@ std::string ToolChain::GetLinkerPath(bool *LinkerIsLLD) const { // -fuse-ld=lld can be used with --ld-path= to inform clang that the binary // that --ld-path= points to is lld. if (const Arg *A = Args.getLastArg(options::OPT_ld_path_EQ)) { - std::string Path(A->getValue()); - if (!Path.empty()) { - if (llvm::sys::path::parent_path(Path).empty()) - Path = GetProgramPath(A->getValue()); - if (llvm::sys::fs::can_execute(Path)) { - if (LinkerIsLLD) - *LinkerIsLLD = UseLinker == "lld"; - return std::string(Path); - } + StringRef LdPath = A->getValue(); + // An empty name must not be searched for: findProgramByName asserts. + std::string FoundPath = LdPath.empty() ? "" : GetProgramPath(A->getValue()); + if (std::optional<std::string> Path = + tools::resolveLdPath(LdPath, FoundPath)) { + if (LinkerIsLLD) + *LinkerIsLLD = UseLinker == "lld"; + return *Path; } getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args); return GetProgramPath(getDefaultLinker()); diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 0590c297edf397..21e0a6f6ba1030 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -392,6 +392,51 @@ void tools::addPathIfExists(const Driver &D, const Twine &Path, Paths.push_back(Path.str()); } +void tools::addPrefixDirs(const ArgList &Args, + SmallVectorImpl<std::string> &PrefixDirs) { + for (const Arg *A : Args.filtered(options::OPT_B)) { + A->claim(); + PrefixDirs.push_back(A->getValue(0)); + } + if (std::optional<std::string> CompilerPathValue = + llvm::sys::Process::GetEnv("COMPILER_PATH")) { + StringRef CompilerPath = *CompilerPathValue; + while (!CompilerPath.empty()) { + std::pair<StringRef, StringRef> Split = + CompilerPath.split(llvm::sys::EnvPathSeparator); + PrefixDirs.push_back(std::string(Split.first)); + CompilerPath = Split.second; + } + } +} + +std::optional<std::string> +tools::findProgramInPrefixDirs(StringRef Name, + ArrayRef<std::string> PrefixDirs) { + for (const std::string &PrefixDir : PrefixDirs) { + SmallString<128> P(PrefixDir); + if (llvm::sys::fs::is_directory(PrefixDir)) + llvm::sys::path::append(P, Name); + else + P += Name; + if (llvm::sys::fs::can_execute(P)) + return std::string(P); + } + return std::nullopt; +} + +std::optional<std::string> tools::resolveLdPath(StringRef LdPath, + StringRef FoundPath) { + if (LdPath.empty()) + return std::nullopt; + std::string Path = llvm::sys::path::parent_path(LdPath).empty() + ? FoundPath.str() + : LdPath.str(); + if (!llvm::sys::fs::can_execute(Path)) + return std::nullopt; + return Path; +} + void tools::handleTargetFeaturesGroup(const Driver &D, const llvm::Triple &Triple, const ArgList &Args, _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
