[clang-tools-extra] 2f8d1e9 - [clangd] When querying drivers by binary, look in PATH too

Sam McCall via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 5 03:54:24 PST 2021


Author: Giulio Girardi
Date: 2021-01-05T12:54:07+01:00
New Revision: 2f8d1e9eb27e111eb6dfd242d88dd7c98005fb5c

URL: https://github.com/llvm/llvm-project/commit/2f8d1e9eb27e111eb6dfd242d88dd7c98005fb5c
DIFF: https://github.com/llvm/llvm-project/commit/2f8d1e9eb27e111eb6dfd242d88dd7c98005fb5c.diff

LOG: [clangd] When querying drivers by binary, look in PATH too

Sometimes compile_commands.json databases are created without an
absolute path for the driver in the command field. By default the driver
name is appended to the current directory, however if no driver is found
in that location assume it was in the default PATH and try finding it
there

Reviewed By: sammccall

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

Added: 
    

Modified: 
    clang-tools-extra/clangd/QueryDriverDatabase.cpp
    clang-tools-extra/clangd/test/system-include-extractor.test

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clangd/QueryDriverDatabase.cpp b/clang-tools-extra/clangd/QueryDriverDatabase.cpp
index 797771ce144e..f1a4b5fcbfc8 100644
--- a/clang-tools-extra/clangd/QueryDriverDatabase.cpp
+++ b/clang-tools-extra/clangd/QueryDriverDatabase.cpp
@@ -136,10 +136,26 @@ llvm::Optional<DriverInfo> parseDriverOutput(llvm::StringRef Output) {
 }
 
 llvm::Optional<DriverInfo>
