forked from qt-creator/qt-creator
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: Nikolai Kosjar <nikolai.kosjar@theqtcompany.com>
This commit is contained in:
committed by
Orgad Shaneh
parent
2a966a8917
commit
b67ebf9ffc
@@ -210,6 +210,10 @@ bool TypeResolver::findTypedef(const QList<LookupItem> &namedTypeItems, FullySpe
|
|||||||
{
|
{
|
||||||
foreach (const LookupItem &it, namedTypeItems) {
|
foreach (const LookupItem &it, namedTypeItems) {
|
||||||
Symbol *declaration = it.declaration();
|
Symbol *declaration = it.declaration();
|
||||||
|
if (!declaration)
|
||||||
|
continue;
|
||||||
|
if (Template *specialization = declaration->asTemplate())
|
||||||
|
declaration = specialization->declaration();
|
||||||
if (!declaration || (!declaration->isTypedef() && !declaration->type().isDecltype()))
|
if (!declaration || (!declaration->isTypedef() && !declaration->type().isDecltype()))
|
||||||
continue;
|
continue;
|
||||||
if (visited.contains(declaration))
|
if (visited.contains(declaration))
|
||||||
@@ -237,7 +241,7 @@ bool TypeResolver::findTypedef(const QList<LookupItem> &namedTypeItems, FullySpe
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
*type = declaration->type();
|
*type = it.type();
|
||||||
}
|
}
|
||||||
|
|
||||||
*scope = it.scope();
|
*scope = it.scope();
|
||||||
|
|||||||
@@ -2917,6 +2917,87 @@ void CppToolsPlugin::test_completion_data()
|
|||||||
<< QLatin1String("Foo")
|
<< QLatin1String("Foo")
|
||||||
<< QLatin1String("bar"));
|
<< 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") << _(
|
QTest::newRow("qualified_name_in_nested_type") << _(
|
||||||
"template<typename _Tp>\n"
|
"template<typename _Tp>\n"
|
||||||
"struct Temp {\n"
|
"struct Temp {\n"
|
||||||
|
|||||||
Reference in New Issue
Block a user