cl: _testdata/method
This commit is contained in:
19
cl/_testdata/method/in.go
Normal file
19
cl/_testdata/method/in.go
Normal 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))
|
||||
}
|
||||
44
cl/_testdata/method/out.ll
Normal file
44
cl/_testdata/method/out.ll
Normal 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
|
||||
}
|
||||
@@ -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),
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user