[clang] 201fdef - libclang: Pass Clang install directory to driver via argv[0].

Peter Collingbourne via cfe-commits cfe-commits at lists.llvm.org
Wed Mar 22 15:31:10 PDT 2023


Author: Peter Collingbourne
Date: 2023-03-22T15:28:21-07:00
New Revision: 201fdef40dd6ec193d18d39638454a3c972f1fec

URL: https://github.com/llvm/llvm-project/commit/201fdef40dd6ec193d18d39638454a3c972f1fec
DIFF: https://github.com/llvm/llvm-project/commit/201fdef40dd6ec193d18d39638454a3c972f1fec.diff

LOG: libclang: Pass Clang install directory to driver via argv[0].

Various driver features, such as the sysroot path detection for Android
targets, rely on being able to find the Clang install directory (look
for callers of `getDriver().getInstalledDir()`). However, the install
directory isn't currently being plumbed through to the driver, which is
conventionally done via the argv[0] passed to the Driver constructor.

It looks like D14695 attempted to fix this by adding another API that
allows specifying the argv[0]. However, rather than requiring every
user of libclang to switch to this API for correct behavior, let's have
the other existing APIs work by default, by using the existing logic in
libclang for finding the install directory.

Differential Revision: https://reviews.llvm.org/D146497

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/include/clang-c/Index.h
    clang/test/Index/record-completion-invocation.c
    clang/test/Index/record-parsing-invocation.c
    clang/tools/libclang/CIndex.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 005bf99a62457..94e0f10a31743 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -368,6 +368,14 @@ libclang
   has an evaluable bit width. Fixes undefined behavior when called on a
   bit-field whose width depends on a template paramter.
 
+- ``clang_parseTranslationUnit`` and ``clang_parseTranslationUnit2`` have been
+  changed to automatically locate the Clang installation directory relative to
+  the location of the libclang binary and use it for system headers installed
+  alongside the Clang installation. It is no longer necessary to manually
+  locate such system headers or use the ``clang_parseTranslationUnit2FullArgv``
+  function for this purpose if libclang has been installed in the default
+  location.
+ 
 Static Analyzer
 ---------------
 - Fix incorrect alignment attribute on the this parameter of certain

diff  --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index c7d32e6a152ae..8275f2941a41c 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -899,8 +899,13 @@ CINDEX_LINKAGE enum CXErrorCode clang_parseTranslationUnit2(
 
 /**
  * Same as clang_parseTranslationUnit2 but requires a full command line
- * for \c command_line_args including argv[0]. This is useful if the standard
- * library paths are relative to the binary.
+ * for \c command_line_args including argv[0].
+ *
+ * This is useful if the driver uses paths relative to the binary and either
+ * you are targeting libclang versions older than Clang 17, or libclang is
+ * installed to a non-standard location. Clang 17 and newer will automatically
+ * use the correct argv[0] if libclang is installed in the lib directory
+ * parallel to the bin directory where the clang binary is installed.
  */
 CINDEX_LINKAGE enum CXErrorCode clang_parseTranslationUnit2FullArgv(
     CXIndex CIdx, const char *source_filename,

diff  --git a/clang/test/Index/record-completion-invocation.c b/clang/test/Index/record-completion-invocation.c
index 4b667134fa2d4..75eb9083908ae 100644
--- a/clang/test/Index/record-completion-invocation.c
+++ b/clang/test/Index/record-completion-invocation.c
@@ -9,4 +9,4 @@
 // RUN: env LIBCLANG_DISABLE_CRASH_RECOVERY=1 CINDEXTEST_INVOCATION_EMISSION_PATH=%t not --crash c-index-test -code-completion-at=%s:10:1 "-remap-file=%s,%S/Inputs/record-parsing-invocation-remap.c" %s
 // RUN: cat %t/libclang-* | FileCheck %s
 
-// CHECK: {"toolchain":"{{.*}}","libclang.operation":"complete","libclang.opts":1,"args":["clang","-fno-spell-checking","{{.*}}record-completion-invocation.c","-Xclang","-detailed-preprocessing-record","-fallow-editor-placeholders"],"invocation-args":["-code-completion-at={{.*}}record-completion-invocation.c:10:1"],"unsaved_file_hashes":[{"name":"{{.*}}record-completion-invocation.c","md5":"aee23773de90e665992b48209351d70e"}]}
+// CHECK: {"toolchain":"{{.*}}","libclang.operation":"complete","libclang.opts":1,"args":["{{.*}}bin{{.*}}clang","-fno-spell-checking","{{.*}}record-completion-invocation.c","-Xclang","-detailed-preprocessing-record","-fallow-editor-placeholders"],"invocation-args":["-code-completion-at={{.*}}record-completion-invocation.c:10:1"],"unsaved_file_hashes":[{"name":"{{.*}}record-completion-invocation.c","md5":"aee23773de90e665992b48209351d70e"}]}

diff  --git a/clang/test/Index/record-parsing-invocation.c b/clang/test/Index/record-parsing-invocation.c
index e0c4cdb05fb00..f370f014fb1cc 100644
--- a/clang/test/Index/record-parsing-invocation.c
+++ b/clang/test/Index/record-parsing-invocation.c
@@ -25,5 +25,5 @@
 #  pragma clang __debug parser_crash
 #endif
 
-// CHECK: {"toolchain":"{{.*}}","libclang.operation":"parse","libclang.opts":1,"args":["clang","-fno-spell-checking","{{.*}}record-parsing-invocation.c","-Xclang","-detailed-preprocessing-record","-fallow-editor-placeholders"]}
-// CHECK-UNSAVED: {"toolchain":"{{.*}}","libclang.operation":"parse","libclang.opts":1,"args":["clang","-fno-spell-checking","{{.*}}record-parsing-invocation.c","-Xclang","-detailed-preprocessing-record","-fallow-editor-placeholders"],"unsaved_file_hashes":[{"name":"{{.*}}record-parsing-invocation.c","md5":"aee23773de90e665992b48209351d70e"}]}
+// CHECK: {"toolchain":"{{.*}}","libclang.operation":"parse","libclang.opts":1,"args":["{{.*}}bin{{.*}}clang","-fno-spell-checking","{{.*}}record-parsing-invocation.c","-Xclang","-detailed-preprocessing-record","-fallow-editor-placeholders"]}
+// CHECK-UNSAVED: {"toolchain":"{{.*}}","libclang.operation":"parse","libclang.opts":1,"args":["{{.*}}bin{{.*}}clang","-fno-spell-checking","{{.*}}record-parsing-invocation.c","-Xclang","-detailed-preprocessing-record","-fallow-editor-placeholders"],"unsaved_file_hashes":[{"name":"{{.*}}record-parsing-invocation.c","md5":"aee23773de90e665992b48209351d70e"}]}

diff  --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 30416e46ce173..2aa12667d37e9 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -4013,8 +4013,17 @@ enum CXErrorCode clang_parseTranslationUnit2(
     struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
     unsigned options, CXTranslationUnit *out_TU) {
   noteBottomOfStack();
+
+  if (!CIdx)
+    return CXError_InvalidArguments;
+
+  SmallString<64> ClangPath(
+      static_cast<CIndexer *>(CIdx)->getClangToolchainPath());
+  llvm::sys::path::append(ClangPath, "bin");
+  llvm::sys::path::append(ClangPath, "clang");
+
   SmallVector<const char *, 4> Args;
-  Args.push_back("clang");
+  Args.push_back(ClangPath.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,


        


More information about the cfe-commits mailing list