aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--abstractmetabuilder.cpp5
-rw-r--r--abstractmetalang.cpp26
-rw-r--r--abstractmetalang.h4
-rw-r--r--tests/testtemplates.cpp53
-rw-r--r--tests/testtemplates.h1
5 files changed, 84 insertions, 5 deletions
diff --git a/abstractmetabuilder.cpp b/abstractmetabuilder.cpp
index 41e4abe9e..29a21a051 100644
--- a/abstractmetabuilder.cpp
+++ b/abstractmetabuilder.cpp
@@ -2564,11 +2564,8 @@ bool AbstractMetaBuilder::inheritTemplate(AbstractMetaClass* subclass,
subclass->addFunction(f);
}
- // Clean up
- foreach (AbstractMetaType *type, templateTypes)
- delete type;
-
subclass->setTemplateBaseClass(templateClass);
+ subclass->setTemplateBaseClassInstantiations(templateTypes);
subclass->setInterfaces(templateClass->interfaces());
subclass->setBaseClass(templateClass->baseClass());
diff --git a/abstractmetalang.cpp b/abstractmetalang.cpp
index 106aed1a0..5c1641c42 100644
--- a/abstractmetalang.cpp
+++ b/abstractmetalang.cpp
@@ -1065,6 +1065,10 @@ AbstractMetaClass::~AbstractMetaClass()
qDeleteAll(m_fields);
qDeleteAll(m_enums);
qDeleteAll(m_orphanInterfaces);
+ if (hasTemplateBaseClassInstantiations()) {
+ foreach (AbstractMetaType* inst, templateBaseClassInstantiations())
+ delete inst;
+ }
}
/*******************************************************************************
@@ -1544,7 +1548,29 @@ QPropertySpec *AbstractMetaClass::propertySpecForReset(const QString &name) cons
return 0;
}
+typedef QHash<const AbstractMetaClass*, AbstractMetaTypeList> AbstractMetaClassBaseTemplateInstantiationsMap;
+Q_GLOBAL_STATIC(AbstractMetaClassBaseTemplateInstantiationsMap, metaClassBaseTemplateInstantiations);
+
+bool AbstractMetaClass::hasTemplateBaseClassInstantiations() const
+{
+ if (!templateBaseClass())
+ return false;
+ return metaClassBaseTemplateInstantiations()->contains(this);
+}
+AbstractMetaTypeList AbstractMetaClass::templateBaseClassInstantiations() const
+{
+ if (!templateBaseClass())
+ return AbstractMetaTypeList();
+ return metaClassBaseTemplateInstantiations()->value(this);
+}
+
+void AbstractMetaClass::setTemplateBaseClassInstantiations(AbstractMetaTypeList& instantiations)
+{
+ if (!templateBaseClass())
+ return;
+ metaClassBaseTemplateInstantiations()->insert(this, instantiations);
+}
static bool functions_contains(const AbstractMetaFunctionList &l, const AbstractMetaFunction *func)
{
diff --git a/abstractmetalang.h b/abstractmetalang.h
index a3a8def6d..2851d1c70 100644
--- a/abstractmetalang.h
+++ b/abstractmetalang.h
@@ -1874,6 +1874,10 @@ public:
m_templateBaseClass = cls;
}
+ bool hasTemplateBaseClassInstantiations() const;
+ AbstractMetaTypeList templateBaseClassInstantiations() const;
+ void setTemplateBaseClassInstantiations(AbstractMetaTypeList& instantiations);
+
void setTypeAlias(bool typeAlias)
{
m_isTypeAlias = typeAlias;
diff --git a/tests/testtemplates.cpp b/tests/testtemplates.cpp
index cd32ac4ac..bfee774d6 100644
--- a/tests/testtemplates.cpp
+++ b/tests/testtemplates.cpp
@@ -285,7 +285,58 @@ void TestTemplates::testTemplateInheritanceMixedWithNamespaceAndForwardDeclarati
QCOMPARE(classB->functions().count(), 3);
}
+void TestTemplates::testTypedefOfInstantiationOfTemplateClass()
+{
+ const char cppCode[] = "\
+ namespace NSpace {\
+ enum ClassType {\
+ TypeOne\
+ };\
+ template<ClassType CLASS_TYPE>\
+ struct BaseTemplateClass {\
+ inline ClassType getClassType() const { CLASS_TYPE; }\
+ };\
+ typedef BaseTemplateClass<TypeOne> TypeOneClass;\
+ }\
+ ";
+
+ const char xmlCode[] = "\
+ <typesystem package='Package'>\
+ <namespace-type name='NSpace'>\
+ <enum-type name='ClassType'/>\
+ <object-type name='BaseTemplateClass' generate='no'/>\
+ <object-type name='TypeOneClass'/>\
+ </namespace-type>\
+ </typesystem>\
+ ";
+
+ TestUtil t(cppCode, xmlCode, false);
+ AbstractMetaClassList classes = t.builder()->classes();
+ QCOMPARE(classes.count(), 3);
+
+ const AbstractMetaClass* base = classes.findClass("BaseTemplateClass");
+ QVERIFY(base);
+ const AbstractMetaClass* one = classes.findClass("TypeOneClass");
+ QVERIFY(one);
+ QCOMPARE(one->templateBaseClass(), base);
+ QCOMPARE(one->functions().count(), base->functions().count());
+ QVERIFY(one->isTypeAlias());
+ const ComplexTypeEntry* oneType = one->typeEntry();
+ const ComplexTypeEntry* baseType = base->typeEntry();
+ QCOMPARE(oneType->baseContainerType(), baseType);
+ QCOMPARE(one->baseClassNames(), QStringList("BaseTemplateClass<TypeOne>"));
+
+ QVERIFY(one->hasTemplateBaseClassInstantiations());
+ AbstractMetaTypeList instantiations = one->templateBaseClassInstantiations();
+ QCOMPARE(instantiations.count(), 1);
+ const AbstractMetaType* inst = instantiations.first();
+ QVERIFY(inst);
+ QVERIFY(!inst->isEnum());
+ QVERIFY(!inst->typeEntry()->isEnum());
+ QVERIFY(inst->typeEntry()->isEnumValue());
+ QCOMPARE(inst->cppSignature(), QString("NSpace::TypeOne"));
+}
+
QTEST_APPLESS_MAIN(TestTemplates)
#include "testtemplates.moc"
-
diff --git a/tests/testtemplates.h b/tests/testtemplates.h
index a06a388b5..1b7267af4 100644
--- a/tests/testtemplates.h
+++ b/tests/testtemplates.h
@@ -38,6 +38,7 @@ private slots:
void testInheritanceFromContainterTemplate();
void testTemplateInheritanceMixedWithForwardDeclaration();
void testTemplateInheritanceMixedWithNamespaceAndForwardDeclaration();
+ void testTypedefOfInstantiationOfTemplateClass();
};
#endif