aboutsummaryrefslogtreecommitdiffstats
path: root/abstractmetabuilder.cpp
diff options
context:
space:
mode:
authorMarcelo Lira <marcelo.lira@openbossa.org>2010-03-26 18:42:45 -0300
committerHugo Parente Lima <hugo.pl@gmail.com>2012-03-09 19:09:58 -0300
commit9a6d442226667bb55eac1b5c6c2e95edcbf1f5e6 (patch)
tree3cf2cca2319ec204bf966c2339b8b8da01b81025 /abstractmetabuilder.cpp
parentc583958bc28ab69bc05a7009c9e512d1a227c985 (diff)
Value type classes now have implicit copy constructors added when needed.
Diffstat (limited to 'abstractmetabuilder.cpp')
-rw-r--r--abstractmetabuilder.cpp44
1 files changed, 40 insertions, 4 deletions
diff --git a/abstractmetabuilder.cpp b/abstractmetabuilder.cpp
index 086c0c7f..6fd7f46a 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)
{