diff options
| author | Haojian Wu <hokein.wu@gmail.com> | 2019-11-13 16:30:07 +0100 |
|---|---|---|
| committer | Haojian Wu <hokein.wu@gmail.com> | 2019-11-15 16:18:27 +0100 |
| commit | 509efe5d8edee5637b26fcb645978325de0a7283 (patch) | |
| tree | 05eea32a0fcdee7a1f6d3c8c7297e4773d69e2ca | |
| parent | e3d5ff5a0b102febcddd9d58f24f18b00d4ecb4e (diff) | |
| download | bcm5719-llvm-509efe5d8edee5637b26fcb645978325de0a7283.tar.gz bcm5719-llvm-509efe5d8edee5637b26fcb645978325de0a7283.zip | |
[clangd] Add isHeaderFile helper.
Summary:
we have a few places using `ASTCtx.getLangOpts().IsHeaderFile` to
determine a header file, but it relies on "-x c-header" compiler flag,
if the compilation command doesn't have this flag, we will get a false
positive. We are encountering this issue in bazel build system.
To solve this problem, we infer the file from file name, actual changes will
come in follow-ups.
Reviewers: sammccall
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D70235
| -rw-r--r-- | clang-tools-extra/clangd/SourceCode.cpp | 13 | ||||
| -rw-r--r-- | clang-tools-extra/clangd/SourceCode.h | 7 | ||||
| -rw-r--r-- | clang-tools-extra/clangd/index/Background.cpp | 6 | ||||
| -rw-r--r-- | clang-tools-extra/clangd/unittests/SourceCodeTests.cpp | 24 |
4 files changed, 44 insertions, 6 deletions
diff --git a/clang-tools-extra/clangd/SourceCode.cpp b/clang-tools-extra/clangd/SourceCode.cpp index d505645a74f..b36d11d64a3 100644 --- a/clang-tools-extra/clangd/SourceCode.cpp +++ b/clang-tools-extra/clangd/SourceCode.cpp @@ -17,6 +17,7 @@ #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TokenKinds.h" +#include "clang/Driver/Types.h" #include "clang/Format/Format.h" #include "clang/Lex/Lexer.h" #include "clang/Lex/Preprocessor.h" @@ -1122,5 +1123,17 @@ EligibleRegion getEligiblePoints(llvm::StringRef Code, return ER; } +bool isHeaderFile(llvm::StringRef FileName, + llvm::Optional<LangOptions> LangOpts) { + // Respect the langOpts, for non-file-extension cases, e.g. standard library + // files. + if (LangOpts && LangOpts->IsHeaderFile) + return true; + namespace types = clang::driver::types; + auto Lang = types::lookupTypeForExtension( + llvm::sys::path::extension(FileName).substr(1)); + return Lang != types::TY_INVALID && types::onlyPrecompileType(Lang); +} + } // namespace clangd } // namespace clang diff --git a/clang-tools-extra/clangd/SourceCode.h b/clang-tools-extra/clangd/SourceCode.h index d20e03f5b87..3b8aacef9bf 100644 --- a/clang-tools-extra/clangd/SourceCode.h +++ b/clang-tools-extra/clangd/SourceCode.h @@ -292,10 +292,15 @@ struct DefinedMacro { llvm::StringRef Name; const MacroInfo *Info; }; -// Gets the macro at a specified \p Loc. +/// Gets the macro at a specified \p Loc. llvm::Optional<DefinedMacro> locateMacroAt(SourceLocation Loc, Preprocessor &PP); +/// Infers whether this is a header from the FileName and LangOpts (if +/// presents). +bool isHeaderFile(llvm::StringRef FileName, + llvm::Optional<LangOptions> LangOpts = llvm::None); + } // namespace clangd } // namespace clang #endif diff --git a/clang-tools-extra/clangd/index/Background.cpp b/clang-tools-extra/clangd/index/Background.cpp index ff6a9e52268..1fa9825291f 100644 --- a/clang-tools-extra/clangd/index/Background.cpp +++ b/clang-tools-extra/clangd/index/Background.cpp @@ -205,11 +205,7 @@ BackgroundIndex::indexFileTask(tooling::CompileCommand Cmd) { } void BackgroundIndex::boostRelated(llvm::StringRef Path) { - namespace types = clang::driver::types; - auto Type = - types::lookupTypeForExtension(llvm::sys::path::extension(Path).substr(1)); - // is this a header? - if (Type != types::TY_INVALID && types::onlyPrecompileType(Type)) + if (isHeaderFile(Path)) Queue.boost(filenameWithoutExtension(Path), IndexBoostedFile); } diff --git a/clang-tools-extra/clangd/unittests/SourceCodeTests.cpp b/clang-tools-extra/clangd/unittests/SourceCodeTests.cpp index e9cd886e1dd..adc09a4f311 100644 --- a/clang-tools-extra/clangd/unittests/SourceCodeTests.cpp +++ b/clang-tools-extra/clangd/unittests/SourceCodeTests.cpp @@ -701,6 +701,30 @@ o foo2; collectIdentifierRanges("Foo", Code.code(), LangOpts)); } +TEST(SourceCodeTests, isHeaderFile) { + // Without lang options. + EXPECT_TRUE(isHeaderFile("foo.h")); + EXPECT_TRUE(isHeaderFile("foo.hh")); + EXPECT_TRUE(isHeaderFile("foo.hpp")); + + EXPECT_FALSE(isHeaderFile("foo.cpp")); + EXPECT_FALSE(isHeaderFile("foo.c++")); + EXPECT_FALSE(isHeaderFile("foo.cxx")); + EXPECT_FALSE(isHeaderFile("foo.cc")); + EXPECT_FALSE(isHeaderFile("foo.c")); + EXPECT_FALSE(isHeaderFile("foo.mm")); + EXPECT_FALSE(isHeaderFile("foo.m")); + + // With lang options + LangOptions LangOpts; + LangOpts.IsHeaderFile = true; + EXPECT_TRUE(isHeaderFile("string", LangOpts)); + // Emulate cases where there is no "-x header" flag for a .h file, we still + // want to treat it as a header. + LangOpts.IsHeaderFile = false; + EXPECT_TRUE(isHeaderFile("header.h", LangOpts)); +} + } // namespace } // namespace clangd } // namespace clang |

