forked from OSchip/llvm-project
[CodeCompletion] Generally consider header files without extension
Real-world use case: The Qt framework's headers have the same name as the respective class defined in them, and Qt's traditional qmake build tool uses -I (rather than -isystem) to pull them in. Reviewed By: sammccall Differential Revision: https://reviews.llvm.org/D112996
This commit is contained in:
parent
ef2d0e0f20
commit
f7500a4ef7
|
@ -9613,6 +9613,10 @@ void Sema::CodeCompleteIncludedFile(llvm::StringRef Dir, bool Angled) {
|
|||
}
|
||||
}
|
||||
|
||||
const StringRef &Dirname = llvm::sys::path::filename(Dir);
|
||||
const bool isQt = Dirname.startswith("Qt") || Dirname == "ActiveQt";
|
||||
const bool ExtensionlessHeaders =
|
||||
IsSystem || isQt || Dir.endswith(".framework/Headers");
|
||||
std::error_code EC;
|
||||
unsigned Count = 0;
|
||||
for (auto It = FS.dir_begin(Dir, EC);
|
||||
|
@ -9639,18 +9643,19 @@ void Sema::CodeCompleteIncludedFile(llvm::StringRef Dir, bool Angled) {
|
|||
|
||||
AddCompletion(Filename, /*IsDirectory=*/true);
|
||||
break;
|
||||
case llvm::sys::fs::file_type::regular_file:
|
||||
// Only files that really look like headers. (Except in system dirs).
|
||||
if (!IsSystem) {
|
||||
// Header extensions from Types.def, which we can't depend on here.
|
||||
if (!(Filename.endswith_insensitive(".h") ||
|
||||
Filename.endswith_insensitive(".hh") ||
|
||||
Filename.endswith_insensitive(".hpp") ||
|
||||
Filename.endswith_insensitive(".inc")))
|
||||
break;
|
||||
}
|
||||
case llvm::sys::fs::file_type::regular_file: {
|
||||
// Only files that really look like headers. (Except in special dirs).
|
||||
// Header extensions from Types.def, which we can't depend on here.
|
||||
const bool IsHeader = Filename.endswith_insensitive(".h") ||
|
||||
Filename.endswith_insensitive(".hh") ||
|
||||
Filename.endswith_insensitive(".hpp") ||
|
||||
Filename.endswith_insensitive(".inc") ||
|
||||
(ExtensionlessHeaders && !Filename.contains('.'));
|
||||
if (!IsHeader)
|
||||
break;
|
||||
AddCompletion(Filename, /*IsDirectory=*/false);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1,35 +1,57 @@
|
|||
// RUN: rm -rf %t && mkdir %t && cp %s %t/main.cc && mkdir %t/a
|
||||
// RUN: touch %t/foo.h && touch %t/foo.cc && touch %t/a/foosys %t/a/foosys.h
|
||||
// RUN: rm -rf %t && mkdir %t && cp %s %t/main.cc && mkdir %t/a && mkdir %t/QtCore && mkdir %t/Headers %t/Some.framework %t/Some.framework/Headers
|
||||
// RUN: touch %t/foo.h && touch %t/foo.cc && touch %t/a/foosys %t/a/foosys.h && touch %t/QtCore/foosys %t/QtCore/foo.h
|
||||
// RUN: touch %t/Headers/foosys %t/Headers/foo.h %t/Some.framework/Headers/foosys %t/Some.framework/Headers/foo.h
|
||||
|
||||
// Quoted string shows header-ish files from CWD, and all from system.
|
||||
#include "foo.h"
|
||||
// RUN: %clang -fsyntax-only -isystem %t/a -Xclang -code-completion-at=%t/main.cc:5:13 %t/main.cc | FileCheck -check-prefix=CHECK-1 %s
|
||||
// RUN: %clang -fsyntax-only -isystem %t/a -Xclang -code-completion-at=%t/main.cc:6:13 %t/main.cc | FileCheck -check-prefix=CHECK-1 %s
|
||||
// CHECK-1-NOT: foo.cc"
|
||||
// CHECK-1: foo.h"
|
||||
// CHECK-1: foosys"
|
||||
|
||||
// Quoted string with dir shows header-ish files in that subdir.
|
||||
#include "a/foosys"
|
||||
// RUN: %clang -fsyntax-only -isystem %t/a -Xclang -code-completion-at=%t/main.cc:12:13 %t/main.cc | FileCheck -check-prefix=CHECK-2 %s
|
||||
// RUN: %clang -fsyntax-only -isystem %t/a -Xclang -code-completion-at=%t/main.cc:13:13 %t/main.cc | FileCheck -check-prefix=CHECK-2 %s
|
||||
// CHECK-2-NOT: foo.h"
|
||||
// CHECK-2: foosys.h"
|
||||
// CHECK-2-NOT: foosys"
|
||||
|
||||
// Angled shows headers from system dirs.
|
||||
#include <foosys>
|
||||
// RUN: %clang -fsyntax-only -isystem %t/a -Xclang -code-completion-at=%t/main.cc:19:13 %t/main.cc | FileCheck -check-prefix=CHECK-3 %s
|
||||
// RUN: %clang -fsyntax-only -isystem %t/a -Xclang -code-completion-at=%t/main.cc:20:13 %t/main.cc | FileCheck -check-prefix=CHECK-3 %s
|
||||
// CHECK-3-NOT: foo.cc>
|
||||
// CHECK-3-NOT: foo.h>
|
||||
// CHECK-3: foosys>
|
||||
|
||||
// With -I rather than -isystem, the header extension is required.
|
||||
#include <foosys>
|
||||
// RUN: %clang -fsyntax-only -I %t/a -Xclang -code-completion-at=%t/main.cc:26:13 %t/main.cc | FileCheck -check-prefix=CHECK-4 %s
|
||||
// RUN: %clang -fsyntax-only -I %t/a -Xclang -code-completion-at=%t/main.cc:27:13 %t/main.cc | FileCheck -check-prefix=CHECK-4 %s
|
||||
// CHECK-4-NOT: foo.cc>
|
||||
// CHECK-4-NOT: foo.h>
|
||||
// CHECK-4-NOT: foosys>
|
||||
|
||||
// Backslash handling.
|
||||
#include "a\foosys"
|
||||
// RUN: %clang -fsyntax-only -isystem %t/a -Xclang -code-completion-at=%t/main.cc:33:13 %t/main.cc -fms-compatibility | FileCheck -check-prefix=CHECK-5 %s
|
||||
// RUN: %clang -fsyntax-only -isystem %t/a -Xclang -code-completion-at=%t/main.cc:34:13 %t/main.cc -fms-compatibility | FileCheck -check-prefix=CHECK-5 %s
|
||||
// CHECK-5: foosys.h"
|
||||
|
||||
// Qt headers don't necessarily have extensions.
|
||||
#include <foosys>
|
||||
// RUN: %clang -fsyntax-only -I %t/QtCore -Xclang -code-completion-at=%t/main.cc:39:13 %t/main.cc -fms-compatibility | FileCheck -check-prefix=CHECK-6 %s
|
||||
// CHECK-6-NOT: foo.cc>
|
||||
// CHECK-6: foo.h>
|
||||
// CHECK-6: foosys>
|
||||
|
||||
// If the include path directly points into a framework's Headers/ directory, we allow extension-less headers.
|
||||
#include <foosys>
|
||||
// RUN: %clang -fsyntax-only -I %t/Some.framework/Headers -Xclang -code-completion-at=%t/main.cc:46:13 %t/main.cc -fms-compatibility | FileCheck -check-prefix=CHECK-7 %s
|
||||
// CHECK-7-NOT: foo.cc>
|
||||
// CHECK-7: foo.h>
|
||||
// CHECK-7: foosys>
|
||||
|
||||
// Simply naming a directory "Headers" is not enough to allow extension-less headers.
|
||||
#include <foosys>
|
||||
// RUN: %clang -fsyntax-only -I %t/Headers -Xclang -code-completion-at=%t/main.cc:53:13 %t/main.cc -fms-compatibility | FileCheck -check-prefix=CHECK-8 %s
|
||||
// CHECK-8-NOT: foo.cc>
|
||||
// CHECK-8: foo.h>
|
||||
// CHECK-8-NOT: foosys>
|
||||
|
|
Loading…
Reference in New Issue