[clang-tools-extra] 98d763a - [clangd] Factor out some helper functions related to heuristic resolution in TargetFinder
Nathan Ridge via cfe-commits
cfe-commits at lists.llvm.org
Thu Jul 9 22:58:51 PDT 2020
Author: Nathan Ridge
Date: 2020-07-10T01:58:34-04:00
New Revision: 98d763ad051f5eab89fa46167516fc8a84f471d0
URL: https://github.com/llvm/llvm-project/commit/98d763ad051f5eab89fa46167516fc8a84f471d0
DIFF: https://github.com/llvm/llvm-project/commit/98d763ad051f5eab89fa46167516fc8a84f471d0.diff
LOG: [clangd] Factor out some helper functions related to heuristic resolution in TargetFinder
Summary:
Two helpers are introduced:
* Some of the logic previously in TargetFinder::Visit*() methods is
factored out into resolveDependentExprToDecls().
* Some of the logic in getMembersReferencedViaDependentName() is
factored out into resolveTypeToRecordDecl().
D82739 will build on this and use these functions in new ways.
Reviewers: hokein
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D83371
Added:
Modified:
clang-tools-extra/clangd/FindTarget.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clangd/FindTarget.cpp b/clang-tools-extra/clangd/FindTarget.cpp
index 1d09e8408c83..627f40c85436 100644
--- a/clang-tools-extra/clangd/FindTarget.cpp
+++ b/clang-tools-extra/clangd/FindTarget.cpp
@@ -58,6 +58,24 @@ nodeToString(const ast_type_traits::DynTypedNode &N) {
return S;
}
+// Helper function for getMembersReferencedViaDependentName()
+// which takes a dependent type `T` and heuristically
+// resolves it to a CXXRecordDecl in which we can try name lookup.
+CXXRecordDecl *resolveTypeToRecordDecl(const Type *T) {
+ assert(T);
+ if (const auto *ICNT = T->getAs<InjectedClassNameType>()) {
+ T = ICNT->getInjectedSpecializationType().getTypePtrOrNull();
+ }
+ const auto *TST = T->getAs<TemplateSpecializationType>();
+ if (!TST)
+ return nullptr;
+ const ClassTemplateDecl *TD = dyn_cast_or_null<ClassTemplateDecl>(
+ TST->getTemplateName().getAsTemplateDecl());
+ if (!TD)
+ return nullptr;
+ return TD->getTemplatedDecl();
+}
+
// 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
@@ -82,25 +100,17 @@ std::vector<const NamedDecl *> getMembersReferencedViaDependentName(
ET->getDecl()->lookup(NameFactory(ET->getDecl()->getASTContext()));
return {Result.begin(), Result.end()};
}
- if (auto *ICNT = T->getAs<InjectedClassNameType>()) {
- T = ICNT->getInjectedSpecializationType().getTypePtrOrNull();
+ if (auto *RD = resolveTypeToRecordDecl(T)) {
+ if (!RD->hasDefinition())
+ return {};
+ RD = RD->getDefinition();
+ DeclarationName Name = NameFactory(RD->getASTContext());
+ return RD->lookupDependentName(Name, [=](const NamedDecl *D) {
+ return IsNonstaticMember ? D->isCXXInstanceMember()
+ : !D->isCXXInstanceMember();
+ });
}
- 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) {
- return IsNonstaticMember ? D->isCXXInstanceMember()
- : !D->isCXXInstanceMember();
- });
+ return {};
}
// Given the type T of a dependent expression that appears of the LHS of a "->",
@@ -144,6 +154,28 @@ const Type *getPointeeType(const Type *T) {
return FirstArg.getAsType().getTypePtrOrNull();
}
+// Try to heuristically resolve a dependent expression `E` to one
+// or more declarations that it likely references.
+std::vector<const NamedDecl *> resolveDependentExprToDecls(const Expr *E) {
+ assert(E->isTypeDependent());
+ if (const auto *ME = dyn_cast<CXXDependentScopeMemberExpr>(E)) {
+ const Type *BaseType = ME->getBaseType().getTypePtrOrNull();
+ if (ME->isArrow()) {
+ BaseType = getPointeeType(BaseType);
+ }
+ return getMembersReferencedViaDependentName(
+ BaseType, [ME](ASTContext &) { return ME->getMember(); },
+ /*IsNonstaticMember=*/true);
+ }
+ if (const auto *RE = dyn_cast<DependentScopeDeclRefExpr>(E)) {
+ return getMembersReferencedViaDependentName(
+ RE->getQualifier()->getAsType(),
+ [RE](ASTContext &) { return RE->getDeclName(); },
+ /*IsNonstaticMember=*/false);
+ }
+ return {};
+}
+
const NamedDecl *getTemplatePattern(const NamedDecl *D) {
if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(D)) {
if (const auto *Result = CRD->getTemplateInstantiationPattern())
@@ -341,21 +373,12 @@ struct TargetFinder {
}
void
VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
- const Type *BaseType = E->getBaseType().getTypePtrOrNull();
- if (E->isArrow()) {
- BaseType = getPointeeType(BaseType);
- }
- for (const NamedDecl *D : getMembersReferencedViaDependentName(
- BaseType, [E](ASTContext &) { return E->getMember(); },
- /*IsNonstaticMember=*/true)) {
+ for (const NamedDecl *D : resolveDependentExprToDecls(E)) {
Outer.add(D, Flags);
}
}
void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E) {
- for (const NamedDecl *D : getMembersReferencedViaDependentName(
- E->getQualifier()->getAsType(),
- [E](ASTContext &) { return E->getDeclName(); },
- /*IsNonstaticMember=*/false)) {
+ for (const NamedDecl *D : resolveDependentExprToDecls(E)) {
Outer.add(D, Flags);
}
}
More information about the cfe-commits
mailing list