https://github.com/dankm updated https://github.com/llvm/llvm-project/pull/65812:
>From 416d75e617cc87b6e497815ce6ad1da630eb14a1 Mon Sep 17 00:00:00 2001 From: Dan McGregor <dan.mcgre...@usask.ca> Date: Mon, 14 Aug 2023 18:44:08 -0600 Subject: [PATCH 1/2] Support: hoist lld's executable name code to Path Instead of using custom code to find the program name throughout the codebase, write one function as a path helper to consistently determine the program name. This globally correctly finds target names with dots in them (ie freebsd13.2). --- lld/COFF/Driver.cpp | 2 +- lld/Common/Args.cpp | 6 ------ lld/ELF/Driver.cpp | 2 +- lld/MachO/Driver.cpp | 2 +- lld/include/lld/Common/Args.h | 2 -- lld/wasm/Driver.cpp | 2 +- lldb/tools/driver/Driver.cpp | 2 +- llvm/include/llvm/Support/Path.h | 15 +++++++++++++++ llvm/lib/Support/Path.cpp | 8 ++++++++ llvm/tools/llvm-ar/llvm-ar.cpp | 3 ++- llvm/tools/llvm-cov/llvm-cov.cpp | 2 +- llvm/tools/llvm-driver/llvm-driver.cpp | 2 +- llvm/tools/llvm-objcopy/llvm-objcopy.cpp | 2 +- llvm/tools/llvm-objdump/llvm-objdump.cpp | 2 +- llvm/tools/llvm-rc/llvm-rc.cpp | 2 +- llvm/tools/llvm-readobj/llvm-readobj.cpp | 2 +- llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp | 2 +- 17 files changed, 37 insertions(+), 21 deletions(-) diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index d7476e91e03e384..03a63bf3a306b4d 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -68,7 +68,7 @@ bool link(ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS, auto *ctx = new COFFLinkerContext; ctx->e.initialize(stdoutOS, stderrOS, exitEarly, disableOutput); - ctx->e.logName = args::getFilenameWithoutExe(args[0]); + ctx->e.logName = sys::path::program_name(args[0]); ctx->e.errorLimitExceededMsg = "too many errors emitted, stopping now" " (use /errorlimit:0 to see all errors)"; diff --git a/lld/Common/Args.cpp b/lld/Common/Args.cpp index 48c934df3a2c931..b02d023fe19aeb5 100644 --- a/lld/Common/Args.cpp +++ b/lld/Common/Args.cpp @@ -85,9 +85,3 @@ std::vector<StringRef> lld::args::getLines(MemoryBufferRef mb) { } return ret; } - -StringRef lld::args::getFilenameWithoutExe(StringRef path) { - if (path.ends_with_insensitive(".exe")) - return sys::path::stem(path); - return sys::path::filename(path); -} diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 9d167293574fa64..957d0da1589caf8 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -143,7 +143,7 @@ bool link(ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS, SharedFile::vernauxNum = 0; }; - ctx->e.logName = args::getFilenameWithoutExe(args[0]); + ctx->e.logName = sys::path::program_name(args[0]); ctx->e.errorLimitExceededMsg = "too many errors emitted, stopping now (use " "--error-limit=0 to see all errors)"; diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp index 00ff3439a043be9..ed0b66d4b2ec6ba 100644 --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -1428,7 +1428,7 @@ bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS, InputFile::resetIdCount(); }; - ctx->e.logName = args::getFilenameWithoutExe(argsArr[0]); + ctx->e.logName = sys::path::program_name(argsArr[0]); MachOOptTable parser; InputArgList args = parser.parse(argsArr.slice(1)); diff --git a/lld/include/lld/Common/Args.h b/lld/include/lld/Common/Args.h index 60f83fbbbf1a3c9..8822707a6a1f212 100644 --- a/lld/include/lld/Common/Args.h +++ b/lld/include/lld/Common/Args.h @@ -38,8 +38,6 @@ uint64_t getZOptionValue(llvm::opt::InputArgList &args, int id, StringRef key, std::vector<StringRef> getLines(MemoryBufferRef mb); -StringRef getFilenameWithoutExe(StringRef path); - } // namespace args } // namespace lld diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp index c2f5f0185781f36..f13aa520f35b100 100644 --- a/lld/wasm/Driver.cpp +++ b/lld/wasm/Driver.cpp @@ -89,7 +89,7 @@ bool link(ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS, auto *ctx = new CommonLinkerContext; ctx->e.initialize(stdoutOS, stderrOS, exitEarly, disableOutput); - ctx->e.logName = args::getFilenameWithoutExe(args[0]); + ctx->e.logName = sys::path::program_name(args[0]); ctx->e.errorLimitExceededMsg = "too many errors emitted, stopping now (use " "-error-limit=0 to see all errors)"; diff --git a/lldb/tools/driver/Driver.cpp b/lldb/tools/driver/Driver.cpp index f8058f868d53ffe..2fb760ca97a001d 100644 --- a/lldb/tools/driver/Driver.cpp +++ b/lldb/tools/driver/Driver.cpp @@ -754,7 +754,7 @@ int main(int argc, char const *argv[]) { ArrayRef<const char *> arg_arr = ArrayRef(argv + 1, argc - 1); opt::InputArgList input_args = T.ParseArgs(arg_arr, MissingArgIndex, MissingArgCount); - llvm::StringRef argv0 = llvm::sys::path::filename(argv[0]); + llvm::StringRef argv0 = llvm::sys::path::program_name(argv[0]); if (input_args.hasArg(OPT_help)) { printHelp(T, argv0); diff --git a/llvm/include/llvm/Support/Path.h b/llvm/include/llvm/Support/Path.h index ce69f32b6cc81ba..405fdc03e020851 100644 --- a/llvm/include/llvm/Support/Path.h +++ b/llvm/include/llvm/Support/Path.h @@ -390,6 +390,21 @@ StringRef stem(StringRef path, Style style = Style::native); /// @result The extension of \a path. StringRef extension(StringRef path, Style style = Style::native); +/// Get the program's name +/// +/// If the path ends with the string .exe, returns the stem of +/// \a path. Otherwise returns the filename of \a path. +/// +/// @code +/// /foo/prog.exe => prog +/// /bar/prog => prog +/// /foo/prog1.2 => prog1.2 +/// @endcode +/// +/// @param path Input path. +/// @result The filename of \a path. Without any .exe component +StringRef program_name(StringRef path, Style style = Style::native); + /// Check whether the given char is a path separator on the host OS. /// /// @param value a character diff --git a/llvm/lib/Support/Path.cpp b/llvm/lib/Support/Path.cpp index 7a57c104ef10e7b..5940c99f203c771 100644 --- a/llvm/lib/Support/Path.cpp +++ b/llvm/lib/Support/Path.cpp @@ -600,6 +600,14 @@ StringRef extension(StringRef path, Style style) { return fname.substr(pos); } +StringRef program_name(StringRef path, Style style) { + // In the future this may need to be extended to other + // program suffixes. + if (path.ends_with_insensitive(".exe")) + return stem(path, style); + return filename(path, style); +} + bool is_separator(char value, Style style) { if (value == '/') return true; diff --git a/llvm/tools/llvm-ar/llvm-ar.cpp b/llvm/tools/llvm-ar/llvm-ar.cpp index 9889ad9de627d51..68b79cb007d1e98 100644 --- a/llvm/tools/llvm-ar/llvm-ar.cpp +++ b/llvm/tools/llvm-ar/llvm-ar.cpp @@ -1508,7 +1508,8 @@ int llvm_ar_main(int argc, char **argv, const llvm::ToolContext &) { llvm::InitializeAllTargetMCs(); llvm::InitializeAllAsmParsers(); - Stem = sys::path::stem(ToolName); + Stem = sys::path::program_name(ToolName); + auto Is = [](StringRef Tool) { // We need to recognize the following filenames. // diff --git a/llvm/tools/llvm-cov/llvm-cov.cpp b/llvm/tools/llvm-cov/llvm-cov.cpp index 5ada55789b24677..e0b9e75f57c441f 100644 --- a/llvm/tools/llvm-cov/llvm-cov.cpp +++ b/llvm/tools/llvm-cov/llvm-cov.cpp @@ -59,7 +59,7 @@ int main(int argc, const char **argv) { InitLLVM X(argc, argv); // If argv[0] is or ends with 'gcov', always be gcov compatible - if (sys::path::stem(argv[0]).ends_with_insensitive("gcov")) + if (sys::path::program_name(argv[0]).ends_with_insensitive("gcov")) return gcovMain(argc, argv); // Check if we are invoking a specific tool command. diff --git a/llvm/tools/llvm-driver/llvm-driver.cpp b/llvm/tools/llvm-driver/llvm-driver.cpp index a0f1ca831d93b6a..ffb3bc0f3a6fdc3 100644 --- a/llvm/tools/llvm-driver/llvm-driver.cpp +++ b/llvm/tools/llvm-driver/llvm-driver.cpp @@ -48,7 +48,7 @@ static int findTool(int Argc, char **Argv, const char *Argv0) { return 0; } - StringRef Stem = sys::path::stem(ToolName); + StringRef Stem = sys::path::program_name(ToolName); auto Is = [=](StringRef Tool) { auto IsImpl = [=](StringRef Stem) { auto I = Stem.rfind_insensitive(Tool); diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp index 2afa97601f5cfd8..9c51958198cb109 100644 --- a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp +++ b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp @@ -74,7 +74,7 @@ static ErrorSuccess reportWarning(Error E) { } static Expected<DriverConfig> getDriverConfig(ArrayRef<const char *> Args) { - StringRef Stem = sys::path::stem(ToolName); + StringRef Stem = sys::path::program_name(ToolName); auto Is = [=](StringRef Tool) { // We need to recognize the following filenames: // diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp index e4e1ceb9b3f97f6..f6a8417afd72c26 100644 --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -3297,7 +3297,7 @@ int llvm_objdump_main(int argc, char **argv, const llvm::ToolContext &) { std::unique_ptr<CommonOptTable> T; OptSpecifier Unknown, HelpFlag, HelpHiddenFlag, VersionFlag; - StringRef Stem = sys::path::stem(ToolName); + StringRef Stem = sys::path::program_name(ToolName); auto Is = [=](StringRef Tool) { // We need to recognize the following filenames: // diff --git a/llvm/tools/llvm-rc/llvm-rc.cpp b/llvm/tools/llvm-rc/llvm-rc.cpp index b955347f2a8646e..2f93a4931f55a6e 100644 --- a/llvm/tools/llvm-rc/llvm-rc.cpp +++ b/llvm/tools/llvm-rc/llvm-rc.cpp @@ -276,7 +276,7 @@ void preprocess(StringRef Src, StringRef Dst, const RcOptions &Opts, } static std::pair<bool, std::string> isWindres(llvm::StringRef Argv0) { - StringRef ProgName = llvm::sys::path::stem(Argv0); + StringRef ProgName = sys::path::program_name(Argv0); // x86_64-w64-mingw32-windres -> x86_64-w64-mingw32, windres // llvm-rc -> "", llvm-rc // aarch64-w64-mingw32-llvm-windres-10.exe -> aarch64-w64-mingw32, llvm-windres diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp index ca633ceff90800e..2735d31202c6e70 100644 --- a/llvm/tools/llvm-readobj/llvm-readobj.cpp +++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp @@ -657,7 +657,7 @@ int llvm_readobj_main(int argc, char **argv, const llvm::ToolContext &) { return 0; } - if (sys::path::stem(argv[0]).contains("readelf")) + if (sys::path::filename(argv[0]).contains("readelf")) opts::Output = opts::GNU; parseOptions(Args); diff --git a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp index 78a0e6772f3fb36..e06a4a0b8fa4827 100644 --- a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp +++ b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp @@ -432,7 +432,7 @@ int llvm_symbolizer_main(int argc, char **argv, const llvm::ToolContext &) { sys::InitializeCOMRAII COM(sys::COMThreadingMode::MultiThreaded); ToolName = argv[0]; - bool IsAddr2Line = sys::path::stem(ToolName).contains("addr2line"); + bool IsAddr2Line = sys::path::filename(ToolName).contains("addr2line"); BumpPtrAllocator A; StringSaver Saver(A); SymbolizerOptTable Tbl; >From 2cec6014163c8557d41fac21c78ab4a5cb536350 Mon Sep 17 00:00:00 2001 From: Dan McGregor <dan.mcgre...@usask.ca> Date: Thu, 14 Sep 2023 13:16:04 -0600 Subject: [PATCH 2/2] Add tests for program_name path function. Simple clang test for now, tests in lld and other tools coming soon. --- clang/lib/Driver/ToolChain.cpp | 9 +------ clang/unittests/Driver/ToolChainTest.cpp | 5 ++++ llvm/test/tools/llvm-ar/tool-name.test | 6 +++++ llvm/unittests/Support/Path.cpp | 32 ++++++++++++++++++++++++ 4 files changed, 44 insertions(+), 8 deletions(-) diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 410757d5f9e1843..7712ff71e9f0c05 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -326,7 +326,7 @@ static const DriverSuffix *FindDriverSuffix(StringRef ProgName, size_t &Pos) { /// Normalize the program name from argv[0] by stripping the file extension if /// present and lower-casing the string on Windows. static std::string normalizeProgramName(llvm::StringRef Argv0) { - std::string ProgName = std::string(llvm::sys::path::filename(Argv0)); + std::string ProgName = std::string(sys::path::program_name(Argv0)); if (is_style_windows(llvm::sys::path::Style::native)) { // Transform to lowercase for case insensitive file systems. std::transform(ProgName.begin(), ProgName.end(), ProgName.begin(), @@ -345,13 +345,6 @@ static const DriverSuffix *parseDriverSuffix(StringRef ProgName, size_t &Pos) { // added via -target as implicit first argument. const DriverSuffix *DS = FindDriverSuffix(ProgName, Pos); - if (!DS && ProgName.endswith(".exe")) { - // Try again after stripping the executable suffix: - // clang++.exe -> clang++ - ProgName = ProgName.drop_back(StringRef(".exe").size()); - DS = FindDriverSuffix(ProgName, Pos); - } - if (!DS) { // Try again after stripping any trailing version number: // clang++3.5 -> clang++ diff --git a/clang/unittests/Driver/ToolChainTest.cpp b/clang/unittests/Driver/ToolChainTest.cpp index ae567abb81a9bb4..1542b099c5fd1b7 100644 --- a/clang/unittests/Driver/ToolChainTest.cpp +++ b/clang/unittests/Driver/ToolChainTest.cpp @@ -430,6 +430,11 @@ TEST(ToolChainTest, GetTargetAndMode) { EXPECT_STREQ(Res.DriverMode, "--driver-mode=g++"); EXPECT_TRUE(Res.TargetIsValid); + Res = ToolChain::getTargetAndModeFromProgramName( + "x86_64-unknown-freebsd13.2-clang-c++"); + EXPECT_TRUE(Res.TargetPrefix == "x86_64-unknown-freebsd13.2"); + EXPECT_TRUE(Res.TargetIsValid); + Res = ToolChain::getTargetAndModeFromProgramName( "x86_64-linux-gnu-clang-c++-tot"); EXPECT_TRUE(Res.TargetPrefix == "x86_64-linux-gnu"); diff --git a/llvm/test/tools/llvm-ar/tool-name.test b/llvm/test/tools/llvm-ar/tool-name.test index f91ef716d5c3adb..ab25b4e630fbb27 100644 --- a/llvm/test/tools/llvm-ar/tool-name.test +++ b/llvm/test/tools/llvm-ar/tool-name.test @@ -5,11 +5,15 @@ # RUN: mkdir %t # RUN: ln -s llvm-ar %t/llvm-ar-9 # RUN: ln -s llvm-ar %t/ar.exe +# RUN: ln -s llvm-ar %t/x86_64-portbld-freebsd13.2-llvm-ar +# RUN: ln -s llvm-ar %t/x86_64-portbld-freebsd13.2-llvm-ar.exe # RUN: ln -s llvm-ar %t/arm-pokymllib32-linux-gnueabi-llvm-ar-9 # RUN: llvm-ar h | FileCheck %s --check-prefix=DEFAULT # RUN: %t/llvm-ar-9 h | FileCheck %s --check-prefix=VERSION # RUN: %t/ar.exe h | FileCheck %s --check-prefix=SUFFIX +# RUN: %t/x86_64-portbld-freebsd13.2-llvm-ar h | FileCheck %s --check-prefix=TARGETDOT +# RUN: %t/x86_64-portbld-freebsd13.2-llvm-ar.exe h | FileCheck %s --check-prefix=MULTIDOT ## Ensure that the "lib" substring does not result in misidentification as the ## llvm-lib tool. # RUN: %t/arm-pokymllib32-linux-gnueabi-llvm-ar-9 h | FileCheck %s --check-prefix=ARM @@ -17,4 +21,6 @@ # DEFAULT: USAGE: llvm-ar{{ }} # VERSION: USAGE: llvm-ar-9{{ }} # SUFFIX: USAGE: ar{{ }} +# TARGETDOT: USAGE: x86_64-portbld-freebsd13.2-llvm-ar{{ }} +# MULTIDOT: USAGE: x86_64-portbld-freebsd13.2-llvm-ar{{ }} # ARM: USAGE: arm-pokymllib32-linux-gnueabi-llvm-ar-9{{ }} diff --git a/llvm/unittests/Support/Path.cpp b/llvm/unittests/Support/Path.cpp index 35a01aa27667933..7f8ed9643451052 100644 --- a/llvm/unittests/Support/Path.cpp +++ b/llvm/unittests/Support/Path.cpp @@ -1696,6 +1696,38 @@ TEST(Support, ReplacePathPrefix) { EXPECT_EQ(Path, "C:\\old/foo\\bar"); } +TEST(Support, FindProgramName) { + StringRef WindowsProgName = path::program_name("C:\\Test\\foo.exe", path::Style::windows); + EXPECT_EQ(WindowsProgName, "foo"); + + StringRef WindowsProgNameManyDots = path::program_name( + "C:\\Test.7\\x86_64-freebsd14.0-clang.exe", path::Style::windows); + EXPECT_EQ(WindowsProgNameManyDots, "x86_64-freebsd14.0-clang"); + + StringRef PosixProgName = path::program_name("/var/empty/clang.exe", + path::Style::posix); + EXPECT_EQ(PosixProgName, "clang"); + + StringRef PosixProgNameManyDotsExe = path::program_name( + "/llvm-test16.4/x86_64-portbld-freebsd13.2-llvm-ar.exe", + path::Style::posix); + EXPECT_EQ(PosixProgNameManyDotsExe, "x86_64-portbld-freebsd13.2-llvm-ar"); + + StringRef PosixProgNameManyDots = path::program_name( + "/llvm-test16.4/x86_64-portbld-freebsd13.2-llvm-ar", + path::Style::posix); + EXPECT_EQ(PosixProgNameManyDots, "x86_64-portbld-freebsd13.2-llvm-ar"); + + StringRef PosixProgNameSh = path::program_name( + "/llvm-test16.4/x86_64-portbld-freebsd13.2-llvm-ar.sh", + path::Style::posix); + EXPECT_EQ(PosixProgNameSh, "x86_64-portbld-freebsd13.2-llvm-ar.sh"); + + StringRef WorseThanFailure = path::program_name("/var/empty/.exe", path::Style::posix); + EXPECT_EQ(WorseThanFailure, ""); + +} + TEST_F(FileSystemTest, OpenFileForRead) { // Create a temp file. int FileDescriptor; _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits