diff --git a/src/libs/cplusplus/FindUsages.cpp b/src/libs/cplusplus/FindUsages.cpp index e83d7d220f0..365073cb27d 100644 --- a/src/libs/cplusplus/FindUsages.cpp +++ b/src/libs/cplusplus/FindUsages.cpp @@ -260,6 +260,8 @@ void FindUsages::checkExpression(unsigned startToken, unsigned endToken, Scope * if (! scope) scope = _currentScope; + // make possible to instantiate templates + typeofExpression.setExpandTemplates(true); const QList results = typeofExpression(expression, scope, TypeOfExpression::Preprocess); reportResult(endToken, results); } diff --git a/src/libs/cplusplus/LookupContext.h b/src/libs/cplusplus/LookupContext.h index 19fec679ead..8144cbfa84d 100644 --- a/src/libs/cplusplus/LookupContext.h +++ b/src/libs/cplusplus/LookupContext.h @@ -281,7 +281,11 @@ public: static const Name *minimalName(Symbol *symbol, ClassOrNamespace *target, Control *control); void setExpandTemplates(bool expandTemplates) - { m_expandTemplates = expandTemplates; } + { + if (_bindings) + _bindings->setExpandTemplates(expandTemplates); + m_expandTemplates = expandTemplates; + } private: // The current expression. diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index f7b0b01756a..6db81d92a8f 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -819,6 +819,8 @@ static QList lazyFindReferences(Scope *scope, QString code, Document::Ptr d TypeOfExpression typeOfExpression; snapshot.insert(doc); typeOfExpression.init(doc, snapshot); + // make possible to instantiate templates + typeOfExpression.setExpandTemplates(true); if (Symbol *canonicalSymbol = CanonicalSymbol::canonicalSymbol(scope, code, typeOfExpression)) return CppModelManagerInterface::instance()->references(canonicalSymbol, typeOfExpression.context()); return QList(); @@ -1522,6 +1524,8 @@ CPPEditorWidget::Link CPPEditorWidget::findLinkAt(const QTextCursor &cursor, TypeOfExpression typeOfExpression; typeOfExpression.init(doc, snapshot); + // make possible to instantiate templates + typeOfExpression.setExpandTemplates(true); const QList resolvedSymbols = typeOfExpression.reference(expression.toUtf8(), scope, TypeOfExpression::Preprocess); diff --git a/src/plugins/cppeditor/cppelementevaluator.cpp b/src/plugins/cppeditor/cppelementevaluator.cpp index c7fc227a521..4f476b66757 100644 --- a/src/plugins/cppeditor/cppelementevaluator.cpp +++ b/src/plugins/cppeditor/cppelementevaluator.cpp @@ -118,6 +118,8 @@ void CppElementEvaluator::execute() TypeOfExpression typeOfExpression; typeOfExpression.init(doc, snapshot); + // make possible to instantiate templates + typeOfExpression.setExpandTemplates(true); const QList &lookupItems = typeOfExpression(expression.toUtf8(), scope); if (lookupItems.isEmpty()) return; diff --git a/src/plugins/cpptools/cppchecksymbols.cpp b/src/plugins/cpptools/cppchecksymbols.cpp index 3e9d6bdcc15..8d930457896 100644 --- a/src/plugins/cpptools/cppchecksymbols.cpp +++ b/src/plugins/cpptools/cppchecksymbols.cpp @@ -324,6 +324,8 @@ CheckSymbols::CheckSymbols(Document::Ptr doc, const LookupContext &context, cons _potentialStatics = collectTypes.statics(); typeOfExpression.init(_doc, _context.snapshot(), _context.bindings()); + // make possible to instantiate templates + typeOfExpression.setExpandTemplates(true); } CheckSymbols::~CheckSymbols() diff --git a/tests/auto/cplusplus/findusages/tst_findusages.cpp b/tests/auto/cplusplus/findusages/tst_findusages.cpp index 0cc1381103e..0d84cb515bc 100644 --- a/tests/auto/cplusplus/findusages/tst_findusages.cpp +++ b/tests/auto/cplusplus/findusages/tst_findusages.cpp @@ -90,6 +90,9 @@ private Q_SLOTS: // void objc_methods(); // void objc_fields(); // void objc_classes(); + + // templates + void instantiateTemplateWithNestedClass(); }; void tst_FindUsages::inlineMethod() @@ -351,5 +354,48 @@ void tst_FindUsages::qproperty_1() QCOMPARE(findUsages.references().size(), 2); } +void tst_FindUsages::instantiateTemplateWithNestedClass() +{ + const QByteArray src = "\n" + "struct Foo\n" + "{ int bar; };\n" + "template \n" + "struct Template\n" + "{\n" + " struct Nested\n" + " {\n" + " T t;\n" + " }nested;\n" + "};\n" + "void f()\n" + "{\n" + " Template templateFoo;\n" + " templateFoo.nested.t.bar;\n" + "}\n" + ; + + Document::Ptr doc = Document::create("simpleTemplate"); + doc->setUtf8Source(src); + doc->parse(); + doc->check(); + + QVERIFY(doc->diagnosticMessages().isEmpty()); + QCOMPARE(doc->globalSymbolCount(), 3U); + + Snapshot snapshot; + snapshot.insert(doc); + + Class *classFoo = doc->globalSymbolAt(0)->asClass(); + QVERIFY(classFoo); + QCOMPARE(classFoo->memberCount(), 1U); + Declaration *barDeclaration = classFoo->memberAt(0)->asDeclaration(); + QVERIFY(barDeclaration); + QCOMPARE(barDeclaration->name()->identifier()->chars(), "bar"); + + FindUsages findUsages(src, doc, snapshot); + findUsages(barDeclaration); + QCOMPARE(findUsages.usages().size(), 2); +} + QTEST_APPLESS_MAIN(tst_FindUsages) #include "tst_findusages.moc"