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

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

Reviewers: sammccall

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D74790
This commit is contained in:
David Goldman 2020-02-18 16:21:12 -05:00
parent f12fb2d99b
commit f50fe5eb6d
2 changed files with 25 additions and 1 deletions

View File

@ -8776,7 +8776,16 @@ void Sema::CodeCompleteIncludedFile(llvm::StringRef Dir, bool Angled) {
if (++Count == 2500) // If we happen to hit a huge directory,
break; // bail out early so we're not too slow.
StringRef Filename = llvm::sys::path::filename(It->path());
switch (It->type()) {
// To know whether a symlink should be treated as file or a directory, we
// have to stat it. This should be cheap enough as there shouldn't be many
// symlinks.
llvm::sys::fs::file_type Type = It->type();
if (Type == llvm::sys::fs::file_type::symlink_file) {
if (auto FileStatus = FS.status(It->path()))
Type = FileStatus->getType();
}
switch (Type) {
case llvm::sys::fs::file_type::directory_file:
// All entries in a framework directory must have a ".framework" suffix,
// but the suffix does not appear in the source code's include/import.

View File

@ -0,0 +1,15 @@
// RUN: rm -rf %t && mkdir -p %t/real/myproj && mkdir -p %t/links
// RUN: touch %t/real/foo.h && ln -s %t/real/foo.h %t/links/foo.h
// RUN: touch %t/real/foobar.h && ln -s %t/real/foobar.h %t/links/foobar.h
// RUN: touch %t/real/myproj/test.h && ln -s %t/real/myproj %t/links/myproj
// Suggest symlinked header files.
#include "foo.h"
// RUN: %clang -fsyntax-only -I%t/links -Xclang -code-completion-at=%s:7:13 %s | FileCheck -check-prefix=CHECK-1 %s
// CHECK-1: foo.h"
// CHECK-1: foobar.h"
// Suggest symlinked folder.
#include "mypr"
// RUN: %clang -fsyntax-only -I%t/links -Xclang -code-completion-at=%s:13:13 %s | FileCheck -check-prefix=CHECK-2 %s
// CHECK-2: myproj/