[clang] [clang-repl] Teach the default orc runtime finder to search in more locations (PR #175416)
Vassil Vassilev via cfe-commits
cfe-commits at lists.llvm.org
Sun Jan 11 00:16:41 PST 2026
https://github.com/vgvassilev created https://github.com/llvm/llvm-project/pull/175416
This should resolve a recent solaris failure reported in #175322.
>From 7403b2a7dbaf965fe3fa5ce1972b0e4ceb792c4f Mon Sep 17 00:00:00 2001
From: Vassil Vassilev <v.g.vassilev at gmail.com>
Date: Sun, 11 Jan 2026 07:18:57 +0000
Subject: [PATCH] [clang-repl] Teach the default orc runtime finder to search
in more locations.
This should resolve a recent solaris failure.
---
clang/lib/Interpreter/Interpreter.cpp | 117 +++++++++++++++++++-------
1 file changed, 88 insertions(+), 29 deletions(-)
diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp
index 0d9f66c4ff07b..763d298b052f2 100644
--- a/clang/lib/Interpreter/Interpreter.cpp
+++ b/clang/lib/Interpreter/Interpreter.cpp
@@ -270,53 +270,112 @@ IncrementalExecutorBuilder::create(llvm::orc::ThreadSafeContext &TSC,
return std::move(Executor);
}
-llvm::Error
-IncrementalExecutorBuilder::UpdateOrcRuntimePath(const driver::Compilation &C) {
+llvm::Error IncrementalExecutorBuilder::UpdateOrcRuntimePath(
+ const clang::driver::Compilation &C) {
if (!IsOutOfProcess)
return llvm::Error::success();
- const std::array<const char *, 3> OrcRTLibNames = {
- "liborc_rt.a", "liborc_rt_osx.a", "liborc_rt-x86_64.a"};
+ // Candidate runtime filenames to look for (tweak as appropriate).
+ static constexpr std::array<const char *, 3> OrcRTLibNames = {
+ "liborc_rt.a",
+ "liborc_rt_osx.a",
+ "liborc_rt-x86_64.a",
+ };
+ // Return the first file found inside 'Base' (Base may be a directory).
auto findInDir = [&](llvm::StringRef Base) -> std::optional<std::string> {
+ if (Base.empty())
+ return std::nullopt;
for (const char *LibName : OrcRTLibNames) {
- llvm::SmallString<256> CandidatePath(Base);
- llvm::sys::path::append(CandidatePath, LibName);
- if (llvm::sys::fs::exists(CandidatePath))
- return std::string(CandidatePath.str());
+ llvm::SmallString<256> Candidate(Base);
+ llvm::sys::path::append(Candidate, LibName);
+ if (llvm::sys::fs::exists(Candidate))
+ return std::string(Candidate.str());
}
return std::nullopt;
};
- const driver::ToolChain &TC = C.getDefaultToolChain();
- std::string SearchedPaths;
- if (std::optional<std::string> CompilerRTPath = TC.getCompilerRTPath()) {
- if (auto Found = findInDir(*CompilerRTPath)) {
- OrcRuntimePath = *Found;
+ const clang::driver::Driver &D = C.getDriver();
+
+ llvm::SmallVector<std::string, 8> triedPaths;
+
+ // Prefer Driver::ResourceDir-derived locations:
+ // ResourceDir is typically: <prefix>/lib/clang/<version>
+ if (!D.ResourceDir.empty()) {
+ llvm::SmallString<256> Resource(D.ResourceDir);
+
+ // Directly searching ResourceDir is cheap and sometimes sufficient.
+ if (auto F = findInDir(Resource)) {
+ OrcRuntimePath = *F;
return llvm::Error::success();
}
- SearchedPaths += *CompilerRTPath;
- } else {
- return llvm::make_error<llvm::StringError>("CompilerRT path not found",
- std::error_code());
+ triedPaths.emplace_back(std::string(Resource.str()));
+
+ // Build <prefix>/lib/clang/<version>/lib. Resource already contains
+ // .../clang/<version>)
+ llvm::SmallString<256> ClangLibDir(Resource);
+ // ClangLibDir currently: <prefix>/lib/clang/<version>
+ // We want: <prefix>/lib/clang/<version>/lib
+ llvm::sys::path::append(ClangLibDir, "lib");
+ if (auto F = findInDir(ClangLibDir)) {
+ OrcRuntimePath = *F;
+ return llvm::Error::success();
+ }
+ triedPaths.emplace_back(std::string(ClangLibDir.str()));
+
+ // Walk up to <prefix>/lib and search there and common variants.
+ llvm::SmallString<256> PrefixLib = Resource;
+ llvm::sys::path::remove_filename(PrefixLib); // remove <version>
+ llvm::sys::path::remove_filename(PrefixLib); // remove clang
+ if (!PrefixLib.empty()) {
+ if (auto F = findInDir(PrefixLib)) {
+ OrcRuntimePath = *F;
+ return llvm::Error::success();
+ }
+ triedPaths.emplace_back(std::string(PrefixLib.str()));
+
+ // Also check <prefix>/<libdir_basename>/clang/<version>/lib if present in
+ // this environment. We extract version from the original ResourceDir
+ // filename (the '<version>' component).
+ llvm::SmallString<64> Version =
+ llvm::sys::path::filename(llvm::StringRef(Resource));
+ llvm::SmallString<256> FormalClangLib = PrefixLib;
+ llvm::sys::path::append(FormalClangLib, "lib", "clang", Version, "lib");
+ if (auto F = findInDir(FormalClangLib)) {
+ OrcRuntimePath = *F;
+ return llvm::Error::success();
+ }
+ triedPaths.emplace_back(std::string(FormalClangLib.str()));
+ }
}
- if (std::optional<std::string> ResourceDir = TC.getRuntimePath()) {
- if (auto Found = findInDir(*ResourceDir)) {
- OrcRuntimePath = *Found;
- return llvm::Error::success();
+ // ToolChain runtime/compiler-rt locations (if available).
+ const clang::driver::ToolChain &TC = C.getDefaultToolChain();
+ for (auto RuntimePath :
+ {TC.getRuntimePath(), std::make_optional(TC.getCompilerRTPath())}) {
+ if (RuntimePath && TC.getVFS().exists(*RuntimePath)) {
+ if (auto Found = findInDir(*RuntimePath)) {
+ OrcRuntimePath = *Found;
+ return llvm::Error::success();
+ } else {
+ triedPaths.emplace_back(*RuntimePath);
+ }
}
- if (!SearchedPaths.empty())
- SearchedPaths += "; ";
- SearchedPaths += *ResourceDir;
- } else {
- return llvm::make_error<llvm::StringError>("ResourceDir path not found",
- std::error_code());
}
+ // If we reached here, nothing was found. Build a helpful error string.
+ std::string Joined;
+ for (size_t i = 0; i < triedPaths.size(); ++i) {
+ if (i)
+ Joined += ", ";
+ Joined += triedPaths[i];
+ }
+ if (Joined.empty())
+ Joined = "<no candidate paths available>";
+
return llvm::make_error<llvm::StringError>(
- llvm::Twine("OrcRuntime library not found in: ") + SearchedPaths,
- std::error_code());
+ llvm::formatv("OrcRuntime library not found in: {0}", Joined).str(),
+ llvm::inconvertibleErrorCode());
}
Interpreter::Interpreter(std::unique_ptr<CompilerInstance> Instance,
More information about the cfe-commits
mailing list