Add support for new features available in gccgo 4.7, notably calling

Entersyscall and Exitsyscall around calls to wrapped C/C++ code.


git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12940 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Ian Lance Taylor 2012-03-20 22:35:40 +00:00
commit 602730a327
4 changed files with 90 additions and 4 deletions

View file

@ -99,6 +99,19 @@ swig -go -help
6g/8g/5g.</td>
</tr>
<tr>
<td>-gccgo-46</td>
<td>Generate code for gccgo 4.6. The default is set by the configure
script.</td> This generates code that does not use some facilities
that are only available in gccgo 4.7 and later.
</tr>
<tr>
<td>-no-gccgo-46</td>
<td>Turn off <code>-gccgo-46</code>, whether set by default or earlier
on the command line.
</tr>
<tr>
<td>-package &lt;name&gt;</td>
<td>Set the name of the Go package to &lt;name&gt;. The default

View file

@ -117,6 +117,16 @@ import _ "runtime/cgo"
%}
#else
%insert(go_header) %{
import "syscall"
type _ syscall.Sockaddr
%}
#endif
/* Function pointers are translated by the code in go.cxx into

View file

@ -13,6 +13,12 @@ char cvsroot_go_cxx[] = "$Id";
#include "cparse.h"
#include <ctype.h>
#ifdef HAVE_GCCGO_46
#define GCCGO_46_DEFAULT true
#else
#define GCCGO_46_DEFAULT false
#endif
class GO:public Language {
static const char *const usage;
@ -20,6 +26,8 @@ class GO:public Language {
String *package;
// Flag for generating gccgo output.
bool gccgo_flag;
// Flag for generating gccgo 4.6 output.
bool gccgo_46_flag;
// Prefix to use with gccgo.
String *go_prefix;
// Name of shared library to import.
@ -82,6 +90,7 @@ class GO:public Language {
public:
GO():package(NULL),
gccgo_flag(false),
gccgo_46_flag(GCCGO_46_DEFAULT),
go_prefix(NULL),
soname(NULL),
long_type_size(32),
@ -139,6 +148,12 @@ private:
} else if (strcmp(argv[i], "-gccgo") == 0) {
Swig_mark_arg(i);
gccgo_flag = true;
} else if (strcmp(argv[i], "-gccgo-46") == 0) {
Swig_mark_arg(i);
gccgo_46_flag = true;
} else if (strcmp(argv[i], "-no-gccgo-46") == 0) {
Swig_mark_arg(i);
gccgo_46_flag = false;
} else if (strcmp(argv[i], "-go-prefix") == 0) {
if (argv[i + 1]) {
go_prefix = NewString(argv[i + 1]);
@ -779,6 +794,10 @@ private:
if (needs_wrapper) {
wrapper_name = buildGoWrapperName(name, overname);
if (gccgo_flag && !gccgo_46_flag) {
Printv(f_go_wrappers, "//extern ", go_prefix, "_", wname, "\n", NULL);
}
Printv(f_go_wrappers, "func ", wrapper_name, "(", NULL);
if (parm_count > required_count) {
Printv(f_go_wrappers, "int", NULL);
@ -826,7 +845,7 @@ private:
}
}
if (gccgo_flag) {
if (gccgo_flag && gccgo_46_flag) {
Printv(f_go_wrappers, " __asm__ (\"", go_prefix, "_", wname, "\")", NULL);
}
@ -835,6 +854,10 @@ private:
// Start defining the Go function.
if (!needs_wrapper && gccgo_flag && !gccgo_46_flag) {
Printv(f_go_wrappers, "//extern ", go_prefix, "_", wname, "\n", NULL);
}
Printv(f_go_wrappers, "func ", NULL);
Parm *p = parms;
@ -936,6 +959,11 @@ private:
}
}
if (gccgo_flag && !gccgo_46_flag) {
Printv(f_go_wrappers, "\tsyscall.Entersyscall()\n", NULL);
Printv(f_go_wrappers, "\tdefer syscall.Exitsyscall()\n", NULL);
}
Printv(f_go_wrappers, "\t", NULL);
if (SwigType_type(result) != T_VOID) {
Printv(f_go_wrappers, "return ", NULL);
@ -976,7 +1004,7 @@ private:
Printv(f_go_wrappers, ")\n", NULL);
Printv(f_go_wrappers, "}\n", NULL);
} else {
if (gccgo_flag) {
if (gccgo_flag && gccgo_46_flag) {
Printv(f_go_wrappers, " __asm__ (\"", go_prefix, "_", wname, "\")\n", NULL);
}
}
@ -2493,6 +2521,11 @@ private:
if (!is_ignored) {
// Declare the C++ wrapper.
if (gccgo_flag && !gccgo_46_flag) {
Printv(f_go_wrappers, "//extern ", go_prefix, "_", wname, "\n", NULL);
}
Printv(f_go_wrappers, "func ", fn_name, NULL);
if (overname) {
Printv(f_go_wrappers, overname, NULL);
@ -2510,7 +2543,7 @@ private:
Printv(f_go_wrappers, ") ", go_type_name, NULL);
if (gccgo_flag) {
if (gccgo_flag && gccgo_46_flag) {
Printv(f_go_wrappers, " __asm__(\"", go_prefix, "_", wname, "\")", NULL);
}
@ -2532,6 +2565,12 @@ private:
Printv(f_go_wrappers, ") ", cn, " {\n", NULL);
Printv(f_go_wrappers, "\tp := &", director_struct_name, "{0, v}\n", NULL);
if (gccgo_flag && !gccgo_46_flag) {
Printv(f_go_wrappers, "\tsyscall.Entersyscall()\n", NULL);
Printv(f_go_wrappers, "\tdefer syscall.Exitsyscall()\n", NULL);
}
Printv(f_go_wrappers, "\tp.", class_receiver, " = ", fn_name, NULL);
if (overname) {
Printv(f_go_wrappers, overname, NULL);
@ -2987,6 +3026,10 @@ private:
String *upcall_gc_name = buildGoWrapperName(upcall_name, overname);
if (gccgo_flag && !gccgo_46_flag) {
Printv(f_go_wrappers, "//extern ", go_prefix, "_", upcall_wname, "\n", NULL);
}
Printv(f_go_wrappers, "func ", upcall_gc_name, "(", go_type_name, NULL);
p = parms;
@ -3006,7 +3049,7 @@ private:
Delete(tm);
}
if (gccgo_flag) {
if (gccgo_flag && gccgo_46_flag) {
Printv(f_go_wrappers, " __asm__(\"", go_prefix, "_", upcall_wname, "\")", NULL);
}
@ -3039,6 +3082,11 @@ private:
Printv(f_go_wrappers, " {\n", NULL);
if (gccgo_flag && !gccgo_46_flag) {
Printv(f_go_wrappers, "\tsyscall.Entersyscall()\n", NULL);
Printv(f_go_wrappers, "\tdefer syscall.Exitsyscall()\n", NULL);
}
Printv(f_go_wrappers, "\tif swig_g, swig_ok := swig_p.v.(", interface_name, "); swig_ok {\n", NULL);
Printv(f_go_wrappers, "\t\t", NULL);
if (SwigType_type(result) != T_VOID) {
@ -3206,6 +3254,11 @@ private:
Printv(f_go_wrappers, " {\n", NULL);
if (gccgo_flag && !gccgo_46_flag) {
Printv(f_go_wrappers, "\tsyscall.Entersyscall()\n", NULL);
Printv(f_go_wrappers, "\tdefer syscall.Exitsyscall()\n", NULL);
}
Printv(f_go_wrappers, "\t", NULL);
if (SwigType_type(result) != T_VOID) {
Printv(f_go_wrappers, "return ", NULL);
@ -3247,6 +3300,12 @@ private:
Printv(f_go_wrappers, "(swig_result ", result_wrapper, ") ", NULL);
}
Printv(f_go_wrappers, "{\n", NULL);
if (gccgo_flag && !gccgo_46_flag) {
Printv(f_go_wrappers, "\tsyscall.Exitsyscall()\n", NULL);
Printv(f_go_wrappers, "\tdefer syscall.Entersyscall()\n", NULL);
}
Printv(f_go_wrappers, "\t", NULL);
if (is_ignored) {

View file

@ -2074,6 +2074,10 @@ else
if test -n "$GO" ; then
if $GO --help 2>/dev/null | grep gccgo >/dev/null 2>&1 ; then
GOGCC=true
go_version=`$GO --version | sed -e 's/[^0-9]* \([0-9.]*\) .*$/\1/' -e 's/[.]//g'`
if test "$go_version" -lt 470; then
AC_DEFINE(HAVE_GCCGO_46, 1, [Define if using gccgo before 4.7.0])
fi
elif test "`echo $GO | sed -e 's|.*/||'`" = "go"; then
GO1=true
GOC=$(sh -c "$(go env) && echo \$GOCHAR")c