[PATCH] D94382: [clangd] Avoid recusion in TargetFinder::add()
Nathan Ridge via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Sun Jan 10 17:49:20 PST 2021
nridge created this revision.
Herald added subscribers: usaxena95, kadircet, arphaman.
nridge requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay, ilya-biryukov.
Herald added a project: clang.
Fixes https://github.com/clangd/clangd/issues/633
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D94382
Files:
clang-tools-extra/clangd/FindTarget.cpp
clang-tools-extra/clangd/unittests/FindTargetTests.cpp
Index: clang-tools-extra/clangd/unittests/FindTargetTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/FindTargetTests.cpp
+++ clang-tools-extra/clangd/unittests/FindTargetTests.cpp
@@ -787,6 +787,47 @@
"template <typename> struct B");
}
+TEST_F(TargetDeclTest, TypedefCascade) {
+ Code = R"cpp(
+ struct C {
+ using type = int;
+ };
+ struct B {
+ using type = C::type;
+ };
+ struct A {
+ using type = B::type;
+ };
+ A::[[type]] waldo;
+ )cpp";
+ EXPECT_DECLS("TypedefTypeLoc",
+ {"using type = int", Rel::Alias | Rel::Underlying},
+ {"using type = C::type", Rel::Alias | Rel::Underlying},
+ {"using type = B::type", Rel::Alias});
+}
+
+TEST_F(TargetDeclTest, RecursiveTemplate) {
+ Flags.push_back("-std=c++20"); // the test case uses concepts
+
+ Code = R"cpp(
+ template <typename T>
+ concept Leaf = false;
+
+ template <typename Tree>
+ struct descend_left {
+ using type = typename descend_left<typename Tree::left>::[[type]];
+ };
+
+ template <Leaf Tree>
+ struct descend_left<Tree> {
+ using type = typename Tree::value;
+ };
+ )cpp";
+ EXPECT_DECLS("DependentNameTypeLoc",
+ {"using type = typename descend_left<typename Tree::left>::type",
+ Rel::Alias});
+}
+
TEST_F(TargetDeclTest, ObjC) {
Flags = {"-xobjective-c"};
Code = R"cpp(
Index: clang-tools-extra/clangd/FindTarget.cpp
===================================================================
--- clang-tools-extra/clangd/FindTarget.cpp
+++ clang-tools-extra/clangd/FindTarget.cpp
@@ -330,6 +330,7 @@
llvm::SmallDenseMap<const NamedDecl *,
std::pair<RelSet, /*InsertionOrder*/ size_t>>
Decls;
+ const Decl *CurrentlyProcessing = nullptr;
RelSet Flags;
template <typename T> void debug(T &Node, RelSet Flags) {
@@ -354,11 +355,28 @@
return Result;
}
+ bool seenDecl(const Decl *Dcl) const {
+ if (CurrentlyProcessing == Dcl)
+ return true;
+ for (const auto &D : Decls)
+ if (D.first == Dcl)
+ return true;
+ return false;
+ }
+
void add(const Decl *Dcl, RelSet Flags) {
const NamedDecl *D = llvm::dyn_cast_or_null<NamedDecl>(Dcl);
if (!D)
return;
debug(*D, Flags);
+
+ // Avoid recursion (which can arise in the presence of heuristic
+ // resolution of dependent names) by exiting early if we have
+ // already seen this decl.
+ if (seenDecl(D))
+ return;
+ CurrentlyProcessing = D;
+
if (const UsingDirectiveDecl *UDD = llvm::dyn_cast<UsingDirectiveDecl>(D))
D = UDD->getNominatedNamespaceAsWritten();
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D94382.315686.patch
Type: text/x-patch
Size: 2831 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20210111/f370709b/attachment-0001.bin>
More information about the cfe-commits
mailing list