This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG7a709689bc17: [clangd] Handle DependentNameType in 
HeuristicResolver::resolveTypeToRecordDecl… (authored by nridge).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D152645/new/

https://reviews.llvm.org/D152645

Files:
  clang-tools-extra/clangd/HeuristicResolver.cpp
  clang-tools-extra/clangd/HeuristicResolver.h
  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
@@ -877,6 +877,22 @@
         }
   )cpp";
   EXPECT_DECLS("CXXDependentScopeMemberExpr", "void find()");
+
+  Code = R"cpp(
+        template <typename T>
+        struct Waldo {
+          void find();
+        };
+        template <typename T>
+        struct MetaWaldo {
+          using Type = Waldo<T>;
+        };
+        template <typename T>
+        void foo(typename MetaWaldo<T>::Type w) {
+          w.[[find]]();
+        }
+  )cpp";
+  EXPECT_DECLS("CXXDependentScopeMemberExpr", "void find()");
 }
 
 TEST_F(TargetDeclTest, DependentTypes) {
Index: clang-tools-extra/clangd/HeuristicResolver.h
===================================================================
--- clang-tools-extra/clangd/HeuristicResolver.h
+++ clang-tools-extra/clangd/HeuristicResolver.h
@@ -94,6 +94,11 @@
   // `E`.
   const Type *resolveExprToType(const Expr *E) const;
   std::vector<const NamedDecl *> resolveExprToDecls(const Expr *E) const;
+
+  // Helper function for HeuristicResolver::resolveDependentMember()
+  // which takes a possibly-dependent type `T` and heuristically
+  // resolves it to a CXXRecordDecl in which we can try name lookup.
+  CXXRecordDecl *resolveTypeToRecordDecl(const Type *T) const;
 };
 
 } // namespace clangd
Index: clang-tools-extra/clangd/HeuristicResolver.cpp
===================================================================
--- clang-tools-extra/clangd/HeuristicResolver.cpp
+++ clang-tools-extra/clangd/HeuristicResolver.cpp
@@ -10,6 +10,7 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/ExprCXX.h"
+#include "clang/AST/Type.h"
 
 namespace clang {
 namespace clangd {
@@ -29,15 +30,39 @@
   return isa<TemplateDecl>(D);
 };
 
+namespace {
+
+const Type *resolveDeclsToType(const std::vector<const NamedDecl *> &Decls,
+                               ASTContext &Ctx) {
+  if (Decls.size() != 1) // Names an overload set -- just bail.
+    return nullptr;
+  if (const auto *TD = dyn_cast<TypeDecl>(Decls[0])) {
+    return Ctx.getTypeDeclType(TD).getTypePtr();
+  }
+  if (const auto *VD = dyn_cast<ValueDecl>(Decls[0])) {
+    return VD->getType().getTypePtrOrNull();
+  }
+  return nullptr;
+}
+
+} // namespace
+
 // Helper function for HeuristicResolver::resolveDependentMember()
 // which takes a possibly-dependent type `T` and heuristically
 // resolves it to a CXXRecordDecl in which we can try name lookup.
-CXXRecordDecl *resolveTypeToRecordDecl(const Type *T) {
+CXXRecordDecl *HeuristicResolver::resolveTypeToRecordDecl(const Type *T) const {
   assert(T);
 
   // Unwrap type sugar such as type aliases.
   T = T->getCanonicalTypeInternal().getTypePtr();
 
+  if (const auto *DNT = T->getAs<DependentNameType>()) {
+    T = resolveDeclsToType(resolveDependentNameType(DNT), Ctx);
+    if (!T)
+      return nullptr;
+    T = T->getCanonicalTypeInternal().getTypePtr();
+  }
+
   if (const auto *RT = T->getAs<RecordType>())
     return dyn_cast<CXXRecordDecl>(RT->getDecl());
 
@@ -185,18 +210,6 @@
       DTST->getIdentifier(), TemplateFilter);
 }
 
-const Type *resolveDeclsToType(const std::vector<const NamedDecl *> &Decls) {
-  if (Decls.size() != 1) // Names an overload set -- just bail.
-    return nullptr;
-  if (const auto *TD = dyn_cast<TypeDecl>(Decls[0])) {
-    return TD->getTypeForDecl();
-  }
-  if (const auto *VD = dyn_cast<ValueDecl>(Decls[0])) {
-    return VD->getType().getTypePtrOrNull();
-  }
-  return nullptr;
-}
-
 std::vector<const NamedDecl *>
 HeuristicResolver::resolveExprToDecls(const Expr *E) const {
   if (const auto *ME = dyn_cast<CXXDependentScopeMemberExpr>(E)) {
@@ -220,7 +233,7 @@
 const Type *HeuristicResolver::resolveExprToType(const Expr *E) const {
   std::vector<const NamedDecl *> Decls = resolveExprToDecls(E);
   if (!Decls.empty())
-    return resolveDeclsToType(Decls);
+    return resolveDeclsToType(Decls, Ctx);
 
   return E->getType().getTypePtr();
 }
@@ -239,9 +252,11 @@
   case NestedNameSpecifier::TypeSpecWithTemplate:
     return NNS->getAsType();
   case NestedNameSpecifier::Identifier: {
-    return resolveDeclsToType(resolveDependentMember(
-        resolveNestedNameSpecifierToType(NNS->getPrefix()),
-        NNS->getAsIdentifier(), TypeFilter));
+    return resolveDeclsToType(
+        resolveDependentMember(
+            resolveNestedNameSpecifierToType(NNS->getPrefix()),
+            NNS->getAsIdentifier(), TypeFilter),
+        Ctx);
   }
   default:
     break;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to