From 2b0e643e3da74af206a1826ae1a52075ac3efdc0 Mon Sep 17 00:00:00 2001 From: Przemyslaw Gorszkowski Date: Sat, 16 Feb 2013 13:28:34 +0100 Subject: [PATCH] C++: fixed resolving complex typedef Unit test describe this complex typedef. Another step to bring code completion for stl containers. Change-Id: I27985c4ea7c26c723d7a88ce42c5ecf164b6c903 Reviewed-by: Erik Verbruggen --- src/libs/3rdparty/cplusplus/Templates.cpp | 20 ++++++++-- src/libs/cplusplus/LookupContext.cpp | 11 ++++++ src/plugins/cpptools/cppcompletion_test.cpp | 43 +++++++++++++++++++++ src/plugins/cpptools/cpptoolsplugin.h | 1 + 4 files changed, 71 insertions(+), 4 deletions(-) diff --git a/src/libs/3rdparty/cplusplus/Templates.cpp b/src/libs/3rdparty/cplusplus/Templates.cpp index c81ed51b09..b813600143 100644 --- a/src/libs/3rdparty/cplusplus/Templates.cpp +++ b/src/libs/3rdparty/cplusplus/Templates.cpp @@ -526,11 +526,23 @@ FullySpecifiedType Subst::apply(const Name *name) const return _previous->apply(name); else if (const QualifiedNameId *q = name->asQualifiedNameId()) { - const NamedType *name = apply(q->base())->asNamedType(); + const NamedType *baseNamedType = apply(q->base())->asNamedType(); const NamedType *unqualified = apply(q->name())->asNamedType(); - if (name && name->name()->identifier() != 0 && unqualified) - return control()->namedType(control()->qualifiedNameId(name->name()->identifier(), - unqualified->name())); + if (baseNamedType) { + if (! unqualified) { + const Name *qualifiedBase = baseNamedType->name(); + const Name *qualifiedName = q->name(); + return control()->namedType(control()->qualifiedNameId(qualifiedBase, + qualifiedName)); + } + else if(baseNamedType->name()->identifier() != 0) { + const QualifiedNameId *clonedQualifiedNameId + = control()->qualifiedNameId(baseNamedType->name()->identifier(), + unqualified->name()); + NamedType *clonedNamedType = control()->namedType(clonedQualifiedNameId); + return clonedNamedType; + } + } } } diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp index b23cf73949..68586bff8b 100644 --- a/src/libs/cplusplus/LookupContext.cpp +++ b/src/libs/cplusplus/LookupContext.cpp @@ -833,6 +833,17 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac oo.showReturnTypes = true; oo.showTemplateParameters = true; qDebug()<<"cloned"<type()); + if (Class *klass = s->asClass()) { + const unsigned klassMemberCount = klass->memberCount(); + for (unsigned i = 0; i < klassMemberCount; ++i){ + Symbol *klassMemberAsSymbol = klass->memberAt(i); + if (klassMemberAsSymbol->isTypedef()) { + if (Declaration *declaration = klassMemberAsSymbol->asDeclaration()) { + qDebug() << "Member: " << oo(declaration->type(), declaration->name()); + } + } + } + } #endif // DEBUG_LOOKUP } instantiateNestedClasses(reference, cloner, subst, instantiation); diff --git a/src/plugins/cpptools/cppcompletion_test.cpp b/src/plugins/cpptools/cppcompletion_test.cpp index 19267fa6e8..fb61faec0d 100644 --- a/src/plugins/cpptools/cppcompletion_test.cpp +++ b/src/plugins/cpptools/cppcompletion_test.cpp @@ -1570,3 +1570,46 @@ void CppToolsPlugin::test_completion_typedef_is_inside_function_before_declarati QVERIFY(completions.contains(QLatin1String("Foo"))); QVERIFY(completions.contains(QLatin1String("bar"))); } + +void CppToolsPlugin::test_completion_resolve_complex_typedef_with_template() +{ + TestData data; + data.srcText = "\n" + "template \n" + "struct Template2\n" + "{\n" + " typedef typename T::template Template1::TT TemplateTypedef;\n" + " TemplateTypedef templateTypedef;\n" + "};\n" + "struct Foo\n" + "{\n" + " int bar;\n" + " template \n" + " struct Template1\n" + " {\n" + " typedef T TT;\n" + " };\n" + "};\n" + "void fun()\n" + "{\n" + " Template2 template2;\n" + " @\n" + " // padding so we get the scope right\n" + "}\n" + ; + setup(&data); + + Utils::ChangeSet change; + QString txt = QLatin1String("template2.templateTypedef."); + change.insert(data.pos, txt); + QTextCursor cursor(data.doc); + change.apply(&cursor); + data.pos += txt.length(); + + QStringList completions = getCompletions(data); + + QCOMPARE(completions.size(), 3); + QVERIFY(completions.contains(QLatin1String("Foo"))); + QVERIFY(completions.contains(QLatin1String("bar"))); + QVERIFY(completions.contains(QLatin1String("Template1"))); +} diff --git a/src/plugins/cpptools/cpptoolsplugin.h b/src/plugins/cpptools/cpptoolsplugin.h index d132ecce67..e7eae03882 100644 --- a/src/plugins/cpptools/cpptoolsplugin.h +++ b/src/plugins/cpptools/cpptoolsplugin.h @@ -122,6 +122,7 @@ private slots: void test_completion_typedef_of_pointer(); void test_completion_typedef_of_pointer_inside_function(); void test_completion_typedef_is_inside_function_before_declaration_block(); + void test_completion_resolve_complex_typedef_with_template(); void test_format_pointerdeclaration_in_simpledeclarations(); void test_format_pointerdeclaration_in_simpledeclarations_data(); -- GitLab