[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