forked from qt-creator/qt-creator
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: Nikolai Kosjar <nikolai.kosjar@digia.com>
This commit is contained in:
@@ -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()
|
||||
|
Reference in New Issue
Block a user