Skip to content

Commit 61dfba6

Browse files
florianlinkmsmolens
florianlink
authored andcommitted
initial version that handles qualified virtual calls better
git-svn-id: http://svn.code.sf.net/p/pythonqt/code/trunk@400 ea8d5007-eb21-0410-b261-ccb3ea6e24a9
1 parent 56ac983 commit 61dfba6

File tree

4 files changed

+76
-21
lines changed

4 files changed

+76
-21
lines changed

generator/shellheadergenerator.cpp

+72-19
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ void ShellHeaderGenerator::write(QTextStream &s, const AbstractMetaClass *meta_c
198198
}
199199

200200
foreach(AbstractMetaFunction* fun, promoteFunctions) {
201+
// normal promoter
201202
if (fun->isStatic()) {
202203
s << "static ";
203204
}
@@ -210,26 +211,37 @@ void ShellHeaderGenerator::write(QTextStream &s, const AbstractMetaClass *meta_c
210211
if (fun->type()) {
211212
s << "return ";
212213
}
213-
if (!fun->isAbstract()) {
214-
s << meta_class->qualifiedCppName() << "::";
215-
}
216-
else {
217-
s << "this->";
218-
}
214+
// always do a direct call, since we want to call the real virtual function here
215+
s << "this->";
219216
s << fun->originalName() << "(";
220-
for (int i = 0; i < args.size(); ++i) {
221-
if (i > 0) {
222-
s << ", ";
217+
writePromoterArgs(args, s);
218+
s << "); }" << endl;
219+
}
220+
221+
foreach(AbstractMetaFunction* fun, promoteFunctions) {
222+
// qualified promoter for virtual functions
223+
if (fun->isVirtual()) {
224+
s << "inline ";
225+
writeFunctionSignature(s, fun, 0, "py_qualified_",
226+
Option(IncludeDefaultExpression | OriginalName | UnderscoreSpaces | ProtectedEnumAsInts));
227+
s << " { ";
228+
QString scriptFunctionName = fun->originalName();
229+
AbstractMetaArgumentList args = fun->arguments();
230+
if (fun->type()) {
231+
s << "return ";
223232
}
224-
if (args.at(i)->type()->isEnum()) {
225-
AbstractMetaEnum* enumType = m_classes.findEnum((EnumTypeEntry *)args.at(i)->type()->typeEntry());
226-
if (enumType && enumType->wasProtected()) {
227-
s << "(" << enumType->typeEntry()->qualifiedCppName() << ")";
228-
}
233+
if (!fun->isAbstract()) {
234+
// call the qualified version, we don't want the virtual function
235+
s << meta_class->qualifiedCppName() << "::";
229236
}
230-
s << args.at(i)->argumentName();
237+
else {
238+
// TODO: this would better be empty and do no call at all...
239+
s << "this->";
240+
}
241+
s << fun->originalName() << "(";
242+
writePromoterArgs(args, s);
243+
s << "); }" << endl;
231244
}
232-
s << "); }" << endl;
233245
}
234246

235247
s << "};" << endl << endl;
@@ -338,16 +350,41 @@ void ShellHeaderGenerator::write(QTextStream &s, const AbstractMetaClass *meta_c
338350
AbstractMetaFunctionList functions = getFunctionsToWrap(meta_class);
339351

340352
foreach (const AbstractMetaFunction *function, functions) {
341-
if (!function->isSlot() || function->isVirtual()) {
342-
353+
if (!function->isSlot()) {
343354
// for debugging:
344355
//functionHasNonConstReferences(function);
345-
346356
s << " ";
347357
writeFunctionSignature(s, function, 0, QString(),
348358
Option(AddOwnershipTemplates | ConvertReferenceToPtr | FirstArgIsWrappedObject | IncludeDefaultExpression | OriginalName | ShowStatic | UnderscoreSpaces | ProtectedEnumAsInts));
349359
s << ";" << endl;
350360
}
361+
if (function->isVirtual()) {
362+
// qualified version that calls the promoter/the qualified version
363+
s << " ";
364+
writeFunctionSignature(s, function, 0, "py_qualified_",
365+
Option(AddOwnershipTemplates | ConvertReferenceToPtr | FirstArgIsWrappedObject | IncludeDefaultExpression | OriginalName | ShowStatic | UnderscoreSpaces | ProtectedEnumAsInts));
366+
s << "{ ";
367+
368+
QString scriptFunctionName = function->originalName();
369+
AbstractMetaArgumentList args = function->arguments();
370+
// call the C++ implementation
371+
if (function->type()) {
372+
s << "return ";
373+
// call the C++ implementation
374+
if (function->type()->isReference()) {
375+
s << "&";
376+
}
377+
}
378+
s << "(((" << promoterClassName(meta_class) << "*)theWrappedObject)->py_qualified_";
379+
s << function->originalName() << "(";
380+
for (int i = 0; i < args.size(); ++i) {
381+
if (i > 0)
382+
s << ", ";
383+
s << args.at(i)->argumentName();
384+
}
385+
s << "));";
386+
s << "}" << endl;
387+
}
351388
}
352389
if (meta_class->hasDefaultToStringFunction() || meta_class->hasToStringCapability()) {
353390
s << " QString py_toString(" << meta_class->qualifiedCppName() << "*);" << endl;
@@ -380,6 +417,22 @@ void ShellHeaderGenerator::write(QTextStream &s, const AbstractMetaClass *meta_c
380417

381418
}
382419

420+
void ShellHeaderGenerator::writePromoterArgs(AbstractMetaArgumentList &args, QTextStream & s)
421+
{
422+
for (int i = 0; i < args.size(); ++i) {
423+
if (i > 0) {
424+
s << ", ";
425+
}
426+
if (args.at(i)->type()->isEnum()) {
427+
AbstractMetaEnum* enumType = m_classes.findEnum((EnumTypeEntry *)args.at(i)->type()->typeEntry());
428+
if (enumType && enumType->wasProtected()) {
429+
s << "(" << enumType->typeEntry()->qualifiedCppName() << ")";
430+
}
431+
}
432+
s << args.at(i)->argumentName();
433+
}
434+
}
435+
383436
void ShellHeaderGenerator::writeInjectedCode(QTextStream &s, const AbstractMetaClass *meta_class, int type, bool recursive)
384437
{
385438
const AbstractMetaClass *cls = meta_class;

generator/shellheadergenerator.h

+3
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ class ShellHeaderGenerator : public ShellGenerator
6060
virtual QString fileNameForClass(const AbstractMetaClass *cls) const;
6161

6262
void write(QTextStream &s, const AbstractMetaClass *meta_class);
63+
64+
void writePromoterArgs(AbstractMetaArgumentList &args, QTextStream & s);
65+
6366
void writeInjectedCode(QTextStream &s, const AbstractMetaClass *meta_class, int type, bool recursive = false);
6467

6568
void writeFieldAccessors(QTextStream &s, const AbstractMetaField *field);

generator/shellimplgenerator.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ void ShellImplGenerator::write(QTextStream &s, const AbstractMetaClass *meta_cla
248248
// write member functions
249249
for (int i = 0; i < functions.size(); ++i) {
250250
AbstractMetaFunction *fun = functions.at(i);
251-
bool needsWrapping = (!fun->isSlot() || fun->isVirtual());
251+
bool needsWrapping = !fun->isSlot();
252252
if (!needsWrapping) {
253253
continue;
254254
}

generator/typesystem_gui.xml

-1
Original file line numberDiff line numberDiff line change
@@ -2099,7 +2099,6 @@ PyObject* constScanLine(QImage* image, int line) {
20992099
<modify-function signature="fontMetrics()const" remove="all"/>
21002100
<modify-function signature="sizeHint()const" rename="getSizeHint"/>
21012101
<modify-function signature="minimumSizeHint()const" rename="getMinimumSizeHint"/>
2102-
<modify-function signature="setVisible(bool)" remove="all"/>
21032102
</object-type>
21042103

21052104
<object-type name="QMessageBox">

0 commit comments

Comments
 (0)