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 dgoldman on Feb 18 2020, 1:24 PM. Authored by
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 -- |
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)