Set internal linkage and keeping default visibility for anonymous functions
Этот коммит содержится в:
родитель
25c8d3ec3a
коммит
05cdde162c
10 изменённых файлов: 123 добавлений и 9 удалений
|
@ -1039,9 +1039,17 @@ func (b *builder) createFunctionStart() {
|
|||
b.addError(b.fn.Pos(), errValue)
|
||||
return
|
||||
}
|
||||
|
||||
b.addStandardDefinedAttributes(b.llvmFn)
|
||||
if !b.info.exported {
|
||||
b.llvmFn.SetVisibility(llvm.HiddenVisibility)
|
||||
// Do not set visibility for local linkage (internal or private).
|
||||
// Otherwise a "local linkage requires default visibility"
|
||||
// assertion error in llvm-project/llvm/include/llvm/IR/GlobalValue.h:236
|
||||
// is thrown.
|
||||
if b.llvmFn.Linkage() != llvm.InternalLinkage &&
|
||||
b.llvmFn.Linkage() != llvm.PrivateLinkage {
|
||||
b.llvmFn.SetVisibility(llvm.HiddenVisibility)
|
||||
}
|
||||
b.llvmFn.SetUnnamedAddr(true)
|
||||
}
|
||||
if b.info.section != "" {
|
||||
|
@ -1265,6 +1273,7 @@ func (b *builder) createFunction() {
|
|||
// Create anonymous functions (closures etc.).
|
||||
for _, sub := range b.fn.AnonFuncs {
|
||||
b := newBuilder(b.compilerContext, b.Builder, sub)
|
||||
b.llvmFn.SetLinkage(llvm.InternalLinkage)
|
||||
b.createFunction()
|
||||
}
|
||||
}
|
||||
|
|
2
compiler/testdata/basic.ll
предоставленный
2
compiler/testdata/basic.ll
предоставленный
|
@ -196,7 +196,7 @@ entry:
|
|||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @"main.foo$1"(%main.kv.0* dereferenceable_or_null(1) %b, i8* %context) unnamed_addr #1 {
|
||||
define internal void @"main.foo$1"(%main.kv.0* dereferenceable_or_null(1) %b, i8* %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
|
6
compiler/testdata/defer-cortex-m-qemu.ll
предоставленный
6
compiler/testdata/defer-cortex-m-qemu.ll
предоставленный
|
@ -115,7 +115,7 @@ declare i8* @llvm.stacksave() #2
|
|||
declare void @runtime.setupDeferFrame(%runtime.deferFrame* dereferenceable_or_null(24), i8*, i8*) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @"main.deferSimple$1"(i8* %context) unnamed_addr #1 {
|
||||
define internal void @"main.deferSimple$1"(i8* %context) unnamed_addr #1 {
|
||||
entry:
|
||||
call void @runtime.printint32(i32 3, i8* undef) #3
|
||||
ret void
|
||||
|
@ -246,14 +246,14 @@ rundefers.end9: ; preds = %rundefers.loophead1
|
|||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @"main.deferMultiple$1"(i8* %context) unnamed_addr #1 {
|
||||
define internal void @"main.deferMultiple$1"(i8* %context) unnamed_addr #1 {
|
||||
entry:
|
||||
call void @runtime.printint32(i32 3, i8* undef) #3
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @"main.deferMultiple$2"(i8* %context) unnamed_addr #1 {
|
||||
define internal void @"main.deferMultiple$2"(i8* %context) unnamed_addr #1 {
|
||||
entry:
|
||||
call void @runtime.printint32(i32 5, i8* undef) #3
|
||||
ret void
|
||||
|
|
4
compiler/testdata/goroutine-cortex-m-qemu-tasks.ll
предоставленный
4
compiler/testdata/goroutine-cortex-m-qemu-tasks.ll
предоставленный
|
@ -51,7 +51,7 @@ entry:
|
|||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @"main.inlineFunctionGoroutine$1"(i32 %x, i8* %context) unnamed_addr #1 {
|
||||
define internal void @"main.inlineFunctionGoroutine$1"(i32 %x, i8* %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ entry:
|
|||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @"main.closureFunctionGoroutine$1"(i32 %x, i8* %context) unnamed_addr #1 {
|
||||
define internal void @"main.closureFunctionGoroutine$1"(i32 %x, i8* %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%unpack.ptr = bitcast i8* %context to i32*
|
||||
store i32 7, i32* %unpack.ptr, align 4
|
||||
|
|
4
compiler/testdata/goroutine-wasm-asyncify.ll
предоставленный
4
compiler/testdata/goroutine-wasm-asyncify.ll
предоставленный
|
@ -53,7 +53,7 @@ entry:
|
|||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @"main.inlineFunctionGoroutine$1"(i32 %x, i8* %context) unnamed_addr #1 {
|
||||
define internal void @"main.inlineFunctionGoroutine$1"(i32 %x, i8* %context) unnamed_addr #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ entry:
|
|||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @"main.closureFunctionGoroutine$1"(i32 %x, i8* %context) unnamed_addr #1 {
|
||||
define internal void @"main.closureFunctionGoroutine$1"(i32 %x, i8* %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%unpack.ptr = bitcast i8* %context to i32*
|
||||
store i32 7, i32* %unpack.ptr, align 4
|
||||
|
|
8
testdata/generics.go
предоставленный
8
testdata/generics.go
предоставленный
|
@ -1,11 +1,19 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/tinygo-org/tinygo/testdata/generics/testa"
|
||||
"github.com/tinygo-org/tinygo/testdata/generics/testb"
|
||||
)
|
||||
|
||||
func main() {
|
||||
println("add:", Add(3, 5))
|
||||
println("add:", Add(int8(3), 5))
|
||||
|
||||
var c C[int]
|
||||
c.F() // issue 2951
|
||||
|
||||
testa.Test()
|
||||
testb.Test()
|
||||
}
|
||||
|
||||
type Integer interface {
|
||||
|
|
4
testdata/generics.txt
предоставленный
4
testdata/generics.txt
предоставленный
|
@ -1,2 +1,6 @@
|
|||
add: 8
|
||||
add: 8
|
||||
value: 101
|
||||
value: 101
|
||||
value: 501
|
||||
value: 501
|
||||
|
|
20
testdata/generics/testa/testa.go
предоставленный
Обычный файл
20
testdata/generics/testa/testa.go
предоставленный
Обычный файл
|
@ -0,0 +1,20 @@
|
|||
package testa
|
||||
|
||||
import (
|
||||
"github.com/tinygo-org/tinygo/testdata/generics/value"
|
||||
)
|
||||
|
||||
func Test() {
|
||||
v := value.New(1)
|
||||
vm := value.Map(v, Plus100)
|
||||
vm.Get(callback, callback)
|
||||
}
|
||||
|
||||
func callback(v int) {
|
||||
println("value:", v)
|
||||
}
|
||||
|
||||
// Plus100 is a `Transform` that adds 100 to `value`.
|
||||
func Plus100(value int) int {
|
||||
return value + 100
|
||||
}
|
20
testdata/generics/testb/testb.go
предоставленный
Обычный файл
20
testdata/generics/testb/testb.go
предоставленный
Обычный файл
|
@ -0,0 +1,20 @@
|
|||
package testb
|
||||
|
||||
import (
|
||||
"github.com/tinygo-org/tinygo/testdata/generics/value"
|
||||
)
|
||||
|
||||
func Test() {
|
||||
v := value.New(1)
|
||||
vm := value.Map(v, Plus500)
|
||||
vm.Get(callback, callback)
|
||||
}
|
||||
|
||||
func callback(v int) {
|
||||
println("value:", v)
|
||||
}
|
||||
|
||||
// Plus500 is a `Transform` that adds 500 to `value`.
|
||||
func Plus500(value int) int {
|
||||
return value + 500
|
||||
}
|
53
testdata/generics/value/value.go
предоставленный
Обычный файл
53
testdata/generics/value/value.go
предоставленный
Обычный файл
|
@ -0,0 +1,53 @@
|
|||
package value
|
||||
|
||||
type (
|
||||
Value[T any] interface {
|
||||
Get(Callback[T], Callback[T])
|
||||
}
|
||||
|
||||
Callback[T any] func(T)
|
||||
|
||||
Transform[S any, D any] func(S) D
|
||||
)
|
||||
|
||||
func New[T any](v T) Value[T] {
|
||||
return &value[T]{
|
||||
v: v,
|
||||
}
|
||||
}
|
||||
|
||||
type value[T any] struct {
|
||||
v T
|
||||
}
|
||||
|
||||
func (v *value[T]) Get(fn1, fn2 Callback[T]) {
|
||||
// For example purposes.
|
||||
// Normally would be asynchronous callback.
|
||||
fn1(v.v)
|
||||
fn2(v.v)
|
||||
}
|
||||
|
||||
func Map[S, D any](v Value[S], tx Transform[S, D]) Value[D] {
|
||||
return &mapper[S, D]{
|
||||
v: v,
|
||||
tx: tx,
|
||||
}
|
||||
}
|
||||
|
||||
type mapper[S, D any] struct {
|
||||
v Value[S]
|
||||
tx Transform[S, D]
|
||||
}
|
||||
|
||||
func (m *mapper[S, D]) Get(fn1, fn2 Callback[D]) {
|
||||
// two callbacks are passed to generate more than
|
||||
// one anonymous function symbol name.
|
||||
m.v.Get(func(v S) {
|
||||
// anonymous function inside of anonymous function.
|
||||
func() {
|
||||
fn1(m.tx(v))
|
||||
}()
|
||||
}, func(v S) {
|
||||
fn2(m.tx(v))
|
||||
})
|
||||
}
|
Загрузка…
Создание таблицы
Сослаться в новой задаче