diff --git a/Doc/Manual/Go.html b/Doc/Manual/Go.html
index cd39d1fa1..a420b2864 100644
--- a/Doc/Manual/Go.html
+++ b/Doc/Manual/Go.html
@@ -99,6 +99,19 @@ swig -go -help
6g/8g/5g.
+
| -package <name> |
Set the name of the Go package to <name>. The default
diff --git a/Lib/go/goruntime.swg b/Lib/go/goruntime.swg
index 6aeeab730..ef23d1211 100644
--- a/Lib/go/goruntime.swg
+++ b/Lib/go/goruntime.swg
@@ -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
diff --git a/Source/Modules/go.cxx b/Source/Modules/go.cxx
index 02910f415..668cb66df 100644
--- a/Source/Modules/go.cxx
+++ b/Source/Modules/go.cxx
@@ -13,6 +13,12 @@ char cvsroot_go_cxx[] = "$Id";
#include "cparse.h"
#include
+#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) {
diff --git a/configure.in b/configure.in
index 40026563c..9e88e7eda 100644
--- a/configure.in
+++ b/configure.in
@@ -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
|