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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits