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:
Przemyslaw Gorszkowski
2015-02-06 12:33:56 +01:00
committed by Orgad Shaneh
parent 7f001dab1b
commit 8c11485edb
2 changed files with 45 additions and 0 deletions

View File

@@ -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);
} }
} }

View File

@@ -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()