[clang-tools-extra] 100dbd1 - [clangd] Handle deduction guides in TargetFinder and ExplicitReferenceCollector
Nathan Ridge via cfe-commits
cfe-commits at lists.llvm.org
Mon Jul 20 22:45:50 PDT 2020
Author: Nathan Ridge
Date: 2020-07-21T01:44:48-04:00
New Revision: 100dbd15624c1ac8d1210e7748462e20fed9a9d9
URL: https://github.com/llvm/llvm-project/commit/100dbd15624c1ac8d1210e7748462e20fed9a9d9
DIFF: https://github.com/llvm/llvm-project/commit/100dbd15624c1ac8d1210e7748462e20fed9a9d9.diff
LOG: [clangd] Handle deduction guides in TargetFinder and ExplicitReferenceCollector
Summary: Fixes https://github.com/clangd/clangd/issues/463.
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D84122
Added:
Modified:
clang-tools-extra/clangd/FindTarget.cpp
clang-tools-extra/clangd/unittests/FindTargetTests.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clangd/FindTarget.cpp b/clang-tools-extra/clangd/FindTarget.cpp
index 627f40c85436..c2887f3306fa 100644
--- a/clang-tools-extra/clangd/FindTarget.cpp
+++ b/clang-tools-extra/clangd/FindTarget.cpp
@@ -302,6 +302,8 @@ struct TargetFinder {
// Record the underlying decl instead, if allowed.
D = USD->getTargetDecl();
Flags |= Rel::Underlying; // continue with the underlying decl.
+ } else if (const auto *DG = dyn_cast<CXXDeductionGuideDecl>(D)) {
+ D = DG->getDeducedTemplate();
}
if (const Decl *Pat = getTemplatePattern(D)) {
@@ -659,6 +661,15 @@ llvm::SmallVector<ReferenceLoc, 2> refInDecl(const Decl *D) {
/*IsDecl=*/true,
{ND}});
}
+
+ void VisitCXXDeductionGuideDecl(const CXXDeductionGuideDecl *DG) {
+ // The class template name in a deduction guide targets the class
+ // template.
+ Refs.push_back(ReferenceLoc{DG->getQualifierLoc(),
+ DG->getNameInfo().getLoc(),
+ /*IsDecl=*/false,
+ {DG->getDeducedTemplate()}});
+ }
};
Visitor V;
diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
index bf5cc62411b7..fa8f4935b1d9 100644
--- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
+++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
@@ -376,6 +376,8 @@ TEST_F(TargetDeclTest, ClassTemplate) {
{"template<> class Foo<int *>", Rel::TemplateInstantiation},
{"template <typename T> class Foo<T *>", Rel::TemplatePattern});
+ Flags.push_back("-std=c++17"); // for CTAD tests
+
Code = R"cpp(
// Class template argument deduction
template <typename T>
@@ -386,9 +388,20 @@ TEST_F(TargetDeclTest, ClassTemplate) {
[[Test]] a(5);
}
)cpp";
- Flags.push_back("-std=c++17");
EXPECT_DECLS("DeducedTemplateSpecializationTypeLoc",
{"struct Test", Rel::TemplatePattern});
+
+ Code = R"cpp(
+ // Deduction guide
+ template <typename T>
+ struct Test {
+ template <typename I>
+ Test(I, I);
+ };
+ template <typename I>
+ [[Test]](I, I) -> Test<typename I::type>;
+ )cpp";
+ EXPECT_DECLS("CXXDeductionGuideDecl", {"template <typename T> struct Test"});
}
TEST_F(TargetDeclTest, Concept) {
@@ -792,8 +805,8 @@ TEST_F(FindExplicitReferencesTest, All) {
goto $1^ten;
}
)cpp",
- "0: targets = {ten}, decl\n"
- "1: targets = {ten}\n"},
+ "0: targets = {ten}, decl\n"
+ "1: targets = {ten}\n"},
// Simple templates.
{R"cpp(
template <class T> struct vector { using value_type = T; };
@@ -1295,7 +1308,7 @@ TEST_F(FindExplicitReferencesTest, All) {
"6: targets = {bar}, decl\n"
"7: targets = {foo()::Bar::Foo}\n"
"8: targets = {foo()::Baz::Field}\n"},
- {R"cpp(
+ {R"cpp(
template<typename T>
void crash(T);
template<typename T>
@@ -1305,10 +1318,9 @@ TEST_F(FindExplicitReferencesTest, All) {
)cpp",
"0: targets = {crash}\n"
"1: targets = {}\n"
- "2: targets = {T}\n"
- },
- // unknown template name should not crash.
- {R"cpp(
+ "2: targets = {T}\n"},
+ // unknown template name should not crash.
+ {R"cpp(
template <template <typename> typename T>
struct Base {};
namespace foo {
@@ -1316,12 +1328,34 @@ TEST_F(FindExplicitReferencesTest, All) {
struct $1^Derive : $2^Base<$3^T::template $4^Unknown> {};
}
)cpp",
- "0: targets = {foo::Derive::T}, decl\n"
- "1: targets = {foo::Derive}, decl\n"
- "2: targets = {Base}\n"
- "3: targets = {foo::Derive::T}\n"
- "4: targets = {}, qualifier = 'T::'\n"},
- };
+ "0: targets = {foo::Derive::T}, decl\n"
+ "1: targets = {foo::Derive}, decl\n"
+ "2: targets = {Base}\n"
+ "3: targets = {foo::Derive::T}\n"
+ "4: targets = {}, qualifier = 'T::'\n"},
+ // deduction guide
+ {R"cpp(
+ namespace foo {
+ template <typename $0^T>
+ struct $1^Test {
+ template <typename $2^I>
+ $3^Test($4^I);
+ };
+ template <typename $5^I>
+ $6^Test($7^I) -> $8^Test<typename $9^I::$10^type>;
+ }
+ )cpp",
+ "0: targets = {T}, decl\n"
+ "1: targets = {foo::Test}, decl\n"
+ "2: targets = {I}, decl\n"
+ "3: targets = {foo::Test::Test<T>}, decl\n"
+ "4: targets = {I}\n"
+ "5: targets = {I}, decl\n"
+ "6: targets = {foo::Test}\n"
+ "7: targets = {I}\n"
+ "8: targets = {foo::Test}\n"
+ "9: targets = {I}\n"
+ "10: targets = {}, qualifier = 'I::'\n"}};
for (const auto &C : Cases) {
llvm::StringRef ExpectedCode = C.first;
More information about the cfe-commits
mailing list