From 8c11485edba3718925624612f2336d7853da297f Mon Sep 17 00:00:00 2001 From: Przemyslaw Gorszkowski Date: Fri, 6 Feb 2015 12:33:56 +0100 Subject: [PATCH] C++: fix dereferencing of nested type and 'auto' Fixed case: template struct List { struct iterator { T *operator->() { return &t; } T &operator*() { return t; } T t; }; iterator begin() { return iterator(); } }; struct Foo { int bar; }; void func() { List list; auto a = list.begin(); (*a).; // code completion doesn't work a->; // code completion does not work } Task-number: QTCREATORBUG-13799 Change-Id: I38e4bfb2f5d728c0b24b0f18b3d78793e90d633b Reviewed-by: Orgad Shaneh Reviewed-by: Nikolai Kosjar --- src/libs/cplusplus/ResolveExpression.cpp | 3 ++ src/plugins/cpptools/cppcompletion_test.cpp | 42 +++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/src/libs/cplusplus/ResolveExpression.cpp b/src/libs/cplusplus/ResolveExpression.cpp index 932a248d34e..adaac12ab5f 100644 --- a/src/libs/cplusplus/ResolveExpression.cpp +++ b/src/libs/cplusplus/ResolveExpression.cpp @@ -730,6 +730,7 @@ bool ResolveExpression::visit(SimpleNameAST *ast) continue; TypeOfExpression exprTyper; + exprTyper.setExpandTemplates(true); Document::Ptr doc = _context.snapshot().document(QString::fromLocal8Bit(decl->fileName())); exprTyper.init(doc, _context.snapshot(), _context.bindings(), QSet(_autoDeclarationsBeingResolved) << decl); @@ -754,10 +755,12 @@ bool ResolveExpression::visit(SimpleNameAST *ast) if (n == 0) { item.setType(newType); item.setScope(typeItems[n].scope()); + item.setBinding(typeItems[n].binding()); } else { LookupItem newItem(item); newItem.setType(newType); newItem.setScope(typeItems[n].scope()); + newItem.setBinding(typeItems[n].binding()); newCandidates.push_back(newItem); } } diff --git a/src/plugins/cpptools/cppcompletion_test.cpp b/src/plugins/cpptools/cppcompletion_test.cpp index 33c84f8df42..bf6bfb4679c 100644 --- a/src/plugins/cpptools/cppcompletion_test.cpp +++ b/src/plugins/cpptools/cppcompletion_test.cpp @@ -2553,6 +2553,48 @@ void CppToolsPlugin::test_completion_data() ) << _("list.begin()->") << (QStringList() << QLatin1String("Foo") << QLatin1String("bar")); + + QTest::newRow("dereference_of_nested_type_opertor_*_and_auto") << _( + "template\n" + "struct QList\n" + "{\n" + " struct iterator\n" + " {\n" + " T &operator*() { return t; }\n" + " T t;\n" + " };\n" + " iterator begin() { return iterator(); }\n" + "};\n" + "struct Foo { int bar; };\n" + "void fun() {\n" + " QList list;\n" + " auto a = list.begin();\n" + " @\n" + "}\n" + ) << _("(*a).") << (QStringList() + << QLatin1String("Foo") + << QLatin1String("bar")); + + QTest::newRow("dereference_of_nested_type_opertor_->_and_auto") << _( + "template\n" + "struct QList\n" + "{\n" + " struct iterator\n" + " {\n" + " T *operator->() { return &t; }\n" + " T t;\n" + " };\n" + " iterator begin() { return iterator(); }\n" + "};\n" + "struct Foo { int bar; };\n" + "void fun() {\n" + " QList list;\n" + " auto a = list.begin();\n" + " @\n" + "}\n" + ) << _("a->") << (QStringList() + << QLatin1String("Foo") + << QLatin1String("bar")); } void CppToolsPlugin::test_completion_member_access_operator()