[PATCH] D76103: [clangd] Extend findTarget()'s dependent name heuristic to handle enumerators

Nathan Ridge via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Mar 12 15:45:24 PDT 2020


nridge created this revision.
Herald added subscribers: cfe-commits, usaxena95, kadircet, arphaman, jkorous, MaskRay, ilya-biryukov.
Herald added a project: clang.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D76103

Files:
  clang-tools-extra/clangd/FindTarget.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
@@ -520,6 +520,14 @@
         void test(unique_ptr<S<T>>& V) {
           V->fo^o();
         }
+      )cpp",
+
+      R"cpp(// Heuristic resolution of dependent enumerator
+        template <typename T>
+        struct Foo {
+          enum class E { [[A]], B };
+          E e = E::A^;
+        };
       )cpp"};
   for (const char *Test : Tests) {
     Annotations T(Test);
Index: clang-tools-extra/clangd/FindTarget.cpp
===================================================================
--- clang-tools-extra/clangd/FindTarget.cpp
+++ clang-tools-extra/clangd/FindTarget.cpp
@@ -57,6 +57,30 @@
   return S;
 }
 
+// This is similar to CXXRecordDecl::lookupDependentName(), but extended
+// to handle certain other kinds of decls (currently, EnumDecl) as well.
+std::vector<const NamedDecl *>
+lookupDependentName(TagDecl *TD, DeclarationName Name,
+                    llvm::function_ref<bool(const NamedDecl *ND)> Filter) {
+  if (TagDecl *Def = TD->getDefinition()) {
+    TD = Def;
+  }
+
+  if (auto *RD = dyn_cast_or_null<CXXRecordDecl>(TD)) {
+    return RD->lookupDependentName(Name, Filter);
+  }
+  if (auto *ED = dyn_cast_or_null<EnumDecl>(TD)) {
+    std::vector<const NamedDecl *> Result;
+    for (const auto *Decl : ED->lookup(Name)) {
+      if (Filter(Decl)) {
+        Result.push_back(Decl);
+      }
+    }
+    return Result;
+  }
+  return {};
+}
+
 // Given a dependent type and a member name, heuristically resolve the
 // name to one or more declarations.
 // The current heuristic is simply to look up the name in the primary
@@ -76,22 +100,24 @@
     bool IsNonstaticMember) {
   if (!T)
     return {};
-  if (auto *ICNT = T->getAs<InjectedClassNameType>()) {
-    T = ICNT->getInjectedSpecializationType().getTypePtrOrNull();
+  TagDecl *LookupInDecl = nullptr;
+  if (auto *ET = T->getAs<EnumType>()) {
+    LookupInDecl = ET->getDecl();
+  } else {
+    if (auto *ICNT = T->getAs<InjectedClassNameType>()) {
+      T = ICNT->getInjectedSpecializationType().getTypePtrOrNull();
+    }
+    auto *TST = T->getAs<TemplateSpecializationType>();
+    if (!TST)
+      return {};
+    const ClassTemplateDecl *TempD = dyn_cast_or_null<ClassTemplateDecl>(
+        TST->getTemplateName().getAsTemplateDecl());
+    if (!TempD)
+      return {};
+    LookupInDecl = TempD->getTemplatedDecl();
   }
-  auto *TST = T->getAs<TemplateSpecializationType>();
-  if (!TST)
-    return {};
-  const ClassTemplateDecl *TD = dyn_cast_or_null<ClassTemplateDecl>(
-      TST->getTemplateName().getAsTemplateDecl());
-  if (!TD)
-    return {};
-  CXXRecordDecl *RD = TD->getTemplatedDecl();
-  if (!RD->hasDefinition())
-    return {};
-  RD = RD->getDefinition();
-  DeclarationName Name = NameFactory(RD->getASTContext());
-  return RD->lookupDependentName(Name, [=](const NamedDecl *D) {
+  DeclarationName Name = NameFactory(LookupInDecl->getASTContext());
+  return lookupDependentName(LookupInDecl, Name, [=](const NamedDecl *D) {
     return IsNonstaticMember ? D->isCXXInstanceMember()
                              : !D->isCXXInstanceMember();
   });


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D76103.250073.patch
Type: text/x-patch
Size: 3308 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200312/2ad5b6da/attachment.bin>


More information about the cfe-commits mailing list