diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -500,8 +501,8 @@ StringRef Component, FileType Type = ToolChain::FT_Static) const; - // Returns target specific runtime paths. - path_list getRuntimePaths() const; + // Returns the target specific runtime path if it exists. + std::optional getRuntimePath() const; // Returns target specific standard library paths. path_list getStdlibPaths() const; diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -2163,16 +2163,8 @@ } if (C.getArgs().hasArg(options::OPT_print_runtime_dir)) { - std::string RuntimePath; - // Get the first existing path, if any. - for (auto Path : TC.getRuntimePaths()) { - if (getVFS().exists(Path)) { - RuntimePath = Path; - break; - } - } - if (!RuntimePath.empty()) - llvm::outs() << RuntimePath << '\n'; + if (std::optional RuntimePath = TC.getRuntimePath()) + llvm::outs() << *RuntimePath << '\n'; else llvm::outs() << TC.getCompilerRTPath() << '\n'; return false; diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -86,8 +86,8 @@ List.push_back(Path); }; - for (const auto &Path : getRuntimePaths()) - addIfExists(getLibraryPaths(), Path); + if (std::optional Path = getRuntimePath()) + getLibraryPaths().push_back(*Path); for (const auto &Path : getStdlibPaths()) addIfExists(getFilePaths(), Path); for (const auto &Path : getArchSpecificLibPaths()) @@ -677,15 +677,18 @@ return Args.MakeArgString(getCompilerRT(Args, Component, Type)); } -ToolChain::path_list ToolChain::getRuntimePaths() const { - path_list Paths; - auto addPathForTriple = [this, &Paths](const llvm::Triple &Triple) { +std::optional ToolChain::getRuntimePath() const { + auto getPathForTriple = + [this](const llvm::Triple &Triple) -> std::optional { SmallString<128> P(D.ResourceDir); llvm::sys::path::append(P, "lib", Triple.str()); - Paths.push_back(std::string(P.str())); + if (getVFS().exists(P)) + return std::string(P); + return {}; }; - addPathForTriple(getTriple()); + if (auto Path = getPathForTriple(getTriple())) + return *Path; // When building with per target runtime directories, various ways of naming // the Arm architecture may have been normalised to simply "arm". @@ -705,7 +708,8 @@ if (getTriple().getArch() == Triple::arm && !getTriple().isArmMClass()) { llvm::Triple ArmTriple = getTriple(); ArmTriple.setArch(Triple::arm); - addPathForTriple(ArmTriple); + if (auto Path = getPathForTriple(ArmTriple)) + return *Path; } // Android targets may include an API level at the end. We still want to fall @@ -714,10 +718,11 @@ getTriple().getEnvironmentName() != "android") { llvm::Triple TripleWithoutLevel = getTriple(); TripleWithoutLevel.setEnvironmentName("android"); - addPathForTriple(TripleWithoutLevel); + if (auto Path = getPathForTriple(TripleWithoutLevel)) + return *Path; } - return Paths; + return {}; } ToolChain::path_list ToolChain::getStdlibPaths() const {