From 07ab80b49e0b51931a7e309b8c62b72a459efe64 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sat, 13 May 2017 17:01:15 +0100 Subject: [PATCH] Add raise methods for throwing c++ exceptions in C#, Java, D The director c++ exceptions are thrown in a helper method instead of in the director overloaded method. This circumvents compiler warnings about throwing exceptions when the method has an exception specification or noexcept. If the exception is thrown, abort will still be called! In Java, the "director:noexcept" typemap can be used to do something else. This typemap should be ported to the other languages too. --- Doc/Manual/Java.html | 16 ++++++++++++++-- Lib/csharp/director.swg | 4 ++++ Lib/d/director.swg | 4 ++++ Lib/java/director.swg | 4 ++++ Source/Modules/csharp.cxx | 2 +- Source/Modules/d.cxx | 2 +- Source/Modules/java.cxx | 2 +- 7 files changed, 29 insertions(+), 5 deletions(-) diff --git a/Doc/Manual/Java.html b/Doc/Manual/Java.html index bd259e60d..c77724bf2 100644 --- a/Doc/Manual/Java.html +++ b/Doc/Manual/Java.html @@ -3923,12 +3923,24 @@ is used in the feature code. Consider the following, which also happens to be th if ($error) { jenv->ExceptionClear(); $directorthrowshandlers - throw Swig::DirectorException(jenv, $error); + Swig::DirectorException::raise(jenv, $error); } %} +

+where Swig::DirectorException::raise is a helper method in the DirectorException class to throw a C++ exception (implemented in director.swg): +

+ +
+
+    static void raise(JNIEnv *jenv, jthrowable throwable) {
+      throw DirectorException(jenv, throwable);
+    }
+
+
+

The code generated using the director:except feature replaces the $directorthrowshandlers special variable with the code in the "directorthrows" typemaps, for each and every exception defined for the method. @@ -3963,7 +3975,7 @@ if (swigerror) { throw std::out_of_range(Swig::JavaExceptionMessage(jenv, swigerror).message()); } - throw Swig::DirectorException(jenv, swigerror); + Swig::DirectorException::raise(jenv, swigerror); } diff --git a/Lib/csharp/director.swg b/Lib/csharp/director.swg index 3438f2bf0..5d2ab5d9b 100644 --- a/Lib/csharp/director.swg +++ b/Lib/csharp/director.swg @@ -41,6 +41,10 @@ namespace Swig { public: DirectorPureVirtualException(const char *msg) : DirectorException(std::string("Attempt to invoke pure virtual method ") + msg) { } + + static void raise(const char *msg) { + throw DirectorPureVirtualException(msg); + } }; } diff --git a/Lib/d/director.swg b/Lib/d/director.swg index a7d9c7688..02da0e0ac 100644 --- a/Lib/d/director.swg +++ b/Lib/d/director.swg @@ -40,6 +40,10 @@ namespace Swig { public: DirectorPureVirtualException(const char *msg) : DirectorException(std::string("Attempted to invoke pure virtual method ") + msg) { } + + static void raise(const char *msg) { + throw DirectorPureVirtualException(msg); + } }; } diff --git a/Lib/java/director.swg b/Lib/java/director.swg index 355e62d67..abde72286 100644 --- a/Lib/java/director.swg +++ b/Lib/java/director.swg @@ -356,6 +356,10 @@ namespace Swig { } } + static void raise(JNIEnv *jenv, jthrowable throwable) { + throw DirectorException(jenv, throwable); + } + private: static char *copypath(const char *srcmsg) { char *target = copystr(srcmsg); diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx index 154fadac5..c41a212e4 100644 --- a/Source/Modules/csharp.cxx +++ b/Source/Modules/csharp.cxx @@ -3935,7 +3935,7 @@ public: } Delete(super_call); } else { - Printf(w->code, " throw Swig::DirectorPureVirtualException(\"%s::%s\");\n", SwigType_namestr(c_classname), SwigType_namestr(name)); + Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"%s::%s\");\n", SwigType_namestr(c_classname), SwigType_namestr(name)); } if (!ignored_method) diff --git a/Source/Modules/d.cxx b/Source/Modules/d.cxx index 05ca6c636..36216b75e 100644 --- a/Source/Modules/d.cxx +++ b/Source/Modules/d.cxx @@ -2077,7 +2077,7 @@ public: } Delete(super_call); } else { - Printf(w->code, " throw Swig::DirectorPureVirtualException(\"%s::%s\");\n", SwigType_namestr(c_classname), SwigType_namestr(name)); + Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"%s::%s\");\n", SwigType_namestr(c_classname), SwigType_namestr(name)); } if (!ignored_method) diff --git a/Source/Modules/java.cxx b/Source/Modules/java.cxx index b380565b5..e53cf1576 100644 --- a/Source/Modules/java.cxx +++ b/Source/Modules/java.cxx @@ -4490,7 +4490,7 @@ public: Printf(directorexcept, "jthrowable $error = jenv->ExceptionOccurred();\n"); Printf(directorexcept, "if ($error) {\n"); Printf(directorexcept, " jenv->ExceptionClear();$directorthrowshandlers\n"); - Printf(directorexcept, " throw Swig::DirectorException(jenv, $error);\n"); + Printf(directorexcept, " Swig::DirectorException::raise(jenv, $error);\n"); Printf(directorexcept, "}\n"); } else { directorexcept = Copy(directorexcept);