[clang-tools-extra] r359214 - [clangd] Optimize "don't include me" check.
Sam McCall via cfe-commits
cfe-commits at lists.llvm.org
Thu Apr 25 10:47:07 PDT 2019
Author: sammccall
Date: Thu Apr 25 10:47:07 2019
New Revision: 359214
URL: http://llvm.org/viewvc/llvm-project?rev=359214&view=rev
Log:
[clangd] Optimize "don't include me" check.
Summary:
llvm::Regex is really slow, and regex evaluation during preamble indexing was
showing up as 25% on a profile of clangd in a codebase with large preambles.
Reviewers: ilya-biryukov
Subscribers: MaskRay, jkorous, arphaman, kadircet, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D61120
Modified:
clang-tools-extra/trunk/clangd/index/SymbolCollector.cpp
clang-tools-extra/trunk/clangd/index/SymbolCollector.h
Modified: clang-tools-extra/trunk/clangd/index/SymbolCollector.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/SymbolCollector.cpp?rev=359214&r1=359213&r2=359214&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/index/SymbolCollector.cpp (original)
+++ clang-tools-extra/trunk/clangd/index/SymbolCollector.cpp Thu Apr 25 10:47:07 2019
@@ -639,7 +639,7 @@ bool SymbolCollector::isSelfContainedHea
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::isSelfContainedHea
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
Modified: clang-tools-extra/trunk/clangd/index/SymbolCollector.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/SymbolCollector.h?rev=359214&r1=359213&r2=359214&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/index/SymbolCollector.h (original)
+++ clang-tools-extra/trunk/clangd/index/SymbolCollector.h Thu Apr 25 10:47:07 2019
@@ -120,12 +120,8 @@ private:
llvm::Optional<std::string> getIncludeHeader(llvm::StringRef QName, FileID);
bool isSelfContainedHeader(FileID);
- // Heuristic to detect headers that aren't self-contained, usually because
- // they need to be included via an umbrella header. e.g. GTK matches this.
- llvm::Regex DontIncludeMePattern = {
- "^[ \t]*#[ \t]*if.*\n" // An #if, #ifndef etc directive, then
- "[ \t]*#[ \t]*error.*include", // an #error directive mentioning "include"
- llvm::Regex::Newline};
+ // Heuristically headers that only want to be included via an umbrella.
+ static bool isDontIncludeMeHeader(llvm::StringRef);
// All Symbols collected from the AST.
SymbolSlab::Builder Symbols;
More information about the cfe-commits
mailing list