[PATCH] D87891: [clangd] findNearbyIdentifier(): guaranteed to give up after 2^N lines
Aleksandr Platonov via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 29 03:27:45 PDT 2020
ArcsinX updated this revision to Diff 294924.
ArcsinX added a comment.
Fix possible UB at bitwise shift.
WordGain => MaxDistance.
Fix LineMin and LineMax values.
Fix comment.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D87891/new/
https://reviews.llvm.org/D87891
Files:
clang-tools-extra/clangd/XRefs.cpp
clang-tools-extra/clangd/unittests/XRefsTests.cpp
Index: clang-tools-extra/clangd/unittests/XRefsTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/XRefsTests.cpp
+++ clang-tools-extra/clangd/unittests/XRefsTests.cpp
@@ -1428,6 +1428,11 @@
// h^i
+
+
+
+
+ int x = hi;
)cpp",
R"cpp(
// prefer nearest occurrence even if several matched tokens
Index: clang-tools-extra/clangd/XRefs.cpp
===================================================================
--- clang-tools-extra/clangd/XRefs.cpp
+++ clang-tools-extra/clangd/XRefs.cpp
@@ -562,19 +562,34 @@
auto Cost = [&](SourceLocation Loc) -> unsigned {
assert(SM.getFileID(Loc) == File && "spelled token in wrong file?");
unsigned Line = SM.getSpellingLineNumber(Loc);
- if (Line > WordLine)
- return 1 + llvm::Log2_64(Line - WordLine);
- if (Line < WordLine)
- return 2 + llvm::Log2_64(WordLine - Line);
- return 0;
+ return Line >= WordLine ? Line - WordLine : 2 * (WordLine - Line);
};
const syntax::Token *BestTok = nullptr;
- // Search bounds are based on word length: 2^N lines forward.
- unsigned BestCost = Word.Text.size() + 1;
+ unsigned BestCost = -1;
+ // Search bounds are based on word length:
+ // - forward: 2^N lines
+ // - backward: 2^(N-1) lines.
+ unsigned MaxDistance =
+ 1U << std::min<unsigned>(Word.Text.size(),
+ std::numeric_limits<unsigned>::digits - 1);
+ // Line number for SM.translateLineCol() should be one-based, also
+ // SM.translateLineCol() can handle line number greater than
+ // number of lines in the file.
+ // - LineMin = max(1, WordLine + 1 - 2^(N-1))
+ // - LineMax = WordLine + 1 + 2^N
+ unsigned LineMin =
+ WordLine + 1 <= MaxDistance / 2 ? 1 : WordLine + 1 - MaxDistance / 2;
+ unsigned LineMax = WordLine + 1 + MaxDistance;
+ SourceLocation LocMin = SM.translateLineCol(File, LineMin, 1);
+ assert(LocMin.isValid());
+ SourceLocation LocMax = SM.translateLineCol(File, LineMax, 1);
+ assert(LocMax.isValid());
// Updates BestTok and BestCost if Tok is a good candidate.
// May return true if the cost is too high for this token.
auto Consider = [&](const syntax::Token &Tok) {
+ if (Tok.location() < LocMin || Tok.location() > LocMax)
+ return true; // we are too far from the word, break the outer loop.
if (!(Tok.kind() == tok::identifier && Tok.text(SM) == Word.Text))
return false;
// No point guessing the same location we started with.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D87891.294924.patch
Type: text/x-patch
Size: 2528 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200929/b9a1552f/attachment.bin>
More information about the cfe-commits
mailing list