Previously any symlinks would be ignored since the directory
traversal doesn't follow them.
With this change we now follow symlinks (via a stat call
in order to figure out the target type of the symlink if it
is valid).
Differential D74790
[Sema][CodeComplete] Handle symlinks for include code completion Authored by dgoldman on Feb 18 2020, 1:24 PM.
Details Previously any symlinks would be ignored since the directory With this change we now follow symlinks (via a stat call
Diff Detail
Event TimelineComment Actions Thanks! I can't see this being a performance problem (famous last words...)
Comment Actions `The test you added in this change seems to be failing on Windows, can you take a look? http://lab.llvm.org:8011/builders/clang-x64-windows-msvc/builds/14409 FAIL: Clang :: CodeCompletion/included-symlinks.cpp (1779 of 16867)
******************** TEST 'Clang :: CodeCompletion/included-symlinks.cpp' FAILED ********************
Script:
--
: 'RUN: at line 1'; rm -rf C:\b\slave\clang-x64-windows-msvc\build\stage1\tools\clang\test\CodeCompletion\Output\included-symlinks.cpp.tmp && mkdir -p C:\b\slave\clang-x64-windows-msvc\build\stage1\tools\clang\test\CodeCompletion\Output\included-symlinks.cpp.tmp/real/myproj && mkdir -p C:\b\slave\clang-x64-windows-msvc\build\stage1\tools\clang\test\CodeCompletion\Output\included-symlinks.cpp.tmp/links
: 'RUN: at line 2'; touch C:\b\slave\clang-x64-windows-msvc\build\stage1\tools\clang\test\CodeCompletion\Output\included-symlinks.cpp.tmp/real/foo.h && ln -s C:\b\slave\clang-x64-windows-msvc\build\stage1\tools\clang\test\CodeCompletion\Output\included-symlinks.cpp.tmp/real/foo.h C:\b\slave\clang-x64-windows-msvc\build\stage1\tools\clang\test\CodeCompletion\Output\included-symlinks.cpp.tmp/links/foo.h
: 'RUN: at line 3'; touch C:\b\slave\clang-x64-windows-msvc\build\stage1\tools\clang\test\CodeCompletion\Output\included-symlinks.cpp.tmp/real/foobar.h && ln -s C:\b\slave\clang-x64-windows-msvc\build\stage1\tools\clang\test\CodeCompletion\Output\included-symlinks.cpp.tmp/real/foobar.h C:\b\slave\clang-x64-windows-msvc\build\stage1\tools\clang\test\CodeCompletion\Output\included-symlinks.cpp.tmp/links/foobar.h
: 'RUN: at line 4'; touch C:\b\slave\clang-x64-windows-msvc\build\stage1\tools\clang\test\CodeCompletion\Output\included-symlinks.cpp.tmp/real/myproj/test.h && ln -s C:\b\slave\clang-x64-windows-msvc\build\stage1\tools\clang\test\CodeCompletion\Output\included-symlinks.cpp.tmp/real/myproj C:\b\slave\clang-x64-windows-msvc\build\stage1\tools\clang\test\CodeCompletion\Output\included-symlinks.cpp.tmp/links/myproj
: 'RUN: at line 8'; c:\b\slave\clang-x64-windows-msvc\build\stage1\bin\clang.exe -fsyntax-only -IC:\b\slave\clang-x64-windows-msvc\build\stage1\tools\clang\test\CodeCompletion\Output\included-symlinks.cpp.tmp/links -Xclang -code-completion-at=C:\b\slave\clang-x64-windows-msvc\llvm-project\clang\test\CodeCompletion\included-symlinks.cpp:7:13 C:\b\slave\clang-x64-windows-msvc\llvm-project\clang\test\CodeCompletion\included-symlinks.cpp | c:\b\slave\clang-x64-windows-msvc\build\stage1\bin\filecheck.exe -check-prefix=CHECK-1 C:\b\slave\clang-x64-windows-msvc\llvm-project\clang\test\CodeCompletion\included-symlinks.cpp
: 'RUN: at line 14'; c:\b\slave\clang-x64-windows-msvc\build\stage1\bin\clang.exe -fsyntax-only -IC:\b\slave\clang-x64-windows-msvc\build\stage1\tools\clang\test\CodeCompletion\Output\included-symlinks.cpp.tmp/links -Xclang -code-completion-at=C:\b\slave\clang-x64-windows-msvc\llvm-project\clang\test\CodeCompletion\included-symlinks.cpp:13:13 C:\b\slave\clang-x64-windows-msvc\llvm-project\clang\test\CodeCompletion\included-symlinks.cpp | c:\b\slave\clang-x64-windows-msvc\build\stage1\bin\filecheck.exe -check-prefix=CHECK-2 C:\b\slave\clang-x64-windows-msvc\llvm-project\clang\test\CodeCompletion\included-symlinks.cpp
--
Exit Code: 1
Command Output (stdout):
--
$ ":" "RUN: at line 1"
$ "rm" "-rf" "C:\b\slave\clang-x64-windows-msvc\build\stage1\tools\clang\test\CodeCompletion\Output\included-symlinks.cpp.tmp"
$ "mkdir" "-p" "C:\b\slave\clang-x64-windows-msvc\build\stage1\tools\clang\test\CodeCompletion\Output\included-symlinks.cpp.tmp/real/myproj"
$ "mkdir" "-p" "C:\b\slave\clang-x64-windows-msvc\build\stage1\tools\clang\test\CodeCompletion\Output\included-symlinks.cpp.tmp/links"
$ ":" "RUN: at line 2"
$ "touch" "C:\b\slave\clang-x64-windows-msvc\build\stage1\tools\clang\test\CodeCompletion\Output\included-symlinks.cpp.tmp/real/foo.h"
$ "ln" "-s" "C:\b\slave\clang-x64-windows-msvc\build\stage1\tools\clang\test\CodeCompletion\Output\included-symlinks.cpp.tmp/real/foo.h" "C:\b\slave\clang-x64-windows-msvc\build\stage1\tools\clang\test\CodeCompletion\Output\included-symlinks.cpp.tmp/links/foo.h"
$ ":" "RUN: at line 3"
$ "touch" "C:\b\slave\clang-x64-windows-msvc\build\stage1\tools\clang\test\CodeCompletion\Output\included-symlinks.cpp.tmp/real/foobar.h"
$ "ln" "-s" "C:\b\slave\clang-x64-windows-msvc\build\stage1\tools\clang\test\CodeCompletion\Output\included-symlinks.cpp.tmp/real/foobar.h" "C:\b\slave\clang-x64-windows-msvc\build\stage1\tools\clang\test\CodeCompletion\Output\included-symlinks.cpp.tmp/links/foobar.h"
$ ":" "RUN: at line 4"
$ "touch" "C:\b\slave\clang-x64-windows-msvc\build\stage1\tools\clang\test\CodeCompletion\Output\included-symlinks.cpp.tmp/real/myproj/test.h"
$ "ln" "-s" "C:\b\slave\clang-x64-windows-msvc\build\stage1\tools\clang\test\CodeCompletion\Output\included-symlinks.cpp.tmp/real/myproj" "C:\b\slave\clang-x64-windows-msvc\build\stage1\tools\clang\test\CodeCompletion\Output\included-symlinks.cpp.tmp/links/myproj"
$ ":" "RUN: at line 8"
$ "c:\b\slave\clang-x64-windows-msvc\build\stage1\bin\clang.exe" "-fsyntax-only" "-IC:\b\slave\clang-x64-windows-msvc\build\stage1\tools\clang\test\CodeCompletion\Output\included-symlinks.cpp.tmp/links" "-Xclang" "-code-completion-at=C:\b\slave\clang-x64-windows-msvc\llvm-project\clang\test\CodeCompletion\included-symlinks.cpp:7:13" "C:\b\slave\clang-x64-windows-msvc\llvm-project\clang\test\CodeCompletion\included-symlinks.cpp"
$ "c:\b\slave\clang-x64-windows-msvc\build\stage1\bin\filecheck.exe" "-check-prefix=CHECK-1" "C:\b\slave\clang-x64-windows-msvc\llvm-project\clang\test\CodeCompletion\included-symlinks.cpp"
# command stderr:
C:\b\slave\clang-x64-windows-msvc\llvm-project\clang\test\CodeCompletion\included-symlinks.cpp:9:13: error: CHECK-1: expected string not found in input
// CHECK-1: foo.h"
^
<stdin>:1:1: note: scanning from here
COMPLETION: Pattern : fontsub.h"
^
<stdin>:1:27: note: possible intended match here
COMPLETION: Pattern : fontsub.h"
^
error: command failed with exit status: 1
--Comment Actions Looks like I need to add a // REQUIRES: shell to the test, will submit a fix shortly | ||||||||||||
I think we can state the problem more directly here:
To know whether a symlink should be treated as file or a directory, we have to stat it.
This is cheap enough as there shouldn't be many symlinks.
(I think we can drop the heuristic idea from the comment, it was a silly premature optimization)