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. + +-gccgo-46 +Generate code for gccgo 4.6. The default is set by the configure + script. This generates code that does not use some facilities + that are only available in gccgo 4.7 and later. + + + +-no-gccgo-46 +Turn off -gccgo-46, whether set by default or earlier + on the command line. + + -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