forked from qt-creator/qt-creator
Revert "C++: add support for resolving typedefs for template arguments"
This reverts commit c228b36ccf.
There are multiple issues with the reverted patch:
* Infinite loop due to indirect recursion e.g. when opening projectmodels.cpp
* Crash when executing CppTools tests on Windows (no infinite loop)
Change-Id: I38f02132ca57d3d32085db6146d0df7d620d7618
Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
This commit is contained in:
committed by
Erik Verbruggen
parent
5d0eb9bd9c
commit
1f53ecd898
@@ -82,46 +82,13 @@ public:
|
|||||||
{
|
{
|
||||||
QSet<Symbol *> visited;
|
QSet<Symbol *> visited;
|
||||||
_binding = binding;
|
_binding = binding;
|
||||||
// Use a hard limit when trying to resolve typedefs.
|
// Use a hard limit when trying to resolve typedefs. Typedefs in templates can refer to
|
||||||
// TODO: Now that template arguments are resolved, use an 'alreadyResolved' container to
|
// each other, each time enhancing the template argument and thus making it impossible to
|
||||||
// handle recursive typedefs.
|
// use an "alreadyResolved" container. FIXME: We might overcome this by resolving the
|
||||||
|
// template parameters.
|
||||||
unsigned maxDepth = 15;
|
unsigned maxDepth = 15;
|
||||||
for (NamedType *namedTy = 0; maxDepth && (namedTy = getNamedType(*type)); --maxDepth) {
|
for (NamedType *namedTy = 0; maxDepth && (namedTy = getNamedType(*type)); --maxDepth) {
|
||||||
NamedType *orgNamedTy = namedTy;
|
QList<LookupItem> namedTypeItems = getNamedTypeItems(namedTy->name(), *scope, _binding);
|
||||||
const Name *name = namedTy->name();
|
|
||||||
if (const QualifiedNameId *qn = name->asQualifiedNameId()) {
|
|
||||||
const Name *name = qn->name();
|
|
||||||
Scope *templateScope = *scope;
|
|
||||||
if (const TemplateNameId *templateNameId = name->asTemplateNameId()) {
|
|
||||||
const TemplateNameId *resolvedTemplateNameId =
|
|
||||||
resolveTemplateParameters(templateNameId, templateScope, binding);
|
|
||||||
const QualifiedNameId *resolvedQualifiedNamedId =
|
|
||||||
_context.bindings()->control()->qualifiedNameId(qn->base(),
|
|
||||||
resolvedTemplateNameId);
|
|
||||||
namedTy = _context.bindings()->control()->namedType(resolvedQualifiedNamedId);
|
|
||||||
}
|
|
||||||
} else if (const TemplateNameId *templateNameId = name->asTemplateNameId()) {
|
|
||||||
Scope *templateScope = *scope;
|
|
||||||
const TemplateNameId *resolvedTemplateNameId =
|
|
||||||
resolveTemplateParameters(templateNameId, templateScope, binding);
|
|
||||||
namedTy = _context.bindings()->control()->namedType(resolvedTemplateNameId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (namedTy != orgNamedTy) {
|
|
||||||
if ((*type)->isPointerType()) {
|
|
||||||
*type = FullySpecifiedType(_context.bindings()->control()->pointerType(
|
|
||||||
FullySpecifiedType(namedTy)));
|
|
||||||
} else if (ReferenceType *referenceType = (*type)->asReferenceType()) {
|
|
||||||
*type = FullySpecifiedType(_context.bindings()->control()->referenceType(
|
|
||||||
FullySpecifiedType(namedTy),
|
|
||||||
referenceType->isRvalueReference()));
|
|
||||||
} else {
|
|
||||||
*type = FullySpecifiedType(namedTy);
|
|
||||||
}
|
|
||||||
name = namedTy->name();
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<LookupItem> namedTypeItems = getNamedTypeItems(name, *scope, _binding);
|
|
||||||
|
|
||||||
if (Q_UNLIKELY(debug))
|
if (Q_UNLIKELY(debug))
|
||||||
qDebug() << "-- we have" << namedTypeItems.size() << "candidates";
|
qDebug() << "-- we have" << namedTypeItems.size() << "candidates";
|
||||||
@@ -132,25 +99,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const TemplateNameId *resolveTemplateParameters(const TemplateNameId *templateNameId,
|
|
||||||
Scope *templateScope,
|
|
||||||
ClassOrNamespace *binding)
|
|
||||||
{
|
|
||||||
std::vector<FullySpecifiedType> resolvedTemplateArguments;
|
|
||||||
const unsigned templArgumentCount = templateNameId->templateArgumentCount();
|
|
||||||
for (unsigned i = 0; i < templArgumentCount; ++i) {
|
|
||||||
FullySpecifiedType resolvedTemplateArgumentType
|
|
||||||
= templateNameId->templateArgumentAt(i);
|
|
||||||
resolve(&resolvedTemplateArgumentType, &templateScope, binding);
|
|
||||||
resolvedTemplateArguments.push_back(resolvedTemplateArgumentType);
|
|
||||||
}
|
|
||||||
|
|
||||||
return _context.bindings()->control()->templateNameId(templateNameId->identifier(),
|
|
||||||
templateNameId->isSpecialization(),
|
|
||||||
&resolvedTemplateArguments[0],
|
|
||||||
templArgumentCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
NamedType *getNamedType(FullySpecifiedType& type) const
|
NamedType *getNamedType(FullySpecifiedType& type) const
|
||||||
{
|
{
|
||||||
NamedType *namedTy = type->asNamedType();
|
NamedType *namedTy = type->asNamedType();
|
||||||
|
|||||||
@@ -2328,34 +2328,6 @@ void CppToolsPlugin::test_completion_data()
|
|||||||
<< QLatin1String("foo")
|
<< QLatin1String("foo")
|
||||||
<< QLatin1String("Foo"));
|
<< QLatin1String("Foo"));
|
||||||
|
|
||||||
QTest::newRow("resolving_template_argument1") << _(
|
|
||||||
"template <typename T>\n"
|
|
||||||
"struct Base { T t; };\n"
|
|
||||||
"struct Foo { int foo; };\n"
|
|
||||||
"void fun() {\n"
|
|
||||||
" typedef Foo TypedefedFoo;\n"
|
|
||||||
" Base<TypedefedFoo> baseFoo;\n"
|
|
||||||
" @\n"
|
|
||||||
"}\n"
|
|
||||||
) << _("baseFoo.t.") << (QStringList()
|
|
||||||
<< QLatin1String("foo")
|
|
||||||
<< QLatin1String("Foo"));
|
|
||||||
|
|
||||||
QTest::newRow("resolving_template_argument2") << _(
|
|
||||||
"namespace NS {\n"
|
|
||||||
"template <typename T>\n"
|
|
||||||
"struct Base { T t; };\n"
|
|
||||||
"}\n"
|
|
||||||
"struct Foo { int foo; };\n"
|
|
||||||
"void fun() {\n"
|
|
||||||
" typedef Foo TypedefedFoo;\n"
|
|
||||||
" NS::Base<TypedefedFoo> baseFoo;\n"
|
|
||||||
" @\n"
|
|
||||||
"}\n"
|
|
||||||
) << _("baseFoo.t.") << (QStringList()
|
|
||||||
<< QLatin1String("foo")
|
|
||||||
<< QLatin1String("Foo"));
|
|
||||||
|
|
||||||
// this is not a valid code(is not compile) but it caused a crash
|
// this is not a valid code(is not compile) but it caused a crash
|
||||||
QTest::newRow("template_specialization_and_initialization_with_pointer2") << _(
|
QTest::newRow("template_specialization_and_initialization_with_pointer2") << _(
|
||||||
"template <typename T1, typename T2 = int>\n"
|
"template <typename T1, typename T2 = int>\n"
|
||||||
|
|||||||
Reference in New Issue
Block a user