diff --git a/cl/compile.go b/cl/compile.go index 917335dc..e9f7bbd3 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -177,15 +177,18 @@ func (p *context) compileMethods(pkg llssa.Package, typ types.Type) { // Global variable. func (p *context) compileGlobal(pkg llssa.Package, gbl *ssa.Global) { typ := gbl.Type() - name, isDef := p.varName(gbl.Pkg.Pkg, gbl) + name, vtype := p.varName(gbl.Pkg.Pkg, gbl) if ignoreName(name) || checkCgo(gbl.Name()) { return } if debugInstr { log.Println("==> NewVar", name, typ) } + if vtype == cVar { + typ = llssa.CType(typ) + } g := pkg.NewVar(name, typ) - if isDef { + if vtype == goVar { g.Init(p.prog.Null(g.Type)) } } @@ -200,6 +203,9 @@ func (p *context) compileFunc(pkg llssa.Package, pkgTypes *types.Package, f *ssa if debugInstr { log.Println("==> NewFunc", name, "type:", sig.Recv(), sig) } + if ftype == cFunc { + sig = llssa.CFuncDecl(sig) + } fn := pkg.NewFunc(name, sig) p.inits = append(p.inits, func() { p.fn = fn diff --git a/cl/import.go b/cl/import.go index e02e5d34..463988eb 100644 --- a/cl/import.go +++ b/cl/import.go @@ -220,12 +220,18 @@ func (p *context) funcName(pkg *types.Package, fn *ssa.Function, ignore bool) (s return name, goFunc } -func (p *context) varName(pkg *types.Package, v *ssa.Global) (vName string, isDef bool) { +const ( + ignoredVar = iota + goVar + cVar +) + +func (p *context) varName(pkg *types.Package, v *ssa.Global) (vName string, vtype int) { name := llssa.FullName(pkg, v.Name()) if v, ok := p.link[name]; ok { - return v, false + return v, cVar } - return name, true + return name, goVar } // funcOf returns a function by name and set ftype = goFunc, cFunc, etc. diff --git a/ssa/type.go b/ssa/type.go index d2e764e2..c87618e0 100644 --- a/ssa/type.go +++ b/ssa/type.go @@ -102,11 +102,16 @@ func methodToFunc(sig *types.Signature) *types.Signature { // ----------------------------------------------------------------------------- -// CType convert a cdecl type into Go type. +// CType convert a C type into Go. func CType(typ types.Type) types.Type { panic("todo") } +// CFuncDecl convert a C function decl into Go signature. +func CFuncDecl(sig *types.Signature) *types.Signature { + panic("todo") +} + // ----------------------------------------------------------------------------- type aType struct { @@ -319,29 +324,29 @@ func (p Program) toLLVMTypes(t *types.Tuple, n int) (ret []llvm.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() - if inC { - hasVArg = HasVArg(tParams, n) - if hasVArg { - n-- + if isDecl || inC { + var tParams = sig.Params() + var n = tParams.Len() + var hasVArg bool + if inC { + hasVArg = HasVArg(tParams, n) + if hasVArg { + n-- + } + } + params := p.toLLVMTypes(tParams, n) + out := sig.Results() + var ret llvm.Type + switch nret := out.Len(); nret { + case 0: + ret = p.tyVoid() + case 1: + ret = p.Type(out.At(0).Type()).ll + default: + ret = p.toLLVMTuple(out) } - } - params := p.toLLVMTypes(tParams, n) - out := sig.Results() - var ret llvm.Type - switch nret := out.Len(); nret { - case 0: - ret = p.tyVoid() - case 1: - ret = p.Type(out.At(0).Type()).ll - default: - ret = p.toLLVMTuple(out) - } - if inC || isDecl { ft = llvm.FunctionType(ret, params, hasVArg) if isDecl { kind = vkFuncDecl