-
Notifications
You must be signed in to change notification settings - Fork 15k
Fix libclang finding the wrong resource paths #164234
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Fix libclang finding the wrong resource paths #164234
Conversation
…clang correctly determines its resource paths. Also add a new function to explicitly get libclangs path.
|
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
|
@llvm/pr-subscribers-clang Author: Lachlan Frawley (Lachlan-Frawley) ChangesFix clang finding the wrong resource paths by giving Seems related to #18150 and #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): After changes here are applied (correct resource paths): Full diff: https://github.com/llvm/llvm-project/pull/164234.diff 3 Files Affected:
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) {
|
Fix libclang finding the wrong resource paths by giving
clang_parseTranslationUnit2()the path to libclang instead of just 'clang'.Seems related to #18150 and #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):
After changes here are applied (correct resource paths):