[clang-tools-extra] r373318 - [clangd] Handle template arguments in findExplicitReferences
Ilya Biryukov via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 1 03:02:24 PDT 2019
Author: ibiryukov
Date: Tue Oct 1 03:02:23 2019
New Revision: 373318
URL: http://llvm.org/viewvc/llvm-project?rev=373318&view=rev
Log:
[clangd] Handle template arguments in findExplicitReferences
Reviewers: kadircet
Reviewed By: kadircet
Subscribers: MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D68137
Modified:
clang-tools-extra/trunk/clangd/FindTarget.cpp
clang-tools-extra/trunk/clangd/unittests/FindTargetTests.cpp
Modified: clang-tools-extra/trunk/clangd/FindTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/FindTarget.cpp?rev=373318&r1=373317&r2=373318&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/FindTarget.cpp (original)
+++ clang-tools-extra/trunk/clangd/FindTarget.cpp Tue Oct 1 03:02:23 2019
@@ -22,6 +22,7 @@
#include "clang/AST/PrettyPrinter.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/TemplateBase.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeLoc.h"
#include "clang/AST/TypeLocVisitor.h"
@@ -565,6 +566,34 @@ public:
return true;
}
+ // We re-define Traverse*, since there's no corresponding Visit*.
+ // TemplateArgumentLoc is the only way to get locations for references to
+ // template template parameters.
+ bool TraverseTemplateArgumentLoc(TemplateArgumentLoc A) {
+ switch (A.getArgument().getKind()) {
+ case TemplateArgument::Template:
+ case TemplateArgument::TemplateExpansion:
+ reportReference(ReferenceLoc{A.getTemplateQualifierLoc(),
+ A.getTemplateNameLoc(),
+ {A.getArgument()
+ .getAsTemplateOrTemplatePattern()
+ .getAsTemplateDecl()}},
+ DynTypedNode::create(A.getArgument()));
+ break;
+ case TemplateArgument::Declaration:
+ break; // FIXME: can this actually happen in TemplateArgumentLoc?
+ case TemplateArgument::Integral:
+ case TemplateArgument::Null:
+ case TemplateArgument::NullPtr:
+ break; // no references.
+ case TemplateArgument::Pack:
+ case TemplateArgument::Type:
+ case TemplateArgument::Expression:
+ break; // Handled by VisitType and VisitExpression.
+ };
+ return RecursiveASTVisitor::TraverseTemplateArgumentLoc(A);
+ }
+
bool VisitDecl(Decl *D) {
visitNode(DynTypedNode::create(*D));
return true;
@@ -623,15 +652,19 @@ private:
auto Ref = explicitReference(N);
if (!Ref)
return;
+ reportReference(*Ref, N);
+ }
+
+ void reportReference(const ReferenceLoc &Ref, DynTypedNode N) {
// Our promise is to return only references from the source code. If we lack
// location information, skip these nodes.
// Normally this should not happen in practice, unless there are bugs in the
// traversals or users started the traversal at an implicit node.
- if (Ref->NameLoc.isInvalid()) {
+ if (Ref.NameLoc.isInvalid()) {
dlog("invalid location at node {0}", nodeToString(N));
return;
}
- Out(*Ref);
+ Out(Ref);
}
llvm::function_ref<void(ReferenceLoc)> Out;
Modified: clang-tools-extra/trunk/clangd/unittests/FindTargetTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/unittests/FindTargetTests.cpp?rev=373318&r1=373317&r2=373318&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/unittests/FindTargetTests.cpp (original)
+++ clang-tools-extra/trunk/clangd/unittests/FindTargetTests.cpp Tue Oct 1 03:02:23 2019
@@ -750,6 +750,39 @@ TEST_F(FindExplicitReferencesTest, All)
}
)cpp",
"0: targets = {I}\n"},
+ // Template template parameters.
+ {R"cpp(
+ template <class T> struct vector {};
+
+ template <template<class> class TT, template<class> class ...TP>
+ void foo() {
+ $0^TT<int> x;
+ $1^foo<$2^TT>();
+ $3^foo<$4^vector>()
+ $5^foo<$6^TP...>();
+ }
+ )cpp",
+ "0: targets = {TT}\n"
+ "1: targets = {foo}\n"
+ "2: targets = {TT}\n"
+ "3: targets = {foo}\n"
+ "4: targets = {vector}\n"
+ "5: targets = {foo}\n"
+ "6: targets = {TP}\n"},
+ // Non-type template parameters with declarations.
+ {R"cpp(
+ int func();
+ template <int(*)()> struct wrapper {};
+
+ template <int(*FuncParam)()>
+ void foo() {
+ $0^wrapper<$1^func> w;
+ $2^FuncParam();
+ }
+ )cpp",
+ "0: targets = {wrapper<&func>}\n"
+ "1: targets = {func}\n"
+ "2: targets = {FuncParam}\n"},
};
for (const auto &C : Cases) {
More information about the cfe-commits
mailing list