cl: _testdata/ptrmthd

This commit is contained in:
xushiwei
2024-04-26 00:31:02 +08:00
parent 87b7ecd1d6
commit 28dd34a136
6 changed files with 178 additions and 25 deletions

View File

@@ -33,6 +33,13 @@ _llgo_0:
ret i64 %2
}
define i64 @"(*main.T).Add"(ptr %0, i64 %1) {
_llgo_0:
%2 = load i64, ptr %0, align 4
%3 = call i64 @"(main.T).Add"(i64 %2, i64 %1)
ret i64 %3
}
declare void @printf(ptr, ...)
define void @main() {

View File

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

View File

@@ -0,0 +1,43 @@
; 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
}
declare void @printf(ptr, ...)
define void @"(*main.T).Print"(ptr %0, i64 %1) {
_llgo_0:
call void (ptr, ...) @printf(ptr %0, i64 %1)
ret void
}
define void @main() {
_llgo_0:
call void @main.init()
call void @"(*main.T).Print"(ptr @main.format, i64 100)
ret void
}

View File

@@ -109,12 +109,17 @@ func (p *context) compileType(pkg llssa.Package, t *ssa.Type) {
if debugInstr {
log.Println("==> NewType", name, typ)
}
p.compileMethods(pkg, typ)
p.compileMethods(pkg, types.NewPointer(typ))
}
func (p *context) compileMethods(pkg llssa.Package, typ types.Type) {
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)
p.compileFunc(pkg, mthd.Obj().Pkg(), ssaMthd)
}
}
@@ -129,17 +134,18 @@ func (p *context) compileGlobal(pkg llssa.Package, gbl *ssa.Global) {
g.Init(p.prog.Null(g.Type))
}
func (p *context) compileFunc(pkg llssa.Package, f *ssa.Function) {
name := p.funcName(f.Pkg.Pkg, f)
func (p *context) compileFunc(pkg llssa.Package, pkgTypes *types.Package, f *ssa.Function) {
sig := f.Signature
name := p.funcName(pkgTypes, f)
/* TODO(xsw): confirm this is not needed more
if name == "unsafe.init" {
return
}
*/
if debugInstr {
log.Println("==> NewFunc", name, f.Signature)
log.Println("==> NewFunc", name, "type:", sig.Recv(), sig)
}
fn := pkg.NewFunc(name, f.Signature)
fn := pkg.NewFunc(name, sig)
p.inits = append(p.inits, func() {
p.fn = fn
defer func() {
@@ -221,16 +227,29 @@ func (p *context) compileInstrAndValue(b llssa.Builder, iv instrAndValue) (ret l
switch v := iv.(type) {
case *ssa.Call:
call := v.Call
kind := funcKind(call.Value)
cv := call.Value
kind := funcKind(cv)
if kind == fnUnsafeInit {
return
}
if debugGoSSA {
log.Println(">>> Call", call.Value, call.Args)
log.Println(">>> Call", cv, call.Args)
}
if builtin, ok := cv.(*ssa.Builtin); ok {
fn := builtin.Name()
if fn == "ssa:wrapnilchk" { // TODO(xsw): check nil ptr
arg := call.Args[0]
ret = p.compileValue(b, arg)
// log.Println("wrapnilchk:", ret.TypeOf())
} else {
args := p.compileValues(b, call.Args, kind)
ret = b.BuiltinCall(fn, args...)
}
} else {
fn := p.compileValue(b, cv)
args := p.compileValues(b, call.Args, kind)
ret = b.Call(fn, args...)
}
fn := p.compileValue(b, call.Value)
args := p.compileValues(b, call.Args, kind)
ret = b.Call(fn, args...)
case *ssa.BinOp:
x := p.compileValue(b, v.X)
y := p.compileValue(b, v.Y)
@@ -238,6 +257,10 @@ func (p *context) compileInstrAndValue(b llssa.Builder, iv instrAndValue) (ret l
case *ssa.UnOp:
x := p.compileValue(b, v.X)
ret = b.UnOp(v.Op, x)
case *ssa.ChangeType:
t := v.Type()
x := p.compileValue(b, v.X)
ret = b.ChangeType(p.prog.Type(t), x)
case *ssa.IndexAddr:
vx := v.X
if _, ok := p.isVArgs(vx); ok { // varargs: this is a varargs index
@@ -418,7 +441,7 @@ func NewPackage(prog llssa.Program, pkg *ssa.Package, files []*ast.File) (ret ll
// Do not try to build generic (non-instantiated) functions.
continue
}
ctx.compileFunc(ret, member)
ctx.compileFunc(ret, member.Pkg.Pkg, member)
case *ssa.Type:
ctx.compileType(ret, member)
case *ssa.Global: