This is an archive of the discontinued LLVM Phabricator instance.

[Sema][CodeComplete] Handle symlinks for include code completion
ClosedPublic

Authored by dgoldman on Feb 18 2020, 1:24 PM.

Details

Summary

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).

Diff Detail

Event Timeline

dgoldman created this revision.Feb 18 2020, 1:24 PM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 18 2020, 1:24 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript
dgoldman updated this revision to Diff 245256.Feb 18 2020, 1:55 PM
  • Add test case
sammccall accepted this revision.Feb 18 2020, 4:36 PM

Thanks! I can't see this being a performance problem (famous last words...)

clang/lib/Sema/SemaCodeComplete.cpp
8780

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)

8784

nit: expand auto here, "type" is vague and It is already auto

8786

nit: inline (if (auto FileStatus = ...))
drop braces around inner if

This revision is now accepted and ready to land.Feb 18 2020, 4:36 PM
dgoldman updated this revision to Diff 245415.Feb 19 2020, 8:26 AM
  • Fixes for Sam's comments
dgoldman marked 3 inline comments as done.Feb 19 2020, 8:27 AM

Thanks! I can't see this being a performance problem (famous last words...)

Technically it is capped at 2500 symlinks =) fingers crossed

This revision was automatically updated to reflect the committed changes.
dyung added a subscriber: dyung.EditedFeb 19 2020, 1:10 PM

`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

--

`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

--

Looks like I need to add a // REQUIRES: shell to the test, will submit a fix shortly