diff --git a/clang-tools-extra/clangd/QueryDriverDatabase.cpp b/clang-tools-extra/clangd/QueryDriverDatabase.cpp --- a/clang-tools-extra/clangd/QueryDriverDatabase.cpp +++ b/clang-tools-extra/clangd/QueryDriverDatabase.cpp @@ -334,6 +334,16 @@ llvm::SmallString<128> Driver(Cmd->CommandLine.front()); llvm::sys::fs::make_absolute(Cmd->Directory, Driver); + if (!llvm::sys::fs::exists(Driver)) { + auto DriverProgram = + llvm::sys::findProgramByName(Cmd->CommandLine.front()); + if (DriverProgram) { + log("System include extraction: driver {0} expanded to {1}", + Cmd->CommandLine.front(), *DriverProgram); + Driver = *DriverProgram; + } + } + if (auto Info = QueriedDrivers.get(/*Key=*/(Driver + ":" + Lang).str(), [&] { return extractSystemIncludesAndTarget( diff --git a/clang-tools-extra/clangd/test/system-include-extractor.test b/clang-tools-extra/clangd/test/system-include-extractor.test --- 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:/..."