aboutsummaryrefslogtreecommitdiffstats
path: root/ApiExtractor
diff options
context:
space:
mode:
authorMatthew Woehlke <matthew.woehlke@kitware.com>2013-10-02 16:40:25 -0400
committerJohn Cummings <jcummings2@users.sf.net>2013-10-09 15:00:27 +0200
commitcdd1bdc5f0f56cbb2a0a1172d4cd947417fed163 (patch)
tree36eb5c0cb426393ccd3663ff99741e244e7d079a /ApiExtractor
parente95be43deb8ace9da4ea67022b4d4a5648d35f01 (diff)
Fix finding container base classes
Move logic to find template classes to its own helper method, and newly use the helper in AbstractMetaBuilder::getBaseClasses. This fixes the latter not finding template base classes, which fixes class topological sorting in some cases. Unfortunately I have not figured out a reliable unit test for this, although printing a debug warning when finding the parent fails (or when a template lookup succeeds) is able to verify that this change is doing something useful. Change-Id: I2a5e0df4035393288b6f69ebc41dc0e64866a182 Reviewed-by: John Cummings <jcummings2@users.sf.net>
Diffstat (limited to 'ApiExtractor')
-rw-r--r--ApiExtractor/abstractmetabuilder.cpp94
-rw-r--r--ApiExtractor/abstractmetabuilder.h2
2 files changed, 64 insertions, 32 deletions
diff --git a/ApiExtractor/abstractmetabuilder.cpp b/ApiExtractor/abstractmetabuilder.cpp
index ce7600e13..d72c27f74 100644
--- a/ApiExtractor/abstractmetabuilder.cpp
+++ b/ApiExtractor/abstractmetabuilder.cpp
@@ -1622,46 +1622,33 @@ bool AbstractMetaBuilder::setupInheritance(AbstractMetaClass *metaClass)
QStringList baseClasses = metaClass->baseClassNames();
- TypeDatabase* types = TypeDatabase::instance();
-
// we only support our own containers and ONLY if there is only one baseclass
- if (baseClasses.size() == 1 && baseClasses.first().count('<') == 1) {
- QStringList scope = metaClass->typeEntry()->qualifiedCppName().split("::");
- scope.removeLast();
- for (int i = scope.size(); i >= 0; --i) {
- QString prefix = i > 0 ? QStringList(scope.mid(0, i)).join("::") + "::" : QString();
- QString completeName = prefix + baseClasses.first();
- TypeParser::Info info = TypeParser::parse(completeName);
- QString baseName = info.qualified_name.join("::");
-
- AbstractMetaClass* templ = 0;
- foreach (AbstractMetaClass *c, m_templates) {
- if (c->typeEntry()->name() == baseName) {
- templ = c;
- break;
- }
- }
-
- if (!templ)
- templ = m_metaClasses.findClass(baseName);
-
- if (templ) {
- setupInheritance(templ);
- inheritTemplate(metaClass, templ, info);
- metaClass->typeEntry()->setBaseContainerType(templ->typeEntry());
- return true;
- }
- ComplexTypeEntry* baseContainerType = types->findContainerType(baseName);
- if (baseContainerType)
- metaClass->typeEntry()->setBaseContainerType(baseContainerType);
+ if (baseClasses.size() == 1 && baseClasses.first().contains('<')) {
+ TypeParser::Info info;
+ ComplexTypeEntry* baseContainerType;
+ AbstractMetaClass* templ = findTemplateClass(baseClasses.first(), metaClass, &info, &baseContainerType);
+ if (templ) {
+ setupInheritance(templ);
+ inheritTemplate(metaClass, templ, info);
+ metaClass->typeEntry()->setBaseContainerType(templ->typeEntry());
+ return true;
}
+ // Container types are not necessarily wrapped as 'real' classes, but
+ // there may still be classes derived from them. In such case, we still
+ // need to set the base container type in order to generate correct
+ // code for type conversion checking.
+ if (baseContainerType)
+ metaClass->typeEntry()->setBaseContainerType(baseContainerType);
+
ReportHandler::warning(QString("template baseclass '%1' of '%2' is not known")
.arg(baseClasses.first())
.arg(metaClass->name()));
return false;
}
+ TypeDatabase* types = TypeDatabase::instance();
+
int primary = -1;
int primaries = 0;
for (int i = 0; i < baseClasses.size(); ++i) {
@@ -2489,11 +2476,54 @@ bool AbstractMetaBuilder::isEnum(const QStringList& qualified_name)
return item && item->kind() == _EnumModelItem::__node_kind;
}
+AbstractMetaClass* AbstractMetaBuilder::findTemplateClass(const QString& name, const AbstractMetaClass *context,
+ TypeParser::Info *info, ComplexTypeEntry **baseContainerType) const
+{
+ TypeParser::Info localInfo;
+ if (!info)
+ info = &localInfo;
+
+ TypeDatabase* types = TypeDatabase::instance();
+
+ QStringList scope = context->typeEntry()->qualifiedCppName().split("::");
+ scope.removeLast();
+ for (int i = scope.size(); i >= 0; --i) {
+ QString prefix = i > 0 ? QStringList(scope.mid(0, i)).join("::") + "::" : QString();
+ QString completeName = prefix + name;
+ *info = TypeParser::parse(completeName);
+ QString qualifiedName = info->qualified_name.join("::");
+
+ AbstractMetaClass* templ = 0;
+ foreach (AbstractMetaClass *c, m_templates) {
+ if (c->typeEntry()->name() == qualifiedName) {
+ templ = c;
+ break;
+ }
+ }
+
+ if (!templ)
+ templ = m_metaClasses.findClass(qualifiedName);
+
+ if (templ)
+ return templ;
+
+ if (baseContainerType)
+ *baseContainerType = types->findContainerType(qualifiedName);
+ }
+
+ return 0;
+}
+
AbstractMetaClassList AbstractMetaBuilder::getBaseClasses(const AbstractMetaClass* metaClass) const
{
AbstractMetaClassList baseClasses;
foreach (const QString& parent, metaClass->baseClassNames()) {
- AbstractMetaClass* cls = m_metaClasses.findClass(parent);
+ AbstractMetaClass* cls = 0;
+ if (parent.contains('<'))
+ cls = findTemplateClass(parent, metaClass);
+ else
+ cls = m_metaClasses.findClass(parent);
+
if (cls)
baseClasses << cls;
}
diff --git a/ApiExtractor/abstractmetabuilder.h b/ApiExtractor/abstractmetabuilder.h
index 09eb38699..94f5a7563 100644
--- a/ApiExtractor/abstractmetabuilder.h
+++ b/ApiExtractor/abstractmetabuilder.h
@@ -164,6 +164,8 @@ public:
return m_globalEnums;
}
+ AbstractMetaClass *findTemplateClass(const QString& name, const AbstractMetaClass *context,
+ TypeParser::Info *info = 0, ComplexTypeEntry **baseContainerType = 0) const;
AbstractMetaClassList getBaseClasses(const AbstractMetaClass* metaClass) const;
bool ancestorHasPrivateCopyConstructor(const AbstractMetaClass* metaClass) const;