From 0bc202d52fca029849e38b05f91efed4d1ee7bd1 Mon Sep 17 00:00:00 2001 From: Przemyslaw Gorszkowski Date: Wed, 9 Jul 2014 09:01:36 +0200 Subject: [PATCH] C++: use pointer in template specialization and initialization Fix code completion for using pointer in template specialization and initialization. Example: template struct S {}; template struct S { T* t; }; struct Foo { int foo; }; int main() { S s; s.t-> //no code completion return 0; } Task-number: QTCREATORBUG-12638 Change-Id: Idcd461806a22f08b76236f2db6346f157b12f5d3 Reviewed-by: Orgad Shaneh --- src/libs/cplusplus/LookupContext.cpp | 10 +++++++ src/plugins/cpptools/cppcompletion_test.cpp | 29 +++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp index 6cc6db42261..98050c911b6 100644 --- a/src/libs/cplusplus/LookupContext.cpp +++ b/src/libs/cplusplus/LookupContext.cpp @@ -1084,6 +1084,10 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac Subst subst(_control.data()); if (_factory->expandTemplates()) { + const TemplateNameId *templSpecId + = templateSpecialization->name()->asTemplateNameId(); + const unsigned templSpecArgumentCount = templSpecId ? + templSpecId->templateArgumentCount() : 0; Clone cloner(_control.data()); for (unsigned i = 0; i < argumentCountOfSpecialization; ++i) { const TypenameArgument *tParam @@ -1098,6 +1102,12 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac templId->templateArgumentAt(i): cloner.type(tParam->type(), &subst); + if (i < templSpecArgumentCount + && templSpecId->templateArgumentAt(i)->isPointerType()) { + if (PointerType *pointerType = ty->asPointerType()) + ty = pointerType->elementType(); + } + subst.bind(cloner.name(name, &subst), ty); } diff --git a/src/plugins/cpptools/cppcompletion_test.cpp b/src/plugins/cpptools/cppcompletion_test.cpp index 3f8e3419ba9..e96c790c6c0 100644 --- a/src/plugins/cpptools/cppcompletion_test.cpp +++ b/src/plugins/cpptools/cppcompletion_test.cpp @@ -2295,6 +2295,35 @@ void CppToolsPlugin::test_completion_data() ) << _("derived.t.") << (QStringList() << QLatin1String("foo") << QLatin1String("Foo")); + + QTest::newRow("template_specialization_and_initialization_with_pointer1") << _( + "template \n" + "struct S {};\n" + "template \n" + "struct S { T *t; };\n" + "struct Foo { int foo; };\n" + "void fun() {\n" + " S s;\n" + " @\n" + "}\n" + ) << _("s.t->") << (QStringList() + << QLatin1String("foo") + << QLatin1String("Foo")); + + // this is not a valid code(is not compile) but it caused a crash + QTest::newRow("template_specialization_and_initialization_with_pointer2") << _( + "template \n" + "struct S {};\n" + "template \n" + "struct S { T1 *t; };\n" + "struct Foo { int foo; };\n" + "void fun() {\n" + " S s;\n" + " @\n" + "}\n" + ) << _("s.t->") << (QStringList() + << QLatin1String("foo") + << QLatin1String("Foo")); } void CppToolsPlugin::test_completion_member_access_operator()