forked from OSchip/llvm-project
[clangd] Have template template arguments target their referenced template decl
Fixes https://github.com/clangd/clangd/issues/473 Differential Revision: https://reviews.llvm.org/D85503
This commit is contained in:
parent
582fd474dd
commit
70d583ad12
|
@ -596,6 +596,19 @@ public:
|
|||
add(CCI->getAnyMember(), Flags);
|
||||
// Constructor calls contain a TypeLoc node, so we don't handle them here.
|
||||
}
|
||||
|
||||
void add(const TemplateArgument &Arg, RelSet Flags) {
|
||||
// Only used for template template arguments.
|
||||
// For type and non-type template arguments, SelectionTree
|
||||
// will hit a more specific node (e.g. a TypeLoc or a
|
||||
// DeclRefExpr).
|
||||
if (Arg.getKind() == TemplateArgument::Template ||
|
||||
Arg.getKind() == TemplateArgument::TemplateExpansion) {
|
||||
if (TemplateDecl *TD = Arg.getAsTemplate().getAsTemplateDecl()) {
|
||||
report(TD, Flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
@ -619,6 +632,8 @@ allTargetDecls(const ast_type_traits::DynTypedNode &N) {
|
|||
Finder.add(*QT, Flags);
|
||||
else if (const CXXCtorInitializer *CCI = N.get<CXXCtorInitializer>())
|
||||
Finder.add(CCI, Flags);
|
||||
else if (const TemplateArgumentLoc *TAL = N.get<TemplateArgumentLoc>())
|
||||
Finder.add(TAL->getArgument(), Flags);
|
||||
|
||||
return Finder.takeDecls();
|
||||
}
|
||||
|
|
|
@ -479,6 +479,10 @@ public:
|
|||
bool TraverseTypeLoc(TypeLoc X) {
|
||||
return traverseNode(&X, [&] { return Base::TraverseTypeLoc(X); });
|
||||
}
|
||||
bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &X) {
|
||||
return traverseNode(&X,
|
||||
[&] { return Base::TraverseTemplateArgumentLoc(X); });
|
||||
}
|
||||
bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc X) {
|
||||
return traverseNode(
|
||||
&X, [&] { return Base::TraverseNestedNameSpecifierLoc(X); });
|
||||
|
|
|
@ -376,6 +376,15 @@ TEST_F(TargetDeclTest, ClassTemplate) {
|
|||
{"template<> class Foo<int *>", Rel::TemplateInstantiation},
|
||||
{"template <typename T> class Foo<T *>", Rel::TemplatePattern});
|
||||
|
||||
Code = R"cpp(
|
||||
// Template template argument.
|
||||
template<typename T> struct Vector {};
|
||||
template <template <typename> class Container>
|
||||
struct A {};
|
||||
A<[[Vector]]> a;
|
||||
)cpp";
|
||||
EXPECT_DECLS("TemplateArgumentLoc", {"template <typename T> struct Vector"});
|
||||
|
||||
Flags.push_back("-std=c++17"); // for CTAD tests
|
||||
|
||||
Code = R"cpp(
|
||||
|
|
|
@ -407,8 +407,16 @@ TEST(SelectionTest, CommonAncestor) {
|
|||
s2[[-^>]]f();
|
||||
}
|
||||
)cpp",
|
||||
"DeclRefExpr"} // DeclRefExpr to the "operator->" method.
|
||||
};
|
||||
"DeclRefExpr"}, // DeclRefExpr to the "operator->" method.
|
||||
|
||||
// Template template argument.
|
||||
{R"cpp(
|
||||
template <typename> class Vector {};
|
||||
template <template <typename> class Container> class A {};
|
||||
A<[[V^ector]]> a;
|
||||
)cpp",
|
||||
"TemplateArgumentLoc"}};
|
||||
|
||||
for (const Case &C : Cases) {
|
||||
trace::TestTracer Tracer;
|
||||
Annotations Test(C.Code);
|
||||
|
|
Loading…
Reference in New Issue