aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2018-11-30 14:21:33 -0800
committerIan Lance Taylor <iant@golang.org>2018-12-01 05:30:16 +0000
commitf70bd914353b2331a48eedb84aceb458982eaac0 (patch)
treeb058a86115fa4225fcdfbfb60b9091e98f2beadc /src
parentc042fedbc8dbbf27603a360d79d59b4969f299ec (diff)
downloadgo-f70bd914353b2331a48eedb84aceb458982eaac0.tar.xz
cmd/cgo: use preprocessor macros to avoid prolog redefinitions
Avoid redefinition errors when a Go file uses a cgo comment to There is no particularly good reason to do this, but there is also no particularly good reason that it should fail. Fixes #27019 Change-Id: Icd6f8197a89be4ee6b03ddae675667998a8b4189 Reviewed-on: https://go-review.googlesource.com/c/152079 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'src')
-rw-r--r--src/cmd/cgo/out.go23
1 files changed, 22 insertions, 1 deletions
diff --git a/src/cmd/cgo/out.go b/src/cmd/cgo/out.go
index bc0b0b6387..c49b51c611 100644
--- a/src/cmd/cgo/out.go
+++ b/src/cmd/cgo/out.go
@@ -1555,6 +1555,7 @@ const builtinProlog = `
/* Define intgo when compiling with GCC. */
typedef ptrdiff_t intgo;
+#define GO_CGO_GOSTRING_TYPEDEF
typedef struct { const char *p; intgo n; } _GoString_;
typedef struct { char *p; intgo n; intgo c; } _GoBytes_;
_GoString_ GoString(char *p);
@@ -1806,15 +1807,20 @@ void localCgoCheckResult(Eface val) {
// because _cgo_export.h defines GoString as a struct while builtinProlog
// defines it as a function. We don't change this to avoid unnecessarily
// breaking existing code.
+// The test of GO_CGO_GOSTRING_TYPEDEF avoids a duplicate definition
+// error if a Go file with a cgo comment #include's the export header
+// generated by a different package.
const builtinExportProlog = `
-#line 1 "cgo-builtin-prolog"
+#line 1 "cgo-builtin-export-prolog"
#include <stddef.h> /* for ptrdiff_t below */
#ifndef GO_CGO_EXPORT_PROLOGUE_H
#define GO_CGO_EXPORT_PROLOGUE_H
+#ifndef GO_CGO_GOSTRING_TYPEDEF
typedef struct { const char *p; ptrdiff_t n; } _GoString_;
+#endif
#endif
`
@@ -1823,6 +1829,19 @@ func (p *Package) gccExportHeaderProlog() string {
return strings.Replace(gccExportHeaderProlog, "GOINTBITS", fmt.Sprint(8*p.IntSize), -1)
}
+// gccExportHeaderProlog is written to the exported header, after the
+// import "C" comment preamble but before the generated declarations
+// of exported functions. This permits the generated declarations to
+// use the type names that appear in goTypes, above.
+//
+// The test of GO_CGO_GOSTRING_TYPEDEF avoids a duplicate definition
+// error if a Go file with a cgo comment #include's the export header
+// generated by a different package. Unfortunately GoString means two
+// different things: in this prolog it means a C name for the Go type,
+// while in the prolog written into the start of the C code generated
+// from a cgo-using Go file it means the C.GoString function. There is
+// no way to resolve this conflict, but it also doesn't make much
+// difference, as Go code never wants to refer to the latter meaning.
const gccExportHeaderProlog = `
/* Start of boilerplate cgo prologue. */
#line 1 "cgo-gcc-export-header-prolog"
@@ -1852,7 +1871,9 @@ typedef double _Complex GoComplex128;
*/
typedef char _check_for_GOINTBITS_bit_pointer_matching_GoInt[sizeof(void*)==GOINTBITS/8 ? 1:-1];
+#ifndef GO_CGO_GOSTRING_TYPEDEF
typedef _GoString_ GoString;
+#endif
typedef void *GoMap;
typedef void *GoChan;
typedef struct { void *t; void *v; } GoInterface;