[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