llgo/ssa: vkFuncDecl/vkFuncPtr/vkClosure
This commit is contained in:
61
ssa/type.go
61
ssa/type.go
@@ -40,12 +40,17 @@ const (
|
||||
vkString
|
||||
vkBool
|
||||
vkPtr
|
||||
vkFunc
|
||||
vkFuncDecl // func decl
|
||||
vkFuncPtr // func ptr in C
|
||||
vkClosure // func ptr in Go
|
||||
vkTuple
|
||||
vkDelayExpr = -1
|
||||
vkPhisExpr = -2
|
||||
)
|
||||
|
||||
// CFuncPtr represents a C function pointer.
|
||||
type CFuncPtr types.Signature
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
const (
|
||||
@@ -97,10 +102,17 @@ func methodToFunc(sig *types.Signature) *types.Signature {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// CType convert a cdecl type into Go type.
|
||||
func CType(typ types.Type) types.Type {
|
||||
panic("todo")
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
type aType struct {
|
||||
ll llvm.Type
|
||||
t types.Type
|
||||
kind valueKind
|
||||
kind valueKind // value kind of llvm.Type
|
||||
}
|
||||
|
||||
type Type = *aType
|
||||
@@ -128,9 +140,11 @@ func (p Program) Field(typ Type, i int) Type {
|
||||
}
|
||||
|
||||
func (p Program) Type(typ types.Type) Type {
|
||||
/* TODO(xsw): no need?
|
||||
if sig, ok := typ.(*types.Signature); ok { // should methodToFunc
|
||||
return p.llvmSignature(sig, true)
|
||||
}
|
||||
*/
|
||||
if v := p.typs.At(typ); v != nil {
|
||||
return v.(Type)
|
||||
}
|
||||
@@ -139,14 +153,9 @@ func (p Program) Type(typ types.Type) Type {
|
||||
return ret
|
||||
}
|
||||
|
||||
func (p Program) llvmSignature(sig *types.Signature, isPtr bool) Type {
|
||||
func (p Program) llvmFuncDecl(sig *types.Signature) Type {
|
||||
sig = methodToFunc(sig)
|
||||
if v := p.typs.At(sig); v != nil {
|
||||
return v.(Type)
|
||||
}
|
||||
ret := p.toLLVMFunc(sig, isPtr)
|
||||
p.typs.Set(sig, ret)
|
||||
return ret
|
||||
return p.toLLVMFunc(sig, false, true) // don't save func decl to cache
|
||||
}
|
||||
|
||||
func (p Program) tyVoidPtr() llvm.Type {
|
||||
@@ -262,6 +271,8 @@ func (p Program) toLLVMType(typ types.Type) Type {
|
||||
return p.toLLVMStruct(t)
|
||||
case *types.Named:
|
||||
return p.toLLVMNamed(t)
|
||||
case *types.Signature:
|
||||
return p.toLLVMFunc(t, false, false)
|
||||
case *types.Array:
|
||||
elem := p.Type(t.Elem())
|
||||
return &aType{llvm.ArrayType(elem.ll, int(t.Len())), typ, vkInvalid}
|
||||
@@ -307,12 +318,17 @@ func (p Program) toLLVMTypes(t *types.Tuple, n int) (ret []llvm.Type) {
|
||||
return
|
||||
}
|
||||
|
||||
func (p Program) toLLVMFunc(sig *types.Signature, isPtr bool) Type {
|
||||
func (p Program) toLLVMFunc(sig *types.Signature, inC, isDecl bool) Type {
|
||||
var hasVArg bool
|
||||
var kind valueKind
|
||||
var ft llvm.Type
|
||||
tParams := sig.Params()
|
||||
n := tParams.Len()
|
||||
hasVArg := HasVArg(tParams, n)
|
||||
if hasVArg {
|
||||
n--
|
||||
if inC {
|
||||
hasVArg = HasVArg(tParams, n)
|
||||
if hasVArg {
|
||||
n--
|
||||
}
|
||||
}
|
||||
params := p.toLLVMTypes(tParams, n)
|
||||
out := sig.Results()
|
||||
@@ -325,11 +341,19 @@ func (p Program) toLLVMFunc(sig *types.Signature, isPtr bool) Type {
|
||||
default:
|
||||
ret = p.toLLVMTuple(out)
|
||||
}
|
||||
ft := llvm.FunctionType(ret, params, hasVArg)
|
||||
if isPtr {
|
||||
ft = llvm.PointerType(ft, 0)
|
||||
if inC || isDecl {
|
||||
ft = llvm.FunctionType(ret, params, hasVArg)
|
||||
if isDecl {
|
||||
kind = vkFuncDecl
|
||||
} else {
|
||||
ft = llvm.PointerType(ft, 0)
|
||||
kind = vkFuncPtr
|
||||
}
|
||||
} else {
|
||||
ft = p.rtClosure()
|
||||
kind = vkClosure
|
||||
}
|
||||
return &aType{ft, sig, vkFunc}
|
||||
return &aType{ft, sig, kind}
|
||||
}
|
||||
|
||||
func (p Program) retType(sig *types.Signature) Type {
|
||||
@@ -349,6 +373,9 @@ func (p Program) toLLVMNamed(typ *types.Named) Type {
|
||||
case *types.Struct:
|
||||
name := NameOf(typ)
|
||||
return &aType{p.toLLVMNamedStruct(name, t), typ, vkInvalid}
|
||||
case *types.Signature:
|
||||
inC := true // TODO(xsw): how to check in C
|
||||
return p.toLLVMFunc(t, inC, false)
|
||||
default:
|
||||
return p.Type(t)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user