diff --git a/cl/_testrt/_intgen/in.go b/cl/_testrt/intgen/in.go similarity index 100% rename from cl/_testrt/_intgen/in.go rename to cl/_testrt/intgen/in.go diff --git a/cl/_testrt/_intgen/out.ll b/cl/_testrt/intgen/out.ll similarity index 97% rename from cl/_testrt/_intgen/out.ll rename to cl/_testrt/intgen/out.ll index 144fd31b..d3e821e2 100644 --- a/cl/_testrt/_intgen/out.ll +++ b/cl/_testrt/intgen/out.ll @@ -21,8 +21,8 @@ _llgo_1: ; preds = %_llgo_2, %_llgo_0 br i1 %8, label %_llgo_2, label %_llgo_3 _llgo_2: ; preds = %_llgo_1 - %9 = extractvalue { i32 ()*, ptr } %1, 0 - %10 = call i32 ()* %9() + %9 = extractvalue { ptr, ptr } %1, 0 + %10 = call addrspace(37) { ptr, ptr } %1() %11 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %4) %12 = getelementptr inbounds i32, ptr %11, i64 %7 store ptr %10, ptr %12, align 8 diff --git a/ssa/expr.go b/ssa/expr.go index 73e7802a..59b03cd7 100644 --- a/ssa/expr.go +++ b/ssa/expr.go @@ -1041,7 +1041,7 @@ func (b Builder) Call(fn Expr, args ...Expr) (ret Expr) { if name == "" { name = "closure" } - fmt.Fprint(&b, "Call ", fn.raw.Type, " ", name) + fmt.Fprint(&b, "Call ", fn.kind, " ", fn.raw.Type, " ", name) sep := ": " for _, arg := range args { fmt.Fprint(&b, sep, arg.impl) diff --git a/ssa/type.go b/ssa/type.go index 48470aeb..ae67cfc4 100644 --- a/ssa/type.go +++ b/ssa/type.go @@ -236,7 +236,8 @@ func (p Program) toType(raw types.Type) Type { case *types.Map: return &aType{p.rtMap(), typ, vkInvalid} case *types.Struct: - return &aType{p.toLLVMStruct(t), typ, vkInvalid} + ll, kind := p.toLLVMStruct(t) + return &aType{ll, typ, kind} case *types.Named: return p.toNamed(t) case *types.Signature: // represents a C function pointer in raw type @@ -256,9 +257,23 @@ func (p Program) toLLVMNamedStruct(name string, raw *types.Struct) llvm.Type { return t } -func (p Program) toLLVMStruct(raw *types.Struct) llvm.Type { +func (p Program) toLLVMStruct(raw *types.Struct) (ret llvm.Type, kind valueKind) { fields := p.toLLVMFields(raw) - return p.ctx.StructType(fields, false) + ret = p.ctx.StructType(fields, false) + if isClosure(raw) { + kind = vkClosure + } + return +} + +func isClosure(raw *types.Struct) bool { + n := raw.NumFields() + if n == 2 { + if _, ok := raw.Field(0).Type().(*types.Signature); ok { + return raw.Field(1).Type() == types.Typ[types.UnsafePointer] + } + } + return false } func (p Program) toLLVMFields(raw *types.Struct) (fields []llvm.Type) {