C++: instantiate template functions

Task-number: QTCREATORBUG-9170

Change-Id: I4cac9124558c1d4f0722192246f3fbeea61d3d7d
Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
This commit is contained in:
Przemyslaw Gorszkowski
2013-05-16 10:20:36 +02:00
committed by Erik Verbruggen
parent bddaab248b
commit 783ec18424
6 changed files with 77 additions and 1 deletions

View File

@@ -692,6 +692,16 @@ void CreateBindings::lookupInScope(const Name *name, Scope *scope,
item.setType(ty); // override the type.
}
// instantiate function template
if (name->isTemplateNameId() && s->isTemplate() && s->asTemplate()->declaration()
&& s->asTemplate()->declaration()->isFunction()) {
const TemplateNameId *instantiation = name->asTemplateNameId();
Template *specialization = s->asTemplate();
Symbol *instantiatedFunctionTemplate = instantiateTemplateFunction(instantiation,
specialization);
item.setType(instantiatedFunctionTemplate->type()); // override the type.
}
result->append(item);
}
}
@@ -1603,3 +1613,29 @@ bool CreateBindings::visit(ObjCMethod *)
return false;
}
Symbol *CreateBindings::instantiateTemplateFunction(const TemplateNameId *instantiation,
Template *specialization) const
{
const unsigned argumentCountOfInitialization = instantiation->templateArgumentCount();
const unsigned argumentCountOfSpecialization = specialization->templateParameterCount();
Clone cloner(_control.data());
Subst subst(_control.data());
for (unsigned i = 0; i < argumentCountOfSpecialization; ++i) {
const TypenameArgument *tParam
= specialization->templateParameterAt(i)->asTypenameArgument();
if (!tParam)
continue;
const Name *name = tParam->name();
if (!name)
continue;
FullySpecifiedType ty = (i < argumentCountOfInitialization) ?
instantiation->templateArgumentAt(i):
cloner.type(tParam->type(), &subst);
subst.bind(cloner.name(name, &subst), ty);
}
return cloner.symbol(specialization, &subst);
}