From b30b69bbf3beed91350f6ccfb0272f7b160f0d17 Mon Sep 17 00:00:00 2001 From: kai666_73 Date: Tue, 2 Sep 2014 17:56:22 +0400 Subject: [PATCH] C++: Find template member access in find usages Example: struct Foo {}; struct Bar { template T *templateFunc() { return 0; } }; struct Test { Bar member; void testFunc(); }; void Test::testFunc() { member.templateFunc(); // "templateFunc" and "Foo" outside of FindUsages } Change-Id: I0c5109d00c67054fe15b3fb98cf8cbca69123d8b Reviewed-by: Orgad Shaneh --- src/libs/cplusplus/FindUsages.cpp | 8 ++- .../cplusplus/findusages/tst_findusages.cpp | 63 +++++++++++++++++++ 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/src/libs/cplusplus/FindUsages.cpp b/src/libs/cplusplus/FindUsages.cpp index 7a6429fd95d..1b4e0c6e2b9 100644 --- a/src/libs/cplusplus/FindUsages.cpp +++ b/src/libs/cplusplus/FindUsages.cpp @@ -2125,10 +2125,12 @@ bool FindUsages::visit(MemberAccessAST *ast) if (ast->member_name) { if (SimpleNameAST *simple = ast->member_name->asSimpleName()) { - if (identifier(simple->identifier_token) == _id) { + if (identifier(simple->identifier_token) == _id) checkExpression(ast->firstToken(), simple->identifier_token); - return false; - } + } else if (TemplateIdAST *templateId = ast->member_name->asTemplateId()) { + if (identifier(templateId->identifier_token) == _id) + checkExpression(ast->firstToken(), templateId->identifier_token); + accept(templateId->template_argument_list); } } diff --git a/tests/auto/cplusplus/findusages/tst_findusages.cpp b/tests/auto/cplusplus/findusages/tst_findusages.cpp index d93d4bfb829..87ead4aa44f 100644 --- a/tests/auto/cplusplus/findusages/tst_findusages.cpp +++ b/tests/auto/cplusplus/findusages/tst_findusages.cpp @@ -118,6 +118,8 @@ private Q_SLOTS: void unicodeIdentifier(); void inAlignas(); + + void memberAccessAsTemplate(); }; void tst_FindUsages::dump(const QList &usages) const @@ -1018,5 +1020,66 @@ void tst_FindUsages::inAlignas() QCOMPARE(find.usages()[1].col, 15); } +void tst_FindUsages::memberAccessAsTemplate() +{ + const QByteArray src = "\n" + "struct Foo {};\n" + "struct Bar {\n" + " template \n" + " T *templateFunc() { return 0; }\n" + "};\n" + "struct Test {\n" + " Bar member;\n" + " void testFunc();\n" + "};\n" + "void Test::testFunc() {\n" + " member.templateFunc();\n" + "}\n"; + + Document::Ptr doc = Document::create("memberAccessAsTemplate"); + doc->setUtf8Source(src); + doc->parse(); + doc->check(); + + QVERIFY(doc->diagnosticMessages().isEmpty()); + QCOMPARE(doc->globalSymbolCount(), 4U); + + Snapshot snapshot; + snapshot.insert(doc); + + { // Test "Foo" + Class *c = doc->globalSymbolAt(0)->asClass(); + QVERIFY(c); + QCOMPARE(c->name()->identifier()->chars(), "Foo"); + + FindUsages find(src, doc, snapshot); + find(c); + QCOMPARE(find.usages().size(), 2); + QCOMPARE(find.usages()[0].line, 1); + QCOMPARE(find.usages()[0].col, 7); + QCOMPARE(find.usages()[1].line, 11); + QCOMPARE(find.usages()[1].col, 24); + } + + { // Test "templateFunc" + Class *c = doc->globalSymbolAt(1)->asClass(); + QVERIFY(c); + QCOMPARE(c->name()->identifier()->chars(), "Bar"); + QCOMPARE(c->memberCount(), 1U); + + Template *f = c->memberAt(0)->asTemplate(); + QVERIFY(f); + QCOMPARE(f->name()->identifier()->chars(), "templateFunc"); + + FindUsages find(src, doc, snapshot); + find(f); + QCOMPARE(find.usages().size(), 2); + QCOMPARE(find.usages()[0].line, 4); + QCOMPARE(find.usages()[0].col, 7); + QCOMPARE(find.usages()[1].line, 11); + QCOMPARE(find.usages()[1].col, 11); + } +} + QTEST_APPLESS_MAIN(tst_FindUsages) #include "tst_findusages.moc"