diff options
author | Marcelo Lira <marcelo.lira@openbossa.org> | 2010-03-26 18:42:45 -0300 |
---|---|---|
committer | Hugo Parente Lima <hugo.pl@gmail.com> | 2012-03-09 19:09:58 -0300 |
commit | 9a6d442226667bb55eac1b5c6c2e95edcbf1f5e6 (patch) | |
tree | 3cf2cca2319ec204bf966c2339b8b8da01b81025 /abstractmetabuilder.cpp | |
parent | c583958bc28ab69bc05a7009c9e512d1a227c985 (diff) |
Value type classes now have implicit copy constructors added when needed.
Diffstat (limited to 'abstractmetabuilder.cpp')
-rw-r--r-- | abstractmetabuilder.cpp | 44 |
1 files changed, 40 insertions, 4 deletions
diff --git a/abstractmetabuilder.cpp b/abstractmetabuilder.cpp index 086c0c7f3..6fd7f46a1 100644 --- a/abstractmetabuilder.cpp +++ b/abstractmetabuilder.cpp @@ -377,8 +377,13 @@ bool AbstractMetaBuilder::build(QIODevice* input) ReportHandler::warning(QString("class '%1' does not have an entry in the type system") .arg(cls->name())); } else { - if (!cls->hasConstructors() && !cls->isFinalInCpp() && !cls->isInterface() && !cls->isNamespace()) - cls->addDefaultConstructor(); + bool couldAddDefaultCtors = !cls->isFinalInCpp() && !cls->isInterface() && !cls->isNamespace(); + if (couldAddDefaultCtors) { + if (!cls->hasConstructors()) + cls->addDefaultConstructor(); + if (cls->typeEntry()->isValue() && !cls->isAbstract() && !cls->hasCopyConstructor()) + cls->addDefaultCopyConstructor(ancestorHasPrivateCopyConstructor(cls)); + } } if (cls->isAbstract() && !cls->isInterface()) @@ -1197,10 +1202,19 @@ void AbstractMetaBuilder::traverseFunctions(ScopeModelItem scopeItem, AbstractMe metaFunction->setPropertySpec(reset); } + // Can not use metaFunction->isCopyConstructor() because + // the function wasn't assigned to its owner class yet. + bool isCopyCtor = false; + if (metaFunction->isConstructor() && metaFunction->arguments().size() == 1) { + const AbstractMetaType* argType = metaFunction->arguments().first()->type(); + isCopyCtor = argType->isConstant() + && argType->isReference() + && argType->typeEntry()->name() == metaFunction->name(); + } bool isInvalidDestructor = metaFunction->isDestructor() && metaFunction->isPrivate(); bool isInvalidConstructor = metaFunction->isConstructor() - && (metaFunction->isPrivate() || metaFunction->isInvalid()); + && ((metaFunction->isPrivate() && !isCopyCtor) || metaFunction->isInvalid()); if ((isInvalidDestructor || isInvalidConstructor) && !metaClass->hasNonPrivateConstructor()) { *metaClass += AbstractMetaAttributes::Final; @@ -1216,7 +1230,7 @@ void AbstractMetaBuilder::traverseFunctions(ScopeModelItem scopeItem, AbstractMe if (!metaFunction->isDestructor() && !metaFunction->isInvalid() - && (!metaFunction->isConstructor() || !metaFunction->isPrivate())) { + && !(metaFunction->isPrivate() && metaFunction->isConstructor() && !isCopyCtor)) { setupFunctionDefaults(metaFunction, metaClass); @@ -2098,6 +2112,28 @@ bool AbstractMetaBuilder::isEnum(const QStringList &qualified_name) return item && item->kind() == _EnumModelItem::__node_kind; } +AbstractMetaClassList AbstractMetaBuilder::getBaseClasses(const AbstractMetaClass* metaClass) const +{ + AbstractMetaClassList baseClasses; + foreach (const QString& parent, metaClass->baseClassNames()) { + AbstractMetaClass* cls = m_metaClasses.findClass(parent); + if (cls) + baseClasses << cls; + } + return baseClasses; +} + +bool AbstractMetaBuilder::ancestorHasPrivateCopyConstructor(const AbstractMetaClass* metaClass) const +{ + if (metaClass->hasPrivateCopyConstructor()) + return true; + foreach (const AbstractMetaClass* cls, getBaseClasses(metaClass)) { + if (ancestorHasPrivateCopyConstructor(cls)) + return true; + } + return false; +} + AbstractMetaType *AbstractMetaBuilder::inheritTemplateType(const QList<AbstractMetaType *> &templateTypes, AbstractMetaType *metaType, bool *ok) { |