cl: funcOf; use gogen/packages.Importer
This commit is contained in:
9
cl/_testdata/_importpkg/in.go
Normal file
9
cl/_testdata/_importpkg/in.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "github.com/goplus/llgo/cl/internal/stdio"
|
||||||
|
|
||||||
|
var hello = [...]int8{'H', 'e', 'l', 'l', 'o', '\n', 0}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
stdio.Printf(&hello[0])
|
||||||
|
}
|
||||||
0
cl/_testdata/_importpkg/out.ll
Normal file
0
cl/_testdata/_importpkg/out.ll
Normal file
@@ -59,14 +59,15 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func funcKind(vfn ssa.Value) int {
|
func funcKind(vfn ssa.Value) int {
|
||||||
if fn, ok := vfn.(*ssa.Function); ok {
|
if fn, ok := vfn.(*ssa.Function); ok && fn.Signature.Recv() == nil {
|
||||||
n := len(fn.Params)
|
params := fn.Signature.Params()
|
||||||
|
n := params.Len()
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
if fn.Name() == "init" && fn.Pkg.Pkg.Path() == "unsafe" {
|
if fn.Name() == "init" && fn.Pkg.Pkg.Path() == "unsafe" {
|
||||||
return fnUnsafeInit
|
return fnUnsafeInit
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
last := fn.Params[n-1]
|
last := params.At(n - 1)
|
||||||
if last.Name() == llssa.NameValist {
|
if last.Name() == llssa.NameValist {
|
||||||
return fnHasVArg
|
return fnHasVArg
|
||||||
}
|
}
|
||||||
@@ -135,6 +136,15 @@ func (p *context) funcName(fn *ssa.Function) string {
|
|||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *context) funcOf(fn *ssa.Function) llssa.Function {
|
||||||
|
pkg := p.pkg
|
||||||
|
name := p.funcName(fn)
|
||||||
|
if ret := pkg.FuncOf(name); ret != nil {
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
return pkg.NewFunc(name, fn.Signature) // TODO: support linkname
|
||||||
|
}
|
||||||
|
|
||||||
func (p *context) compileType(pkg llssa.Package, member *ssa.Type) {
|
func (p *context) compileType(pkg llssa.Package, member *ssa.Type) {
|
||||||
panic("todo")
|
panic("todo")
|
||||||
}
|
}
|
||||||
@@ -279,10 +289,7 @@ func (p *context) compileValue(b llssa.Builder, v ssa.Value) llssa.Expr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case *ssa.Function:
|
case *ssa.Function:
|
||||||
if v.Pkg != p.goPkg {
|
fn := p.funcOf(v)
|
||||||
panic("todo")
|
|
||||||
}
|
|
||||||
fn := p.pkg.FuncOf(p.funcName(v))
|
|
||||||
return fn.Expr
|
return fn.Expr
|
||||||
case *ssa.Global:
|
case *ssa.Global:
|
||||||
if v.Pkg != p.goPkg {
|
if v.Pkg != p.goPkg {
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ package cl
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/importer"
|
|
||||||
"go/parser"
|
"go/parser"
|
||||||
"go/token"
|
"go/token"
|
||||||
"go/types"
|
"go/types"
|
||||||
@@ -28,9 +27,11 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
llssa "github.com/goplus/llgo/ssa"
|
"github.com/goplus/gogen/packages"
|
||||||
"golang.org/x/tools/go/ssa"
|
"golang.org/x/tools/go/ssa"
|
||||||
"golang.org/x/tools/go/ssa/ssautil"
|
"golang.org/x/tools/go/ssa/ssautil"
|
||||||
|
|
||||||
|
llssa "github.com/goplus/llgo/ssa"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestFromTestdata(t *testing.T) {
|
func TestFromTestdata(t *testing.T) {
|
||||||
@@ -88,8 +89,9 @@ func testCompileEx(t *testing.T, src any, fname, expected string) {
|
|||||||
files := []*ast.File{f}
|
files := []*ast.File{f}
|
||||||
name := f.Name.Name
|
name := f.Name.Name
|
||||||
pkg := types.NewPackage(name, name)
|
pkg := types.NewPackage(name, name)
|
||||||
|
imp := packages.NewImporter(fset)
|
||||||
foo, _, err := ssautil.BuildPackage(
|
foo, _, err := ssautil.BuildPackage(
|
||||||
&types.Config{Importer: importer.Default()}, fset, pkg, files, ssa.SanityCheckFunctions)
|
&types.Config{Importer: imp}, fset, pkg, files, ssa.SanityCheckFunctions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("BuildPackage failed:", err)
|
t.Fatal("BuildPackage failed:", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,5 +2,5 @@ package stdio
|
|||||||
|
|
||||||
import _ "unsafe"
|
import _ "unsafe"
|
||||||
|
|
||||||
//go:linkname printf printf
|
//go:linkname Printf printf
|
||||||
func printf(format *int8, __llgo_va_list ...any)
|
func Printf(format *int8, __llgo_va_list ...any)
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -4,6 +4,7 @@ go 1.18
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/aykevl/go-wasm v0.0.1
|
github.com/aykevl/go-wasm v0.0.1
|
||||||
|
github.com/goplus/gogen v1.15.2
|
||||||
github.com/goplus/gop v1.2.6
|
github.com/goplus/gop v1.2.6
|
||||||
github.com/goplus/llvm v0.7.1-0.20240420180312-6230a4ea7a47
|
github.com/goplus/llvm v0.7.1-0.20240420180312-6230a4ea7a47
|
||||||
github.com/qiniu/x v1.13.10
|
github.com/qiniu/x v1.13.10
|
||||||
@@ -11,7 +12,6 @@ require (
|
|||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/goplus/gogen v1.15.2 // indirect
|
|
||||||
github.com/goplus/mod v0.13.10 // indirect
|
github.com/goplus/mod v0.13.10 // indirect
|
||||||
golang.org/x/mod v0.17.0 // indirect
|
golang.org/x/mod v0.17.0 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -87,6 +87,9 @@ func TestNamedStruct(t *testing.T) {
|
|||||||
prog := NewProgram(nil)
|
prog := NewProgram(nil)
|
||||||
pkg := prog.NewPackage("bar", "foo/bar")
|
pkg := prog.NewPackage("bar", "foo/bar")
|
||||||
pkg.NewVar("a", empty)
|
pkg.NewVar("a", empty)
|
||||||
|
if pkg.VarOf("a") == nil {
|
||||||
|
t.Fatal("VarOf failed")
|
||||||
|
}
|
||||||
assertPkg(t, pkg, `; ModuleID = 'foo/bar'
|
assertPkg(t, pkg, `; ModuleID = 'foo/bar'
|
||||||
source_filename = "foo/bar"
|
source_filename = "foo/bar"
|
||||||
|
|
||||||
@@ -102,6 +105,12 @@ func TestDeclFunc(t *testing.T) {
|
|||||||
params := types.NewTuple(types.NewVar(0, nil, "a", types.Typ[types.Int]))
|
params := types.NewTuple(types.NewVar(0, nil, "a", types.Typ[types.Int]))
|
||||||
sig := types.NewSignatureType(nil, nil, nil, params, nil, false)
|
sig := types.NewSignatureType(nil, nil, nil, params, nil, false)
|
||||||
pkg.NewFunc("fn", sig)
|
pkg.NewFunc("fn", sig)
|
||||||
|
if pkg.FuncOf("fn") == nil {
|
||||||
|
t.Fatal("FuncOf failed")
|
||||||
|
}
|
||||||
|
if prog.retType(sig) != prog.Void() {
|
||||||
|
t.Fatal("retType failed")
|
||||||
|
}
|
||||||
assertPkg(t, pkg, `; ModuleID = 'foo/bar'
|
assertPkg(t, pkg, `; ModuleID = 'foo/bar'
|
||||||
source_filename = "foo/bar"
|
source_filename = "foo/bar"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user