From 3f757a6595810031ff753c661b3ec5dc3c95ef59 Mon Sep 17 00:00:00 2001 From: Lachlan Frawley Date: Mon, 20 Oct 2025 21:16:09 +1000 Subject: [PATCH] Feed in libclang path inside clang_parseTranslationUnit2() to ensure clang correctly determines its resource paths. Also add a new function to explicitly get libclangs path. --- clang/tools/libclang/CIndex.cpp | 6 +++++- clang/tools/libclang/CIndexer.cpp | 31 ++++++++++++++++++++++--------- clang/tools/libclang/CIndexer.h | 4 ++++ 3 files changed, 31 insertions(+), 10 deletions(-) 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 Args; - Args.push_back("clang"); + + CIndexer *CXXIdx = static_cast(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 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) {