[clang] Fix clang finding the wrong resource paths (PR #164234)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Oct 20 04:34:36 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Lachlan Frawley (Lachlan-Frawley)
<details>
<summary>Changes</summary>
Fix clang finding the wrong resource paths by giving `clang_parseTranslationUnit2()` the path to libclang instead of just 'clang'.
Seems related to https://github.com/llvm/llvm-project/issues/18150 and https://github.com/llvm/llvm-project/issues/51256
Minimal example repo: https://github.com/Lachlan-Frawley/libclang-resource-path-minimal-example
Having thought about this a bit, I've considered it might be the wrong approach to solve the problem, but it does work.
Before fix is applied (showing bad resource paths):
```
clang version 22.0.0git (https://github.com/Lachlan-Frawley/llvm-project.git 5b5eacc5790365b90878a79893325bfae00ed693)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir:
Found candidate GCC installation: /../lib/gcc/x86_64-linux-gnu/11
Found candidate GCC installation: /../lib/gcc/x86_64-linux-gnu/12
Selected GCC installation: /../lib/gcc/x86_64-linux-gnu/12
Candidate multilib: .;@<!-- -->m64
Candidate multilib: 32;@<!-- -->m32
Candidate multilib: x32;@<!-- -->mx32
Selected multilib: .;@<!-- -->m64
ignoring nonexistent directory "lib/clang/22/include"
ignoring nonexistent directory "/../lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/include"
ignoring nonexistent directory "/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
my-cpp-header.h:4:10: fatal error: 'cstdint' file not found
MY_CONSTEXPR_VALUE -> 0
```
After changes here are applied (correct resource paths):
```
clang version 22.0.0git (https://github.com/Lachlan-Frawley/llvm-project.git 5b5eacc5790365b90878a79893325bfae00ed693)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /home/workspace/clang-mre/llvm-project/build/lib
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/11
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/12
Selected GCC installation: /usr/lib/gcc/x86_64-linux-gnu/12
Candidate multilib: .;@<!-- -->m64
Candidate multilib: 32;@<!-- -->m32
Candidate multilib: x32;@<!-- -->mx32
Selected multilib: .;@<!-- -->m64
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/include"
ignoring nonexistent directory "/include"
#include "..." search starts here:
#include <...> search starts here:
/home/workspace/clang-mre/llvm-project/build/lib/../include/x86_64-unknown-linux-gnu/c++/v1
/home/workspace/clang-mre/llvm-project/build/lib/../include/c++/v1
/home/workspace/clang-mre/llvm-project/build/lib/clang/22/include
/usr/local/include
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
MY_CONSTEXPR_VALUE -> 6
```
---
Full diff: https://github.com/llvm/llvm-project/pull/164234.diff
3 Files Affected:
- (modified) clang/tools/libclang/CIndex.cpp (+5-1)
- (modified) clang/tools/libclang/CIndexer.cpp (+22-9)
- (modified) clang/tools/libclang/CIndexer.h (+4)
``````````diff
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index fc27fd29da933..9d74ee61473eb 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -4414,7 +4414,11 @@ enum CXErrorCode clang_parseTranslationUnit2(
unsigned options, CXTranslationUnit *out_TU) {
noteBottomOfStack();
SmallVector<const char *, 4> Args;
- Args.push_back("clang");
+
+ CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
+ auto library_path = CXXIdx->getLibClangPath();
+ Args.push_back(library_path.c_str());
+
Args.append(command_line_args, command_line_args + num_command_line_args);
return clang_parseTranslationUnit2FullArgv(
CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
diff --git a/clang/tools/libclang/CIndexer.cpp b/clang/tools/libclang/CIndexer.cpp
index 11d9312b64849..fbb9342800ac8 100644
--- a/clang/tools/libclang/CIndexer.cpp
+++ b/clang/tools/libclang/CIndexer.cpp
@@ -96,7 +96,21 @@ const std::string &CIndexer::getClangResourcesPath() {
if (!ResourcesPath.empty())
return ResourcesPath;
- SmallString<128> LibClangPath;
+ if (CachedLibClangPath.empty())
+ getLibClangPath();
+
+ // Cache our result.
+ ResourcesPath = driver::Driver::GetResourcesPath(CachedLibClangPath);
+ return ResourcesPath;
+}
+
+const std::string &CIndexer::getLibClangPath()
+{
+ // Did we already compute the path?
+ if (!CachedLibClangPath.empty())
+ return CachedLibClangPath;
+
+ SmallString<128> ResultPath;
// Find the location where this library lives (libclang.dylib).
#ifdef _WIN32
@@ -106,9 +120,9 @@ const std::string &CIndexer::getClangResourcesPath() {
sizeof(mbi));
GetModuleFileNameA((HINSTANCE)mbi.AllocationBase, path, MAX_PATH);
- LibClangPath += path;
+ ResultPath += path;
#elif defined(_AIX)
- getClangResourcesPathImplAIX(LibClangPath);
+ getClangResourcesPathImplAIX(ResultPath);
#else
bool PathFound = false;
#if defined(CLANG_HAVE_DLFCN_H) && defined(CLANG_HAVE_DLADDR)
@@ -116,7 +130,7 @@ const std::string &CIndexer::getClangResourcesPath() {
// This silly cast below avoids a C++ warning.
if (dladdr((void *)(uintptr_t)clang_createTranslationUnit, &info) != 0) {
// We now have the CIndex directory, locate clang relative to it.
- LibClangPath += info.dli_fname;
+ ResultPath += info.dli_fname;
PathFound = true;
}
#endif
@@ -126,19 +140,18 @@ const std::string &CIndexer::getClangResourcesPath() {
// If we can't get the path using dladdr, try to get the main executable
// path. This may be needed when we're statically linking libclang with
// musl libc, for example.
- LibClangPath += Path;
+ ResultPath += Path;
} else {
// It's rather unlikely we end up here. But it could happen, so report an
// error instead of crashing.
- llvm::report_fatal_error("could not locate Clang resource path");
+ llvm::report_fatal_error("could not locate libclang path");
}
}
#endif
- // Cache our result.
- ResourcesPath = driver::Driver::GetResourcesPath(LibClangPath);
- return ResourcesPath;
+ CachedLibClangPath = std::string(ResultPath);
+ return CachedLibClangPath;
}
StringRef CIndexer::getClangToolchainPath() {
diff --git a/clang/tools/libclang/CIndexer.h b/clang/tools/libclang/CIndexer.h
index 83268a2016c8f..226fa5bf6e3f1 100644
--- a/clang/tools/libclang/CIndexer.h
+++ b/clang/tools/libclang/CIndexer.h
@@ -37,6 +37,7 @@ class CIndexer {
bool StorePreamblesInMemory = false;
unsigned Options; // CXGlobalOptFlags.
+ std::string CachedLibClangPath;
std::string ResourcesPath;
std::shared_ptr<PCHContainerOperations> PCHContainerOps;
@@ -77,6 +78,9 @@ class CIndexer {
/// Get the path of the clang resource files.
const std::string &getClangResourcesPath();
+ /// Get the path of libclang.
+ const std::string &getLibClangPath();
+
StringRef getClangToolchainPath();
void setStorePreamblesInMemory(bool StoreInMemory) {
``````````
</details>
https://github.com/llvm/llvm-project/pull/164234
More information about the cfe-commits
mailing list