Skip to content

Commit 7129956

Browse files
usiemsmrbean-bremen
authored andcommitted
Generate modern C++ code with nullptr and override
This mostly works, there are only a few cases where the override is missing for virtual destructors. I still wanted to commit my work, since I will currently not work further on it.
1 parent 1224d2d commit 7129956

File tree

6 files changed

+45
-15
lines changed

6 files changed

+45
-15
lines changed

generator/abstractmetabuilder.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1303,6 +1303,7 @@ void AbstractMetaBuilder::traverseFunctions(ScopeModelItem scope_item, AbstractM
13031303
if (!meta_function->isPublic()) {
13041304
meta_class->setHasPublicDestructor(false);
13051305
}
1306+
meta_class->setHasVirtualDestructor(meta_function->isVirtual());
13061307
}
13071308
}
13081309
}
@@ -1407,8 +1408,11 @@ bool AbstractMetaBuilder::setupInheritance(AbstractMetaClass *meta_class)
14071408
if (types->isClassRejected(base_classes.at(i)))
14081409
continue;
14091410

1411+
AbstractMetaClass *base_class = m_meta_classes.findClass(base_classes.at(i));
1412+
if (base_class) {
1413+
meta_class->addSuperClass(base_class);
1414+
}
14101415
if (i != primary) {
1411-
AbstractMetaClass *base_class = m_meta_classes.findClass(base_classes.at(i));
14121416
if (base_class == 0) {
14131417
ReportHandler::warning(QString("class not found for setup inheritance '%1'").arg(base_classes.at(i)));
14141418
return false;

generator/abstractmetalang.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,6 +1173,23 @@ QPropertySpec *AbstractMetaClass::propertySpecForReset(const QString &name) cons
11731173
return 0;
11741174
}
11751175

1176+
bool AbstractMetaClass::hasVirtualDestructor() const
1177+
{
1178+
if (m_has_virtual_destructor) {
1179+
return true;
1180+
}
1181+
else {
1182+
// check all super classes
1183+
for (int i = 0; i < m_super_classes.size(); ++i) {
1184+
AbstractMetaClass* super_class = m_super_classes.at(i);
1185+
if (super_class->hasVirtualDestructor()) {
1186+
return true;
1187+
}
1188+
}
1189+
}
1190+
return false;
1191+
}
1192+
11761193

11771194

11781195
static bool functions_contains(const AbstractMetaFunctionList &l, const AbstractMetaFunction *func)

generator/abstractmetalang.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,7 @@ class AbstractMetaClass : public AbstractMetaAttributes
674674
m_has_nonprivateconstructor(false),
675675
m_functions_fixed(false),
676676
m_has_public_destructor(true),
677+
m_has_virtual_destructor(false),
677678
m_force_shell_class(false),
678679
m_has_hash_function(false),
679680
m_has_equals_operator(false),
@@ -709,6 +710,8 @@ class AbstractMetaClass : public AbstractMetaAttributes
709710
void setHasNonPrivateConstructor(bool on) { m_has_nonprivateconstructor = on; }
710711
bool hasPublicDestructor() const { return m_has_public_destructor; }
711712
void setHasPublicDestructor(bool on) { m_has_public_destructor = on; }
713+
bool hasVirtualDestructor() const;
714+
void setHasVirtualDestructor(bool on) { m_has_virtual_destructor = on; }
712715

713716
QString destructorException() const { return m_destructor_exception; }
714717
void setDestructorException(const QString &exception) { m_destructor_exception = exception; }
@@ -749,6 +752,10 @@ class AbstractMetaClass : public AbstractMetaAttributes
749752
AbstractMetaClass *baseClass() const { return m_base_class; }
750753
void setBaseClass(AbstractMetaClass *base_class) { m_base_class = base_class; }
751754

755+
// this lists _all_ super classes of this class
756+
QList<AbstractMetaClass *> superClasses() const { return m_super_classes; }
757+
void addSuperClass(AbstractMetaClass *super_class) { m_super_classes.append(super_class); }
758+
752759
const AbstractMetaClass *enclosingClass() const { return m_enclosing_class; }
753760
void setEnclosingClass(AbstractMetaClass *cl) { m_enclosing_class = cl; }
754761

@@ -849,16 +856,18 @@ class AbstractMetaClass : public AbstractMetaAttributes
849856
uint m_has_nonprivateconstructor : 1;
850857
uint m_functions_fixed : 1;
851858
uint m_has_public_destructor : 1;
859+
uint m_has_virtual_destructor : 1;
852860
uint m_force_shell_class : 1;
853861
uint m_has_hash_function : 1;
854862
uint m_has_equals_operator : 1;
855863
uint m_has_clone_operator :1;
856864
uint m_is_type_alias : 1;
857-
uint m_reserved : 19;
865+
uint m_reserved : 18;
858866
QString m_destructor_exception;
859867

860868
const AbstractMetaClass *m_enclosing_class;
861869
AbstractMetaClass *m_base_class;
870+
QList<AbstractMetaClass*> m_super_classes;
862871
const AbstractMetaClass *m_template_base_class;
863872
AbstractMetaFunctionList m_functions;
864873
AbstractMetaFieldList m_fields;

generator/setupgenerator.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ void SetupGenerator::generate()
346346
}
347347
shellCreator = ", " + setInstanceFunc + "<" + ShellGenerator::shellClassName(cls) + ">";
348348
} else {
349-
shellCreator = ", NULL";
349+
shellCreator = ", nullptr";
350350
}
351351
QString operatorCodes = getOperatorCodes(cls).join("|");
352352
if (operatorCodes.isEmpty()) {
@@ -431,7 +431,7 @@ QStringList SetupGenerator::writePolymorphicHandler(QTextStream &s, const QStrin
431431
s << "static void* polymorphichandler_" << handler
432432
<< "(const void *ptr, const char **class_name)" << endl
433433
<< "{" << endl
434-
<< " Q_ASSERT(ptr != 0);" << endl
434+
<< " Q_ASSERT(ptr != nullptr);" << endl
435435
<< " " << cls->qualifiedCppName() << " *object = ("
436436
<< cls->qualifiedCppName() << " *)ptr;" << endl;
437437
}
@@ -456,7 +456,7 @@ QStringList SetupGenerator::writePolymorphicHandler(QTextStream &s, const QStrin
456456

457457
// Close the function if it has been opened
458458
if (!first) {
459-
s << " return NULL;" << endl
459+
s << " return nullptr;" << endl
460460
<< "}" << endl;
461461
}
462462
}

generator/shellheadergenerator.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -150,24 +150,24 @@ void ShellHeaderGenerator::write(QTextStream &s, const AbstractMetaClass *meta_c
150150
s << ", ";
151151
s << args.at(i)->argumentName();
152152
}
153-
s << "),_wrapper(NULL) {";
153+
s << "),_wrapper(nullptr) {";
154154
writeInjectedCode(s, meta_class, TypeSystem::PyInheritShellConstructorCode, true);
155155
s << "};" << endl;
156156
}
157157
s << endl;
158-
s << " ~" << shellClassName(meta_class) << "();" << endl;
158+
const AbstractMetaClass* c = meta_class;
159+
s << " ~" << shellClassName(meta_class) << "()" << (meta_class->hasVirtualDestructor() ? " override" : "") << ";" << endl;
159160
s << endl;
160161

