search for partial specialization for arrays

A<int[]> now prefer second specialization for
template<typename T> class A
template<typename T> class A<[]>

Change-Id: I32e874f78b2f5b363d088fbab6a8897e42e44035
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@digia.com>
This commit is contained in:
Filipp
2014-08-18 15:53:59 +04:00
committed by Nikolai Kosjar
parent fa4e839bbe
commit 077bbf6803
3 changed files with 82 additions and 5 deletions

View File

@@ -922,8 +922,31 @@ ClassOrNamespace *ClassOrNamespace::lookupType_helper(const Name *name,
return 0;
}
ClassOrNamespace *ClassOrNamespace::findSpecializationWithPointer(const TemplateNameId *templId,
const TemplateNameIdTable &specializations)
static ClassOrNamespace *findSpecializationWithMatchingTemplateArgument(const Name *argumentName,
ClassOrNamespace *reference)
{
foreach (Symbol *s, reference->symbols()) {
if (Class *clazz = s->asClass()) {
if (Template *templateSpecialization = clazz->enclosingTemplate()) {
const unsigned argumentCountOfSpecialization
= templateSpecialization->templateParameterCount();
for (unsigned i = 0; i < argumentCountOfSpecialization; ++i) {
if (TypenameArgument *tParam
= templateSpecialization->templateParameterAt(i)->asTypenameArgument()) {
if (const Name *name = tParam->name()) {
if (compareName(name, argumentName))
return reference;
}
}
}
}
}
}
return 0;
}
ClassOrNamespace *ClassOrNamespace::findSpecialization(const TemplateNameId *templId,
const TemplateNameIdTable &specializations)
{
// we go through all specialization and try to find that one with template argument as pointer
for (TemplateNameIdTable::const_iterator cit = specializations.begin();
@@ -949,6 +972,21 @@ ClassOrNamespace *ClassOrNamespace::findSpecializationWithPointer(const Template
&& specPointer->elementType().type()->isNamedType()) {
return cit->second;
}
ArrayType *specArray
= specializationTemplateArgument.type()->asArrayType();
if (specArray && initializationTemplateArgument.type()->isArrayType()) {
if (const NamedType *argumentNamedType
= specArray->elementType().type()->asNamedType()) {
if (const Name *argumentName = argumentNamedType->name()) {
if (ClassOrNamespace *reference
= findSpecializationWithMatchingTemplateArgument(
argumentName, cit->second)) {
return reference;
}
}
}
}
}
}
}
@@ -1026,7 +1064,7 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac
reference = cit->second;
} else {
ClassOrNamespace *specializationWithPointer
= findSpecializationWithPointer(templId, specializations);
= findSpecialization(templId, specializations);
if (specializationWithPointer)
reference = specializationWithPointer;
// TODO: find the best specialization(probably partial) for this instantiation