aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcelo Lira <marcelo.lira@openbossa.org>2011-01-11 17:31:34 -0300
committerHugo Parente Lima <hugo.pl@gmail.com>2012-03-08 16:12:53 -0300
commit640537a691a2cd0830e12810714ec0cc5164242a (patch)
tree73b3e643d5e405e3489dec117dfa6f09b2eb89cd
parent4799e166ed4ec9d4a6c89769c1bc23e6931a03ba (diff)
The overload decisor must put enums before types implicitly convertible from integers.
Otherwise the enum value will be an acceptable argument for a class that expects an integer (signed or unsigned) to be implicitly built, and the enum argument will never be called.
-rw-r--r--generator/overloaddata.cpp23
1 files changed, 23 insertions, 0 deletions
diff --git a/generator/overloaddata.cpp b/generator/overloaddata.cpp
index 29a1615ff..926f5d988 100644
--- a/generator/overloaddata.cpp
+++ b/generator/overloaddata.cpp
@@ -225,11 +225,14 @@ void OverloadData::sortNextOverloads()
for (int i = 0; i < numPrimitives; ++i)
hasPrimitive[i] = sortData.map.contains(primitiveTypes[i]);
+ QStringList classesWithIntegerImplicitConversion;
+
foreach(OverloadData* ov, m_nextOverloadData) {
const AbstractMetaType* targetType = ov->argType();
const TypeEntry* targetTypeEntry = getAliasedTypeEntry(targetType->typeEntry());
QString targetTypeEntryName = getTypeName(targetType);
+ // Process implicit conversions
foreach(AbstractMetaFunction* function, m_generator->implicitConversions(targetType)) {
QString convertibleType;
if (function->isConversionOperator())
@@ -237,6 +240,9 @@ void OverloadData::sortNextOverloads()
else
convertibleType = getTypeName(function->arguments().first()->type());
+ if (convertibleType == "int" || convertibleType == "unsigned int")
+ classesWithIntegerImplicitConversion << targetTypeEntryName;
+
if (!sortData.map.contains(convertibleType))
continue;
@@ -249,6 +255,8 @@ void OverloadData::sortNextOverloads()
graph.addEdge(convertibleTypeId, targetTypeId);
}
+
+ // Process template instantiations
foreach (const AbstractMetaType* instantiation, targetType->instantiations()) {
if (sortData.map.contains(getTypeName(instantiation))) {
int target = sortData.map[targetTypeEntryName];
@@ -286,6 +294,7 @@ void OverloadData::sortNextOverloads()
}
if (targetTypeEntry->isEnum()) {
+ // Enum values must precede primitive types.
for (int i = 0; i < numPrimitives; ++i) {
if (hasPrimitive[i])
graph.addEdge(sortData.map[targetTypeEntryName], sortData.map[primitiveTypes[i]]);
@@ -293,6 +302,20 @@ void OverloadData::sortNextOverloads()
}
}
+ foreach(OverloadData* ov, m_nextOverloadData) {
+ const AbstractMetaType* targetType = ov->argType();
+ if (!targetType->isEnum())
+ continue;
+
+ const TypeEntry* targetTypeEntry = getAliasedTypeEntry(targetType->typeEntry());
+ QString targetTypeEntryName = getTypeName(targetType);
+
+ // Enum values must precede types implicitly convertible from "int" or "unsigned int".
+ foreach (const QString& implicitFromInt, classesWithIntegerImplicitConversion)
+ graph.addEdge(sortData.map[targetTypeEntryName], sortData.map[implicitFromInt]);
+ }
+
+
// Special case for double(int i) (not tracked by m_generator->implicitConversions
foreach (const QString& signedIntegerName, signedIntegerPrimitives) {
if (sortData.map.contains(signedIntegerName)) {