diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2018-09-14 11:48:10 +0200 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2018-09-27 06:16:46 +0000 |
commit | 2412e332a9984891aa481176141d403183ac3b11 (patch) | |
tree | 5646f4a929a3585131eb09009f404834a55c6cd2 /sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp | |
parent | 0f8b1cf2daae6fcc0a922a9e2514f12374eeee31 (diff) |
Add exception handling
Add XML elements specifying an exception handling mode to type system,
complex type entries (classes) and function modifications.
From the mode and the exception specification as detected
by Clang, deduce whether to generate try/catch code.
Task-number: PYSIDE-62
Change-Id: Ib76adc21cefd81bf9f82f819a3c151056c33a3b7
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Christian Tismer <tismer@stackless.com>
Diffstat (limited to 'sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp')
-rw-r--r-- | sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp | 52 |
1 files changed, 46 insertions, 6 deletions
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp index 8ff2310e9..ed700e4fa 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp @@ -1878,12 +1878,40 @@ bool AbstractMetaBuilderPrivate::setArrayArgumentType(AbstractMetaFunction *func return true; } +static bool generateExceptionHandling(const AbstractMetaFunction *func, + ExceptionSpecification spec, + TypeSystem::ExceptionHandling handling) +{ + switch (func->functionType()) { + case AbstractMetaFunction::CopyConstructorFunction: + case AbstractMetaFunction::MoveConstructorFunction: + case AbstractMetaFunction::AssignmentOperatorFunction: + case AbstractMetaFunction::MoveAssignmentOperatorFunction: + case AbstractMetaFunction::DestructorFunction: + return false; + default: + break; + } + switch (handling) { + case TypeSystem::ExceptionHandling::On: + return true; + case TypeSystem::ExceptionHandling::AutoDefaultToOn: + return spec != ExceptionSpecification::NoExcept; + case TypeSystem::ExceptionHandling::AutoDefaultToOff: + return spec == ExceptionSpecification::Throws; + default: + break; + } + return false; +} + AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const FunctionModelItem &functionItem) { if (functionItem->isDeleted() || !functionItem->templateParameters().isEmpty()) return nullptr; QString functionName = functionItem->name(); QString className; + TypeSystem::ExceptionHandling exceptionHandling = TypeSystem::ExceptionHandling::Unspecified; if (m_currentClass) { // Clang: Skip qt_metacast(), qt_metacall(), expanded from Q_OBJECT // and overridden metaObject(), QGADGET helpers @@ -1892,6 +1920,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio return nullptr; } className = m_currentClass->typeEntry()->qualifiedCppName(); + exceptionHandling = m_currentClass->typeEntry()->exceptionHandling(); if (functionName == QLatin1String("metaObject") && className != QLatin1String("QObject")) return nullptr; } @@ -2050,6 +2079,19 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio metaFunction->setArguments(metaArguments); + const FunctionModificationList functionMods = metaFunction->modifications(m_currentClass); + + for (const FunctionModification &mod : functionMods) { + if (mod.exceptionHandling() != TypeSystem::ExceptionHandling::Unspecified) { + exceptionHandling = mod.exceptionHandling(); + break; + } + } + + metaFunction->setGenerateExceptionHandling(generateExceptionHandling(metaFunction, + functionItem->exceptionSpecification(), + exceptionHandling)); + // Find the correct default values for (int i = 0, size = metaArguments.size(); i < size; ++i) { const ArgumentModelItem &arg = arguments.at(i); @@ -2060,9 +2102,8 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio if (m_currentClass) { replacedExpression = metaFunction->replacedDefaultExpression(m_currentClass, i + 1); } else { - FunctionModificationList mods = TypeDatabase::instance()->functionModifications(metaFunction->minimalSignature()); - if (!mods.isEmpty()) { - QVector<ArgumentModification> argMods = mods.constFirst().argument_mods; + if (!functionMods.isEmpty()) { + QVector<ArgumentModification> argMods = functionMods.constFirst().argument_mods; if (!argMods.isEmpty()) replacedExpression = argMods.constFirst().replacedDefaultExpression; } @@ -2101,9 +2142,8 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio } if (!metaArguments.isEmpty()) { - const FunctionModificationList &mods = metaFunction->modifications(m_currentClass); - fixArgumentNames(metaFunction, mods); - for (const FunctionModification &mod : mods) { + fixArgumentNames(metaFunction, functionMods); + for (const FunctionModification &mod : functionMods) { for (const ArgumentModification &argMod : mod.argument_mods) { if (argMod.array) setArrayArgumentType(metaFunction, functionItem, argMod.index - 1); |