summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clangd/index/SymbolCollector.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang-tools-extra/clangd/index/SymbolCollector.cpp')
-rw-r--r--clang-tools-extra/clangd/index/SymbolCollector.cpp33
1 files changed, 32 insertions, 1 deletions
diff --git a/clang-tools-extra/clangd/index/SymbolCollector.cpp b/clang-tools-extra/clangd/index/SymbolCollector.cpp
index d4dc29a6213..05e2c5cd894 100644
--- a/clang-tools-extra/clangd/index/SymbolCollector.cpp
+++ b/clang-tools-extra/clangd/index/SymbolCollector.cpp
@@ -639,7 +639,7 @@ bool SymbolCollector::isSelfContainedHeader(FileID FID) {
return false;
// This pattern indicates that a header can't be used without
// particular preprocessor state, usually set up by another header.
- if (DontIncludeMePattern.match(SM.getBufferData(FID)))
+ if (isDontIncludeMeHeader(SM.getBufferData(FID)))
return false;
return true;
};
@@ -650,5 +650,36 @@ bool SymbolCollector::isSelfContainedHeader(FileID FID) {
return R.first->second;
}
+// Is Line an #if or #ifdef directive?
+static bool isIf(llvm::StringRef Line) {
+ Line = Line.ltrim();
+ if (!Line.consume_front("#"))
+ return false;
+ Line = Line.ltrim();
+ return Line.startswith("if");
+}
+// Is Line an #error directive mentioning includes?
+static bool isErrorAboutInclude(llvm::StringRef Line) {
+ Line = Line.ltrim();
+ if (!Line.consume_front("#"))
+ return false;
+ Line = Line.ltrim();
+ if (! Line.startswith("error"))
+ return false;
+ return Line.contains_lower("includ"); // Matches "include" or "including".
+}
+
+bool SymbolCollector::isDontIncludeMeHeader(llvm::StringRef Content) {
+ llvm::StringRef Line;
+ // Only sniff up to 100 lines or 10KB.
+ Content = Content.take_front(100*100);
+ for (unsigned I = 0; I < 100 && !Content.empty(); ++I) {
+ std::tie(Line, Content) = Content.split('\n');
+ if (isIf(Line) && isErrorAboutInclude(Content.split('\n').first))
+ return true;
+ }
+ return false;
+}
+
} // namespace clangd
} // namespace clang
OpenPOWER on IntegriCloud