C++: nested class with enclosing template class

The parent of instantiation of nested class of template class
should be the instantiation of enclosing template class.

To prevent the infinite loop for case with local typedef of enclosing
template we should not change a parent of typedefed instatiation of
enclosing template. Example:
template <typename T>
struct Enclosing
{
  typedef Enclosing<T> EnclosingT;// first case
  struct Nested
  {
    typedef Enclosing<T> EnclosingT;// second case
  };
};

Task-number: QTCREATORBUG-11752
Task-number: QTCREATORBUG-11999
Change-Id: Iadd7b5ef73ee0c4881f59c9dabfe03339f55827b
Reviewed-by: default avatarNikolai Kosjar <nikolai.kosjar@digia.com>
parent 0bc202d5
......@@ -88,6 +88,19 @@ static void path_helper(Symbol *symbol, QList<const Name *> *names)
}
}
static bool isNestedInstantiationEnclosingTemplate(
ClassOrNamespace *nestedClassOrNamespaceInstantiation,
ClassOrNamespace *enclosingTemplateClassInstantiation)
{
while (enclosingTemplateClassInstantiation) {
if (enclosingTemplateClassInstantiation == nestedClassOrNamespaceInstantiation)
return false;
enclosingTemplateClassInstantiation = enclosingTemplateClassInstantiation->parent();
}
return true;
}
namespace CPlusPlus {
static inline bool compareName(const Name *name, const Name *other)
......@@ -1282,6 +1295,10 @@ void ClassOrNamespace::NestedClassInstantiator::instantiate(ClassOrNamespace *en
}
}
if (isNestedInstantiationEnclosingTemplate(nestedClassOrNamespaceInstantiation,
enclosingTemplateClass)) {
nestedClassOrNamespaceInstantiation->_parent = enclosingTemplateClassInstantiation;
}
instantiate(nestedClassOrNamespace, nestedClassOrNamespaceInstantiation);
enclosingTemplateClassInstantiation->_classOrNamespaces[nestedName] =
......
......@@ -306,8 +306,6 @@ void CppToolsPlugin::test_completion()
expectedCompletions.sort();
QEXPECT_FAIL("enum_in_function_in_struct_in_function", "doesn't work", Abort);
QEXPECT_FAIL("nested_class_in_template_class_QTCREATORBUG-11752",
"related to infiniteLoopLocalTypedef_QTCREATORBUG-11999", Abort);
QCOMPARE(actualCompletions, expectedCompletions);
}
......@@ -2264,6 +2262,26 @@ void CppToolsPlugin::test_completion_data()
<< QLatin1String("foo")
<< QLatin1String("Foo"));
QTest::newRow("infiniteLoopLocalTypedef_QTCREATORBUG-11999") << _(
"template <typename T>\n"
"struct Temp\n"
"{\n"
" struct Nested\n"
" {\n"
" typedef Temp<T> TempT;\n"
" T t;\n"
" };\n"
" Nested nested;\n"
"};\n"
"struct Foo { int foo; };\n"
"void fun() {\n"
" Temp<Foo> tempFoo;\n"
" @\n"
"}\n"
) << _("tempFoo.nested.t.") << (QStringList()
<< QLatin1String("foo")
<< QLatin1String("Foo"));
QTest::newRow("lambda_parameter") << _(
"auto func = [](int arg1) { return @; };\n"
) << _("ar") << (QStringList()
......
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