summaryrefslogtreecommitdiffstats
path: root/generator/overloaddata.cpp
diff options
context:
space:
mode:
authorMarcelo Lira <marcelo.lira@openbossa.org>2011-01-11 17:31:34 -0300
committerMarcelo Lira <marcelo.lira@openbossa.org>2011-01-11 17:31:34 -0300
commitd9902755a46c299cd50550ae1c7932d1ac4d8f70 (patch)
treeea396dc43f7b3f8308fe803bc8e9d20c5c2eaa07 /generator/overloaddata.cpp
parent5fccb1dafa71929b5a7968d5a3a99f5b442bc2e2 (diff)
downloadshiboken-d9902755a46c299cd50550ae1c7932d1ac4d8f70.tar.gz
shiboken-d9902755a46c299cd50550ae1c7932d1ac4d8f70.tar.xz
shiboken-d9902755a46c299cd50550ae1c7932d1ac4d8f70.zip
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.
Diffstat (limited to 'generator/overloaddata.cpp')
-rw-r--r--generator/overloaddata.cpp23
1 files changed, 23 insertions, 0 deletions
diff --git a/generator/overloaddata.cpp b/generator/overloaddata.cpp
index 29a1615f..926f5d98 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)) {