[clang-tools-extra] r361823 - [clangd] Compute expected type for templates

Ilya Biryukov via cfe-commits cfe-commits at lists.llvm.org
Tue May 28 06:56:21 PDT 2019


Author: ibiryukov
Date: Tue May 28 06:56:21 2019
New Revision: 361823

URL: http://llvm.org/viewvc/llvm-project?rev=361823&view=rev
Log:
[clangd] Compute expected type for templates

Reviewers: sammccall

Reviewed By: sammccall

Subscribers: MaskRay, jkorous, arphaman, kadircet, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D62515

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

Modified: clang-tools-extra/trunk/clangd/ExpectedTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ExpectedTypes.cpp?rev=361823&r1=361822&r2=361823&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ExpectedTypes.cpp (original)
+++ clang-tools-extra/trunk/clangd/ExpectedTypes.cpp Tue May 28 06:56:21 2019
@@ -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 const Type *toEquivClass(ASTConte
 
 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();

Modified: clang-tools-extra/trunk/clangd/unittests/ExpectedTypeTest.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/unittests/ExpectedTypeTest.cpp?rev=361823&r1=361822&r2=361823&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/unittests/ExpectedTypeTest.cpp (original)
+++ clang-tools-extra/trunk/clangd/unittests/ExpectedTypeTest.cpp Tue May 28 06:56:21 2019
@@ -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 @@ protected:
     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 @@ TEST_F(ExpectedTypeConversionTest, Funct
   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




More information about the cfe-commits mailing list