Skip to content

Commit c956f73

Browse files
Marcelo Lirahugopl
Marcelo Lira
authored andcommitted
AbstractMetaClasses now hold the instantiation types for the templates they implement.
AbstractMetaClasses that are typedefs for template class instantiations use to keep the template from where they derive, but didn't keep the values used for the derivation. Now this is fixed, and with an unit test. Reviewed by Luciano Wolf <[email protected]> Reviewed by Renato Araújo <[email protected]>
1 parent 389dab8 commit c956f73

5 files changed

+84
-5
lines changed

abstractmetabuilder.cpp

+1-4
Original file line numberDiff line numberDiff line change
@@ -2564,11 +2564,8 @@ bool AbstractMetaBuilder::inheritTemplate(AbstractMetaClass* subclass,
25642564
subclass->addFunction(f);
25652565
}
25662566

2567-
// Clean up
2568-
foreach (AbstractMetaType *type, templateTypes)
2569-
delete type;
2570-
25712567
subclass->setTemplateBaseClass(templateClass);
2568+
subclass->setTemplateBaseClassInstantiations(templateTypes);
25722569
subclass->setInterfaces(templateClass->interfaces());
25732570
subclass->setBaseClass(templateClass->baseClass());
25742571

abstractmetalang.cpp

+26
Original file line numberDiff line numberDiff line change
@@ -1065,6 +1065,10 @@ AbstractMetaClass::~AbstractMetaClass()
10651065
qDeleteAll(m_fields);
10661066
qDeleteAll(m_enums);
10671067
qDeleteAll(m_orphanInterfaces);
1068+
if (hasTemplateBaseClassInstantiations()) {
1069+
foreach (AbstractMetaType* inst, templateBaseClassInstantiations())
1070+
delete inst;
1071+
}
10681072
}
10691073

10701074
/*******************************************************************************
@@ -1544,7 +1548,29 @@ QPropertySpec *AbstractMetaClass::propertySpecForReset(const QString &name) cons
15441548
return 0;
15451549
}
15461550

1551+
typedef QHash<const AbstractMetaClass*, AbstractMetaTypeList> AbstractMetaClassBaseTemplateInstantiationsMap;
1552+
Q_GLOBAL_STATIC(AbstractMetaClassBaseTemplateInstantiationsMap, metaClassBaseTemplateInstantiations);
1553+
1554+
bool AbstractMetaClass::hasTemplateBaseClassInstantiations() const
1555+
{
1556+
if (!templateBaseClass())
1557+
return false;
1558+
return metaClassBaseTemplateInstantiations()->contains(this);
1559+
}
15471560

1561+
AbstractMetaTypeList AbstractMetaClass::templateBaseClassInstantiations() const
1562+
{
1563+
if (!templateBaseClass())
1564+
return AbstractMetaTypeList();
1565+
return metaClassBaseTemplateInstantiations()->value(this);
1566+
}
1567+
1568+
void AbstractMetaClass::setTemplateBaseClassInstantiations(AbstractMetaTypeList& instantiations)
1569+
{
1570+
if (!templateBaseClass())
1571+
return;
1572+
metaClassBaseTemplateInstantiations()->insert(this, instantiations);
1573+
}
15481574

15491575
static bool functions_contains(const AbstractMetaFunctionList &l, const AbstractMetaFunction *func)
15501576
{

abstractmetalang.h

+4
Original file line numberDiff line numberDiff line change
@@ -1874,6 +1874,10 @@ class APIEXTRACTOR_API AbstractMetaClass : public AbstractMetaAttributes
18741874
m_templateBaseClass = cls;
18751875
}
18761876

1877+
bool hasTemplateBaseClassInstantiations() const;
1878+
AbstractMetaTypeList templateBaseClassInstantiations() const;
1879+
void setTemplateBaseClassInstantiations(AbstractMetaTypeList& instantiations);
1880+
18771881
void setTypeAlias(bool typeAlias)
18781882
{
18791883
m_isTypeAlias = typeAlias;

tests/testtemplates.cpp

+52-1
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,58 @@ void TestTemplates::testTemplateInheritanceMixedWithNamespaceAndForwardDeclarati
285285
QCOMPARE(classB->functions().count(), 3);
286286
}
287287

288+
void TestTemplates::testTypedefOfInstantiationOfTemplateClass()
289+
{
290+
const char cppCode[] = "\
291+
namespace NSpace {\
292+
enum ClassType {\
293+
TypeOne\
294+
};\
295+
template<ClassType CLASS_TYPE>\
296+
struct BaseTemplateClass {\
297+
inline ClassType getClassType() const { CLASS_TYPE; }\
298+
};\
299+
typedef BaseTemplateClass<TypeOne> TypeOneClass;\
300+
}\
301+
";
302+
303+
const char xmlCode[] = "\
304+
<typesystem package='Package'>\
305+
<namespace-type name='NSpace'>\
306+
<enum-type name='ClassType'/>\
307+
<object-type name='BaseTemplateClass' generate='no'/>\
308+
<object-type name='TypeOneClass'/>\
309+
</namespace-type>\
310+
</typesystem>\
311+
";
312+
313+
TestUtil t(cppCode, xmlCode, false);
314+
AbstractMetaClassList classes = t.builder()->classes();
315+
QCOMPARE(classes.count(), 3);
316+
317+
const AbstractMetaClass* base = classes.findClass("BaseTemplateClass");
318+
QVERIFY(base);
319+
const AbstractMetaClass* one = classes.findClass("TypeOneClass");
320+
QVERIFY(one);
321+
QCOMPARE(one->templateBaseClass(), base);
322+
QCOMPARE(one->functions().count(), base->functions().count());
323+
QVERIFY(one->isTypeAlias());
324+
const ComplexTypeEntry* oneType = one->typeEntry();
325+
const ComplexTypeEntry* baseType = base->typeEntry();
326+
QCOMPARE(oneType->baseContainerType(), baseType);
327+
QCOMPARE(one->baseClassNames(), QStringList("BaseTemplateClass<TypeOne>"));
328+
329+
QVERIFY(one->hasTemplateBaseClassInstantiations());
330+
AbstractMetaTypeList instantiations = one->templateBaseClassInstantiations();
331+
QCOMPARE(instantiations.count(), 1);
332+
const AbstractMetaType* inst = instantiations.first();
333+
QVERIFY(inst);
334+
QVERIFY(!inst->isEnum());
335+
QVERIFY(!inst->typeEntry()->isEnum());
336+
QVERIFY(inst->typeEntry()->isEnumValue());
337+
QCOMPARE(inst->cppSignature(), QString("NSpace::TypeOne"));
338+
}
339+
288340
QTEST_APPLESS_MAIN(TestTemplates)
289341

290342
#include "testtemplates.moc"
291-

tests/testtemplates.h

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ private slots:
3838
void testInheritanceFromContainterTemplate();
3939
void testTemplateInheritanceMixedWithForwardDeclaration();
4040
void testTemplateInheritanceMixedWithNamespaceAndForwardDeclaration();
41+
void testTypedefOfInstantiationOfTemplateClass();
4142
};
4243

4344
#endif

0 commit comments

Comments
 (0)