Commit b67ebf9f authored by Orgad Shaneh's avatar Orgad Shaneh Committed by Orgad Shaneh

C++: Fix lookup for instantiation of using

Yet another std::vector issue...

Use-cases:
// Case 1
template<typename T>
using type = T;

// Case 2
struct Parent {
    template<typename T>
    using type = T;
};

// Case 3
template<typename T>
struct ParentT {
    template<typename DT>
    using type = DT;
};

struct Foo { int bar; };

void func()
{
    type<Foo> p1;
    Parent::type<Foo> p2;
    ParentT<Foo>::type<Foo> p3;
    // bar not highlighted
    p1.bar;
    p2.bar;
    p3.bar;
}

Task-number: QTCREATORBUG-14480
Change-Id: I9ab08ea7360a432c48eb4b85aa0d63e08d2464c1
Reviewed-by: default avatarNikolai Kosjar <nikolai.kosjar@theqtcompany.com>
parent 2a966a89
......@@ -210,6 +210,10 @@ bool TypeResolver::findTypedef(const QList<LookupItem> &namedTypeItems, FullySpe
{
foreach (const LookupItem &it, namedTypeItems) {
Symbol *declaration = it.declaration();
if (!declaration)
continue;
if (Template *specialization = declaration->asTemplate())
declaration = specialization->declaration();
if (!declaration || (!declaration->isTypedef() && !declaration->type().isDecltype()))
continue;
if (visited.contains(declaration))
......@@ -237,7 +241,7 @@ bool TypeResolver::findTypedef(const QList<LookupItem> &namedTypeItems, FullySpe
return true;
}
} else {
*type = declaration->type();
*type = it.type();
}
*scope = it.scope();
......
......@@ -2917,6 +2917,87 @@ void CppToolsPlugin::test_completion_data()
<< QLatin1String("Foo")
<< QLatin1String("bar"));
QTest::newRow("template_using_instantiation") << _(
"template<typename _Tp>\n"
"using T = _Tp;\n"
"\n"
"struct Foo { int bar; };\n"
"\n"
"void func()\n"
"{\n"
" T<Foo> p;\n"
" @\n"
"}\n"
) << _("p.") << (QStringList()
<< QLatin1String("Foo")
<< QLatin1String("bar"));
QTest::newRow("nested_template_using_instantiation") << _(
"struct Parent {\n"
" template<typename _Tp>\n"
" using T = _Tp;\n"
"};\n"
"\n"
"struct Foo { int bar; };\n"
"\n"
"void func()\n"
"{\n"
" Parent::T<Foo> p;\n"
" @;\n"
"}\n"
) << _("p.") << (QStringList()
<< QLatin1String("Foo")
<< QLatin1String("bar"));
QTest::newRow("nested_template_using_instantiation_in_template_class") << _(
"template<typename ParentT>\n"
"struct Parent {\n"
" template<typename _Tp>\n"
" using T = _Tp;\n"
"};\n"
"\n"
"struct Foo { int bar; };\n"
"\n"
"void func()\n"
"{\n"
" Parent<Foo>::T<Foo> p;\n"
" @;\n"
"}\n"
) << _("p.") << (QStringList()
<< QLatin1String("Foo")
<< QLatin1String("bar"));
QTest::newRow("recursive_nested_template_using_instantiation") << _(
"struct Foo { int bar; };\n"
"\n"
"struct A { typedef Foo value_type; };\n"
"\n"
"template<typename T>\n"
"struct Traits\n"
"{\n"
" typedef Foo value_type;\n"
"\n"
" template<typename _Tp>\n"
" using U = T;\n"
"};\n"
"\n"
"template<typename T>\n"
"struct Temp\n"
"{\n"
" typedef Traits<T> TraitsT;\n"
" typedef typename T::value_type value_type;\n"
" typedef typename TraitsT::template U<Foo> rebind;\n"
"};\n"
"\n"
"void func()\n"
"{\n"
" typename Temp<typename Temp<A>::rebind>::value_type p;\n"
" @\n"
"}\n"
) << _("p.") << (QStringList()
<< QLatin1String("Foo")
<< QLatin1String("bar"));
QTest::newRow("qualified_name_in_nested_type") << _(
"template<typename _Tp>\n"
"struct Temp {\n"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment