cl: _testdata/method

This commit is contained in:
xushiwei
2024-04-25 21:44:23 +08:00
parent 0f00add402
commit 87b7ecd1d6
7 changed files with 115 additions and 15 deletions

19
cl/_testdata/method/in.go Normal file
View File

@@ -0,0 +1,19 @@
package main
import _ "unsafe"
type T int
func (a T) Add(b T) T {
return a + b
}
//go:linkname printf printf
func printf(format *int8, __llgo_va_list ...any)
var format = [...]int8{'H', 'e', 'l', 'l', 'o', ' ', '%', 'd', '\n', 0}
func main() {
a := T(1)
printf(&format[0], a.Add(2))
}

View File

@@ -0,0 +1,44 @@
; ModuleID = 'main'
source_filename = "main"
@"main.init$guard" = global ptr null
@main.format = global ptr null
define void @main.init() {
_llgo_0:
%0 = load i1, ptr @"main.init$guard", align 1
br i1 %0, label %_llgo_2, label %_llgo_1
_llgo_1: ; preds = %_llgo_0
store i1 true, ptr @"main.init$guard", align 1
store i8 72, ptr @main.format, align 1
store i8 101, ptr getelementptr inbounds (i8, ptr @main.format, i64 1), align 1
store i8 108, ptr getelementptr inbounds (i8, ptr @main.format, i64 2), align 1
store i8 108, ptr getelementptr inbounds (i8, ptr @main.format, i64 3), align 1
store i8 111, ptr getelementptr inbounds (i8, ptr @main.format, i64 4), align 1
store i8 32, ptr getelementptr inbounds (i8, ptr @main.format, i64 5), align 1
store i8 37, ptr getelementptr inbounds (i8, ptr @main.format, i64 6), align 1
store i8 100, ptr getelementptr inbounds (i8, ptr @main.format, i64 7), align 1
store i8 10, ptr getelementptr inbounds (i8, ptr @main.format, i64 8), align 1
store i8 0, ptr getelementptr inbounds (i8, ptr @main.format, i64 9), align 1
br label %_llgo_2
_llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void
}
define i64 @"(main.T).Add"(i64 %0, i64 %1) {
_llgo_0:
%2 = add i64 %0, %1
ret i64 %2
}
declare void @printf(ptr, ...)
define void @main() {
_llgo_0:
call void @main.init()
%0 = call i64 @"(main.T).Add"(i64 1, i64 2)
call void (ptr, ...) @printf(ptr @main.format, i64 %0)
ret void
}

View File

@@ -92,6 +92,7 @@ type context struct {
pkg llssa.Package
fn llssa.Function
fset *token.FileSet
goProg *ssa.Program
goTyps *types.Package
goPkg *ssa.Package
link map[string]string // pkgPath.nameInPkg => linkname
@@ -101,8 +102,20 @@ type context struct {
inits []func()
}
func (p *context) compileType(pkg llssa.Package, member *ssa.Type) {
panic("todo")
func (p *context) compileType(pkg llssa.Package, t *ssa.Type) {
tn := t.Object().(*types.TypeName)
typ := tn.Type()
name := fullName(tn.Pkg(), tn.Name())
if debugInstr {
log.Println("==> NewType", name, typ)
}
prog := p.goProg
mthds := prog.MethodSets.MethodSet(typ)
for i, n := 0, mthds.Len(); i < n; i++ {
mthd := mthds.At(i)
ssaMthd := prog.MethodValue(mthd)
p.compileFunc(pkg, ssaMthd)
}
}
// Global variable.
@@ -118,11 +131,13 @@ func (p *context) compileGlobal(pkg llssa.Package, gbl *ssa.Global) {
func (p *context) compileFunc(pkg llssa.Package, f *ssa.Function) {
name := p.funcName(f.Pkg.Pkg, f)
/* TODO(xsw): confirm this is not needed more
if name == "unsafe.init" {
return
}
*/
if debugInstr {
log.Println("==> NewFunc", name)
log.Println("==> NewFunc", name, f.Signature)
}
fn := pkg.NewFunc(name, f.Signature)
p.inits = append(p.inits, func() {
@@ -378,6 +393,7 @@ func NewPackage(prog llssa.Program, pkg *ssa.Package, files []*ast.File) (ret ll
return iPos < jPos
})
pkgProg := pkg.Prog
pkgTypes := pkg.Pkg
pkgName, pkgPath := pkgTypes.Name(), pathOf(pkgTypes)
ret = prog.NewPackage(pkgName, pkgPath)
@@ -385,7 +401,8 @@ func NewPackage(prog llssa.Program, pkg *ssa.Package, files []*ast.File) (ret ll
ctx := &context{
prog: prog,
pkg: ret,
fset: pkg.Prog.Fset,
fset: pkgProg.Fset,
goProg: pkgProg,
goTyps: pkgTypes,
goPkg: pkg,
link: make(map[string]string),

View File

@@ -116,7 +116,13 @@ func fullName(pkg *types.Package, name string) string {
return pathOf(pkg) + "." + name
}
// func: pkg.name
// method: (pkg.T).name
func funcName(pkg *types.Package, fn *ssa.Function) string {
sig := fn.Signature
if recv := sig.Recv(); recv != nil {
return "(" + recv.Type().String() + ")." + fn.Name()
}
ret := fullName(pkg, fn.Name())
if ret == "main.main" {
ret = "main"