-extractSystemIncludesAndTarget(PathRef Driver, llvm::StringRef Lang,
+extractSystemIncludesAndTarget(llvm::SmallString<128> Driver,
+                               llvm::StringRef Lang,
                                llvm::ArrayRef<std::string> CommandLine,
                                const llvm::Regex &QueryDriverRegex) {
   trace::Span Tracer("Extract system includes and target");
+
+  if (!llvm::sys::path::is_absolute(Driver)) {
+    assert(llvm::none_of(
+        Driver, [](char C) { return llvm::sys::path::is_separator(C); }));
+    auto DriverProgram = llvm::sys::findProgramByName(Driver);
+    if (DriverProgram) {
+      vlog("System include extraction: driver {0} expanded to {1}", Driver,
+           *DriverProgram);
+      Driver = *DriverProgram;
+    } else {
+      elog("System include extraction: driver {0} not found in PATH", Driver);
+      return llvm::None;
+    }
+  }
+
   SPAN_ATTACH(Tracer, "driver", Driver);
   SPAN_ATTACH(Tracer, "lang", Lang);
 
@@ -332,7 +348,11 @@ class QueryDriverDatabase : public GlobalCompilationDatabase {
     }
 
     llvm::SmallString<128> Driver(Cmd->CommandLine.front());
-    llvm::sys::fs::make_absolute(Cmd->Directory, Driver);
+    if (llvm::any_of(Driver,
+                       [](char C) { return llvm::sys::path::is_separator(C); }))
+      // Driver is a not a single executable name but instead a path (either
+      // relative or absolute).
+      llvm::sys::fs::make_absolute(Cmd->Directory, Driver);
 
     if (auto Info =
             QueriedDrivers.get(/*Key=*/(Driver + ":" + Lang).str(), [&] {

diff  --git a/clang-tools-extra/clangd/test/system-include-extractor.test b/clang-tools-extra/clangd/test/system-include-extractor.test
index 59989be6ca6c..c861a2346470 100644
--- a/clang-tools-extra/clangd/test/system-include-extractor.test
+++ b/clang-tools-extra/clangd/test/system-include-extractor.test
@@ -3,21 +3,24 @@
 # The mock driver below is a shell script:
 # REQUIRES: shell
 
+# Create a bin directory to store the mock-driver and add it to the path
+# RUN: mkdir -p %t.dir/bin
+# RUN: export PATH=%t.dir/bin:$PATH
 # Generate a mock-driver that will print %temp_dir%/my/dir and
 # %temp_dir%/my/dir2 as include search paths.
-# RUN: echo '#!/bin/sh' >> %t.dir/my_driver.sh
-# RUN: echo '[ "$0" = "%t.dir/my_driver.sh" ] || exit' >> %t.dir/my_driver.sh
-# RUN: echo 'args="$*"' >> %t.dir/my_driver.sh
-# RUN: echo '[ -z "${args##*"-nostdinc"*}" ] || exit' >> %t.dir/my_driver.sh
-# RUN: echo '[ -z "${args##*"-isysroot=/isysroot"*}" ] || exit' >> %t.dir/my_driver.sh
-# RUN: echo 'echo " $* " | grep " --sysroot /my/sysroot/path " || exit' >> %t.dir/my_driver.sh
-# RUN: echo 'echo line to ignore >&2' >> %t.dir/my_driver.sh
-# RUN: echo 'printf "Target: arm-linux-gnueabihf\r\n" >&2' >> %t.dir/my_driver.sh
-# RUN: echo 'printf "#include <...> search starts here:\r\n" >&2' >> %t.dir/my_driver.sh
-# RUN: echo 'echo %t.dir/my/dir/ >&2' >> %t.dir/my_driver.sh
-# RUN: echo 'echo %t.dir/my/dir2/ >&2' >> %t.dir/my_driver.sh
-# RUN: echo 'printf "End of search list.\r\n" >&2' >> %t.dir/my_driver.sh
-# RUN: chmod +x %t.dir/my_driver.sh
+# RUN: echo '#!/bin/sh' >> %t.dir/bin/my_driver.sh
+# RUN: echo '[ "$0" = "%t.dir/bin/my_driver.sh" ] || exit' >> %t.dir/bin/my_driver.sh
+# RUN: echo 'args="$*"' >> %t.dir/bin/my_driver.sh
+# RUN: echo '[ -z "${args##*"-nostdinc"*}" ] || exit' >> %t.dir/bin/my_driver.sh
+# RUN: echo '[ -z "${args##*"-isysroot=/isysroot"*}" ] || exit' >> %t.dir/bin/my_driver.sh
+# RUN: echo 'echo " $* " | grep " --sysroot /my/sysroot/path " || exit' >> %t.dir/bin/my_driver.sh
+# RUN: echo 'echo line to ignore >&2' >> %t.dir/bin/my_driver.sh
+# RUN: echo 'printf "Target: arm-linux-gnueabihf\r\n" >&2' >> %t.dir/bin/my_driver.sh
+# RUN: echo 'printf "#include <...> search starts here:\r\n" >&2' >> %t.dir/bin/my_driver.sh
+# RUN: echo 'echo %t.dir/my/dir/ >&2' >> %t.dir/bin/my_driver.sh
+# RUN: echo 'echo %t.dir/my/dir2/ >&2' >> %t.dir/bin/my_driver.sh
+# RUN: echo 'printf "End of search list.\r\n" >&2' >> %t.dir/bin/my_driver.sh
+# RUN: chmod +x %t.dir/bin/my_driver.sh
 
 # Create header files my/dir/a.h and my/dir2/b.h
 # RUN: mkdir -p %t.dir/my/dir
@@ -27,7 +30,7 @@
 
 # Generate a compile_commands.json that will query the mock driver we've
 # created. Which should add a.h and b.h into include search path.
-# RUN: echo '[{"directory": "%/t.dir", "command": "%/t.dir/my_driver.sh the-file.cpp -nostdinc --sysroot /my/sysroot/path -isysroot=/isysroot", "file": "the-file.cpp"}]' > %t.dir/compile_commands.json
+# RUN: echo '[{"directory": "%/t.dir", "command": "my_driver.sh the-file.cpp -nostdinc --sysroot /my/sysroot/path -isysroot=/isysroot", "file": "the-file.cpp"}]' > %t.dir/compile_commands.json
 
 # RUN: sed -e "s|INPUT_DIR|%/t.dir|g" %s > %t.test.1
 # On Windows, we need the URI in didOpen to look like "uri":"file:///C:/..."


        


More information about the cfe-commits mailing list