diff options
author | Ayke van Laethem <[email protected]> | 2021-11-11 14:12:38 +0100 |
---|---|---|
committer | Ron Evans <[email protected]> | 2021-11-24 21:09:29 +0100 |
commit | 1789570f52598e96b1d638b9d52910d0278b8f15 (patch) | |
tree | ba2a44866de226ea4b71a1d5045fe1e21da968d4 /cgo | |
parent | a536ddcda8025233ad093f5f76d9d728ab67fa3f (diff) | |
download | tinygo-1789570f52598e96b1d638b9d52910d0278b8f15.tar.gz tinygo-1789570f52598e96b1d638b9d52910d0278b8f15.zip |
cgo: add //go: pragmas to generated functions and globals
This patch adds //go: pragmas directly to declared functions and
globals found during CGo processing. This simplifies the logic in the
compiler: it no longer has to consider special "C." prefixed function
names. It also makes the cgo pass more flexible in the pragmas it emits
for functions and global variables.
Diffstat (limited to 'cgo')
-rw-r--r-- | cgo/cgo.go | 32 | ||||
-rw-r--r-- | cgo/cgo_test.go | 9 | ||||
-rw-r--r-- | cgo/testdata/symbols.go | 23 | ||||
-rw-r--r-- | cgo/testdata/symbols.out.go | 44 | ||||
-rw-r--r-- | cgo/testdata/types.go | 10 | ||||
-rw-r--r-- | cgo/testdata/types.out.go | 5 |
6 files changed, 97 insertions, 26 deletions
diff --git a/cgo/cgo.go b/cgo/cgo.go index dc1173962..defae0bca 100644 --- a/cgo/cgo.go +++ b/cgo/cgo.go @@ -496,6 +496,14 @@ func (p *cgoPackage) addFuncDecls() { } args := make([]*ast.Field, len(fn.args)) decl := &ast.FuncDecl{ + Doc: &ast.CommentGroup{ + List: []*ast.Comment{ + { + Slash: fn.pos - 1, + Text: "//export " + name, + }, + }, + }, Name: &ast.Ident{ NamePos: fn.pos, Name: "C." + name, @@ -512,14 +520,10 @@ func (p *cgoPackage) addFuncDecls() { }, } if fn.variadic { - decl.Doc = &ast.CommentGroup{ - List: []*ast.Comment{ - { - Slash: fn.pos, - Text: "//go:variadic", - }, - }, - } + decl.Doc.List = append(decl.Doc.List, &ast.Comment{ + Slash: fn.pos - 1, + Text: "//go:variadic", + }) } obj.Decl = decl for i, arg := range fn.args { @@ -652,13 +656,21 @@ func (p *cgoPackage) addVarDecls() { } sort.Strings(names) for _, name := range names { + global := p.globals[name] gen := &ast.GenDecl{ - TokPos: token.NoPos, + TokPos: global.pos, Tok: token.VAR, Lparen: token.NoPos, Rparen: token.NoPos, + Doc: &ast.CommentGroup{ + List: []*ast.Comment{ + { + Slash: global.pos - 1, + Text: "//go:extern " + name, + }, + }, + }, } - global := p.globals[name] obj := &ast.Object{ Kind: ast.Var, Name: "C." + name, diff --git a/cgo/cgo_test.go b/cgo/cgo_test.go index a50437120..b46c36dd6 100644 --- a/cgo/cgo_test.go +++ b/cgo/cgo_test.go @@ -30,7 +30,14 @@ func normalizeResult(result string) string { func TestCGo(t *testing.T) { var cflags = []string{"--target=armv6m-unknown-unknown-eabi"} - for _, name := range []string{"basic", "errors", "types", "flags", "const"} { + for _, name := range []string{ + "basic", + "errors", + "types", + "symbols", + "flags", + "const", + } { name := name // avoid a race condition t.Run(name, func(t *testing.T) { // Skip tests that require specific Go version. diff --git a/cgo/testdata/symbols.go b/cgo/testdata/symbols.go new file mode 100644 index 000000000..c724cd921 --- /dev/null +++ b/cgo/testdata/symbols.go @@ -0,0 +1,23 @@ +package main + +/* +// Function signatures. +int foo(int a, int b); +void variadic0(); +void variadic2(int x, int y, ...); + +// Global variable signatures. +extern int someValue; +*/ +import "C" + +// Test function signatures. +func accessFunctions() { + C.foo(3, 4) + C.variadic0() + C.variadic2(3, 5) +} + +func accessGlobals() { + _ = C.someValue +} diff --git a/cgo/testdata/symbols.out.go b/cgo/testdata/symbols.out.go new file mode 100644 index 000000000..97a9522b7 --- /dev/null +++ b/cgo/testdata/symbols.out.go @@ -0,0 +1,44 @@ +package main + +import "unsafe" + +var _ unsafe.Pointer + +//export foo +func C.foo(a C.int, b C.int) C.int + +//export variadic0 +//go:variadic +func C.variadic0() + +//export variadic2 +//go:variadic +func C.variadic2(x C.int, y C.int) + +var C.foo$funcaddr unsafe.Pointer +var C.variadic0$funcaddr unsafe.Pointer +var C.variadic2$funcaddr unsafe.Pointer + +//go:extern someValue +var C.someValue C.int + +type C.int16_t = int16 +type C.int32_t = int32 +type C.int64_t = int64 +type C.int8_t = int8 +type C.uint16_t = uint16 +type C.uint32_t = uint32 +type C.uint64_t = uint64 +type C.uint8_t = uint8 +type C.uintptr_t = uintptr +type C.char uint8 +type C.int int32 +type C.long int32 +type C.longlong int64 +type C.schar int8 +type C.short int16 +type C.uchar uint8 +type C.uint uint32 +type C.ulong uint32 +type C.ulonglong uint64 +type C.ushort uint16 diff --git a/cgo/testdata/types.go b/cgo/testdata/types.go index 42bd61369..50d5b8b66 100644 --- a/cgo/testdata/types.go +++ b/cgo/testdata/types.go @@ -104,10 +104,6 @@ typedef struct { unsigned char e : 3; // Note that C++ allows bitfields bigger than the underlying type. } bitfield_t; - -// Function signatures. -void variadic0(); -void variadic2(int x, int y, ...); */ import "C" @@ -171,9 +167,3 @@ func accessUnion() { var _ *C.int = union2d.unionfield_i() var _ *[2]float64 = union2d.unionfield_d() } - -// Test function signatures. -func accessFunctions() { - C.variadic0() - C.variadic2(3, 5) -} diff --git a/cgo/testdata/types.out.go b/cgo/testdata/types.out.go index c89e9b005..1864e33f5 100644 --- a/cgo/testdata/types.out.go +++ b/cgo/testdata/types.out.go @@ -4,11 +4,6 @@ import "unsafe" var _ unsafe.Pointer -func C.variadic0() //go:variadic -func C.variadic2(x C.int, y C.int) //go:variadic -var C.variadic0$funcaddr unsafe.Pointer -var C.variadic2$funcaddr unsafe.Pointer - const C.option2A = 20 const C.optionA = 0 const C.optionB = 1 |