161162
foreach(AbstractMetaFunction* fun, virtualsForShell) {
162-
s << "virtual ";
163163
writeFunctionSignature(s, fun, 0, QString(),
164164
Option(IncludeDefaultExpression | OriginalName | ShowStatic | UnderscoreSpaces));
165-
s << ";" << endl;
165+
s << " override;" << endl;
166166
}
167167
s << endl;
168168
if (meta_class->isQObject()) {
169-
s << " const QMetaObject* metaObject() const;" << endl;
170-
s << " int qt_metacall(QMetaObject::Call call, int id, void** args);" << endl;
169+
s << " const QMetaObject* metaObject() const override;" << endl;
170+
s << " int qt_metacall(QMetaObject::Call call, int id, void** args) override;" << endl;
171171
}
172172
writeInjectedCode(s, meta_class, TypeSystem::PyShellDeclaration);
173173
writeInjectedCode(s, meta_class, TypeSystem::PyInheritShellDeclaration, true);

generator/shellimplgenerator.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ void ShellImplGenerator::write(QTextStream &s, const AbstractMetaClass *meta_cla
155155
writeTypeInfo(s, fun->type(), typeOptions);
156156
s << " returnValue{};" << endl;
157157
}
158-
s << " void* args[" << QString::number(args.size() + 1) << "] = {NULL";
158+
s << " void* args[" << QString::number(args.size() + 1) << "] = {nullptr";
159159
for (int i = 0; i < args.size(); ++i) {
160160
s << ", (void*)&" << args.at(i)->indexedName();
161161
}
@@ -164,9 +164,9 @@ void ShellImplGenerator::write(QTextStream &s, const AbstractMetaClass *meta_cla
164164
s << " PyObject* result = PythonQtSignalTarget::call(obj, methodInfo, args, true);" << endl;
165165
if (hasReturnValue) {
166166
s << " if (result) {" << endl;
167-
s << " args[0] = PythonQtConv::ConvertPythonToQt(methodInfo->parameters().at(0), result, false, NULL, &returnValue);" << endl;
167+
s << " args[0] = PythonQtConv::ConvertPythonToQt(methodInfo->parameters().at(0), result, false, nullptr, &returnValue);" << endl;
168168
s << " if (args[0]!=&returnValue) {" << endl;
169-
s << " if (args[0]==NULL) {" << endl;
169+
s << " if (args[0]==nullptr) {" << endl;
170170
s << " PythonQt::priv()->handleVirtualOverloadReturnError(\"" << fun->name() << "\", methodInfo, result);" << endl;
171171
s << " } else {" << endl;
172172
s << " returnValue = *((";
@@ -202,7 +202,7 @@ void ShellImplGenerator::write(QTextStream &s, const AbstractMetaClass *meta_cla
202202
// return empty default object
203203
s << "return ";
204204
if (fun->type()->indirections()>0) {
205-
s << "0;";
205+
s << "nullptr;";
206206
} else {
207207
writeTypeInfo(s, fun->type(), typeOptions);
208208
s << "();";

0 commit comments

Comments
 (0)