C++: Fix code compl. for instantiation of template specialization

It works for full specialization. Instantiate of the partial
specialization has to be implemented(finding appropriate partial
specialization-on going)

Added unit test.

Change-Id: I8ef5ea963e7c665e0d67d390b3a833486773dab0
Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
This commit is contained in:
Przemyslaw Gorszkowski
2013-01-12 22:05:41 +01:00
parent 0135609973
commit ffba28d26a
13 changed files with 149 additions and 23 deletions

View File

@@ -716,6 +716,42 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac
ClassOrNamespace *reference = it->second;
const TemplateNameId *templId = name->asTemplateNameId();
if (templId) {
// if it is a TemplateNameId it could be a specialization(full or partial) or
// instantiation of one of the specialization(reference->_specialization) or
// base class(reference)
if (templId->isSpecialization()) {
// if it is a specialization we try to find or create new one and
// add to base class(reference)
TemplateNameIdTable::const_iterator cit = reference->_specializations.find(templId);
if (cit != reference->_specializations.end()) {
return cit->second;
} else {
ClassOrNamespace *newSpecialization = _factory->allocClassOrNamespace(reference);
#ifdef DEBUG_LOOKUP
newSpecialization->_name = templId;
#endif // DEBUG_LOOKUP
reference->_specializations[templId] = newSpecialization;
return newSpecialization;
}
} else {
TemplateNameId *nonConstTemplId = const_cast<TemplateNameId *>(templId);
// make this instantiation looks like specialization which help to find
// full specialization for this instantiation
nonConstTemplId->setIsSpecialization(true);
TemplateNameIdTable::const_iterator cit = reference->_specializations.find(templId);
if (cit != reference->_specializations.end()) {
// we found full specialization
reference = cit->second;
} else {
// TODO: find the best specialization(probably partial) for this instantiation
}
// let's instantiation be instantiation
nonConstTemplId->setIsSpecialization(false);
}
}
// The reference binding might still be missing some of its base classes in the case they
// are templates. We need to collect them now. First, we track the bases which are already
// part of the binding so we can identify the missings ones later.
@@ -737,7 +773,6 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac
if (!referenceClass)
return reference;
const TemplateNameId *templId = name->asTemplateNameId();
if ((! templId && _alreadyConsideredClasses.contains(referenceClass)) ||
(templId &&
_alreadyConsideredTemplates.contains(templId))) {
@@ -752,9 +787,6 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac
// If we are dealling with a template type, more work is required, since we need to
// construct all instantiation data.
if (templId) {
if (_instantiations.contains(templId))
return _instantiations[templId];
_alreadyConsideredTemplates.insert(templId);
ClassOrNamespace *instantiation = _factory->allocClassOrNamespace(reference);
#ifdef DEBUG_LOOKUP
@@ -863,7 +895,6 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac
}
_alreadyConsideredTemplates.clear(templId);
_instantiations[templId] = instantiation;
return instantiation;
}