Skip to content

Commit

Permalink
Fix creation of duplicate redirections
Browse files Browse the repository at this point in the history
Change processing of redirections to bind redirections starting with the
most derived class, rather than the other way around, and to ignore
method signatures that have already been bound. This prevents us adding
the same signature more than once, which confuses the overload
resolution and produces generated code with build errors.

Note that this isn't quite right as it doesn't account for the usual
shadowing rules. While this in and of itself would not be hard to
implement, it would possibly cause more harm than good given that we
don't appear to parse 'using' declarations, and so would tend to drop
more methods than we should in real life code.

Change-Id: Ic19776f283153d30b2f1bd56d7969fd535750b26
  • Loading branch information
mwoehlke-kitware committed Oct 15, 2013
1 parent 75d2964 commit 390d0ed
Showing 1 changed file with 21 additions and 8 deletions.
29 changes: 21 additions & 8 deletions ApiExtractor/abstractmetabuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,15 @@ static bool entryHasFunction(const ComplexTypeEntry *entry, const QString &signa
return false;
}

static bool classHasFunction(const AbstractMetaClass *metaClass, const QString &minimalSignature)
{
foreach (const AbstractMetaFunction *function, metaClass->functions()) {
if (function->minimalSignature() == minimalSignature)
return true;
}
return false;
}

AbstractMetaBuilder::AbstractMetaBuilder() : m_currentClass(0), m_logDirectory(QString('.')+QDir::separator())
{
}
Expand Down Expand Up @@ -1496,21 +1505,17 @@ void AbstractMetaBuilder::traverseInstantiation(ComplexTypeEntry *entry, Abstrac

void AbstractMetaBuilder::addRedirections(ComplexTypeEntry *entry, AbstractMetaClass* metaClass, AbstractMetaClass* fromClass, const QString &accessor)
{
// Add redirections from the class's primary base class
if (fromClass->baseClass())
addRedirections(entry, metaClass, fromClass->baseClass(), accessor);

// Add redirections from the class's interfaces
foreach (AbstractMetaClass *iface, fromClass->interfaces())
addRedirections(entry, metaClass, iface, accessor);

// Add redirections from the class itself
foreach (AbstractMetaFunction *function, fromClass->functions()) {
if (!function->isStatic() && !function->isConstructor() && function->isPublic()) {
QString signature = function->minimalSignature();
if (signature.endsWith("const"))
signature = signature.left((signature.length() - 5));

// Skip function if it already exists (e.g. overloaded virtuals or shadowed methods)
if (classHasFunction(metaClass, signature))
continue;

// Generate meta function and add to meta class
QString returnType = (function->type() ? function->type()->cppSignature() : QString("void"));
AddedFunction addedFunction(signature, returnType, 0.0);
Expand Down Expand Up @@ -1541,6 +1546,14 @@ void AbstractMetaBuilder::addRedirections(ComplexTypeEntry *entry, AbstractMetaC
}
}
}

// Add redirections from the class's primary base class
if (fromClass->baseClass())
addRedirections(entry, metaClass, fromClass->baseClass(), accessor);

// Add redirections from the class's interfaces
foreach (AbstractMetaClass *iface, fromClass->interfaces())
addRedirections(entry, metaClass, iface, accessor);
}

void AbstractMetaBuilder::setupFunctionDefaults(AbstractMetaFunction* metaFunction, AbstractMetaClass *metaClass)
Expand Down

0 comments on commit 390d0ed

Please sign in to comment.