forked from qt-creator/qt-creator
C++: fix dereferencing of nested type and 'auto'
Fixed case: template<class T> 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<Foo> 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 <orgads@gmail.com> Reviewed-by: Nikolai Kosjar <nikolai.kosjar@theqtcompany.com>
This commit is contained in:
committed by
Orgad Shaneh
parent
7f001dab1b
commit
8c11485edb
@@ -730,6 +730,7 @@ bool ResolveExpression::visit(SimpleNameAST *ast)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
TypeOfExpression exprTyper;
|
TypeOfExpression exprTyper;
|
||||||
|
exprTyper.setExpandTemplates(true);
|
||||||
Document::Ptr doc = _context.snapshot().document(QString::fromLocal8Bit(decl->fileName()));
|
Document::Ptr doc = _context.snapshot().document(QString::fromLocal8Bit(decl->fileName()));
|
||||||
exprTyper.init(doc, _context.snapshot(), _context.bindings(),
|
exprTyper.init(doc, _context.snapshot(), _context.bindings(),
|
||||||
QSet<const Declaration* >(_autoDeclarationsBeingResolved) << decl);
|
QSet<const Declaration* >(_autoDeclarationsBeingResolved) << decl);
|
||||||
@@ -754,10 +755,12 @@ bool ResolveExpression::visit(SimpleNameAST *ast)
|
|||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
item.setType(newType);
|
item.setType(newType);
|
||||||
item.setScope(typeItems[n].scope());
|
item.setScope(typeItems[n].scope());
|
||||||
|
item.setBinding(typeItems[n].binding());
|
||||||
} else {
|
} else {
|
||||||
LookupItem newItem(item);
|
LookupItem newItem(item);
|
||||||
newItem.setType(newType);
|
newItem.setType(newType);
|
||||||
newItem.setScope(typeItems[n].scope());
|
newItem.setScope(typeItems[n].scope());
|
||||||
|
newItem.setBinding(typeItems[n].binding());
|
||||||
newCandidates.push_back(newItem);
|
newCandidates.push_back(newItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2553,6 +2553,48 @@ void CppToolsPlugin::test_completion_data()
|
|||||||
) << _("list.begin()->") << (QStringList()
|
) << _("list.begin()->") << (QStringList()
|
||||||
<< QLatin1String("Foo")
|
<< QLatin1String("Foo")
|
||||||
<< QLatin1String("bar"));
|
<< QLatin1String("bar"));
|
||||||
|
|
||||||
|
QTest::newRow("dereference_of_nested_type_opertor_*_and_auto") << _(
|
||||||
|
"template<typename T>\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<Foo> 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<typename T>\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<Foo> list;\n"
|
||||||
|
" auto a = list.begin();\n"
|
||||||
|
" @\n"
|
||||||
|
"}\n"
|
||||||
|
) << _("a->") << (QStringList()
|
||||||
|
<< QLatin1String("Foo")
|
||||||
|
<< QLatin1String("bar"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppToolsPlugin::test_completion_member_access_operator()
|
void CppToolsPlugin::test_completion_member_access_operator()
|
||||||
|
Reference in New Issue
Block a user