summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang-tools-extra/clangd/SourceCode.cpp13
-rw-r--r--clang-tools-extra/clangd/SourceCode.h7
-rw-r--r--clang-tools-extra/clangd/index/Background.cpp6
-rw-r--r--clang-tools-extra/clangd/unittests/SourceCodeTests.cpp24
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
OpenPOWER on IntegriCloud