[clang-tools-extra] 95f0f69 - [clangd] Handle the new Using TemplateName.
Haojian Wu via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 20 06:42:34 PDT 2022
Author: Haojian Wu
Date: 2022-04-20T15:42:24+02:00
New Revision: 95f0f69441fb8b33528d25ba2b40e3fa703c6ea5
URL: https://github.com/llvm/llvm-project/commit/95f0f69441fb8b33528d25ba2b40e3fa703c6ea5
DIFF: https://github.com/llvm/llvm-project/commit/95f0f69441fb8b33528d25ba2b40e3fa703c6ea5.diff
LOG: [clangd] Handle the new Using TemplateName.
Add supports in FindTarget and IncludeCleaner. This would
improve AST-based features on a tempalte which is found via a using
declaration. For example, go-to-def on `vect^or<int> v;` gives us the
location of `using std::vector`, which was not previously.
Base on https://reviews.llvm.org/D123127
Differential Revision: https://reviews.llvm.org/D123212
Added:
Modified:
clang-tools-extra/clangd/FindTarget.cpp
clang-tools-extra/clangd/IncludeCleaner.cpp
clang-tools-extra/clangd/unittests/FindTargetTests.cpp
clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clangd/FindTarget.cpp b/clang-tools-extra/clangd/FindTarget.cpp
index 404e852e179ca..dcdac55c26b70 100644
--- a/clang-tools-extra/clangd/FindTarget.cpp
+++ b/clang-tools-extra/clangd/FindTarget.cpp
@@ -384,11 +384,14 @@ struct TargetFinder {
}
void VisitDeducedTemplateSpecializationType(
const DeducedTemplateSpecializationType *DTST) {
+ if (const auto *USD = DTST->getTemplateName().getAsUsingShadowDecl())
+ Outer.add(USD, Flags);
+
// FIXME: This is a workaround for https://llvm.org/PR42914,
// which is causing DTST->getDeducedType() to be empty. We
// fall back to the template pattern and miss the instantiation
// even when it's known in principle. Once that bug is fixed,
- // this method can be removed (the existing handling in
+ // the following code can be removed (the existing handling in
// VisitDeducedType() is sufficient).
if (auto *TD = DTST->getTemplateName().getAsTemplateDecl())
Outer.add(TD->getTemplatedDecl(), Flags | Rel::TemplatePattern);
@@ -419,6 +422,9 @@ struct TargetFinder {
VisitTemplateSpecializationType(const TemplateSpecializationType *TST) {
// Have to handle these case-by-case.
+ if (const auto *UTN = TST->getTemplateName().getAsUsingShadowDecl())
+ Outer.add(UTN, Flags);
+
// templated type aliases: there's no specialized/instantiated using
// decl to point to. So try to find a decl for the underlying type
// (after substitution), and failing that point to the (templated) using
@@ -508,6 +514,9 @@ struct TargetFinder {
Arg.getAsTemplateOrTemplatePattern().getAsTemplateDecl()) {
report(TD, Flags);
}
+ if (const auto *USD =
+ Arg.getAsTemplateOrTemplatePattern().getAsUsingShadowDecl())
+ add(USD, Flags);
}
}
};
diff --git a/clang-tools-extra/clangd/IncludeCleaner.cpp b/clang-tools-extra/clangd/IncludeCleaner.cpp
index e6c8d9e76ed67..5b7f01d82fbac 100644
--- a/clang-tools-extra/clangd/IncludeCleaner.cpp
+++ b/clang-tools-extra/clangd/IncludeCleaner.cpp
@@ -79,11 +79,29 @@ class ReferencedLocationCrawler
}
bool VisitTemplateSpecializationType(TemplateSpecializationType *TST) {
- add(TST->getTemplateName().getAsTemplateDecl()); // Primary template.
+ // Using templateName case is handled by the override TraverseTemplateName.
+ if (TST->getTemplateName().getKind() == TemplateName::UsingTemplate)
+ return true;
add(TST->getAsCXXRecordDecl()); // Specialization
return true;
}
+ // There is no VisitTemplateName in RAV, thus we override the Traverse version
+ // to handle the Using TemplateName case.
+ bool TraverseTemplateName(TemplateName TN) {
+ VisitTemplateName(TN);
+ return Base::TraverseTemplateName(TN);
+ }
+ // A pseudo VisitTemplateName, dispatched by the above TraverseTemplateName!
+ bool VisitTemplateName(TemplateName TN) {
+ if (const auto *USD = TN.getAsUsingShadowDecl()) {
+ add(USD);
+ return true;
+ }
+ add(TN.getAsTemplateDecl()); // Primary template.
+ return true;
+ }
+
bool VisitUsingType(UsingType *UT) {
add(UT->getFoundDecl());
return true;
diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
index 7026f7fced3c9..c21114fa45b07 100644
--- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
+++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
@@ -229,6 +229,45 @@ TEST_F(TargetDeclTest, UsingDecl) {
)cpp";
EXPECT_DECLS("UnresolvedUsingValueDecl", {"using Base<T>::waldo", Rel::Alias},
{"void waldo()"});
+
+ Code = R"cpp(
+ namespace ns {
+ template<typename T> class S {};
+ }
+
+ using ns::S;
+
+ template<typename T>
+ using A = [[S]]<T>;
+ )cpp";
+ EXPECT_DECLS("TemplateSpecializationTypeLoc", {"using ns::S", Rel::Alias},
+ {"template <typename T> class S"},
+ {"class S", Rel::TemplatePattern});
+
+ Code = R"cpp(
+ namespace ns {
+ template<typename T> class S {};
+ }
+
+ using ns::S;
+ template <template <typename> class T> class X {};
+ using B = X<[[S]]>;
+ )cpp";
+ EXPECT_DECLS("TemplateArgumentLoc", {"using ns::S", Rel::Alias},
+ {"template <typename T> class S"});
+
+ Code = R"cpp(
+ namespace ns {
+ template<typename T> class S { public: S(T); };
+ }
+
+ using ns::S;
+ [[S]] s(123);
+ )cpp";
+ Flags.push_back("-std=c++17"); // For CTAD feature.
+ EXPECT_DECLS("DeducedTemplateSpecializationTypeLoc",
+ {"using ns::S", Rel::Alias}, {"template <typename T> class S"},
+ {"class S", Rel::TemplatePattern});
}
TEST_F(TargetDeclTest, BaseSpecifier) {
diff --git a/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp b/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
index ffecea5713215..4a376a87297f9 100644
--- a/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
+++ b/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
@@ -79,9 +79,22 @@ TEST(IncludeCleaner, ReferencedLocations) {
"using namespace ns;",
},
{
+ // Refs from UsingTypeLoc and implicit constructor!
"struct ^A {}; using B = A; using ^C = B;",
"C a;",
},
+ {"namespace ns { template<typename T> class A {}; } using ns::^A;",
+ "A<int>* a;"},
+ {"namespace ns { template<typename T> class A {}; } using ns::^A;",
+ R"cpp(
+ template <template <typename> class T> class X {};
+ X<A> x;
+ )cpp"},
+ {R"cpp(
+ namespace ns { template<typename T> struct ^A { ^A(T); }; }
+ using ns::^A;
+ )cpp",
+ "A CATD(123);"},
{
"typedef bool ^Y; template <typename T> struct ^X {};",
"X<Y> x;",
@@ -227,6 +240,7 @@ TEST(IncludeCleaner, ReferencedLocations) {
TU.Code = T.MainCode;
Annotations Header(T.HeaderCode);
TU.HeaderCode = Header.code().str();
+ TU.ExtraArgs.push_back("-std=c++17");
auto AST = TU.build();
std::vector<Position> Points;
More information about the cfe-commits
mailing list