[PATCH] D62515: [clangd] Compute expected type for templates

Ilya Biryukov via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue May 28 03:43:00 PDT 2019


ilya-biryukov created this revision.
ilya-biryukov added a reviewer: sammccall.
Herald added subscribers: kadircet, arphaman, jkorous, MaskRay.
Herald added a project: clang.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D62515

Files:
  clang-tools-extra/clangd/ExpectedTypes.cpp
  clang-tools-extra/clangd/unittests/ExpectedTypeTest.cpp


Index: clang-tools-extra/clangd/unittests/ExpectedTypeTest.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/ExpectedTypeTest.cpp
+++ clang-tools-extra/clangd/unittests/ExpectedTypeTest.cpp
@@ -11,6 +11,7 @@
 #include "TestTU.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
+#include "llvm/ADT/None.h"
 #include "llvm/ADT/StringRef.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
@@ -31,16 +32,14 @@
     AST = TestTU::withCode(Code).build();
   }
 
-  const ValueDecl *decl(llvm::StringRef Name) {
-    return &cast<ValueDecl>(findDecl(*AST, Name));
-  }
+  const NamedDecl *decl(llvm::StringRef Name) { return &findDecl(*AST, Name); }
 
   QualType typeOf(llvm::StringRef Name) {
-    return decl(Name)->getType().getCanonicalType();
+    return cast<ValueDecl>(decl(Name))->getType().getCanonicalType();
   }
 
   /// An overload for convenience.
-  llvm::Optional<OpaqueType> fromCompletionResult(const ValueDecl *D) {
+  llvm::Optional<OpaqueType> fromCompletionResult(const NamedDecl *D) {
     return OpaqueType::fromCompletionResult(
         ASTCtx(), CodeCompletionResult(D, CCP_Declaration));
   }
@@ -148,6 +147,29 @@
   EXPECT_EQ(fromCompletionResult(decl("returns_ptr")), IntPtrTy);
 }
 
+TEST_F(ExpectedTypeConversionTest, Templates) {
+  build(R"cpp(
+template <class T>
+int* returns_not_dependent();
+template <class T>
+T* returns_dependent();
+
+template <class T>
+int* var_not_dependent = nullptr;
+template <class T>
+T* var_dependent = nullptr;
+
+int* int_ptr_;
+  )cpp");
+
+  auto IntPtrTy = *OpaqueType::fromType(ASTCtx(), typeOf("int_ptr_"));
+  EXPECT_EQ(fromCompletionResult(decl("returns_not_dependent")), IntPtrTy);
+  EXPECT_EQ(fromCompletionResult(decl("returns_dependent")), llvm::None);
+
+  EXPECT_EQ(fromCompletionResult(decl("var_not_dependent")), IntPtrTy);
+  EXPECT_EQ(fromCompletionResult(decl("var_dependent")), llvm::None);
+}
+
 } // namespace
 } // namespace clangd
 } // namespace clang
Index: clang-tools-extra/clangd/ExpectedTypes.cpp
===================================================================
--- clang-tools-extra/clangd/ExpectedTypes.cpp
+++ clang-tools-extra/clangd/ExpectedTypes.cpp
@@ -8,9 +8,11 @@
 
 #include "ExpectedTypes.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Type.h"
 #include "clang/Index/USRGeneration.h"
 #include "clang/Sema/CodeCompleteConsumer.h"
+#include "llvm/ADT/None.h"
 #include "llvm/ADT/STLExtras.h"
 
 namespace clang {
@@ -41,7 +43,13 @@
 
 static llvm::Optional<QualType>
 typeOfCompletion(const CodeCompletionResult &R) {
-  auto *VD = dyn_cast_or_null<ValueDecl>(R.Declaration);
+  const NamedDecl *D = R.Declaration;
+  if (!D)
+    return llvm::None;
+  // Templates do not have a type on their own, look at the templated decl.
+  if (auto *Template = dyn_cast<TemplateDecl>(D))
+    D = Template->getTemplatedDecl();
+  auto *VD = dyn_cast<ValueDecl>(D);
   if (!VD)
     return llvm::None; // We handle only variables and functions below.
   auto T = VD->getType();


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D62515.201632.patch
Type: text/x-patch
Size: 3105 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190528/be397efe/attachment-0001.bin>


More information about the cfe-commits mailing list